aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonid <logvinov.leon@gmail.com>2017-09-20 20:59:48 +0800
committerGitHub <noreply@github.com>2017-09-20 20:59:48 +0800
commitd424933d70a0a6a210b19960451ef2796844c8d8 (patch)
tree349592a214b320b9a60e2775093639fe9ad6c278
parentfe9f692a4f472e5decbda96aad6afaf98c10d850 (diff)
parent91679caf936d3b3df369b2339c55468b222c9a16 (diff)
downloaddexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.tar
dexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.tar.gz
dexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.tar.bz2
dexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.tar.lz
dexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.tar.xz
dexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.tar.zst
dexon-sol-tools-d424933d70a0a6a210b19960451ef2796844c8d8.zip
Merge pull request #165 from 0xProject/feature/configurable-addresses
Allow users to pass contract addresses as a config
-rw-r--r--CHANGELOG.md8
-rw-r--r--src/0x.ts35
-rw-r--r--src/artifacts/TokenTransferProxy.json128
-rw-r--r--src/contract_wrappers/contract_wrapper.ts5
-rw-r--r--src/contract_wrappers/ether_token_wrapper.ts6
-rw-r--r--src/contract_wrappers/exchange_wrapper.ts12
-rw-r--r--src/contract_wrappers/token_registry_wrapper.ts16
-rw-r--r--src/contract_wrappers/token_transfer_proxy_wrapper.ts9
-rw-r--r--src/contract_wrappers/token_wrapper.ts21
-rw-r--r--src/schemas/zero_ex_config_schema.ts10
-rw-r--r--src/types.ts12
-rw-r--r--test/0x.js_test.ts29
-rw-r--r--test/artifacts_test.ts2
13 files changed, 137 insertions, 156 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bd1f5f34..61031c089 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# CHANGELOG
+v0.16.0 - _September 20, 2017_
+------------------------
+ * Added the ability to specify custom contract addresses to be used with 0x.js (#165)
+ * ZeroExConfig.exchangeContractAddress
+ * ZeroExConfig.tokenRegistryContractAddress
+ * ZeroExConfig.etherTokenContractAddress
+ * Added `zeroEx.tokenRegistry.getContractAddressAsync` (#165)
+
v0.15.0 - _September 8, 2017_
------------------------
* Added the ability to specify a historical `blockNumber` at which to query the blockchain's state when calling a token or exchange method (#161)
diff --git a/src/0x.ts b/src/0x.ts
index 5d5604780..e6fdf68e1 100644
--- a/src/0x.ts
+++ b/src/0x.ts
@@ -32,6 +32,7 @@ import {
TransactionReceiptWithDecodedLogs,
LogWithDecodedArgs,
} from './types';
+import {zeroExConfigSchema} from './schemas/zero_ex_config_schema';
// Customize our BigNumber instances
bigNumberConfigs.configure();
@@ -180,6 +181,9 @@ export class ZeroEx {
*/
constructor(provider: Web3Provider, config?: ZeroExConfig) {
assert.isWeb3Provider('provider', provider);
+ if (!_.isUndefined(config)) {
+ assert.doesConformToSchema('config', config, zeroExConfigSchema);
+ }
if (_.isUndefined((provider as any).sendAsync)) {
// Web3@1.0 provider doesn't support synchronous http requests,
// so it only has an async `send` method, instead of a `send` and `sendAsync` in web3@0.x.x`
@@ -194,11 +198,22 @@ export class ZeroEx {
gasPrice,
};
this._web3Wrapper = new Web3Wrapper(provider, defaults);
- this.token = new TokenWrapper(this._web3Wrapper);
- this.proxy = new TokenTransferProxyWrapper(this._web3Wrapper);
- this.exchange = new ExchangeWrapper(this._web3Wrapper, this.token);
- this.tokenRegistry = new TokenRegistryWrapper(this._web3Wrapper);
- this.etherToken = new EtherTokenWrapper(this._web3Wrapper, this.token);
+ this.token = new TokenWrapper(
+ this._web3Wrapper,
+ this._getTokenTransferProxyAddressAsync.bind(this),
+ );
+ const exchageContractAddressIfExists = _.isUndefined(config) ? undefined : config.exchangeContractAddress;
+ this.exchange = new ExchangeWrapper(this._web3Wrapper, this.token, exchageContractAddressIfExists);
+ this.proxy = new TokenTransferProxyWrapper(
+ this._web3Wrapper,
+ this._getTokenTransferProxyAddressAsync.bind(this),
+ );
+ const tokenRegistryContractAddressIfExists = _.isUndefined(config) ?
+ undefined :
+ config.tokenRegistryContractAddress;
+ this.tokenRegistry = new TokenRegistryWrapper(this._web3Wrapper, tokenRegistryContractAddressIfExists);
+ const etherTokenContractAddressIfExists = _.isUndefined(config) ? undefined : config.etherTokenContractAddress;
+ this.etherToken = new EtherTokenWrapper(this._web3Wrapper, this.token, etherTokenContractAddressIfExists);
}
/**
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
@@ -306,4 +321,14 @@ export class ZeroEx {
});
return txReceiptPromise;
}
+ /*
+ * HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from
+ * an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle.
+ * In order to break this - we create this function here and pass it as a parameter to the `TokenWrapper`
+ * and `ProxyWrapper`.
+ */
+ private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+ const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync();
+ return tokenTransferProxyAddress;
+ }
}
diff --git a/src/artifacts/TokenTransferProxy.json b/src/artifacts/TokenTransferProxy.json
index e3f6f5e51..beeb16cfe 100644
--- a/src/artifacts/TokenTransferProxy.json
+++ b/src/artifacts/TokenTransferProxy.json
@@ -168,131 +168,7 @@
}
],
"unlinked_binary": "0x60606040525b60008054600160a060020a03191633600160a060020a03161790555b5b6106e6806100316000396000f300606060405236156100725763ffffffff60e060020a60003504166315dacbea811461007457806342f1181e146100b3578063494503d4146100d157806370712939146101005780638da5cb5b1461011e578063b91816111461014a578063d39de6e91461017a578063f2fde38b146101e5575bfe5b341561007c57fe5b61009f600160a060020a0360043581169060243581169060443516606435610203565b604080519115158252519081900360200190f35b34156100bb57fe5b6100cf600160a060020a03600435166102ae565b005b34156100d957fe5b6100e4600435610390565b60408051600160a060020a039092168252519081900360200190f35b341561010857fe5b6100cf600160a060020a03600435166103c2565b005b341561012657fe5b6100e461055a565b60408051600160a060020a039092168252519081900360200190f35b341561015257fe5b61009f600160a060020a0360043516610569565b604080519115158252519081900360200190f35b341561018257fe5b61018a61057e565b60408051602080825283518183015283519192839290830191858101910280838382156101d2575b8051825260208311156101d257601f1990920191602091820191016101b2565b5050509050019250505060405180910390f35b34156101ed57fe5b6100cf600160a060020a03600435166105e7565b005b600160a060020a03331660009081526001602052604081205460ff16151561022b5760006000fd5b6040805160006020918201819052825160e060020a6323b872dd028152600160a060020a0388811660048301528781166024830152604482018790529351938916936323b872dd9360648084019491938390030190829087803b151561028d57fe5b6102c65a03f1151561029b57fe5b5050604051519150505b5b949350505050565b60005433600160a060020a039081169116146102ca5760006000fd5b600160a060020a038116600090815260016020526040902054819060ff16156102f35760006000fd5b600160a060020a0382166000908152600160208190526040909120805460ff191682179055600280549091810161032a8382610633565b916000526020600020900160005b81546101009190910a600160a060020a0381810219909216868316918202179092556040513390911692507f94bb87f4c15c4587ff559a7584006fa01ddf9299359be6b512b94527aa961aca90600090a35b5b505b50565b600280548290811061039e57fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b6000805433600160a060020a039081169116146103df5760006000fd5b600160a060020a038216600090815260016020526040902054829060ff1615156104095760006000fd5b600160a060020a0383166000908152600160205260408120805460ff1916905591505b6002548210156105195782600160a060020a031660028381548110151561044f57fe5b906000526020600020900160005b9054906101000a9004600160a060020a0316600160a060020a0316141561050d5760028054600019810190811061049057fe5b906000526020600020900160005b9054906101000a9004600160a060020a03166002838154811015156104bf57fe5b906000526020600020900160005b6101000a815481600160a060020a030219169083600160a060020a0316021790555060016002818180549050039150816105079190610633565b50610519565b5b60019091019061042c565b604051600160a060020a0333811691908516907ff5b347a1e40749dd050f5f07fbdbeb7e3efa9756903044dd29401fd1d4bb4a1c90600090a35b5b505b5050565b600054600160a060020a031681565b60016020526000908152604090205460ff1681565b610586610687565b60028054806020026020016040519081016040528092919081815260200182805480156105dc57602002820191906000526020600020905b8154600160a060020a031681526001909101906020018083116105be575b505050505090505b90565b60005433600160a060020a039081169116146106035760006000fd5b600160a060020a0381161561038d5760008054600160a060020a031916600160a060020a0383161790555b5b5b50565b81548183558181151161055357600083815260209020610553918101908301610699565b5b505050565b81548183558181151161055357600083815260209020610553918101908301610699565b5b505050565b60408051602081019091526000815290565b6105e491905b808211156106b3576000815560010161069f565b5090565b905600a165627a7a72305820d2924957bb88a128789172e164d874fe5445218fc2dde2f5eb265839a1f341a20029",
- "networks": {
- "1": {
- "links": {},
- "events": {
- "0x94bb87f4c15c4587ff559a7584006fa01ddf9299359be6b512b94527aa961aca": {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "target",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "LogAuthorizedAddressAdded",
- "type": "event"
- },
- "0xf5b347a1e40749dd050f5f07fbdbeb7e3efa9756903044dd29401fd1d4bb4a1c": {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "target",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "LogAuthorizedAddressRemoved",
- "type": "event"
- }
- },
- "updated_at": 1502478966000,
- "address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
- },
- "42": {
- "links": {},
- "events": {
- "0x94bb87f4c15c4587ff559a7584006fa01ddf9299359be6b512b94527aa961aca": {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "target",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "LogAuthorizedAddressAdded",
- "type": "event"
- },
- "0xf5b347a1e40749dd050f5f07fbdbeb7e3efa9756903044dd29401fd1d4bb4a1c": {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "target",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "LogAuthorizedAddressRemoved",
- "type": "event"
- }
- },
- "updated_at": 1502391794384,
- "address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
- },
- "50": {
- "links": {},
- "events": {
- "0x94bb87f4c15c4587ff559a7584006fa01ddf9299359be6b512b94527aa961aca": {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "target",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "LogAuthorizedAddressAdded",
- "type": "event"
- },
- "0xf5b347a1e40749dd050f5f07fbdbeb7e3efa9756903044dd29401fd1d4bb4a1c": {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "name": "target",
- "type": "address"
- },
- {
- "indexed": true,
- "name": "caller",
- "type": "address"
- }
- ],
- "name": "LogAuthorizedAddressRemoved",
- "type": "event"
- }
- },
- "updated_at": 1503318938227,
- "address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
- }
- },
+ "networks": {},
"schema_version": "0.0.5",
"updated_at": 1503318938227
-} \ No newline at end of file
+}
diff --git a/src/contract_wrappers/contract_wrapper.ts b/src/contract_wrappers/contract_wrapper.ts
index 4e3fb5029..2a55b53d9 100644
--- a/src/contract_wrappers/contract_wrapper.ts
+++ b/src/contract_wrappers/contract_wrapper.ts
@@ -10,9 +10,10 @@ export class ContractWrapper {
this._web3Wrapper = web3Wrapper;
}
protected async _instantiateContractIfExistsAsync<A extends Web3.ContractInstance>(artifact: Artifact,
- address?: string): Promise<A> {
+ addressIfExists?: string,
+ ): Promise<A> {
const contractInstance =
- await this._web3Wrapper.getContractInstanceFromArtifactAsync<A>(artifact, address);
+ await this._web3Wrapper.getContractInstanceFromArtifactAsync<A>(artifact, addressIfExists);
return contractInstance;
}
}
diff --git a/src/contract_wrappers/ether_token_wrapper.ts b/src/contract_wrappers/ether_token_wrapper.ts
index b86309f90..f15e766f0 100644
--- a/src/contract_wrappers/ether_token_wrapper.ts
+++ b/src/contract_wrappers/ether_token_wrapper.ts
@@ -13,9 +13,11 @@ import {artifacts} from '../artifacts';
export class EtherTokenWrapper extends ContractWrapper {
private _etherTokenContractIfExists?: EtherTokenContract;
private _tokenWrapper: TokenWrapper;
- constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper) {
+ private _contractAddressIfExists?: string;
+ constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper, contractAddressIfExists?: string) {
super(web3Wrapper);
this._tokenWrapper = tokenWrapper;
+ this._contractAddressIfExists = contractAddressIfExists;
}
/**
* Deposit ETH into the Wrapped ETH smart contract and issues the equivalent number of wrapped ETH tokens
@@ -76,7 +78,7 @@ export class EtherTokenWrapper extends ContractWrapper {
return this._etherTokenContractIfExists;
}
const contractInstance = await this._instantiateContractIfExistsAsync<EtherTokenContract>(
- artifacts.EtherTokenArtifact,
+ artifacts.EtherTokenArtifact, this._contractAddressIfExists,
);
this._etherTokenContractIfExists = contractInstance as EtherTokenContract;
return this._etherTokenContractIfExists;
diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts
index 73c4d935b..54d7f62d5 100644
--- a/src/contract_wrappers/exchange_wrapper.ts
+++ b/src/contract_wrappers/exchange_wrapper.ts
@@ -56,6 +56,7 @@ export class ExchangeWrapper extends ContractWrapper {
[ExchangeContractErrCodes.ERROR_FILL_TRUNCATION]: ExchangeContractErrs.OrderFillRoundingError,
[ExchangeContractErrCodes.ERROR_FILL_BALANCE_ALLOWANCE]: ExchangeContractErrs.FillBalanceAllowanceError,
};
+ private _contractAddressIfExists?: string;
private static _getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] {
const orderAddresses: OrderAddresses = [
order.maker,
@@ -74,11 +75,12 @@ export class ExchangeWrapper extends ContractWrapper {
];
return [orderAddresses, orderValues];
}
- constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper) {
+ constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper, contractAddressIfExists?: string) {
super(web3Wrapper);
this._tokenWrapper = tokenWrapper;
this._orderValidationUtils = new OrderValidationUtils(tokenWrapper, this);
this._exchangeLogEventEmitters = [];
+ this._contractAddressIfExists = contractAddressIfExists;
}
/**
* Returns the unavailable takerAmount of an order. Unavailable amount is defined as the total
@@ -738,7 +740,7 @@ export class ExchangeWrapper extends ContractWrapper {
return this._exchangeContractIfExists;
}
const contractInstance = await this._instantiateContractIfExistsAsync<ExchangeContract>(
- artifacts.ExchangeArtifact,
+ artifacts.ExchangeArtifact, this._contractAddressIfExists,
);
this._exchangeContractIfExists = contractInstance as ExchangeContract;
return this._exchangeContractIfExists;
@@ -748,4 +750,10 @@ export class ExchangeWrapper extends ContractWrapper {
const ZRXtokenAddress = await exchangeInstance.ZRX_TOKEN_CONTRACT.callAsync();
return ZRXtokenAddress;
}
+ private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync();
+ const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase();
+ return tokenTransferProxyAddressLowerCase;
+ }
}
diff --git a/src/contract_wrappers/token_registry_wrapper.ts b/src/contract_wrappers/token_registry_wrapper.ts
index 528a88e06..2cc5a9aa0 100644
--- a/src/contract_wrappers/token_registry_wrapper.ts
+++ b/src/contract_wrappers/token_registry_wrapper.ts
@@ -11,8 +11,10 @@ import {artifacts} from '../artifacts';
*/
export class TokenRegistryWrapper extends ContractWrapper {
private _tokenRegistryContractIfExists?: TokenRegistryContract;
- constructor(web3Wrapper: Web3Wrapper) {
+ private _contractAddressIfExists?: string;
+ constructor(web3Wrapper: Web3Wrapper, contractAddressIfExists?: string) {
super(web3Wrapper);
+ this._contractAddressIfExists = contractAddressIfExists;
}
/**
* Retrieves all the tokens currently listed in the Token Registry smart contract
@@ -82,6 +84,16 @@ export class TokenRegistryWrapper extends ContractWrapper {
const token = this._createTokenFromMetadata(metadata);
return token;
}
+ /**
+ * Retrieves the Ethereum address of the TokenRegistry contract deployed on the network
+ * that the user-passed web3 provider is connected to.
+ * @returns The Ethereum address of the TokenRegistry contract being used.
+ */
+ public async getContractAddressAsync(): Promise<string> {
+ const tokenRegistryInstance = await this._getTokenRegistryContractAsync();
+ const tokenRegistryAddress = tokenRegistryInstance.address;
+ return tokenRegistryAddress;
+ }
private _createTokenFromMetadata(metadata: TokenMetadata): Token|undefined {
if (metadata[0] === constants.NULL_ADDRESS) {
return undefined;
@@ -102,7 +114,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
return this._tokenRegistryContractIfExists;
}
const contractInstance = await this._instantiateContractIfExistsAsync<TokenRegistryContract>(
- artifacts.TokenRegistryArtifact,
+ artifacts.TokenRegistryArtifact, this._contractAddressIfExists,
);
this._tokenRegistryContractIfExists = contractInstance as TokenRegistryContract;
return this._tokenRegistryContractIfExists;
diff --git a/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/src/contract_wrappers/token_transfer_proxy_wrapper.ts
index 528d661d1..f81845af9 100644
--- a/src/contract_wrappers/token_transfer_proxy_wrapper.ts
+++ b/src/contract_wrappers/token_transfer_proxy_wrapper.ts
@@ -1,4 +1,5 @@
import * as _ from 'lodash';
+import {Web3Wrapper} from '../web3_wrapper';
import {ContractWrapper} from './contract_wrapper';
import {artifacts} from '../artifacts';
import {TokenTransferProxyContract} from '../types';
@@ -8,6 +9,11 @@ import {TokenTransferProxyContract} from '../types';
*/
export class TokenTransferProxyWrapper extends ContractWrapper {
private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract;
+ private _tokenTransferProxyContractAddressFetcher: () => Promise<string>;
+ constructor(web3Wrapper: Web3Wrapper, tokenTransferProxyContractAddressFetcher: () => Promise<string>) {
+ super(web3Wrapper);
+ this._tokenTransferProxyContractAddressFetcher = tokenTransferProxyContractAddressFetcher;
+ }
/**
* Check if the Exchange contract address is authorized by the TokenTransferProxy contract.
* @param exchangeContractAddress The hex encoded address of the Exchange contract to call.
@@ -44,8 +50,9 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
return this._tokenTransferProxyContractIfExists;
}
+ const contractAddress = await this._tokenTransferProxyContractAddressFetcher();
const contractInstance = await this._instantiateContractIfExistsAsync<TokenTransferProxyContract>(
- artifacts.TokenTransferProxyArtifact,
+ artifacts.TokenTransferProxyArtifact, contractAddress,
);
this._tokenTransferProxyContractIfExists = contractInstance as TokenTransferProxyContract;
return this._tokenTransferProxyContractIfExists;
diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts
index bdfdf0c74..f7f0a0ce3 100644
--- a/src/contract_wrappers/token_wrapper.ts
+++ b/src/contract_wrappers/token_wrapper.ts
@@ -31,10 +31,12 @@ export class TokenWrapper extends ContractWrapper {
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
private _tokenContractsByAddress: {[address: string]: TokenContract};
private _tokenLogEventEmitters: ContractEventEmitter[];
- constructor(web3Wrapper: Web3Wrapper) {
+ private _tokenTransferProxyContractAddressFetcher: () => Promise<string>;
+ constructor(web3Wrapper: Web3Wrapper, tokenTransferProxyContractAddressFetcher: () => Promise<string>) {
super(web3Wrapper);
this._tokenContractsByAddress = {};
this._tokenLogEventEmitters = [];
+ this._tokenTransferProxyContractAddressFetcher = tokenTransferProxyContractAddressFetcher;
}
/**
* Retrieves an owner's ERC20 token balance.
@@ -133,7 +135,7 @@ export class TokenWrapper extends ContractWrapper {
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
- const proxyAddress = await this._getProxyAddressAsync();
+ const proxyAddress = await this._getTokenTransferProxyAddressAsync();
const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts);
return allowanceInBaseUnits;
}
@@ -152,7 +154,7 @@ export class TokenWrapper extends ContractWrapper {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isBigNumber('amountInBaseUnits', amountInBaseUnits);
- const proxyAddress = await this._getProxyAddressAsync();
+ const proxyAddress = await this._getTokenTransferProxyAddressAsync();
const txHash = await this.setAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits);
return txHash;
}
@@ -299,15 +301,8 @@ export class TokenWrapper extends ContractWrapper {
this._tokenContractsByAddress[tokenAddress] = tokenContract;
return tokenContract;
}
- private async _getProxyAddressAsync() {
- const networkIdIfExists = await this._web3Wrapper.getNetworkIdIfExistsAsync();
- const proxyNetworkConfigsIfExists = _.isUndefined(networkIdIfExists) ?
- undefined :
- artifacts.TokenTransferProxyArtifact.networks[networkIdIfExists];
- if (_.isUndefined(proxyNetworkConfigsIfExists)) {
- throw new Error(ZeroExError.ContractNotDeployedOnNetwork);
- }
- const proxyAddress = proxyNetworkConfigsIfExists.address.toLowerCase();
- return proxyAddress;
+ private async _getTokenTransferProxyAddressAsync(): Promise<string> {
+ const tokenTransferProxyContractAddress = await this._tokenTransferProxyContractAddressFetcher();
+ return tokenTransferProxyContractAddress;
}
}
diff --git a/src/schemas/zero_ex_config_schema.ts b/src/schemas/zero_ex_config_schema.ts
new file mode 100644
index 000000000..179e29c31
--- /dev/null
+++ b/src/schemas/zero_ex_config_schema.ts
@@ -0,0 +1,10 @@
+export const zeroExConfigSchema = {
+ id: '/ZeroExConfig',
+ properties: {
+ gasPrice: {$ref: '/Number'},
+ exchangeContractAddress: {$ref: '/Address'},
+ tokenRegistryContractAddress: {$ref: '/Address'},
+ etherTokenContractAddress: {$ref: '/Address'},
+ },
+ type: 'object',
+};
diff --git a/src/types.ts b/src/types.ts
index eb83d7c2b..29fb40e73 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -51,6 +51,9 @@ export interface ExchangeContract extends Web3.ContractInstance {
ZRX_TOKEN_CONTRACT: {
callAsync: () => Promise<string>;
};
+ TOKEN_TRANSFER_PROXY_CONTRACT: {
+ callAsync: () => Promise<string>;
+ };
getUnavailableTakerTokenAmount: {
callAsync: (orderHash: string, defaultBlock?: Web3.BlockParam) => Promise<BigNumber.BigNumber>;
};
@@ -386,8 +389,17 @@ export interface JSONRPCPayload {
method: string;
}
+/*
+ * gasPrice: Gas price to use with every transaction
+ * exchangeContractAddress: The address of an exchange contract to use
+ * tokenRegistryContractAddress: The address of a token registry contract to use
+ * etherTokenContractAddress: The address of an ether token contract to use
+ */
export interface ZeroExConfig {
gasPrice?: BigNumber.BigNumber; // Gas price to use with every transaction
+ exchangeContractAddress?: string;
+ tokenRegistryContractAddress?: string;
+ etherTokenContractAddress?: string;
}
export type TransactionReceipt = Web3.TransactionReceipt;
diff --git a/test/0x.js_test.ts b/test/0x.js_test.ts
index 5461a7d3f..cc6b91e99 100644
--- a/test/0x.js_test.ts
+++ b/test/0x.js_test.ts
@@ -4,12 +4,11 @@ import {chaiSetup} from './utils/chai_setup';
import 'mocha';
import * as BigNumber from 'bignumber.js';
import * as Sinon from 'sinon';
-import {ZeroEx, Order} from '../src';
+import {ZeroEx, Order, ZeroExError, LogWithDecodedArgs} from '../src';
import {constants} from './utils/constants';
import {TokenUtils} from './utils/token_utils';
import {web3Factory} from './utils/web3_factory';
import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-import {LogWithDecodedArgs} from '../src';
const blockchainLifecycle = new BlockchainLifecycle();
chaiSetup.configure();
@@ -231,4 +230,30 @@ describe('ZeroEx library', () => {
expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
});
+ describe('#config', () => {
+ it('allows to specify exchange contract address', async () => {
+ const config = {
+ exchangeContractAddress: ZeroEx.NULL_ADDRESS,
+ };
+ const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, config);
+ return expect(zeroExWithWrongExchangeAddress.exchange.getContractAddressAsync())
+ .to.be.rejectedWith(ZeroExError.ContractDoesNotExist);
+ });
+ it('allows to specify ether token contract address', async () => {
+ const config = {
+ etherTokenContractAddress: ZeroEx.NULL_ADDRESS,
+ };
+ const zeroExWithWrongEtherTokenAddress = new ZeroEx(web3.currentProvider, config);
+ return expect(zeroExWithWrongEtherTokenAddress.etherToken.getContractAddressAsync())
+ .to.be.rejectedWith(ZeroExError.ContractDoesNotExist);
+ });
+ it('allows to specify token registry token contract address', async () => {
+ const config = {
+ tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
+ };
+ const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, config);
+ return expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddressAsync())
+ .to.be.rejectedWith(ZeroExError.ContractDoesNotExist);
+ });
+ });
});
diff --git a/test/artifacts_test.ts b/test/artifacts_test.ts
index 65d75f16e..bd34a6b91 100644
--- a/test/artifacts_test.ts
+++ b/test/artifacts_test.ts
@@ -23,7 +23,7 @@ describe('Artifacts', () => {
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
}).timeout(TIMEOUT);
it('proxy contract is deployed', async () => {
- await (zeroEx.token as any)._getProxyAddressAsync();
+ await (zeroEx.token as any)._getTokenTransferProxyAddressAsync();
}).timeout(TIMEOUT);
it('exchange contract is deployed', async () => {
await zeroEx.exchange.getContractAddressAsync();