From f3e6ef0fa96e2252e41b7ed6f2c3e88a1560153e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 8 Feb 2018 18:01:53 +0100 Subject: Better validate ZeroExConfig on public networks --- packages/0x.js/src/0x.ts | 5 +++ .../0x.js/src/schemas/zero_ex_config_schema.ts | 24 +-------------- .../zero_ex_private_network_config_schema.ts | 35 +++++++++++++++++++++ .../zero_ex_public_network_config_schema.ts | 29 +++++++++++++++++ packages/0x.js/src/types.ts | 36 ++++++++++++++++------ packages/assert/src/index.ts | 5 +-- 6 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts create mode 100644 packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts index 6cfa65cc2..d024e6097 100644 --- a/packages/0x.js/src/0x.ts +++ b/packages/0x.js/src/0x.ts @@ -13,6 +13,8 @@ import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_pr import { TokenWrapper } from './contract_wrappers/token_wrapper'; import { OrderStateWatcher } from './order_watcher/order_state_watcher'; import { zeroExConfigSchema } from './schemas/zero_ex_config_schema'; +import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema'; +import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema'; import { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types'; import { assert } from './utils/assert'; import { constants } from './utils/constants'; @@ -20,6 +22,9 @@ import { decorators } from './utils/decorators'; import { signatureUtils } from './utils/signature_utils'; import { utils } from './utils/utils'; +assert.schemaValidator.addSchema(zeroExPrivateNetworkConfigSchema); +assert.schemaValidator.addSchema(zeroExPublicNetworkConfigSchema); + /** * The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality * and all calls to the library should be made through a ZeroEx instance. diff --git a/packages/0x.js/src/schemas/zero_ex_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_config_schema.ts index 546b1c2d0..a9c3c64fc 100644 --- a/packages/0x.js/src/schemas/zero_ex_config_schema.ts +++ b/packages/0x.js/src/schemas/zero_ex_config_schema.ts @@ -1,27 +1,5 @@ export const zeroExConfigSchema = { id: '/ZeroExConfig', - properties: { - networkId: { - type: 'number', - minimum: 0, - }, - gasPrice: { $ref: '/Number' }, - exchangeContractAddress: { $ref: '/Address' }, - tokenRegistryContractAddress: { $ref: '/Address' }, - orderWatcherConfig: { - type: 'object', - properties: { - pollingIntervalMs: { - type: 'number', - minimum: 0, - }, - numConfirmations: { - type: 'number', - minimum: 0, - }, - }, - }, - }, + oneOf: [{ $ref: '/ZeroExPrivateNetworkConfig' }, { $ref: '/ZeroExPublicNetworkConfig' }], type: 'object', - required: ['networkId'], }; diff --git a/packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts new file mode 100644 index 000000000..f7f649a6d --- /dev/null +++ b/packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts @@ -0,0 +1,35 @@ +export const zeroExPrivateNetworkConfigSchema = { + id: '/ZeroExPrivateNetworkConfig', + properties: { + networkId: { + type: 'number', + minimum: 1, + }, + gasPrice: { $ref: '/Number' }, + zrxContractAddress: { $ref: '/Address' }, + exchangeContractAddress: { $ref: '/Address' }, + tokenRegistryContractAddress: { $ref: '/Address' }, + tokenTransferProxyContractAddress: { $ref: '/Address' }, + orderWatcherConfig: { + type: 'object', + properties: { + pollingIntervalMs: { + type: 'number', + minimum: 0, + }, + numConfirmations: { + type: 'number', + minimum: 0, + }, + }, + }, + }, + type: 'object', + required: [ + 'networkId', + 'zrxContractAddress', + 'exchangeContractAddress', + 'tokenRegistryContractAddress', + 'tokenTransferProxyContractAddress', + ], +}; diff --git a/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts new file mode 100644 index 000000000..9da31481a --- /dev/null +++ b/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts @@ -0,0 +1,29 @@ +export const zeroExPublicNetworkConfigSchema = { + id: '/ZeroExPublicNetworkConfig', + properties: { + networkId: { + type: 'number', + enum: [1, 3, 4, 42, 50], + }, + gasPrice: { $ref: '/Number' }, + zrxContractAddress: { $ref: '/Address' }, + exchangeContractAddress: { $ref: '/Address' }, + tokenRegistryContractAddress: { $ref: '/Address' }, + tokenTransferProxyContractAddress: { $ref: '/Address' }, + orderWatcherConfig: { + type: 'object', + properties: { + pollingIntervalMs: { + type: 'number', + minimum: 0, + }, + numConfirmations: { + type: 'number', + minimum: 0, + }, + }, + }, + }, + type: 'object', + required: ['networkId'], +}; diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index ab97f7775..f0660391b 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -9,6 +9,10 @@ import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/g import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token'; export enum ZeroExError { + ZRXAddressRequired = 'ZRX_ADDREESS_REQUIRED', + ExchangeAddressRequired = 'EXCHANGE_ADDREESS_REQUIRED', + TokenRegistryAddressRequired = 'TOKEN_REGISTRY_ADDREESS_REQUIRED', + TokenTransferProxyAddressRequired = 'TOKEN_TRANSFER_PROXY_ADDREESS_REQUIRED', ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST', ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST', EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST', @@ -195,8 +199,28 @@ export interface OrderStateWatcherConfig { cleanupJobIntervalMs?: number; } +export interface ZeroExPublicNetworkConfig { + networkId: 1 | 3 | 4 | 42 | 50; + gasPrice?: BigNumber; + exchangeContractAddress?: string; + zrxContractAddress?: string; + tokenRegistryContractAddress?: string; + tokenTransferProxyContractAddress?: string; + orderWatcherConfig?: OrderStateWatcherConfig; +} + +export interface ZeroExPrivateNetworkConfig { + networkId: number; + gasPrice?: BigNumber; + exchangeContractAddress: string; + zrxContractAddress: string; + tokenRegistryContractAddress: string; + tokenTransferProxyContractAddress: string; + orderWatcherConfig?: OrderStateWatcherConfig; +} + /* - * networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 42-kovan, 50-testrpc) + * networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc) * gasPrice: Gas price to use with every transaction * exchangeContractAddress: The address of an exchange contract to use * zrxContractAddress: The address of the ZRX contract to use @@ -204,15 +228,7 @@ export interface OrderStateWatcherConfig { * tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use * orderWatcherConfig: All the configs related to the orderWatcher */ -export interface ZeroExConfig { - networkId: number; - gasPrice?: BigNumber; - exchangeContractAddress?: string; - zrxContractAddress?: string; - tokenRegistryContractAddress?: string; - tokenTransferProxyContractAddress?: string; - orderWatcherConfig?: OrderStateWatcherConfig; -} +export type ZeroExConfig = ZeroExPublicNetworkConfig | ZeroExPrivateNetworkConfig; export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken'; diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts index 7ad574ec7..38b330a46 100644 --- a/packages/assert/src/index.ts +++ b/packages/assert/src/index.ts @@ -4,8 +4,10 @@ import * as _ from 'lodash'; import * as validUrl from 'valid-url'; const HEX_REGEX = /^0x[0-9A-F]*$/i; +const schemaValidator = new SchemaValidator(); export const assert = { + schemaValidator, isBigNumber(variableName: string, value: BigNumber): void { const isBigNumber = _.isObject(value) && (value as any).isBigNumber; this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value)); @@ -67,8 +69,7 @@ export const assert = { this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value)); }, doesConformToSchema(variableName: string, value: any, schema: Schema): void { - const schemaValidator = new SchemaValidator(); - const validationResult = schemaValidator.validate(value, schema); + const validationResult = assert.schemaValidator.validate(value, schema); const hasValidationErrors = validationResult.errors.length > 0; const msg = `Expected ${variableName} to conform to schema ${schema.id} Encountered: ${JSON.stringify(value, null, '\t')} -- cgit From 98b78c56c5fb5fbcbda11da993fb8d88f3b71df8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 9 Feb 2018 10:11:12 +0100 Subject: Add entries to the CHANGELOG --- packages/0x.js/CHANGELOG.md | 4 ++++ packages/0x.js/src/index.ts | 2 ++ packages/0x.js/src/types.ts | 4 ---- packages/assert/CHANGELOG.md | 4 ++++ packages/website/ts/containers/zero_ex_js_documentation.tsx | 2 ++ 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index 0af474c74..57cd381ee 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.33.0 - _TBD, 2018_ + + * Improve validation to force passing contract addresses on private networks (#385) + ## v0.32.2 - _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index 161945443..bb689f6dc 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -16,6 +16,8 @@ export { ContractEventArgs, Web3Provider, ZeroExConfig, + ZeroExPublicNetworkConfig, + ZeroExPrivateNetworkConfig, MethodOpts, OrderTransactionOpts, TransactionOpts, diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index f0660391b..886beeaaa 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -9,10 +9,6 @@ import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/g import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token'; export enum ZeroExError { - ZRXAddressRequired = 'ZRX_ADDREESS_REQUIRED', - ExchangeAddressRequired = 'EXCHANGE_ADDREESS_REQUIRED', - TokenRegistryAddressRequired = 'TOKEN_REGISTRY_ADDREESS_REQUIRED', - TokenTransferProxyAddressRequired = 'TOKEN_TRANSFER_PROXY_ADDREESS_REQUIRED', ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST', ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST', EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST', diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md index 23c2c5e56..ed3577c44 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.1.0 - _TBD, 2018_ + + * Add schemaValidator as a field so that one can add custom schemas (#385) + ## v0.0.18 - _February 9, 2017_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.tsx index 96c8c257d..018b99f8d 100644 --- a/packages/website/ts/containers/zero_ex_js_documentation.tsx +++ b/packages/website/ts/containers/zero_ex_js_documentation.tsx @@ -101,6 +101,8 @@ const docsInfoConfig: DocsInfoConfig = { 'ApprovalContractEventArgs', 'TokenContractEventArgs', 'ZeroExConfig', + 'ZeroExPublicNetworkConfig', + 'ZeroExPrivateNetworkConfig', 'TransactionReceiptWithDecodedLogs', 'LogWithDecodedArgs', 'EtherTokenEvents', -- cgit From 49375c73d474fc844f3ee5b8f49244a33be52638 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 9 Feb 2018 10:33:33 +0100 Subject: Fix tests --- packages/0x.js/src/utils/assert.ts | 2 +- packages/0x.js/test/ether_token_wrapper_test.ts | 11 +++++++---- packages/0x.js/test/expiration_watcher_test.ts | 2 +- packages/0x.js/test/token_wrapper_test.ts | 1 + packages/0x.js/test/utils/constants.ts | 6 +++--- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/0x.js/src/utils/assert.ts b/packages/0x.js/src/utils/assert.ts index c21f2dbca..f81e02f78 100644 --- a/packages/0x.js/src/utils/assert.ts +++ b/packages/0x.js/src/utils/assert.ts @@ -1,7 +1,7 @@ import { assert as sharedAssert } from '@0xproject/assert'; // We need those two unused imports because they're actually used by sharedAssert which gets injected here // tslint:disable-next-line:no-unused-variable -import { Schema } from '@0xproject/json-schemas'; +import { Schema, SchemaValidator } from '@0xproject/json-schemas'; // tslint:disable-next-line:no-unused-variable import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts index da49ec467..72086dff0 100644 --- a/packages/0x.js/test/ether_token_wrapper_test.ts +++ b/packages/0x.js/test/ether_token_wrapper_test.ts @@ -75,11 +75,14 @@ describe('EtherTokenWrapper', () => { const contractAddressIfExists = zeroEx.etherToken.getContractAddressIfExists(); expect(contractAddressIfExists).to.not.be.undefined(); }); - it('should return undefined if connected to an unknown network', () => { + it('should throw if connected to a private network and contract addresses are not specified', () => { const UNKNOWN_NETWORK_NETWORK_ID = 10; - const unknownNetworkZeroEx = new ZeroEx(web3.currentProvider, { networkId: UNKNOWN_NETWORK_NETWORK_ID }); - const contractAddressIfExists = unknownNetworkZeroEx.etherToken.getContractAddressIfExists(); - expect(contractAddressIfExists).to.be.undefined(); + expect( + () => + new ZeroEx(web3.currentProvider, { + networkId: UNKNOWN_NETWORK_NETWORK_ID, + } as any), + ).to.throw(); }); }); describe('#depositAsync', () => { diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts index b49dee8e5..7f79e3802 100644 --- a/packages/0x.js/test/expiration_watcher_test.ts +++ b/packages/0x.js/test/expiration_watcher_test.ts @@ -9,10 +9,10 @@ import * as Web3 from 'web3'; import { ZeroEx } from '../src/0x'; import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher'; import { DoneCallback, Token } from '../src/types'; -import { constants } from '../src/utils/constants'; import { utils } from '../src/utils/utils'; import { chaiSetup } from './utils/chai_setup'; +import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; import { reportNoErrorCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index 34ebe30c2..6ecad4ccf 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -15,6 +15,7 @@ import { TransferContractEventArgs, ZeroEx, ZeroExError, + ZeroExPublicNetworkConfig, } from '../src'; import { DoneCallback } from '../src/types'; diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts index cf030259c..bd7841feb 100644 --- a/packages/0x.js/test/utils/constants.ts +++ b/packages/0x.js/test/utils/constants.ts @@ -1,8 +1,8 @@ export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - ROPSTEN_NETWORK_ID: 3, - KOVAN_NETWORK_ID: 42, - TESTRPC_NETWORK_ID: 50, + ROPSTEN_NETWORK_ID: 3 as 3, + KOVAN_NETWORK_ID: 42 as 42, + TESTRPC_NETWORK_ID: 50 as 50, KOVAN_RPC_URL: 'https://kovan.infura.io/', ROPSTEN_RPC_URL: 'https://ropsten.infura.io/', ZRX_DECIMALS: 18, -- cgit From b53a1b51d6b7e6ec768b974f656329599585bee6 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 9 Feb 2018 10:47:41 +0100 Subject: Add type cast --- packages/contracts/util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/util/constants.ts b/packages/contracts/util/constants.ts index e61b2f802..0d46ad67f 100644 --- a/packages/contracts/util/constants.ts +++ b/packages/contracts/util/constants.ts @@ -2,7 +2,7 @@ export const constants = { NULL_BYTES: '0x', INVALID_OPCODE: 'invalid opcode', REVERT: 'revert', - TESTRPC_NETWORK_ID: 50, + TESTRPC_NETWORK_ID: 50 as 50, MAX_ETHERTOKEN_WITHDRAW_GAS: 43000, MAX_TOKEN_TRANSFERFROM_GAS: 80000, MAX_TOKEN_APPROVE_GAS: 60000, -- cgit From 4d482438f554b50f3a5097d30ca37967b7aca994 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 14 Feb 2018 11:24:42 -0800 Subject: Access property over this --- packages/assert/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts index 38b330a46..383cc2c42 100644 --- a/packages/assert/src/index.ts +++ b/packages/assert/src/index.ts @@ -69,7 +69,7 @@ export const assert = { this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value)); }, doesConformToSchema(variableName: string, value: any, schema: Schema): void { - const validationResult = assert.schemaValidator.validate(value, schema); + const validationResult = this.schemaValidator.validate(value, schema); const hasValidationErrors = validationResult.errors.length > 0; const msg = `Expected ${variableName} to conform to schema ${schema.id} Encountered: ${JSON.stringify(value, null, '\t')} -- cgit From db52e877404b8f053bbdea823f1f6afd6eccecd1 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Wed, 14 Feb 2018 15:23:06 -0800 Subject: Remove type-level validation --- packages/0x.js/src/index.ts | 2 -- packages/0x.js/src/types.ts | 30 +++++++--------------- packages/0x.js/test/token_wrapper_test.ts | 1 - packages/0x.js/test/utils/constants.ts | 6 ++--- .../ts/containers/zero_ex_js_documentation.tsx | 2 -- 5 files changed, 12 insertions(+), 29 deletions(-) diff --git a/packages/0x.js/src/index.ts b/packages/0x.js/src/index.ts index bb689f6dc..161945443 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -16,8 +16,6 @@ export { ContractEventArgs, Web3Provider, ZeroExConfig, - ZeroExPublicNetworkConfig, - ZeroExPrivateNetworkConfig, MethodOpts, OrderTransactionOpts, TransactionOpts, diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index 886beeaaa..0a3037258 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -195,26 +195,6 @@ export interface OrderStateWatcherConfig { cleanupJobIntervalMs?: number; } -export interface ZeroExPublicNetworkConfig { - networkId: 1 | 3 | 4 | 42 | 50; - gasPrice?: BigNumber; - exchangeContractAddress?: string; - zrxContractAddress?: string; - tokenRegistryContractAddress?: string; - tokenTransferProxyContractAddress?: string; - orderWatcherConfig?: OrderStateWatcherConfig; -} - -export interface ZeroExPrivateNetworkConfig { - networkId: number; - gasPrice?: BigNumber; - exchangeContractAddress: string; - zrxContractAddress: string; - tokenRegistryContractAddress: string; - tokenTransferProxyContractAddress: string; - orderWatcherConfig?: OrderStateWatcherConfig; -} - /* * networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc) * gasPrice: Gas price to use with every transaction @@ -224,7 +204,15 @@ export interface ZeroExPrivateNetworkConfig { * tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use * orderWatcherConfig: All the configs related to the orderWatcher */ -export type ZeroExConfig = ZeroExPublicNetworkConfig | ZeroExPrivateNetworkConfig; +export interface ZeroExConfig { + networkId: number; + gasPrice?: BigNumber; + exchangeContractAddress?: string; + zrxContractAddress?: string; + tokenRegistryContractAddress?: string; + tokenTransferProxyContractAddress?: string; + orderWatcherConfig?: OrderStateWatcherConfig; +} export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken'; diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index 6ecad4ccf..34ebe30c2 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -15,7 +15,6 @@ import { TransferContractEventArgs, ZeroEx, ZeroExError, - ZeroExPublicNetworkConfig, } from '../src'; import { DoneCallback } from '../src/types'; diff --git a/packages/0x.js/test/utils/constants.ts b/packages/0x.js/test/utils/constants.ts index bd7841feb..cf030259c 100644 --- a/packages/0x.js/test/utils/constants.ts +++ b/packages/0x.js/test/utils/constants.ts @@ -1,8 +1,8 @@ export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - ROPSTEN_NETWORK_ID: 3 as 3, - KOVAN_NETWORK_ID: 42 as 42, - TESTRPC_NETWORK_ID: 50 as 50, + ROPSTEN_NETWORK_ID: 3, + KOVAN_NETWORK_ID: 42, + TESTRPC_NETWORK_ID: 50, KOVAN_RPC_URL: 'https://kovan.infura.io/', ROPSTEN_RPC_URL: 'https://ropsten.infura.io/', ZRX_DECIMALS: 18, diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.tsx index 018b99f8d..96c8c257d 100644 --- a/packages/website/ts/containers/zero_ex_js_documentation.tsx +++ b/packages/website/ts/containers/zero_ex_js_documentation.tsx @@ -101,8 +101,6 @@ const docsInfoConfig: DocsInfoConfig = { 'ApprovalContractEventArgs', 'TokenContractEventArgs', 'ZeroExConfig', - 'ZeroExPublicNetworkConfig', - 'ZeroExPrivateNetworkConfig', 'TransactionReceiptWithDecodedLogs', 'LogWithDecodedArgs', 'EtherTokenEvents', -- cgit From fe9e319a6136d4be4fa94287ad709a127c548750 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 20 Feb 2018 11:34:29 -0800 Subject: Remove a type assertion --- packages/contracts/util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/util/constants.ts b/packages/contracts/util/constants.ts index 0d46ad67f..e61b2f802 100644 --- a/packages/contracts/util/constants.ts +++ b/packages/contracts/util/constants.ts @@ -2,7 +2,7 @@ export const constants = { NULL_BYTES: '0x', INVALID_OPCODE: 'invalid opcode', REVERT: 'revert', - TESTRPC_NETWORK_ID: 50 as 50, + TESTRPC_NETWORK_ID: 50, MAX_ETHERTOKEN_WITHDRAW_GAS: 43000, MAX_TOKEN_TRANSFERFROM_GAS: 80000, MAX_TOKEN_APPROVE_GAS: 60000, -- cgit From 7b67afae06c93290e6d8c4a4f0de2435f31ae714 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 20 Feb 2018 11:39:36 -0800 Subject: Change assert.doesConformToShema interface --- packages/0x.js/src/0x.ts | 8 ++++---- packages/assert/src/index.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts index d024e6097..c578478d8 100644 --- a/packages/0x.js/src/0x.ts +++ b/packages/0x.js/src/0x.ts @@ -22,9 +22,6 @@ import { decorators } from './utils/decorators'; import { signatureUtils } from './utils/signature_utils'; import { utils } from './utils/utils'; -assert.schemaValidator.addSchema(zeroExPrivateNetworkConfigSchema); -assert.schemaValidator.addSchema(zeroExPublicNetworkConfigSchema); - /** * The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality * and all calls to the library should be made through a ZeroEx instance. @@ -168,7 +165,10 @@ export class ZeroEx { */ constructor(provider: Web3Provider, config: ZeroExConfig) { assert.isWeb3Provider('provider', provider); - assert.doesConformToSchema('config', config, zeroExConfigSchema); + assert.doesConformToSchema('config', config, zeroExConfigSchema, [ + zeroExPrivateNetworkConfigSchema, + zeroExPublicNetworkConfigSchema, + ]); const artifactJSONs = _.values(artifacts); const abiArrays = _.map(artifactJSONs, artifact => artifact.abi); this._abiDecoder = new AbiDecoder(abiArrays); diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts index 383cc2c42..71f2cbeb2 100644 --- a/packages/assert/src/index.ts +++ b/packages/assert/src/index.ts @@ -4,10 +4,8 @@ import * as _ from 'lodash'; import * as validUrl from 'valid-url'; const HEX_REGEX = /^0x[0-9A-F]*$/i; -const schemaValidator = new SchemaValidator(); export const assert = { - schemaValidator, isBigNumber(variableName: string, value: BigNumber): void { const isBigNumber = _.isObject(value) && (value as any).isBigNumber; this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value)); @@ -68,8 +66,10 @@ export const assert = { const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync); this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value)); }, - doesConformToSchema(variableName: string, value: any, schema: Schema): void { - const validationResult = this.schemaValidator.validate(value, schema); + doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void { + const schemaValidator = new SchemaValidator(); + _.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator)); + const validationResult = schemaValidator.validate(value, schema); const hasValidationErrors = validationResult.errors.length > 0; const msg = `Expected ${variableName} to conform to schema ${schema.id} Encountered: ${JSON.stringify(value, null, '\t')} -- cgit From 0fb81a11a87eb24f82d459375803904e7795e6a4 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 20 Feb 2018 12:03:21 -0800 Subject: Remove unused import --- packages/0x.js/src/utils/assert.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/0x.js/src/utils/assert.ts b/packages/0x.js/src/utils/assert.ts index f81e02f78..c21f2dbca 100644 --- a/packages/0x.js/src/utils/assert.ts +++ b/packages/0x.js/src/utils/assert.ts @@ -1,7 +1,7 @@ import { assert as sharedAssert } from '@0xproject/assert'; // We need those two unused imports because they're actually used by sharedAssert which gets injected here // tslint:disable-next-line:no-unused-variable -import { Schema, SchemaValidator } from '@0xproject/json-schemas'; +import { Schema } from '@0xproject/json-schemas'; // tslint:disable-next-line:no-unused-variable import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; -- cgit From c85c14210fb3af93733430328d07b46007c84da1 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 20 Feb 2018 12:03:33 -0800 Subject: Remove unused CHANGELOG entry --- packages/assert/CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md index ed3577c44..23c2c5e56 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -1,9 +1,5 @@ # CHANGELOG -## v0.1.0 - _TBD, 2018_ - - * Add schemaValidator as a field so that one can add custom schemas (#385) - ## v0.0.18 - _February 9, 2017_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) -- cgit From 3120d854f855a01ad7bce3427a64d931de1879d3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 20 Feb 2018 12:09:39 -0800 Subject: Update CHANGELOG --- packages/assert/CHANGELOG.md | 4 ++++ packages/assert/src/index.ts | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md index 23c2c5e56..f512f7b10 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.1.0 - _TBD, 2018_ + + * Add an optional parameter `subSchemas` to `doesConformToSchema` method (#385) + ## v0.0.18 - _February 9, 2017_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts index 71f2cbeb2..4d090e493 100644 --- a/packages/assert/src/index.ts +++ b/packages/assert/src/index.ts @@ -68,7 +68,9 @@ export const assert = { }, doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void { const schemaValidator = new SchemaValidator(); - _.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator)); + if (!_.isUndefined(subSchemas)) { + _.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator)); + } const validationResult = schemaValidator.validate(value, schema); const hasValidationErrors = validationResult.errors.length > 0; const msg = `Expected ${variableName} to conform to schema ${schema.id} -- cgit From 66b36f6d8f7c0f0487e53badb035ac50e1ec5669 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Wed, 21 Feb 2018 16:34:14 -0800 Subject: Begin refactoring out doc generator template --- .../ts/containers/connect_documentation.tsx | 8 +- .../containers/smart_contracts_documentation.tsx | 8 +- .../ts/containers/zero_ex_js_documentation.tsx | 8 +- .../website/ts/pages/documentation/doc_page.tsx | 107 +++++++++++++++++ .../ts/pages/documentation/documentation.tsx | 126 ++++++--------------- 5 files changed, 151 insertions(+), 106 deletions(-) create mode 100644 packages/website/ts/pages/documentation/doc_page.tsx diff --git a/packages/website/ts/containers/connect_documentation.tsx b/packages/website/ts/containers/connect_documentation.tsx index 2488329dd..bff8db35d 100644 --- a/packages/website/ts/containers/connect_documentation.tsx +++ b/packages/website/ts/containers/connect_documentation.tsx @@ -2,8 +2,8 @@ import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; +import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation'; import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; import { DocsInfoConfig, Environments, WebsitePaths } from 'ts/types'; @@ -91,7 +91,7 @@ interface ConnectedDispatch { dispatcher: Dispatcher; } -const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({ +const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({ docsVersion: state.docsVersion, availableDocVersions: state.availableDocVersions, translate: state.translate, @@ -102,6 +102,6 @@ const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ dispatcher: new Dispatcher(dispatch), }); -export const Documentation: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( - DocumentationComponent, +export const Documentation: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( + DocPageComponent, ); diff --git a/packages/website/ts/containers/smart_contracts_documentation.tsx b/packages/website/ts/containers/smart_contracts_documentation.tsx index c4731f929..caf57f1c2 100644 --- a/packages/website/ts/containers/smart_contracts_documentation.tsx +++ b/packages/website/ts/containers/smart_contracts_documentation.tsx @@ -2,8 +2,8 @@ import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; +import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation'; import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; import { DocsInfoConfig, SmartContractDocSections as Sections, WebsitePaths } from 'ts/types'; @@ -49,7 +49,7 @@ interface ConnectedDispatch { docsInfo: DocsInfo; } -const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({ +const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({ docsVersion: state.docsVersion, availableDocVersions: state.availableDocVersions, translate: state.translate, @@ -60,6 +60,6 @@ const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ docsInfo, }); -export const Documentation: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( - DocumentationComponent, +export const Documentation: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( + DocPageComponent, ); diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.tsx index a32a87f7f..67089d9e3 100644 --- a/packages/website/ts/containers/zero_ex_js_documentation.tsx +++ b/packages/website/ts/containers/zero_ex_js_documentation.tsx @@ -2,8 +2,8 @@ import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; +import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation'; import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; import { DocsInfoConfig, Environments, WebsitePaths } from 'ts/types'; @@ -162,7 +162,7 @@ interface ConnectedDispatch { dispatcher: Dispatcher; } -const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({ +const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({ docsVersion: state.docsVersion, availableDocVersions: state.availableDocVersions, docsInfo, @@ -173,6 +173,6 @@ const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ dispatcher: new Dispatcher(dispatch), }); -export const Documentation: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( - DocumentationComponent, +export const Documentation: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( + DocPageComponent, ); diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx new file mode 100644 index 000000000..7d81ca1d5 --- /dev/null +++ b/packages/website/ts/pages/documentation/doc_page.tsx @@ -0,0 +1,107 @@ +import findVersions = require('find-versions'); +import * as _ from 'lodash'; +import * as React from 'react'; +import DocumentTitle = require('react-document-title'); +import semverSort = require('semver-sort'); +import { TopBar } from 'ts/components/top_bar/top_bar'; +import { DocsInfo } from 'ts/pages/documentation/docs_info'; +import { Documentation } from 'ts/pages/documentation/documentation'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { DocAgnosticFormat, DoxityDocObj, MenuSubsectionsBySection } from 'ts/types'; +import { docUtils } from 'ts/utils/doc_utils'; +import { Translate } from 'ts/utils/translate'; + +export interface DocPageProps { + location: Location; + dispatcher: Dispatcher; + docsVersion: string; + availableDocVersions: string[]; + docsInfo: DocsInfo; + translate: Translate; +} + +interface DocPageState { + docAgnosticFormat?: DocAgnosticFormat; +} + +export class DocPage extends React.Component { + private _isUnmounted: boolean; + constructor(props: DocPageProps) { + super(props); + this._isUnmounted = false; + this.state = { + docAgnosticFormat: undefined, + }; + } + public componentWillMount() { + const pathName = this.props.location.pathname; + const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1); + const versions = findVersions(lastSegment); + const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined; + // tslint:disable-next-line:no-floating-promises + this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists); + } + public componentWillUnmount() { + this._isUnmounted = true; + } + + public render() { + const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat) + ? {} + : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat); + return ( +
+ + + +
+ ); + } + private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise { + const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot); + const versions = _.keys(versionToFileName); + this.props.dispatcher.updateAvailableDocVersions(versions); + const sortedVersions = semverSort.desc(versions); + const latestVersion = sortedVersions[0]; + + let versionToFetch = latestVersion; + if (!_.isUndefined(preferredVersionIfExists)) { + const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists]; + if (!_.isUndefined(preferredVersionFileNameIfExists)) { + versionToFetch = preferredVersionIfExists; + } + } + this.props.dispatcher.updateCurrentDocsVersion(versionToFetch); + + const versionFileNameToFetch = versionToFileName[versionToFetch]; + const versionDocObj = await docUtils.getJSONDocFileAsync( + versionFileNameToFetch, + this.props.docsInfo.docsJsonRoot, + ); + const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj); + + if (!this._isUnmounted) { + this.setState({ + docAgnosticFormat, + }); + } + } +} diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx index 285471166..17cb41069 100644 --- a/packages/website/ts/pages/documentation/documentation.tsx +++ b/packages/website/ts/pages/documentation/documentation.tsx @@ -1,11 +1,7 @@ -import findVersions = require('find-versions'); import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import * as React from 'react'; -import DocumentTitle = require('react-document-title'); import { scroller } from 'react-scroll'; -import semverSort = require('semver-sort'); -import { TopBar } from 'ts/components/top_bar/top_bar'; import { Badge } from 'ts/components/ui/badge'; import { Comment } from 'ts/pages/documentation/comment'; import { DocsInfo } from 'ts/pages/documentation/docs_info'; @@ -24,6 +20,7 @@ import { DoxityDocObj, EtherscanLinkSuffixes, Event, + MenuSubsectionsBySection, Networks, Property, SolidityMethod, @@ -34,7 +31,6 @@ import { import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; -import { docUtils } from 'ts/utils/doc_utils'; import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; @@ -48,20 +44,19 @@ const networkNameToColor: { [network: string]: string } = { [Networks.Rinkeby]: colors.darkYellow, }; -export interface DocumentationAllProps { - source: string; +export interface DocumentationProps { location: Location; dispatcher: Dispatcher; docsVersion: string; availableDocVersions: string[]; docsInfo: DocsInfo; translate: Translate; -} - -interface DocumentationState { docAgnosticFormat?: DocAgnosticFormat; + menuSubsectionsBySection: MenuSubsectionsBySection; } +interface DocumentationState {} + const styles: Styles = { mainContainers: { position: 'absolute', @@ -81,57 +76,17 @@ const styles: Styles = { }, }; -export class Documentation extends React.Component { - private _isUnmounted: boolean; - constructor(props: DocumentationAllProps) { - super(props); - this._isUnmounted = false; - this.state = { - docAgnosticFormat: undefined, - }; - } - public componentWillMount() { - const pathName = this.props.location.pathname; - const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1); - const versions = findVersions(lastSegment); - const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined; - // tslint:disable-next-line:no-floating-promises - this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists); - } - public componentWillUnmount() { - this._isUnmounted = true; +export class Documentation extends React.Component { + public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) { + if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) { + this._scrollToHash(); + } } public render() { - const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat) - ? {} - : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat); return (
- - - {_.isUndefined(this.state.docAgnosticFormat) ? ( -
-
-
- -
-
- Loading documentation... -
-
-
+ {_.isUndefined(this.props.docAgnosticFormat) ? ( + this._renderLoading() ) : (
@@ -175,11 +130,28 @@ export class Documentation extends React.Component ); } + private _renderLoading() { + return ( +
+
+
+ +
+
+ Loading documentation... +
+
+
+ ); + } private _renderDocumentation(): React.ReactNode { const subMenus = _.values(this.props.docsInfo.getMenu()); const orderedSectionNames = _.flatten(subMenus); - const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat); + const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat); const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName)); return renderedSections; @@ -196,7 +168,7 @@ export class Documentation extends React.Component { - const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot); - const versions = _.keys(versionToFileName); - this.props.dispatcher.updateAvailableDocVersions(versions); - const sortedVersions = semverSort.desc(versions); - const latestVersion = sortedVersions[0]; - - let versionToFetch = latestVersion; - if (!_.isUndefined(preferredVersionIfExists)) { - const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists]; - if (!_.isUndefined(preferredVersionFileNameIfExists)) { - versionToFetch = preferredVersionIfExists; - } - } - this.props.dispatcher.updateCurrentDocsVersion(versionToFetch); - - const versionFileNameToFetch = versionToFileName[versionToFetch]; - const versionDocObj = await docUtils.getJSONDocFileAsync( - versionFileNameToFetch, - this.props.docsInfo.docsJsonRoot, - ); - const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj); - - if (!this._isUnmounted) { - this.setState( - { - docAgnosticFormat, - }, - () => { - this._scrollToHash(); - }, - ); - } - } } -- cgit From 93adee36b095b0dc7bed442e7cb9a3b022f29da0 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 22 Feb 2018 00:35:16 -0800 Subject: Move all dependencies on @0xproject/types out of devDependencies --- packages/contracts/package.json | 2 +- packages/dev-utils/package.json | 2 +- packages/subproviders/package.json | 2 +- packages/utils/package.json | 2 +- packages/web3-wrapper/package.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 6655df86f..0a3a6fc84 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -38,7 +38,6 @@ "devDependencies": { "@0xproject/dev-utils": "^0.1.0", "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", "@types/bluebird": "^3.5.3", "@types/lodash": "^4.14.86", "@types/node": "^8.0.53", @@ -66,6 +65,7 @@ "0x.js": "^0.32.4", "@0xproject/deployer": "^0.1.0", "@0xproject/json-schemas": "^0.7.12", + "@0xproject/types": "^0.2.3", "@0xproject/utils": "^0.3.4", "@0xproject/web3-wrapper": "^0.1.14", "bluebird": "^3.5.0", diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 515edc353..dc6410211 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -24,7 +24,6 @@ "homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md", "devDependencies": { "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", "@0xproject/web3-wrapper": "^0.1.14", "@types/lodash": "^4.14.86", "@types/mocha": "^2.2.42", @@ -40,6 +39,7 @@ }, "dependencies": { "@0xproject/subproviders": "^0.5.0", + "@0xproject/types": "^0.2.3", "@0xproject/utils": "^0.3.4", "ethereumjs-util": "^5.1.2", "lodash": "^4.17.4", diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 0c791b80f..5e9c2ed89 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "@0xproject/assert": "^0.0.20", + "@0xproject/types": "^0.2.3", "@0xproject/utils": "^0.3.4", "bn.js": "^4.11.8", "es6-promisify": "^5.0.0", @@ -33,7 +34,6 @@ }, "devDependencies": { "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", "@0xproject/utils": "^0.3.4", "@types/lodash": "^4.14.86", "@types/mocha": "^2.2.42", diff --git a/packages/utils/package.json b/packages/utils/package.json index 750ecaa2f..14ccabcf4 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -21,7 +21,6 @@ "homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md", "devDependencies": { "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", "@types/lodash": "^4.14.86", "npm-run-all": "^4.1.2", "shx": "^0.2.2", @@ -30,6 +29,7 @@ "web3-typescript-typings": "^0.9.11" }, "dependencies": { + "@0xproject/types": "^0.2.3", "bignumber.js": "~4.1.0", "js-sha3": "^0.7.0", "lodash": "^4.17.4", diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index 8e861b1d5..8f87bb118 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -21,7 +21,6 @@ "homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md", "devDependencies": { "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", "@types/lodash": "^4.14.86", "npm-run-all": "^4.1.2", "shx": "^0.2.2", @@ -30,6 +29,7 @@ "web3-typescript-typings": "^0.9.11" }, "dependencies": { + "@0xproject/types": "^0.2.3", "@0xproject/utils": "^0.3.4", "lodash": "^4.17.4", "web3": "^0.20.0" -- cgit From 3d2c5d67afb6a754ed7a0b883ff93bf330660eff Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 22 Feb 2018 16:32:19 -0800 Subject: Fix Russian translation --- packages/website/translations/russian.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/translations/russian.json b/packages/website/translations/russian.json index a4e47264b..c103960c0 100644 --- a/packages/website/translations/russian.json +++ b/packages/website/translations/russian.json @@ -3,7 +3,7 @@ "TOP_TAGLINE": "0x — это протокол с открытым кодом, позволяющий торговать токенами ERC20, на блокчейне Ethereum.", "BUILD_CALL_TO_ACTION": "Разрабатывайте на 0x", "COMMUNITY_CALL_TO_ACTION": "Сообщество", - "PROJECTS_HEADER": "Прожкты разработанные на 0х", + "PROJECTS_HEADER": "Проекты разработанные на 0х", "FULL_LIST_PROMPT": "Просмотреть", "FULL_LIST_LINK": "полный список", "TOKENIZED_SECTION_HEADER": "Сегодняшний мир движется к токенизации ценности", -- cgit From 31f9a848f90fa53d5d3817fe6cfb668a44919ef6 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 6 Feb 2018 15:06:56 -0800 Subject: Lowercase public addresses Normalize the public api addresses to lowercase to prevent an avoidable error --- packages/0x.js/src/0x.ts | 15 ++- .../src/contract_wrappers/ether_token_wrapper.ts | 37 ++++-- .../src/contract_wrappers/exchange_wrapper.ts | 52 +++++--- .../contract_wrappers/token_registry_wrapper.ts | 5 +- .../token_transfer_proxy_wrapper.ts | 7 +- .../0x.js/src/contract_wrappers/token_wrapper.ts | 145 ++++++++++++++------- 6 files changed, 172 insertions(+), 89 deletions(-) diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts index 6cfa65cc2..c37b3e1ef 100644 --- a/packages/0x.js/src/0x.ts +++ b/packages/0x.js/src/0x.ts @@ -71,11 +71,12 @@ export class ZeroEx { * @return Whether the signature is valid for the supplied signerAddress and data. */ public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean { + const normalizedSignerAddress = signerAddress.toLowerCase(); assert.isHexString('data', data); assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema); - assert.isETHAddressHex('signerAddress', signerAddress); + assert.isETHAddressHex('signerAddress', normalizedSignerAddress); - const isValidSignature = signatureUtils.isValidSignature(data, signature, signerAddress); + const isValidSignature = signatureUtils.isValidSignature(data, signature, normalizedSignerAddress); return isValidSignature; } /** @@ -244,7 +245,9 @@ export class ZeroEx { shouldAddPersonalMessagePrefix: boolean, ): Promise { assert.isHexString('orderHash', orderHash); - await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper); + const normalizedSignerAddress = signerAddress.toLowerCase(); + assert.isETHAddressHex('signerAddress', normalizedSignerAddress); + await assert.isSenderAddressAsync('signerAddress', normalizedSignerAddress, this._web3Wrapper); let msgHashHex = orderHash; if (shouldAddPersonalMessagePrefix) { @@ -253,7 +256,7 @@ export class ZeroEx { msgHashHex = ethUtil.bufferToHex(msgHashBuff); } - const signature = await this._web3Wrapper.signTransactionAsync(signerAddress, msgHashHex); + const signature = await this._web3Wrapper.signTransactionAsync(normalizedSignerAddress, msgHashHex); // HACK: There is no consensus on whether the signatureHex string should be formatted as // v + r + s OR r + s + v, and different clients (even different versions of the same client) @@ -262,7 +265,7 @@ export class ZeroEx { const validVParamValues = [27, 28]; const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature); if (_.includes(validVParamValues, ecSignatureVRS.v)) { - const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, signerAddress); + const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress); if (isValidVRSSignature) { return ecSignatureVRS; } @@ -270,7 +273,7 @@ export class ZeroEx { const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature); if (_.includes(validVParamValues, ecSignatureRSV.v)) { - const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, signerAddress); + const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress); if (isValidRSVSignature) { return ecSignatureRSV; } diff --git a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts index db7cdee43..236b2be4f 100644 --- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts @@ -41,15 +41,19 @@ export class EtherTokenWrapper extends ContractWrapper { depositor: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedDepositorAddress = depositor.toLowerCase(); + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + assert.isETHAddressHex('depositor', normalizedDepositorAddress); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.isValidBaseUnitAmount('amountInWei', amountInWei); - await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper); + await assert.isSenderAddressAsync('depositor', normalizedDepositorAddress, this._web3Wrapper); - const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor); + const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(normalizedDepositorAddress); assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit); - const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress); + const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); const txHash = await wethContract.deposit.sendTransactionAsync({ - from: depositor, + from: normalizedDepositorAddress, value: amountInWei, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, @@ -71,15 +75,22 @@ export class EtherTokenWrapper extends ContractWrapper { withdrawer: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + const normalizedWithdrawerAddress = withdrawer.toLowerCase(); + assert.isETHAddressHex('withdrawer', normalizedWithdrawerAddress); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.isValidBaseUnitAmount('amountInWei', amountInWei); - await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper); + await assert.isSenderAddressAsync('withdrawer', normalizedWithdrawerAddress, this._web3Wrapper); - const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer); + const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync( + normalizedEtherTokenAddress, + normalizedWithdrawerAddress, + ); assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal); - const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress); + const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, { - from: withdrawer, + from: normalizedWithdrawerAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }); @@ -100,12 +111,13 @@ export class EtherTokenWrapper extends ContractWrapper { blockRange: BlockRange, indexFilterValues: IndexedFilterValues, ): Promise>> { - assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const logs = await this._getLogsAsync( - etherTokenAddress, + normalizedEtherTokenAddress, eventName, blockRange, indexFilterValues, @@ -128,12 +140,13 @@ export class EtherTokenWrapper extends ContractWrapper { indexFilterValues: IndexedFilterValues, callback: EventCallback, ): string { - assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); const subscriptionToken = this._subscribe( - etherTokenAddress, + normalizedEtherTokenAddress, eventName, indexFilterValues, artifacts.EtherTokenArtifact.abi, diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index c82b7ecf5..71f0618f0 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -179,7 +179,9 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const exchangeInstance = await this._getExchangeContractAsync(); const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) @@ -192,7 +194,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -208,7 +210,7 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder.ecSignature.r, signedOrder.ecSignature.s, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -253,7 +255,9 @@ export class ExchangeWrapper extends ContractWrapper { ); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ? SHOULD_VALIDATE_BY_DEFAULT @@ -267,7 +271,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, signedOrder, fillTakerTokenAmount.minus(filledTakerTokenAmount), - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount); @@ -301,7 +305,7 @@ export class ExchangeWrapper extends ContractWrapper { rArray, sArray, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -344,7 +348,9 @@ export class ExchangeWrapper extends ContractWrapper { ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, ); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ? SHOULD_VALIDATE_BY_DEFAULT : orderTransactionOpts.shouldValidate; @@ -356,7 +362,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -389,7 +395,7 @@ export class ExchangeWrapper extends ContractWrapper { rArray, sArray, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -416,7 +422,9 @@ export class ExchangeWrapper extends ContractWrapper { ): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const exchangeInstance = await this._getExchangeContractAsync(); @@ -430,7 +438,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -444,7 +452,7 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder.ecSignature.r, signedOrder.ecSignature.s, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -475,7 +483,9 @@ export class ExchangeWrapper extends ContractWrapper { exchangeContractAddresses, ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, ); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); if (_.isEmpty(orderFillRequests)) { throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); } @@ -492,7 +502,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -520,7 +530,7 @@ export class ExchangeWrapper extends ContractWrapper { rParams, sParams, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -756,14 +766,16 @@ export class ExchangeWrapper extends ContractWrapper { ): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const zrxTokenAddress = this.getZRXTokenAddress(); const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -802,14 +814,16 @@ export class ExchangeWrapper extends ContractWrapper { ): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const zrxTokenAddress = this.getZRXTokenAddress(); const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } diff --git a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts index f54aaf0f8..508ff15d7 100644 --- a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts @@ -57,10 +57,11 @@ export class TokenRegistryWrapper extends ContractWrapper { * @return An object that conforms to the Token interface or undefined if token not found. */ public async getTokenIfExistsAsync(address: string): Promise { - assert.isETHAddressHex('address', address); + const normalizedAddress = address.toLowerCase(); + assert.isETHAddressHex('address', normalizedAddress); const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address); + const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress); const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); return token; } diff --git a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts index f5d9d108a..41afd2f67 100644 --- a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts @@ -2,6 +2,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; +import { assert } from '../utils/assert'; import { ContractWrapper } from './contract_wrapper'; import { TokenTransferProxyContract } from './generated/token_transfer_proxy'; @@ -22,8 +23,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper { * @return Whether the exchangeContractAddress is authorized. */ public async isAuthorizedAsync(exchangeContractAddress: string): Promise { + const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); + assert.isETHAddressHex('exchangeContractAddress', normalizedExchangeContractAddress); const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync(); - const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(exchangeContractAddress); + const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync( + normalizedExchangeContractAddress, + ); return isAuthorized; } /** diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts index a018006b8..61da8c6ef 100644 --- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts @@ -44,12 +44,14 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts?: MethodOpts, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let balance = await tokenContract.balanceOf.callAsync(ownerAddress, defaultBlock); + let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, defaultBlock); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber balance = new BigNumber(balance); return balance; @@ -72,14 +74,17 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper); - assert.isETHAddressHex('spenderAddress', spenderAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); + await assert.isSenderAddressAsync('ownerAddress', normalizedOwnerAddress, this._web3Wrapper); + assert.isETHAddressHex('spenderAddress', normalizedSpenderAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - const tokenContract = await this._getTokenContractAsync(tokenAddress); - const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, { - from: ownerAddress, + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, { + from: normalizedOwnerAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }); @@ -103,10 +108,16 @@ export class TokenWrapper extends ContractWrapper { spenderAddress: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); + assert.isETHAddressHex('spenderAddress', normalizedSpenderAddress); const txHash = await this.setAllowanceAsync( - tokenAddress, - ownerAddress, - spenderAddress, + normalizedTokenAddress, + normalizedOwnerAddress, + normalizedSpenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts, ); @@ -126,12 +137,19 @@ export class TokenWrapper extends ContractWrapper { spenderAddress: string, methodOpts?: MethodOpts, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let allowanceInBaseUnits = await tokenContract.allowance.callAsync(ownerAddress, spenderAddress, defaultBlock); + let allowanceInBaseUnits = await tokenContract.allowance.callAsync( + normalizedOwnerAddress, + normalizedSpenderAddress, + defaultBlock, + ); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits); return allowanceInBaseUnits; @@ -147,11 +165,18 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts?: MethodOpts, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress(); - const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts); + const allowanceInBaseUnits = await this.getAllowanceAsync( + normalizedTokenAddress, + normalizedOwnerAddress, + proxyAddress, + methodOpts, + ); return allowanceInBaseUnits; } /** @@ -170,14 +195,16 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress(); const txHash = await this.setAllowanceAsync( - tokenAddress, - ownerAddress, + normalizedTokenAddress, + normalizedOwnerAddress, proxyAddress, amountInBaseUnits, txOpts, @@ -200,9 +227,13 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); const txHash = await this.setProxyAllowanceAsync( - tokenAddress, - ownerAddress, + normalizedTokenAddress, + normalizedOwnerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts, ); @@ -224,20 +255,24 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - assert.isETHAddressHex('tokenAddress', tokenAddress); - await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedFromAddress = fromAddress.toLowerCase(); + const normalizedToAddress = toAddress.toLowerCase(); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.isETHAddressHex('toAddress', toAddress); + assert.isETHAddressHex('fromAddress', normalizedFromAddress); + await assert.isSenderAddressAsync('fromAddress', normalizedFromAddress, this._web3Wrapper); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress); + const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress); if (fromAddressBalance.lessThan(amountInBaseUnits)) { throw new Error(ZeroExError.InsufficientBalanceForTransfer); } - const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, { - from: fromAddress, + const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, { + from: normalizedFromAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }); @@ -265,30 +300,39 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isETHAddressHex('fromAddress', fromAddress); - assert.isETHAddressHex('toAddress', toAddress); - await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + const normalizedToAddress = toAddress.toLowerCase(); + const normalizedFromAddress = fromAddress.toLowerCase(); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedSenderAddress = senderAddress.toLowerCase(); + assert.isETHAddressHex('toAddress', normalizedToAddress); + assert.isETHAddressHex('fromAddress', normalizedFromAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); + assert.isETHAddressHex('senderAddress', normalizedSenderAddress); + await assert.isSenderAddressAsync('senderAddress', normalizedSenderAddress, this._web3Wrapper); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress); + const fromAddressAllowance = await this.getAllowanceAsync( + normalizedTokenAddress, + normalizedFromAddress, + normalizedSenderAddress, + ); if (fromAddressAllowance.lessThan(amountInBaseUnits)) { throw new Error(ZeroExError.InsufficientAllowanceForTransfer); } - const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress); + const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress); if (fromAddressBalance.lessThan(amountInBaseUnits)) { throw new Error(ZeroExError.InsufficientBalanceForTransfer); } const txHash = await tokenContract.transferFrom.sendTransactionAsync( - fromAddress, - toAddress, + normalizedFromAddress, + normalizedToAddress, amountInBaseUnits, { - from: senderAddress, + from: normalizedSenderAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }, @@ -310,12 +354,13 @@ export class TokenWrapper extends ContractWrapper { indexFilterValues: IndexedFilterValues, callback: EventCallback, ): string { - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); const subscriptionToken = this._subscribe( - tokenAddress, + normalizedTokenAddress, eventName, indexFilterValues, artifacts.TokenArtifact.abi, @@ -351,12 +396,13 @@ export class TokenWrapper extends ContractWrapper { blockRange: BlockRange, indexFilterValues: IndexedFilterValues, ): Promise>> { - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const logs = await this._getLogsAsync( - tokenAddress, + normalizedTokenAddress, eventName, blockRange, indexFilterValues, @@ -369,17 +415,18 @@ export class TokenWrapper extends ContractWrapper { this._tokenContractsByAddress = {}; } private async _getTokenContractAsync(tokenAddress: string): Promise { - let tokenContract = this._tokenContractsByAddress[tokenAddress]; + const normalizedTokenAddress = tokenAddress.toLowerCase(); + let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress]; if (!_.isUndefined(tokenContract)) { return tokenContract; } const web3ContractInstance = await this._instantiateContractIfExistsAsync( artifacts.TokenArtifact, - tokenAddress, + normalizedTokenAddress, ); const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults()); tokenContract = contractInstance; - this._tokenContractsByAddress[tokenAddress] = tokenContract; + this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract; return tokenContract; } } -- cgit From f689d335c0c4042e7ecf3e4636db3434d0dcd7a8 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Thu, 22 Feb 2018 18:34:56 -0800 Subject: Check maker is valid address --- packages/0x.js/src/contract_wrappers/exchange_wrapper.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index 71f0618f0..7db13a1ba 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -554,6 +554,8 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesConformToSchema('order', order, schemas.orderSchema); assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount); await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper); + const normalizedMakerAddress = order.maker.toLowerCase(); + assert.isETHAddressHex('order.maker', normalizedMakerAddress); const exchangeInstance = await this._getExchangeContractAsync(); @@ -576,7 +578,7 @@ export class ExchangeWrapper extends ContractWrapper { orderValues, cancelTakerTokenAmount, { - from: order.maker, + from: normalizedMakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -612,7 +614,10 @@ export class ExchangeWrapper extends ContractWrapper { const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker); assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed); const maker = makers[0]; - await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper); + const normalizedMakerAddress = maker.toLowerCase(); + assert.isETHAddressHex('maker', normalizedMakerAddress); + await assert.isSenderAddressAsync('maker', normalizedMakerAddress, this._web3Wrapper); + const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ? SHOULD_VALIDATE_BY_DEFAULT : orderTransactionOpts.shouldValidate; @@ -646,7 +651,7 @@ export class ExchangeWrapper extends ContractWrapper { orderValues, cancelTakerTokenAmounts, { - from: maker, + from: normalizedMakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, -- cgit From 6e43e89b2d6679def241c5014fc08202f74550b2 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 23 Feb 2018 13:48:00 -0800 Subject: re-add google analytics code --- packages/website/public/index.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/website/public/index.html b/packages/website/public/index.html index 75ca9a4ed..c28e4abf4 100644 --- a/packages/website/public/index.html +++ b/packages/website/public/index.html @@ -23,6 +23,18 @@ + + + +