From 3a7bb97ad1182eb9c718797bda8dca5eb5d7f9cd Mon Sep 17 00:00:00 2001 From: Alex Browne Date: Wed, 3 Oct 2018 16:21:17 -0700 Subject: Remove artifacts from migrations package and update contract-wrappers accordingly --- .../contract-wrappers/src/contract_wrappers.ts | 56 +++++++----------- .../src/contract_wrappers/contract_wrapper.ts | 59 +----------------- .../src/contract_wrappers/erc20_proxy_wrapper.ts | 39 ++++-------- .../src/contract_wrappers/erc20_token_wrapper.ts | 28 ++++----- .../src/contract_wrappers/erc721_proxy_wrapper.ts | 39 ++++-------- .../src/contract_wrappers/erc721_token_wrapper.ts | 32 +++++----- .../src/contract_wrappers/ether_token_wrapper.ts | 37 ++++-------- .../src/contract_wrappers/exchange_wrapper.ts | 64 ++++++-------------- .../src/contract_wrappers/forwarder_wrapper.ts | 69 +++++----------------- .../contract_wrappers/order_validator_wrapper.ts | 16 ++--- packages/contract-wrappers/src/types.ts | 8 +-- 11 files changed, 129 insertions(+), 318 deletions(-) (limited to 'packages/contract-wrappers/src') diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts index b272fabda..8e4693da6 100644 --- a/packages/contract-wrappers/src/contract_wrappers.ts +++ b/packages/contract-wrappers/src/contract_wrappers.ts @@ -83,46 +83,29 @@ export class ContractWrappers { const blockPollingIntervalMs = _.isUndefined(config.blockPollingIntervalMs) ? constants.DEFAULT_BLOCK_POLLING_INTERVAL : config.blockPollingIntervalMs; - this.erc20Proxy = new ERC20ProxyWrapper(this._web3Wrapper, config.networkId, config.erc20ProxyContractAddress); - this.erc721Proxy = new ERC721ProxyWrapper( - this._web3Wrapper, - config.networkId, - config.erc721ProxyContractAddress, - ); - this.erc20Token = new ERC20TokenWrapper( - this._web3Wrapper, - config.networkId, - this.erc20Proxy, - blockPollingIntervalMs, - ); - this.erc721Token = new ERC721TokenWrapper( - this._web3Wrapper, - config.networkId, - this.erc721Proxy, - blockPollingIntervalMs, - ); - this.etherToken = new EtherTokenWrapper( - this._web3Wrapper, - config.networkId, - this.erc20Token, - blockPollingIntervalMs, - ); + if (_.isUndefined(config.contractAddresses.erc20Proxy)) { + throw new Error('config.contractAddresses.erc20Proxy is required for testing'); + } + this.erc20Proxy = new ERC20ProxyWrapper(this._web3Wrapper, config.contractAddresses.erc20Proxy); + this.erc721Proxy = new ERC721ProxyWrapper(this._web3Wrapper, config.contractAddresses.erc721Proxy); + this.erc20Token = new ERC20TokenWrapper(this._web3Wrapper, this.erc20Proxy, blockPollingIntervalMs); + this.erc721Token = new ERC721TokenWrapper(this._web3Wrapper, this.erc721Proxy, blockPollingIntervalMs); + this.etherToken = new EtherTokenWrapper(this._web3Wrapper, this.erc20Token, blockPollingIntervalMs); this.exchange = new ExchangeWrapper( this._web3Wrapper, - config.networkId, this.erc20Token, this.erc721Token, - config.exchangeContractAddress, - config.zrxContractAddress, + config.contractAddresses.exchange, + config.contractAddresses.zrxToken, blockPollingIntervalMs, ); this.forwarder = new ForwarderWrapper( this._web3Wrapper, - config.networkId, - config.forwarderContractAddress, - config.zrxContractAddress, + config.contractAddresses.forwarder, + config.contractAddresses.zrxToken, + config.contractAddresses.etherToken, ); - this.orderValidator = new OrderValidatorWrapper(this._web3Wrapper, config.networkId); + this.orderValidator = new OrderValidatorWrapper(this._web3Wrapper, config.contractAddresses.orderValidator); } /** * Sets a new web3 provider for 0x.js. Updating the provider will stop all @@ -130,16 +113,17 @@ export class ContractWrappers { * @param provider The Web3Provider you would like the 0x.js library to use from now on. * @param networkId The id of the network your provider is connected to */ - public setProvider(provider: Provider, networkId: number): void { + public setProvider(provider: Provider): void { + // TODO(albrow): Make sure all contract wrappers are called below. this._web3Wrapper.setProvider(provider); (this.exchange as any)._invalidateContractInstances(); - (this.exchange as any)._setNetworkId(networkId); (this.erc20Token as any)._invalidateContractInstances(); - (this.erc20Token as any)._setNetworkId(networkId); (this.erc20Proxy as any)._invalidateContractInstance(); - (this.erc20Proxy as any)._setNetworkId(networkId); + (this.erc721Token as any)._invalidateContractInstances(); + (this.erc721Proxy as any)._invalidateContractInstance(); (this.etherToken as any)._invalidateContractInstance(); - (this.etherToken as any)._setNetworkId(networkId); + (this.forwarder as any)._invalidateContractInstance(); + (this.orderValidator as any)._invalidateContractInstance(); } /** * Get the provider instance currently used by 0x.js diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index f7a89e3be..aed9d44db 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -3,7 +3,6 @@ import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; import { BlockParamLiteral, ContractAbi, - ContractArtifact, FilterObject, LogEntry, LogWithDecodedArgs, @@ -24,22 +23,9 @@ import { import { constants } from '../utils/constants'; import { filterUtils } from '../utils/filter_utils'; -const CONTRACT_NAME_TO_NOT_FOUND_ERROR: { - [contractName: string]: ContractWrappersError; -} = { - ZRX: ContractWrappersError.ZRXContractDoesNotExist, - EtherToken: ContractWrappersError.EtherTokenContractDoesNotExist, - ERC20Token: ContractWrappersError.ERC20TokenContractDoesNotExist, - ERC20Proxy: ContractWrappersError.ERC20ProxyContractDoesNotExist, - ERC721Token: ContractWrappersError.ERC721TokenContractDoesNotExist, - ERC721Proxy: ContractWrappersError.ERC721ProxyContractDoesNotExist, - Exchange: ContractWrappersError.ExchangeContractDoesNotExist, -}; - export abstract class ContractWrapper { public abstract abi: ContractAbi; protected _web3Wrapper: Web3Wrapper; - protected _networkId: number; private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined; private _blockPollingIntervalMs: number; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; @@ -56,9 +42,8 @@ export abstract class ContractWrapper { logUtils.warn(err); } } - constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) { + constructor(web3Wrapper: Web3Wrapper, blockPollingIntervalMs?: number) { this._web3Wrapper = web3Wrapper; - this._networkId = networkId; this._blockPollingIntervalMs = _.isUndefined(blockPollingIntervalMs) ? constants.DEFAULT_BLOCK_POLLING_INTERVAL : blockPollingIntervalMs; @@ -124,40 +109,6 @@ export abstract class ContractWrapper { const logWithDecodedArgs = abiDecoder.tryToDecodeLogOrNoop(log); return logWithDecodedArgs; } - protected async _getContractAbiAndAddressFromArtifactsAsync( - artifact: ContractArtifact, - addressIfExists?: string, - ): Promise<[ContractAbi, string]> { - let contractAddress: string; - if (_.isUndefined(addressIfExists)) { - if (_.isUndefined(artifact.networks[this._networkId])) { - throw new Error(ContractWrappersError.ContractNotDeployedOnNetwork); - } - contractAddress = artifact.networks[this._networkId].address.toLowerCase(); - } else { - contractAddress = addressIfExists; - } - const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress); - if (!doesContractExist) { - throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contractName]); - } - const abiAndAddress: [ContractAbi, string] = [artifact.compilerOutput.abi, contractAddress]; - return abiAndAddress; - } - protected _getContractAddress(artifact: ContractArtifact, addressIfExists?: string): string { - if (_.isUndefined(addressIfExists)) { - if (_.isUndefined(artifact.networks[this._networkId])) { - throw new Error(ContractWrappersError.ContractNotDeployedOnNetwork); - } - const contractAddress = artifact.networks[this._networkId].address; - if (_.isUndefined(contractAddress)) { - throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contractName]); - } - return contractAddress; - } else { - return addressIfExists; - } - } private _onLogStateChanged(isRemoved: boolean, rawLog: RawLogEntry): void { const log: LogEntry = marshaller.unmarshalLog(rawLog); _.forEach(this._filters, (filter: FilterObject, filterToken: string) => { @@ -222,14 +173,6 @@ export abstract class ContractWrapper { }); return logs as RawLogEntry[]; } - // HACK: This should be a package-scoped method (which doesn't exist in TS) - // We don't want this method available in the public interface for all classes - // who inherit from ContractWrapper, and it is only used by the internal implementation - // of those higher classes. - // tslint:disable-next-line:no-unused-variable - private _setNetworkId(networkId: number): void { - this._networkId = networkId; - } private _stopBlockAndLogStream(): void { if (_.isUndefined(this._blockAndLogStreamerIfExists)) { throw new Error(ContractWrappersError.SubscriptionNotFound); diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts index 5900f0502..31b3b6755 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts @@ -13,25 +13,25 @@ import { ContractWrapper } from './contract_wrapper'; */ export class ERC20ProxyWrapper extends ContractWrapper { public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi; + public address: string; private _erc20ProxyContractIfExists?: wrappers.ERC20ProxyContract; - private _contractAddressIfExists?: string; /** * Instantiate ERC20ProxyWrapper * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId - * @param contractAddressIfExists The contract address to use. This is usually pulled from - * the artifacts but needs to be specified when using with your own custom testnet. + * @param address The address of the ERC20Proxy contract */ - constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { - super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; + // TODO(albrow): Make address optional and default to looking up the address + // based in a hard-coded mapping based on web3Wrapper network id. + constructor(web3Wrapper: Web3Wrapper, address: string) { + super(web3Wrapper); + this.address = address; } /** * Get the 4 bytes ID of this asset proxy * @return Proxy id */ public async getProxyIdAsync(): Promise { - const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const ERC20ProxyContractInstance = this._getERC20ProxyContract(); const proxyId = (await ERC20ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId; return proxyId; } @@ -43,7 +43,7 @@ export class ERC20ProxyWrapper extends ContractWrapper { public async isAuthorizedAsync(exchangeContractAddress: string): Promise { assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress); const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); - const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const ERC20ProxyContractInstance = this._getERC20ProxyContract(); const isAuthorized = await ERC20ProxyContractInstance.authorized.callAsync(normalizedExchangeContractAddress); return isAuthorized; } @@ -52,36 +52,23 @@ export class ERC20ProxyWrapper extends ContractWrapper { * @return The list of authorized addresses. */ public async getAuthorizedAddressesAsync(): Promise { - const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const ERC20ProxyContractInstance = this._getERC20ProxyContract(); const authorizedAddresses = await ERC20ProxyContractInstance.getAuthorizedAddresses.callAsync(); return authorizedAddresses; } - /** - * Retrieves the Ethereum address of the ERC20Proxy contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the ERC20Proxy contract being used. - */ - public getContractAddress(): string { - const contractAddress = this._getContractAddress(artifacts.ERC20Proxy, this._contractAddressIfExists); - return contractAddress; - } // HACK: We don't want this method to be visible to the other units within that package but not to the end user. // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. // tslint:disable-next-line:no-unused-variable private _invalidateContractInstance(): void { delete this._erc20ProxyContractIfExists; } - private async _getERC20ProxyContractAsync(): Promise { + private _getERC20ProxyContract(): wrappers.ERC20ProxyContract { if (!_.isUndefined(this._erc20ProxyContractIfExists)) { return this._erc20ProxyContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC20Proxy, - this._contractAddressIfExists, - ); const contractInstance = new wrappers.ERC20ProxyContract( - abi, - address, + this.abi, + this.address, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts index 3be5bcaee..53cda5d08 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts @@ -36,17 +36,11 @@ export class ERC20TokenWrapper extends ContractWrapper { /** * Instantiate ERC20TokenWrapper * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId * @param erc20ProxyWrapper The ERC20ProxyWrapper instance to use * @param blockPollingIntervalMs The block polling interval to use for active subscriptions */ - constructor( - web3Wrapper: Web3Wrapper, - networkId: number, - erc20ProxyWrapper: ERC20ProxyWrapper, - blockPollingIntervalMs?: number, - ) { - super(web3Wrapper, networkId, blockPollingIntervalMs); + constructor(web3Wrapper: Web3Wrapper, erc20ProxyWrapper: ERC20ProxyWrapper, blockPollingIntervalMs?: number) { + super(web3Wrapper, blockPollingIntervalMs); this._tokenContractsByAddress = {}; this._erc20ProxyWrapper = erc20ProxyWrapper; } @@ -188,7 +182,7 @@ export class ERC20TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts: MethodOpts = {}, ): Promise { - const proxyAddress = this._erc20ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc20ProxyWrapper.address; const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts); return allowanceInBaseUnits; } @@ -208,7 +202,7 @@ export class ERC20TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - const proxyAddress = this._erc20ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc20ProxyWrapper.address; const txHash = await this.setAllowanceAsync( tokenAddress, ownerAddress, @@ -434,13 +428,15 @@ export class ERC20TokenWrapper extends ContractWrapper { if (!_.isUndefined(tokenContract)) { return tokenContract; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC20Token, - normalizedTokenAddress, - ); + // TODO(albrow): Do we really still need this check? The default error + // looks okay to me. + const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(tokenAddress); + if (!doesContractExist) { + throw new Error(ContractWrappersError.ERC20TokenContractDoesNotExist); + } const contractInstance = new wrappers.ERC20TokenContract( - abi, - address, + this.abi, + normalizedTokenAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts index 6ba162213..2472d512b 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts @@ -13,25 +13,25 @@ import { ContractWrapper } from './contract_wrapper'; */ export class ERC721ProxyWrapper extends ContractWrapper { public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi; + public address: string; private _erc721ProxyContractIfExists?: wrappers.ERC721ProxyContract; - private _contractAddressIfExists?: string; /** * Instantiate ERC721ProxyWrapper * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId - * @param contractAddressIfExists The contract address to use. This is usually pulled from - * the artifacts but needs to be specified when using with your own custom testnet. + * @param address The address of the ERC721Proxy contract */ - constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { - super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; + // TODO(albrow): Make address optional and default to looking up the address + // based in a hard-coded mapping based on web3Wrapper network id. + constructor(web3Wrapper: Web3Wrapper, address: string) { + super(web3Wrapper); + this.address = address; } /** * Get the 4 bytes ID of this asset proxy * @return Proxy id */ public async getProxyIdAsync(): Promise { - const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const ERC721ProxyContractInstance = await this._getERC721ProxyContract(); const proxyId = (await ERC721ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId; return proxyId; } @@ -43,7 +43,7 @@ export class ERC721ProxyWrapper extends ContractWrapper { public async isAuthorizedAsync(exchangeContractAddress: string): Promise { assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress); const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); - const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const ERC721ProxyContractInstance = await this._getERC721ProxyContract(); const isAuthorized = await ERC721ProxyContractInstance.authorized.callAsync(normalizedExchangeContractAddress); return isAuthorized; } @@ -52,36 +52,23 @@ export class ERC721ProxyWrapper extends ContractWrapper { * @return The list of authorized addresses. */ public async getAuthorizedAddressesAsync(): Promise { - const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const ERC721ProxyContractInstance = await this._getERC721ProxyContract(); const authorizedAddresses = await ERC721ProxyContractInstance.getAuthorizedAddresses.callAsync(); return authorizedAddresses; } - /** - * Retrieves the Ethereum address of the ERC721Proxy contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the ERC721Proxy contract being used. - */ - public getContractAddress(): string { - const contractAddress = this._getContractAddress(artifacts.ERC721Proxy, this._contractAddressIfExists); - return contractAddress; - } // HACK: We don't want this method to be visible to the other units within that package but not to the end user. // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. // tslint:disable-next-line:no-unused-variable private _invalidateContractInstance(): void { delete this._erc721ProxyContractIfExists; } - private async _getERC721ProxyContractAsync(): Promise { + private _getERC721ProxyContract(): wrappers.ERC721ProxyContract { if (!_.isUndefined(this._erc721ProxyContractIfExists)) { return this._erc721ProxyContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC721Proxy, - this._contractAddressIfExists, - ); const contractInstance = new wrappers.ERC721ProxyContract( - abi, - address, + this.abi, + this.address, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts index 23b335710..7fcd74eaf 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts @@ -35,17 +35,11 @@ export class ERC721TokenWrapper extends ContractWrapper { /** * Instantiate ERC721TokenWrapper * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId * @param erc721ProxyWrapper The ERC721ProxyWrapper instance to use * @param blockPollingIntervalMs The block polling interval to use for active subscriptions */ - constructor( - web3Wrapper: Web3Wrapper, - networkId: number, - erc721ProxyWrapper: ERC721ProxyWrapper, - blockPollingIntervalMs?: number, - ) { - super(web3Wrapper, networkId, blockPollingIntervalMs); + constructor(web3Wrapper: Web3Wrapper, erc721ProxyWrapper: ERC721ProxyWrapper, blockPollingIntervalMs?: number) { + super(web3Wrapper, blockPollingIntervalMs); this._tokenContractsByAddress = {}; this._erc721ProxyWrapper = erc721ProxyWrapper; } @@ -149,7 +143,7 @@ export class ERC721TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts: MethodOpts = {}, ): Promise { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const isProxyApprovedForAll = await this.isApprovedForAllAsync( tokenAddress, ownerAddress, @@ -198,7 +192,7 @@ export class ERC721TokenWrapper extends ContractWrapper { tokenId: BigNumber, methodOpts: MethodOpts = {}, ): Promise { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const approvedAddress = await this.getApprovedIfExistsAsync(tokenAddress, tokenId, methodOpts); const isProxyApproved = approvedAddress === proxyAddress; return isProxyApproved; @@ -259,7 +253,7 @@ export class ERC721TokenWrapper extends ContractWrapper { isApproved: boolean, txOpts: TransactionOpts = {}, ): Promise { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const txHash = await this.setApprovalForAllAsync(tokenAddress, ownerAddress, proxyAddress, isApproved, txOpts); return txHash; } @@ -317,7 +311,7 @@ export class ERC721TokenWrapper extends ContractWrapper { tokenId: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const txHash = await this.setApprovalAsync(tokenAddress, proxyAddress, tokenId, txOpts); return txHash; } @@ -461,13 +455,15 @@ export class ERC721TokenWrapper extends ContractWrapper { if (!_.isUndefined(tokenContract)) { return tokenContract; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC721Token, - normalizedTokenAddress, - ); + // TODO(albrow): Do we really still need this check? The default error + // looks okay to me. + const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(tokenAddress); + if (!doesContractExist) { + throw new Error(ContractWrappersError.ERC721TokenContractDoesNotExist); + } const contractInstance = new wrappers.ERC721TokenContract( - abi, - address, + this.abi, + normalizedTokenAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts index 30653adf2..526324abd 100644 --- a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts @@ -30,13 +30,8 @@ export class EtherTokenWrapper extends ContractWrapper { * @param erc20TokenWrapper The ERC20TokenWrapper instance to use * @param blockPollingIntervalMs The block polling interval to use for active subscriptions */ - constructor( - web3Wrapper: Web3Wrapper, - networkId: number, - erc20TokenWrapper: ERC20TokenWrapper, - blockPollingIntervalMs?: number, - ) { - super(web3Wrapper, networkId, blockPollingIntervalMs); + constructor(web3Wrapper: Web3Wrapper, erc20TokenWrapper: ERC20TokenWrapper, blockPollingIntervalMs?: number) { + super(web3Wrapper, blockPollingIntervalMs); this._erc20TokenWrapper = erc20TokenWrapper; } /** @@ -191,19 +186,6 @@ export class EtherTokenWrapper extends ContractWrapper { public unsubscribeAll(): void { super._unsubscribeAll(); } - /** - * Retrieves the Ethereum address of the EtherToken contract deployed on the network - * that the user-passed web3 provider is connected to. If it's not Kovan, Ropsten, Rinkeby, Mainnet or TestRPC - * (networkId: 50), it will return undefined (e.g a private network). - * @returns The Ethereum address of the EtherToken contract or undefined. - */ - public getContractAddressIfExists(): string | undefined { - const networkSpecificArtifact = artifacts.WETH9.networks[this._networkId]; - const contractAddressIfExists = _.isUndefined(networkSpecificArtifact) - ? undefined - : networkSpecificArtifact.address; - return contractAddressIfExists; - } // tslint:disable-next-line:no-unused-variable private _invalidateContractInstance(): void { this.unsubscribeAll(); @@ -214,13 +196,16 @@ export class EtherTokenWrapper extends ContractWrapper { if (!_.isUndefined(etherTokenContract)) { return etherTokenContract; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.WETH9, - etherTokenAddress, - ); + // TODO(albrow): Do we really still need this check? The default error + // looks okay to me. + // TODO(albrow): Should we normalize the token address here? + const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(etherTokenAddress); + if (!doesContractExist) { + throw new Error(ContractWrappersError.EtherTokenContractDoesNotExist); + } const contractInstance = new wrappers.WETH9Contract( - abi, - address, + this.abi, + etherTokenAddress, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts index 613747720..b65baee55 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -24,7 +24,6 @@ import { IndexedFilterValues, MethodOpts, OrderInfo, - OrderStatus, OrderTransactionOpts, ValidateOrderFillableOpts, } from '../types'; @@ -42,35 +41,34 @@ import { ERC721TokenWrapper } from './erc721_token_wrapper'; */ export class ExchangeWrapper extends ContractWrapper { public abi: ContractAbi = artifacts.Exchange.compilerOutput.abi; + public address: string; + public zrxTokenAddress: string; private _exchangeContractIfExists?: wrappers.ExchangeContract; private _erc721TokenWrapper: ERC721TokenWrapper; private _erc20TokenWrapper: ERC20TokenWrapper; - private _contractAddressIfExists?: string; - private _zrxContractAddressIfExists?: string; /** * Instantiate ExchangeWrapper - * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId - * @param contractAddressIfExists The exchange contract address to use. This is usually pulled from - * the artifacts but needs to be specified when using with your own custom testnet. - * @param zrxContractAddressIfExists The ZRXToken contract address to use. This is usually pulled from - * the artifacts but needs to be specified when using with your own custom testnet. - * @param blockPollingIntervalMs The block polling interval to use for active subscriptions + * @param web3Wrapper Web3Wrapper instance to use. + * @param erc20TokenWrapper ERC20TokenWrapper instance to use. + * @param erc721TokenWrapper ERC721TokenWrapper instance to use. + * @param address The address of the Exchange contract. + * @param zrxTokenAddress The address of the ZRX Token contract. + * @param blockPollingIntervalMs The block polling interval to use for active subscriptions. */ constructor( web3Wrapper: Web3Wrapper, - networkId: number, erc20TokenWrapper: ERC20TokenWrapper, erc721TokenWrapper: ERC721TokenWrapper, - contractAddressIfExists?: string, - zrxContractAddressIfExists?: string, + // TODO(albrow): Make address optional? + address: string, + zrxTokenAddress: string, blockPollingIntervalMs?: number, ) { - super(web3Wrapper, networkId, blockPollingIntervalMs); + super(web3Wrapper, blockPollingIntervalMs); this._erc20TokenWrapper = erc20TokenWrapper; this._erc721TokenWrapper = erc721TokenWrapper; - this._contractAddressIfExists = contractAddressIfExists; - this._zrxContractAddressIfExists = zrxContractAddressIfExists; + this.address = address; + this.zrxTokenAddress = zrxTokenAddress; } /** * Retrieve the address of an asset proxy by signature. @@ -1050,9 +1048,8 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesBelongToStringEnum('eventName', eventName, wrappers.ExchangeEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); - const exchangeContractAddress = this.getContractAddress(); const subscriptionToken = this._subscribe( - exchangeContractAddress, + this.address, eventName, indexFilterValues, artifacts.Exchange.compilerOutput.abi, @@ -1090,9 +1087,8 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesBelongToStringEnum('eventName', eventName, wrappers.ExchangeEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); - const exchangeContractAddress = this.getContractAddress(); const logs = await this._getLogsAsync( - exchangeContractAddress, + this.address, eventName, blockRange, indexFilterValues, @@ -1158,30 +1154,12 @@ export class ExchangeWrapper extends ContractWrapper { this.getZRXAssetData(), ); } - /** - * Retrieves the Ethereum address of the Exchange contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the Exchange contract being used. - */ - public getContractAddress(): string { - const contractAddress = this._getContractAddress(artifacts.Exchange, this._contractAddressIfExists); - return contractAddress; - } - /** - * Returns the ZRX token address used by the exchange contract. - * @return Address of ZRX token - */ - public getZRXTokenAddress(): string { - const contractAddress = this._getContractAddress(artifacts.ZRXToken, this._zrxContractAddressIfExists); - return contractAddress; - } /** * Returns the ZRX asset data used by the exchange contract. * @return ZRX asset data */ public getZRXAssetData(): string { - const zrxTokenAddress = this.getZRXTokenAddress(); - const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenAddress); + const zrxAssetData = assetDataUtils.encodeERC20AssetData(this.zrxTokenAddress); return zrxAssetData; } /** @@ -1204,13 +1182,9 @@ export class ExchangeWrapper extends ContractWrapper { if (!_.isUndefined(this._exchangeContractIfExists)) { return this._exchangeContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.Exchange, - this._contractAddressIfExists, - ); const contractInstance = new wrappers.ExchangeContract( - abi, - address, + this.abi, + this.address, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts index 854a8381b..cd8f9ece9 100644 --- a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts @@ -22,18 +22,16 @@ import { ContractWrapper } from './contract_wrapper'; */ export class ForwarderWrapper extends ContractWrapper { public abi: ContractAbi = artifacts.Forwarder.compilerOutput.abi; + public address: string; + public zrxTokenAddress: string; + public etherTokenAddress: string; private _forwarderContractIfExists?: wrappers.ForwarderContract; - private _contractAddressIfExists?: string; - private _zrxContractAddressIfExists?: string; - constructor( - web3Wrapper: Web3Wrapper, - networkId: number, - contractAddressIfExists?: string, - zrxContractAddressIfExists?: string, - ) { - super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; - this._zrxContractAddressIfExists = zrxContractAddressIfExists; + // TODO(albrow): Make addresses optional? + constructor(web3Wrapper: Web3Wrapper, address: string, zrxTokenAddress: string, etherTokenAddress: string) { + super(web3Wrapper); + this.address = address; + this.zrxTokenAddress = zrxTokenAddress; + this.etherTokenAddress = etherTokenAddress; } /** * Purchases as much of orders' makerAssets as possible by selling up to 95% of transaction's ETH value. @@ -72,12 +70,8 @@ export class ForwarderWrapper extends ContractWrapper { assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress); assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); // other assertions - assert.ordersCanBeUsedForForwarderContract(signedOrders, this.getEtherTokenAddress()); - assert.feeOrdersCanBeUsedForForwarderContract( - signedFeeOrders, - this.getZRXTokenAddress(), - this.getEtherTokenAddress(), - ); + assert.ordersCanBeUsedForForwarderContract(signedOrders, this.etherTokenAddress); + assert.feeOrdersCanBeUsedForForwarderContract(signedFeeOrders, this.zrxTokenAddress, this.etherTokenAddress); // format feePercentage const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage); // lowercase input addresses @@ -164,12 +158,8 @@ export class ForwarderWrapper extends ContractWrapper { assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress); assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]); // other assertions - assert.ordersCanBeUsedForForwarderContract(signedOrders, this.getEtherTokenAddress()); - assert.feeOrdersCanBeUsedForForwarderContract( - signedFeeOrders, - this.getZRXTokenAddress(), - this.getEtherTokenAddress(), - ); + assert.ordersCanBeUsedForForwarderContract(signedOrders, this.etherTokenAddress); + assert.feeOrdersCanBeUsedForForwarderContract(signedFeeOrders, this.zrxTokenAddress, this.etherTokenAddress); // format feePercentage const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage); // lowercase input addresses @@ -219,31 +209,6 @@ export class ForwarderWrapper extends ContractWrapper { ); return txHash; } - /** - * Retrieves the Ethereum address of the Forwarder contract deployed on the network - * that the user-passed web3 provider is connected to. - * @returns The Ethereum address of the Forwarder contract being used. - */ - public getContractAddress(): string { - const contractAddress = this._getContractAddress(artifacts.Forwarder, this._contractAddressIfExists); - return contractAddress; - } - /** - * Returns the ZRX token address used by the forwarder contract. - * @return Address of ZRX token - */ - public getZRXTokenAddress(): string { - const contractAddress = this._getContractAddress(artifacts.ZRXToken, this._zrxContractAddressIfExists); - return contractAddress; - } - /** - * Returns the Ether token address used by the forwarder contract. - * @return Address of Ether token - */ - public getEtherTokenAddress(): string { - const contractAddress = this._getContractAddress(artifacts.WETH9); - return contractAddress; - } // HACK: We don't want this method to be visible to the other units within that package but not to the end user. // TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused. // tslint:disable-next-line:no-unused-variable @@ -254,13 +219,9 @@ export class ForwarderWrapper extends ContractWrapper { if (!_.isUndefined(this._forwarderContractIfExists)) { return this._forwarderContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.Forwarder, - this._contractAddressIfExists, - ); const contractInstance = new wrappers.ForwarderContract( - abi, - address, + this.abi, + this.address, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts index 02f9dd4de..23e0d42c1 100644 --- a/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts @@ -16,14 +16,17 @@ import { ContractWrapper } from './contract_wrapper'; */ export class OrderValidatorWrapper extends ContractWrapper { public abi: ContractAbi = artifacts.OrderValidator.compilerOutput.abi; + public address: string; private _orderValidatorContractIfExists?: wrappers.OrderValidatorContract; /** * Instantiate OrderValidatorWrapper - * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId + * @param web3Wrapper Web3Wrapper instance to use. + * @param address The address of the OrderValidator contract. */ - constructor(web3Wrapper: Web3Wrapper, networkId: number) { - super(web3Wrapper, networkId); + // TODO(albrow): Make address optional? + constructor(web3Wrapper: Web3Wrapper, address: string) { + super(web3Wrapper); + this.address = address; } /** * Get an object conforming to OrderAndTraderInfo containing on-chain information of the provided order and address @@ -173,10 +176,9 @@ export class OrderValidatorWrapper extends ContractWrapper { if (!_.isUndefined(this._orderValidatorContractIfExists)) { return this._orderValidatorContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(artifacts.OrderValidator); const contractInstance = new wrappers.OrderValidatorContract( - abi, - address, + this.abi, + this.address, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); diff --git a/packages/contract-wrappers/src/types.ts b/packages/contract-wrappers/src/types.ts index 0ac5f05e4..f882cc188 100644 --- a/packages/contract-wrappers/src/types.ts +++ b/packages/contract-wrappers/src/types.ts @@ -1,7 +1,7 @@ import { wrappers } from '@0xproject/contracts'; +import { ContractAddresses, OrderState, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; -import { OrderState, SignedOrder } from '@0xproject/types'; import { BlockParam, ContractEventArg, DecodedLogArgs, LogEntryEvent, LogWithDecodedArgs } from 'ethereum-types'; export enum ExchangeWrapperError { @@ -120,11 +120,7 @@ export type SyncMethod = (...args: any[]) => any; export interface ContractWrappersConfig { networkId: number; gasPrice?: BigNumber; - exchangeContractAddress?: string; - zrxContractAddress?: string; - erc20ProxyContractAddress?: string; - erc721ProxyContractAddress?: string; - forwarderContractAddress?: string; + contractAddresses: ContractAddresses; blockPollingIntervalMs?: number; } -- cgit v1.2.3