diff options
Diffstat (limited to 'packages/contract-wrappers/src/contract_wrappers')
9 files changed, 201 insertions, 376 deletions
diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index f7a89e3be..749aaae10 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -1,9 +1,8 @@ -import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils'; -import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; +import { AbiDecoder, intervalUtils, logUtils } from '@0x/utils'; +import { marshaller, Web3Wrapper } from '@0x/web3-wrapper'; import { BlockParamLiteral, ContractAbi, - ContractArtifact, FilterObject, LogEntry, LogWithDecodedArgs, @@ -24,27 +23,15 @@ 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; + protected _web3Wrapper: Web3Wrapper; private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined; - private _blockPollingIntervalMs: number; + private readonly _blockPollingIntervalMs: number; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; - private _filters: { [filterToken: string]: FilterObject }; - private _filterCallbacks: { + private readonly _filters: { [filterToken: string]: FilterObject }; + private readonly _filterCallbacks: { [filterToken: string]: EventCallback<ContractEventArgs>; }; private _onLogAddedSubscriptionToken: string | undefined; @@ -124,40 +111,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<ArgsType extends ContractEventArgs>(isRemoved: boolean, rawLog: RawLogEntry): void { const log: LogEntry = marshaller.unmarshalLog(rawLog); _.forEach(this._filters, (filter: FilterObject, filterToken: string) => { @@ -222,14 +175,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 ff027d78a..45460bd6d 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts @@ -1,38 +1,42 @@ -import { AssetProxyId } from '@0xproject/types'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ERC20ProxyContract } from '@0x/abi-gen-wrappers'; +import { ERC20Proxy } from '@0x/contract-artifacts'; +import { AssetProxyId } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { assert } from '../utils/assert'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { ContractWrapper } from './contract_wrapper'; -import { ERC20ProxyContract } from './generated/erc20_proxy'; /** * This class includes the functionality related to interacting with the ERC20Proxy contract. */ export class ERC20ProxyWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi; + public abi: ContractAbi = ERC20Proxy.compilerOutput.abi; + public address: string; private _erc20ProxyContractIfExists?: 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. If undefined, will + * default to the known address corresponding to the networkId. */ - constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { + constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).erc20Proxy : address; } /** * Get the 4 bytes ID of this asset proxy * @return Proxy id */ public async getProxyIdAsync(): Promise<AssetProxyId> { - const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync(); + const ERC20ProxyContractInstance = this._getERC20ProxyContract(); + // Note(albrow): Below is a TSLint false positive. Code won't compile if + // you remove the type assertion. + /* tslint:disable-next-line:no-unnecessary-type-assertion */ const proxyId = (await ERC20ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId; return proxyId; } @@ -44,7 +48,7 @@ export class ERC20ProxyWrapper extends ContractWrapper { public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> { 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; } @@ -53,36 +57,17 @@ export class ERC20ProxyWrapper extends ContractWrapper { * @return The list of authorized addresses. */ public async getAuthorizedAddressesAsync(): Promise<string[]> { - 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<ERC20ProxyContract> { + private _getERC20ProxyContract(): ERC20ProxyContract { if (!_.isUndefined(this._erc20ProxyContractIfExists)) { return this._erc20ProxyContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC20Proxy, - this._contractAddressIfExists, - ); const contractInstance = new 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 4625cef6a..5e0ec1951 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts @@ -1,10 +1,11 @@ -import { schemas } from '@0xproject/json-schemas'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ERC20TokenContract, ERC20TokenEventArgs, ERC20TokenEvents } from '@0x/abi-gen-wrappers'; +import { ERC20Token } from '@0x/contract-artifacts'; +import { schemas } from '@0x/json-schemas'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { methodOptsSchema } from '../schemas/method_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; import { @@ -17,12 +18,10 @@ import { } from '../types'; import { assert } from '../utils/assert'; import { constants } from '../utils/constants'; +import { utils } from '../utils/utils'; import { ContractWrapper } from './contract_wrapper'; import { ERC20ProxyWrapper } from './erc20_proxy_wrapper'; -import { ERC20TokenContract, ERC20TokenEventArgs, ERC20TokenEvents } from './generated/erc20_token'; - -const removeUndefinedProperties = _.pickBy; /** * This class includes all the functionality related to interacting with ERC20 token contracts. @@ -30,10 +29,10 @@ const removeUndefinedProperties = _.pickBy; * to the 0x ERC20 Proxy smart contract. */ export class ERC20TokenWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.ERC20Token.compilerOutput.abi; + public abi: ContractAbi = ERC20Token.compilerOutput.abi; public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; - private _tokenContractsByAddress: { [address: string]: ERC20TokenContract }; - private _erc20ProxyWrapper: ERC20ProxyWrapper; + private readonly _tokenContractsByAddress: { [address: string]: ERC20TokenContract }; + private readonly _erc20ProxyWrapper: ERC20ProxyWrapper; /** * Instantiate ERC20TokenWrapper * @param web3Wrapper Web3Wrapper instance to use @@ -108,7 +107,7 @@ export class ERC20TokenWrapper extends ContractWrapper { const txHash = await tokenContract.approve.sendTransactionAsync( normalizedSpenderAddress, amountInBaseUnits, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ from: normalizedOwnerAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, @@ -189,7 +188,7 @@ export class ERC20TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts: MethodOpts = {}, ): Promise<BigNumber> { - const proxyAddress = this._erc20ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc20ProxyWrapper.address; const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts); return allowanceInBaseUnits; } @@ -209,7 +208,7 @@ export class ERC20TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise<string> { - const proxyAddress = this._erc20ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc20ProxyWrapper.address; const txHash = await this.setAllowanceAsync( tokenAddress, ownerAddress, @@ -278,7 +277,7 @@ export class ERC20TokenWrapper extends ContractWrapper { const txHash = await tokenContract.transfer.sendTransactionAsync( normalizedToAddress, amountInBaseUnits, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ from: normalizedFromAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, @@ -339,7 +338,7 @@ export class ERC20TokenWrapper extends ContractWrapper { normalizedFromAddress, normalizedToAddress, amountInBaseUnits, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ from: normalizedSenderAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, @@ -373,7 +372,7 @@ export class ERC20TokenWrapper extends ContractWrapper { normalizedTokenAddress, eventName, indexFilterValues, - artifacts.ERC20Token.compilerOutput.abi, + ERC20Token.compilerOutput.abi, callback, isVerbose, ); @@ -418,30 +417,19 @@ export class ERC20TokenWrapper extends ContractWrapper { eventName, blockRange, indexFilterValues, - artifacts.ERC20Token.compilerOutput.abi, + ERC20Token.compilerOutput.abi, ); return logs; } - // 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 _invalidateContractInstances(): void { - this.unsubscribeAll(); - this._tokenContractsByAddress = {}; - } private async _getTokenContractAsync(tokenAddress: string): Promise<ERC20TokenContract> { const normalizedTokenAddress = tokenAddress.toLowerCase(); let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress]; if (!_.isUndefined(tokenContract)) { return tokenContract; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC20Token, - normalizedTokenAddress, - ); const contractInstance = new 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 933c1dc27..12758e191 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts @@ -1,38 +1,42 @@ -import { AssetProxyId } from '@0xproject/types'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ERC721ProxyContract } from '@0x/abi-gen-wrappers'; +import { ERC721Proxy } from '@0x/contract-artifacts'; +import { AssetProxyId } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { assert } from '../utils/assert'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { ContractWrapper } from './contract_wrapper'; -import { ERC721ProxyContract } from './generated/erc721_proxy'; /** * This class includes the functionality related to interacting with the ERC721Proxy contract. */ export class ERC721ProxyWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi; + public abi: ContractAbi = ERC721Proxy.compilerOutput.abi; + public address: string; private _erc721ProxyContractIfExists?: 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. If undefined, + * will default to the known address corresponding to the networkId. */ - constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) { + constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).erc721Proxy : address; } /** * Get the 4 bytes ID of this asset proxy * @return Proxy id */ public async getProxyIdAsync(): Promise<AssetProxyId> { - const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync(); + const ERC721ProxyContractInstance = await this._getERC721ProxyContract(); + // Note(albrow): Below is a TSLint false positive. Code won't compile if + // you remove the type assertion. + /* tslint:disable-next-line:no-unnecessary-type-assertion */ const proxyId = (await ERC721ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId; return proxyId; } @@ -44,7 +48,7 @@ export class ERC721ProxyWrapper extends ContractWrapper { public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> { 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; } @@ -53,36 +57,17 @@ export class ERC721ProxyWrapper extends ContractWrapper { * @return The list of authorized addresses. */ public async getAuthorizedAddressesAsync(): Promise<string[]> { - 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<ERC721ProxyContract> { + private _getERC721ProxyContract(): ERC721ProxyContract { if (!_.isUndefined(this._erc721ProxyContractIfExists)) { return this._erc721ProxyContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC721Proxy, - this._contractAddressIfExists, - ); const contractInstance = new 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 590dbbf74..1610af47b 100644 --- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts @@ -1,10 +1,11 @@ -import { schemas } from '@0xproject/json-schemas'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ERC721TokenContract, ERC721TokenEventArgs, ERC721TokenEvents } from '@0x/abi-gen-wrappers'; +import { ERC721Token } from '@0x/contract-artifacts'; +import { schemas } from '@0x/json-schemas'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { methodOptsSchema } from '../schemas/method_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; import { @@ -17,12 +18,10 @@ import { } from '../types'; import { assert } from '../utils/assert'; import { constants } from '../utils/constants'; +import { utils } from '../utils/utils'; import { ContractWrapper } from './contract_wrapper'; import { ERC721ProxyWrapper } from './erc721_proxy_wrapper'; -import { ERC721TokenContract, ERC721TokenEventArgs, ERC721TokenEvents } from './generated/erc721_token'; - -const removeUndefinedProperties = _.pickBy; /** * This class includes all the functionality related to interacting with ERC721 token contracts. @@ -30,9 +29,9 @@ const removeUndefinedProperties = _.pickBy; * to the 0x ERC721 Proxy smart contract. */ export class ERC721TokenWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.ERC721Token.compilerOutput.abi; - private _tokenContractsByAddress: { [address: string]: ERC721TokenContract }; - private _erc721ProxyWrapper: ERC721ProxyWrapper; + public abi: ContractAbi = ERC721Token.compilerOutput.abi; + private readonly _tokenContractsByAddress: { [address: string]: ERC721TokenContract }; + private readonly _erc721ProxyWrapper: ERC721ProxyWrapper; /** * Instantiate ERC721TokenWrapper * @param web3Wrapper Web3Wrapper instance to use @@ -150,7 +149,7 @@ export class ERC721TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts: MethodOpts = {}, ): Promise<boolean> { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const isProxyApprovedForAll = await this.isApprovedForAllAsync( tokenAddress, ownerAddress, @@ -199,7 +198,7 @@ export class ERC721TokenWrapper extends ContractWrapper { tokenId: BigNumber, methodOpts: MethodOpts = {}, ): Promise<boolean> { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const approvedAddress = await this.getApprovedIfExistsAsync(tokenAddress, tokenId, methodOpts); const isProxyApproved = approvedAddress === proxyAddress; return isProxyApproved; @@ -235,7 +234,7 @@ export class ERC721TokenWrapper extends ContractWrapper { const txHash = await tokenContract.setApprovalForAll.sendTransactionAsync( normalizedOperatorAddress, isApproved, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, from: normalizedOwnerAddress, @@ -260,7 +259,7 @@ export class ERC721TokenWrapper extends ContractWrapper { isApproved: boolean, txOpts: TransactionOpts = {}, ): Promise<string> { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const txHash = await this.setApprovalForAllAsync(tokenAddress, ownerAddress, proxyAddress, isApproved, txOpts); return txHash; } @@ -295,7 +294,7 @@ export class ERC721TokenWrapper extends ContractWrapper { const txHash = await tokenContract.approve.sendTransactionAsync( normalizedApprovedAddress, tokenId, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, from: tokenOwnerAddress, @@ -318,7 +317,7 @@ export class ERC721TokenWrapper extends ContractWrapper { tokenId: BigNumber, txOpts: TransactionOpts = {}, ): Promise<string> { - const proxyAddress = this._erc721ProxyWrapper.getContractAddress(); + const proxyAddress = this._erc721ProxyWrapper.address; const txHash = await this.setApprovalAsync(tokenAddress, proxyAddress, tokenId, txOpts); return txHash; } @@ -366,7 +365,7 @@ export class ERC721TokenWrapper extends ContractWrapper { ownerAddress, normalizedReceiverAddress, tokenId, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, from: normalizedSenderAddress, @@ -400,7 +399,7 @@ export class ERC721TokenWrapper extends ContractWrapper { normalizedTokenAddress, eventName, indexFilterValues, - artifacts.ERC721Token.compilerOutput.abi, + ERC721Token.compilerOutput.abi, callback, isVerbose, ); @@ -445,30 +444,19 @@ export class ERC721TokenWrapper extends ContractWrapper { eventName, blockRange, indexFilterValues, - artifacts.ERC721Token.compilerOutput.abi, + ERC721Token.compilerOutput.abi, ); return logs; } - // 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 _invalidateContractInstances(): void { - this.unsubscribeAll(); - this._tokenContractsByAddress = {}; - } private async _getTokenContractAsync(tokenAddress: string): Promise<ERC721TokenContract> { const normalizedTokenAddress = tokenAddress.toLowerCase(); let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress]; if (!_.isUndefined(tokenContract)) { return tokenContract; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.ERC721Token, - normalizedTokenAddress, - ); const contractInstance = new 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 1ac01812e..913c47cf7 100644 --- a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts @@ -1,29 +1,28 @@ -import { schemas } from '@0xproject/json-schemas'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { WETH9Contract, WETH9EventArgs, WETH9Events } from '@0x/abi-gen-wrappers'; +import { WETH9 } from '@0x/contract-artifacts'; +import { schemas } from '@0x/json-schemas'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { BlockRange, ContractWrappersError, EventCallback, IndexedFilterValues, TransactionOpts } from '../types'; import { assert } from '../utils/assert'; +import { utils } from '../utils/utils'; import { ContractWrapper } from './contract_wrapper'; import { ERC20TokenWrapper } from './erc20_token_wrapper'; -import { WETH9Contract, WETH9EventArgs, WETH9Events } from './generated/weth9'; - -const removeUndefinedProperties = _.pickBy; /** * This class includes all the functionality related to interacting with a wrapped Ether ERC20 token contract. * The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back. */ export class EtherTokenWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.EtherToken.compilerOutput.abi; - private _etherTokenContractsByAddress: { + public abi: ContractAbi = WETH9.compilerOutput.abi; + private readonly _etherTokenContractsByAddress: { [address: string]: WETH9Contract; } = {}; - private _erc20TokenWrapper: ERC20TokenWrapper; + private readonly _erc20TokenWrapper: ERC20TokenWrapper; /** * Instantiate EtherTokenWrapper. * @param web3Wrapper Web3Wrapper instance to use @@ -67,7 +66,7 @@ export class EtherTokenWrapper extends ContractWrapper { const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); const txHash = await wethContract.deposit.sendTransactionAsync( - removeUndefinedProperties({ + utils.removeUndefinedProperties({ from: normalizedDepositorAddress, value: amountInWei, gas: txOpts.gasLimit, @@ -109,7 +108,7 @@ export class EtherTokenWrapper extends ContractWrapper { const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); const txHash = await wethContract.withdraw.sendTransactionAsync( amountInWei, - removeUndefinedProperties({ + utils.removeUndefinedProperties({ from: normalizedWithdrawerAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, @@ -142,7 +141,7 @@ export class EtherTokenWrapper extends ContractWrapper { eventName, blockRange, indexFilterValues, - artifacts.EtherToken.compilerOutput.abi, + WETH9.compilerOutput.abi, ); return logs; } @@ -172,7 +171,7 @@ export class EtherTokenWrapper extends ContractWrapper { normalizedEtherTokenAddress, eventName, indexFilterValues, - artifacts.EtherToken.compilerOutput.abi, + WETH9.compilerOutput.abi, callback, isVerbose, ); @@ -192,36 +191,14 @@ 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.EtherToken.networks[this._networkId]; - const contractAddressIfExists = _.isUndefined(networkSpecificArtifact) - ? undefined - : networkSpecificArtifact.address; - return contractAddressIfExists; - } - // tslint:disable-next-line:no-unused-variable - private _invalidateContractInstance(): void { - this.unsubscribeAll(); - this._etherTokenContractsByAddress = {}; - } private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<WETH9Contract> { let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress]; if (!_.isUndefined(etherTokenContract)) { return etherTokenContract; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.EtherToken, - etherTokenAddress, - ); const contractInstance = new 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 dc9ffcbf7..c76e51eee 100644 --- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts @@ -1,22 +1,24 @@ -import { schemas } from '@0xproject/json-schemas'; +import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from '@0x/abi-gen-wrappers'; +import { Exchange } from '@0x/contract-artifacts'; +import { schemas } from '@0x/json-schemas'; import { assetDataUtils, BalanceAndProxyAllowanceLazyStore, ExchangeTransferSimulator, OrderValidationUtils, -} from '@0xproject/order-utils'; -import { AssetProxyId, Order, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +} from '@0x/order-utils'; +import { AssetProxyId, Order, SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { BlockParamLiteral, ContractAbi, LogWithDecodedArgs } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { AssetBalanceAndProxyAllowanceFetcher } from '../fetchers/asset_balance_and_proxy_allowance_fetcher'; import { OrderFilledCancelledFetcher } from '../fetchers/order_filled_cancelled_fetcher'; import { methodOptsSchema } from '../schemas/method_opts_schema'; import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; +import { validateOrderFillableOptsSchema } from '../schemas/validate_order_fillable_opts_schema'; import { BlockRange, EventCallback, @@ -24,54 +26,58 @@ import { IndexedFilterValues, MethodOpts, OrderInfo, - OrderStatus, OrderTransactionOpts, ValidateOrderFillableOpts, } from '../types'; import { assert } from '../utils/assert'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { decorators } from '../utils/decorators'; import { TransactionEncoder } from '../utils/transaction_encoder'; import { ContractWrapper } from './contract_wrapper'; import { ERC20TokenWrapper } from './erc20_token_wrapper'; import { ERC721TokenWrapper } from './erc721_token_wrapper'; -import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange'; /** * This class includes all the functionality related to calling methods, sending transactions and subscribing to * events of the 0x V2 Exchange smart contract. */ export class ExchangeWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.Exchange.compilerOutput.abi; + public abi: ContractAbi = Exchange.compilerOutput.abi; + public address: string; + public zrxTokenAddress: string; private _exchangeContractIfExists?: ExchangeContract; - private _erc721TokenWrapper: ERC721TokenWrapper; - private _erc20TokenWrapper: ERC20TokenWrapper; - private _contractAddressIfExists?: string; - private _zrxContractAddressIfExists?: string; + private readonly _erc721TokenWrapper: ERC721TokenWrapper; + private readonly _erc20TokenWrapper: ERC20TokenWrapper; /** * 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 networkId Desired networkId. + * @param erc20TokenWrapper ERC20TokenWrapper instance to use. + * @param erc721TokenWrapper ERC721TokenWrapper instance to use. + * @param address The address of the Exchange contract. If undefined, will + * default to the known address corresponding to the networkId. + * @param zrxTokenAddress The address of the ZRXToken contract. If + * undefined, will default to the known address corresponding to the + * networkId. + * @param blockPollingIntervalMs The block polling interval to use for active subscriptions. */ constructor( web3Wrapper: Web3Wrapper, networkId: number, erc20TokenWrapper: ERC20TokenWrapper, erc721TokenWrapper: ERC721TokenWrapper, - contractAddressIfExists?: string, - zrxContractAddressIfExists?: string, + address?: string, + zrxTokenAddress?: string, blockPollingIntervalMs?: number, ) { super(web3Wrapper, networkId, blockPollingIntervalMs); this._erc20TokenWrapper = erc20TokenWrapper; this._erc721TokenWrapper = erc721TokenWrapper; - this._contractAddressIfExists = contractAddressIfExists; - this._zrxContractAddressIfExists = zrxContractAddressIfExists; + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).exchange : address; + this.zrxTokenAddress = _.isUndefined(zrxTokenAddress) + ? _getDefaultContractAddresses(networkId).zrxToken + : zrxTokenAddress; } /** * Retrieve the address of an asset proxy by signature. @@ -1051,12 +1057,11 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); - const exchangeContractAddress = this.getContractAddress(); const subscriptionToken = this._subscribe<ArgsType>( - exchangeContractAddress, + this.address, eventName, indexFilterValues, - artifacts.Exchange.compilerOutput.abi, + Exchange.compilerOutput.abi, callback, isVerbose, ); @@ -1091,13 +1096,12 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); - const exchangeContractAddress = this.getContractAddress(); const logs = await this._getLogsAsync<ArgsType>( - exchangeContractAddress, + this.address, eventName, blockRange, indexFilterValues, - artifacts.Exchange.compilerOutput.abi, + Exchange.compilerOutput.abi, ); return logs; } @@ -1111,6 +1115,9 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder: SignedOrder, opts: ValidateOrderFillableOpts = {}, ): Promise<void> { + assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); + assert.doesConformToSchema('opts', opts, validateOrderFillableOptsSchema); + const balanceAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher( this._erc20TokenWrapper, this._erc721TokenWrapper, @@ -1121,7 +1128,7 @@ export class ExchangeWrapper extends ContractWrapper { const expectedFillTakerTokenAmountIfExists = opts.expectedFillTakerTokenAmount; const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest); - const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher); + const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider()); await orderValidationUtils.validateOrderFillableOrThrowAsync( exchangeTradeSimulator, signedOrder, @@ -1149,7 +1156,7 @@ export class ExchangeWrapper extends ContractWrapper { const exchangeTradeSimulator = new ExchangeTransferSimulator(balanceAllowanceStore); const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest); - const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher); + const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider()); await orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeSimulator, this._web3Wrapper.getProvider(), @@ -1160,29 +1167,11 @@ export class ExchangeWrapper extends ContractWrapper { ); } /** - * 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; } /** @@ -1195,23 +1184,14 @@ export class ExchangeWrapper extends ContractWrapper { const encoder = new TransactionEncoder(exchangeInstance); return encoder; } - // tslint:disable:no-unused-variable - private _invalidateContractInstances(): void { - this.unsubscribeAll(); - delete this._exchangeContractIfExists; - } // tslint:enable:no-unused-variable private async _getExchangeContractAsync(): Promise<ExchangeContract> { if (!_.isUndefined(this._exchangeContractIfExists)) { return this._exchangeContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.Exchange, - this._contractAddressIfExists, - ); const contractInstance = new 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 c19edf188..80742e030 100644 --- a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts @@ -1,40 +1,62 @@ -import { schemas } from '@0xproject/json-schemas'; -import { AssetProxyId, SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { ForwarderContract } from '@0x/abi-gen-wrappers'; +import { Forwarder } from '@0x/contract-artifacts'; +import { schemas } from '@0x/json-schemas'; +import { SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema'; import { txOptsSchema } from '../schemas/tx_opts_schema'; import { OrderTransactionOpts } from '../types'; import { assert } from '../utils/assert'; import { calldataOptimizationUtils } from '../utils/calldata_optimization_utils'; import { constants } from '../utils/constants'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { decorators } from '../utils/decorators'; import { utils } from '../utils/utils'; import { ContractWrapper } from './contract_wrapper'; -import { ForwarderContract } from './generated/forwarder'; /** * This class includes the functionality related to interacting with the Forwarder contract. */ export class ForwarderWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.Forwarder.compilerOutput.abi; + public abi: ContractAbi = Forwarder.compilerOutput.abi; + public address: string; + public zrxTokenAddress: string; + public etherTokenAddress: string; private _forwarderContractIfExists?: ForwarderContract; - private _contractAddressIfExists?: string; - private _zrxContractAddressIfExists?: string; + + /** + * Instantiate ForwarderWrapper + * @param web3Wrapper Web3Wrapper instance to use. + * @param networkId Desired networkId. + * @param address The address of the Exchange contract. If undefined, will + * default to the known address corresponding to the networkId. + * @param zrxTokenAddress The address of the ZRXToken contract. If + * undefined, will default to the known address corresponding to the + * networkId. + * @param etherTokenAddress The address of a WETH (Ether token) contract. If + * undefined, will default to the known address corresponding to the + * networkId. + */ constructor( web3Wrapper: Web3Wrapper, networkId: number, - contractAddressIfExists?: string, - zrxContractAddressIfExists?: string, + address?: string, + zrxTokenAddress?: string, + etherTokenAddress?: string, ) { super(web3Wrapper, networkId); - this._contractAddressIfExists = contractAddressIfExists; - this._zrxContractAddressIfExists = zrxContractAddressIfExists; + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).exchange : address; + this.zrxTokenAddress = _.isUndefined(zrxTokenAddress) + ? _getDefaultContractAddresses(networkId).zrxToken + : zrxTokenAddress; + this.etherTokenAddress = _.isUndefined(etherTokenAddress) + ? _getDefaultContractAddresses(networkId).etherToken + : etherTokenAddress; } /** * Purchases as much of orders' makerAssets as possible by selling up to 95% of transaction's ETH value. @@ -73,12 +95,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 @@ -100,7 +118,7 @@ export class ForwarderWrapper extends ContractWrapper { optimizedFeeOrders, feeSignatures, formattedFeePercentage, - feeRecipientAddress, + normalizedFeeRecipientAddress, { value: ethAmount, from: normalizedTakerAddress, @@ -165,12 +183,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 @@ -193,7 +207,7 @@ export class ForwarderWrapper extends ContractWrapper { optimizedFeeOrders, feeSignatures, formattedFeePercentage, - feeRecipientAddress, + normalizedFeeRecipientAddress, { value: ethAmount, from: normalizedTakerAddress, @@ -220,48 +234,13 @@ 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.EtherToken); - 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._forwarderContractIfExists; - } private async _getForwarderContractAsync(): Promise<ForwarderContract> { if (!_.isUndefined(this._forwarderContractIfExists)) { return this._forwarderContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( - artifacts.Forwarder, - this._contractAddressIfExists, - ); const contractInstance = new 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 1da88f624..c186e080e 100644 --- a/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/order_validator_wrapper.ts @@ -1,30 +1,35 @@ -import { schemas } from '@0xproject/json-schemas'; -import { SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { OrderValidatorContract } from '@0x/abi-gen-wrappers'; +import { OrderValidator } from '@0x/contract-artifacts'; +import { schemas } from '@0x/json-schemas'; +import { SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { ContractAbi } from 'ethereum-types'; import * as _ from 'lodash'; -import { artifacts } from '../artifacts'; import { BalanceAndAllowance, OrderAndTraderInfo, TraderInfo } from '../types'; import { assert } from '../utils/assert'; +import { _getDefaultContractAddresses } from '../utils/contract_addresses'; import { ContractWrapper } from './contract_wrapper'; -import { OrderValidatorContract } from './generated/order_validator'; /** * This class includes the functionality related to interacting with the OrderValidator contract. */ export class OrderValidatorWrapper extends ContractWrapper { - public abi: ContractAbi = artifacts.OrderValidator.compilerOutput.abi; + public abi: ContractAbi = OrderValidator.compilerOutput.abi; + public address: string; private _orderValidatorContractIfExists?: OrderValidatorContract; /** * Instantiate OrderValidatorWrapper - * @param web3Wrapper Web3Wrapper instance to use - * @param networkId Desired networkId + * @param web3Wrapper Web3Wrapper instance to use. + * @param networkId Desired networkId. + * @param address The address of the OrderValidator contract. If undefined, + * will default to the known address corresponding to the networkId. */ - constructor(web3Wrapper: Web3Wrapper, networkId: number) { + constructor(web3Wrapper: Web3Wrapper, networkId: number, address?: string) { super(web3Wrapper, networkId); + this.address = _.isUndefined(address) ? _getDefaultContractAddresses(networkId).exchange : address; } /** * Get an object conforming to OrderAndTraderInfo containing on-chain information of the provided order and address @@ -164,20 +169,13 @@ export class OrderValidatorWrapper extends ContractWrapper { const result = await OrderValidatorContractInstance.getERC721TokenOwner.callAsync(tokenAddress, tokenId); return result; } - // 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._orderValidatorContractIfExists; - } private async _getOrderValidatorContractAsync(): Promise<OrderValidatorContract> { if (!_.isUndefined(this._orderValidatorContractIfExists)) { return this._orderValidatorContractIfExists; } - const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(artifacts.OrderValidator); const contractInstance = new OrderValidatorContract( - abi, - address, + this.abi, + this.address, this._web3Wrapper.getProvider(), this._web3Wrapper.getContractDefaults(), ); |