From 0b326a8bbefd7efee4ebc8b56cbc3faab52e93d6 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 10:50:41 -0800 Subject: Add web3Wrapper.callAsync and remove web3Wrapper.getContractInstance --- .prettierignore | 1 - packages/web3-wrapper/CHANGELOG.md | 9 ++++++--- packages/web3-wrapper/src/index.ts | 12 ++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.prettierignore b/.prettierignore index c3738481a..385c15654 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,4 @@ lib -generated .nyc_output /packages/contracts/src/artifacts package.json diff --git a/packages/web3-wrapper/CHANGELOG.md b/packages/web3-wrapper/CHANGELOG.md index 387aafb3a..eef665d24 100644 --- a/packages/web3-wrapper/CHANGELOG.md +++ b/packages/web3-wrapper/CHANGELOG.md @@ -1,9 +1,12 @@ # CHANGELOG -## v0.2.XX - _TBD_ 2018 +## v0.2.0 _TBD, 2018_ - * Ensure all returned user addresses are lowercase (#373) + * Ensure all returned user addresses are lowercase (#373) + * Add `web3Wrapper.callAsync` (#413) + * Make `web3Wrapper.estimateGas` accept whole `txData` instead of `data` (#413) + * Remove `web3Wrapper.getContractInstance` (#413) -## v0.1.12 - _February 9, 2018_ +## v0.1.12 _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts index 7f3452c98..e7c875430 100644 --- a/packages/web3-wrapper/src/index.ts +++ b/packages/web3-wrapper/src/index.ts @@ -128,14 +128,14 @@ export class Web3Wrapper { const web3Contract = this._web3.eth.contract(abi); return web3Contract; } - public getContractInstance(abi: Web3.ContractAbi, address: string): Web3.ContractInstance { - const web3ContractInstance = this.getContractFromAbi(abi).at(address); - return web3ContractInstance; - } - public async estimateGasAsync(data: string): Promise { - const gas = await promisify(this._web3.eth.estimateGas)({ data }); + public async estimateGasAsync(txData: Partial): Promise { + const gas = await promisify(this._web3.eth.estimateGas)(txData); return gas; } + public async callAsync(callData: Web3.CallData): Promise { + const rawCalllResult = await promisify(this._web3.eth.call)(callData); + return rawCalllResult; + } public async sendTransactionAsync(txData: Web3.TxData): Promise { const txHash = await promisify(this._web3.eth.sendTransaction)(txData); return txHash; -- cgit v1.2.3 From 42a5da1df44d579045c92ea30ed62872ff6603b4 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 10:52:00 -0800 Subject: Fix default paths --- packages/deployer/src/cli.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/deployer/src/cli.ts b/packages/deployer/src/cli.ts index ba156ac20..cff676179 100644 --- a/packages/deployer/src/cli.ts +++ b/packages/deployer/src/cli.ts @@ -10,8 +10,8 @@ import { constants } from './utils/constants'; import { CliOptions, CompilerOptions, DeployerOptions } from './utils/types'; const DEFAULT_OPTIMIZER_ENABLED = false; -const DEFAULT_CONTRACTS_DIR = path.resolve('src'); -const DEFAULT_ARTIFACTS_DIR = path.resolve('artifacts'); +const DEFAULT_CONTRACTS_DIR = path.resolve('src/contracts'); +const DEFAULT_ARTIFACTS_DIR = path.resolve('src/artifacts'); const DEFAULT_NETWORK_ID = 50; const DEFAULT_JSONRPC_PORT = 8545; const DEFAULT_GAS_PRICE = (10 ** 9 * 2).toString(); -- cgit v1.2.3 From 0409c9c1e5a30380745c3406666d3fc6234d76c0 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 10:52:12 -0800 Subject: Fix default contract set calculation --- packages/deployer/src/cli.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/deployer/src/cli.ts b/packages/deployer/src/cli.ts index cff676179..c976e8f97 100644 --- a/packages/deployer/src/cli.ts +++ b/packages/deployer/src/cli.ts @@ -100,6 +100,9 @@ async function onDeployCommand(argv: CliOptions): Promise { */ function getContractsSetFromList(contracts: string): Set { const specifiedContracts = new Set(); + if (contracts === '*') { + return new Set(['*']); + } const contractsArray = contracts.split(','); _.forEach(contractsArray, contractName => { const fileName = `${contractName}${constants.SOLIDITY_FILE_EXTENSION}`; -- cgit v1.2.3 From 5fbdf9cfb94836335aaaf6a6bcbb231d35b3e882 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 10:52:50 -0800 Subject: Pass whole txData to estimateGas --- packages/deployer/src/deployer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/deployer/src/deployer.ts b/packages/deployer/src/deployer.ts index 021645fd1..6710bcc85 100644 --- a/packages/deployer/src/deployer.ts +++ b/packages/deployer/src/deployer.ts @@ -174,7 +174,7 @@ export class Deployer { const block = await this.web3Wrapper.getBlockAsync('latest'); let gas: number; try { - const gasEstimate: number = await this.web3Wrapper.estimateGasAsync(data); + const gasEstimate: number = await this.web3Wrapper.estimateGasAsync({ data }); gas = Math.min(gasEstimate + EXTRA_GAS, block.gasLimit); } catch (err) { gas = block.gasLimit; -- cgit v1.2.3 From f5275d3ad75d2a989556de99cdef82bcf2cd687c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 10:57:23 -0800 Subject: Add data to TxData --- packages/types/CHANGELOG.md | 4 ++++ packages/types/src/index.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index b1cb721d2..bea6f07bc 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.2.4 - _TBD, 2018_ + + * Add `data` to `TxData` (#TBD) + ## v0.2.1 - _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index cb17936f7..484faa93d 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -2,6 +2,7 @@ import { BigNumber } from 'bignumber.js'; import * as Web3 from 'web3'; export interface TxData { + data?: string; from?: string; gas?: number; gasPrice?: BigNumber; -- cgit v1.2.3 From 2d561bc8a05e8d1fca91cde93bae2080d87be926 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 11:35:44 -0800 Subject: Allow users to specify the contracts backend in abi-gen --- .../0x.js/contract_templates/contract.handlebars | 10 ++-- .../contract_templates/partials/call.handlebars | 20 +++++--- .../contract_templates/partials/tx.handlebars | 36 +++++++++------ packages/0x.js/package.json | 3 +- .../src/contract_wrappers/contract_wrapper.ts | 8 ++-- .../src/contract_wrappers/ether_token_wrapper.ts | 4 +- .../src/contract_wrappers/exchange_wrapper.ts | 6 +-- .../contract_wrappers/generated/base_contract.ts | 53 ++++++++++++++++++---- .../contract_wrappers/token_registry_wrapper.ts | 12 ++--- .../token_transfer_proxy_wrapper.ts | 7 +-- .../0x.js/src/contract_wrappers/token_wrapper.ts | 4 +- packages/0x.js/src/globals.d.ts | 28 ++++++++++++ packages/0x.js/src/types.ts | 2 +- packages/0x.js/test/utils/fill_scenarios.ts | 6 +-- packages/abi-gen/CHANGELOG.md | 4 ++ packages/abi-gen/src/index.ts | 13 ++++-- packages/abi-gen/src/types.ts | 5 ++ packages/abi-gen/src/utils.ts | 18 ++++++-- yarn.lock | 31 ++++++++++++- 19 files changed, 199 insertions(+), 71 deletions(-) diff --git a/packages/0x.js/contract_templates/contract.handlebars b/packages/0x.js/contract_templates/contract.handlebars index 33699b8a7..2954145a7 100644 --- a/packages/0x.js/contract_templates/contract.handlebars +++ b/packages/0x.js/contract_templates/contract.handlebars @@ -6,6 +6,9 @@ // tslint:disable-next-line:no-unused-variable import { TxData, TxDataPayable } from '@0xproject/types'; import { BigNumber, classUtils, promisify } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as ethersContracts from 'ethers-contracts'; +import * as _ from 'lodash'; import * as Web3 from 'web3'; import {BaseContract} from './base_contract'; @@ -28,6 +31,7 @@ export enum {{contractName}}Events { {{/each}} {{/if}} +// tslint:disable:no-parameter-reassignment export class {{contractName}}Contract extends BaseContract { {{#each methods}} {{#this.constant}} @@ -37,8 +41,8 @@ export class {{contractName}}Contract extends BaseContract { {{> tx contractName=../contractName}} {{/this.constant}} {{/each}} - constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial) { - super(web3ContractInstance, defaults); - classUtils.bindAll(this, ['_web3ContractInstance', '_defaults']); + constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { + super(web3Wrapper, abi, address); + classUtils.bindAll(this, ['_ethersInterface', '_address', '_abi', '_web3Wrapper']); } } // tslint:disable:max-file-line-count diff --git a/packages/0x.js/contract_templates/partials/call.handlebars b/packages/0x.js/contract_templates/partials/call.handlebars index 0475136f0..c533712b7 100644 --- a/packages/0x.js/contract_templates/partials/call.handlebars +++ b/packages/0x.js/contract_templates/partials/call.handlebars @@ -4,12 +4,20 @@ public {{this.name}} = { defaultBlock?: Web3.BlockParam, ): Promise<{{> return_type outputs=outputs}}> { const self = this as {{contractName}}Contract; - const result = await promisify<{{> return_type outputs=outputs}}>( - self._web3ContractInstance.{{this.name}}.call, - self._web3ContractInstance, - )( + const inputAbi = _.find(this._abi, {name: '{{this.name}}'}).inputs; + [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); + const callDescription = self._ethersInterface.functions.{{this.name}}( {{> params inputs=inputs}} - ); - return result; + ) as ethersContracts.CallDescription; + const callData = await self._applyDefaultsToTxDataAsync( + { + data: callDescription.data, + } + ) + const rawCallResult = await self._web3Wrapper.callAsync(callData); + let resultArray = callDescription.parse(rawCallResult); + const outputAbi = _.find(this._abi, {name: '{{this.name}}'}).outputs; + resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); + return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; }, }; diff --git a/packages/0x.js/contract_templates/partials/tx.handlebars b/packages/0x.js/contract_templates/partials/tx.handlebars index 9df83266a..aae9aa404 100644 --- a/packages/0x.js/contract_templates/partials/tx.handlebars +++ b/packages/0x.js/contract_templates/partials/tx.handlebars @@ -9,19 +9,22 @@ public {{this.name}} = { {{/this.payable}} ): Promise { const self = this as {{contractName}}Contract; + const inputAbi = _.find(this._abi, {name: '{{this.name}}'}).inputs; + [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); + const data = this._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ).data const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( - txData, + { + ...txData, + data, + }, self.{{this.name}}.estimateGasAsync.bind( self, {{> params inputs=inputs}} ), ); - const txHash = await promisify( - self._web3ContractInstance.{{this.name}}, self._web3ContractInstance, - )( - {{> params inputs=inputs}} - txDataWithDefaults, - ); + const txHash = await this._web3Wrapper.sendTransactionAsync(txDataWithDefaults); return txHash; }, async estimateGasAsync( @@ -29,15 +32,16 @@ public {{this.name}} = { txData: TxData = {}, ): Promise { const self = this as {{contractName}}Contract; - const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( - txData, - ); - const gas = await promisify( - self._web3ContractInstance.{{this.name}}.estimateGas, self._web3ContractInstance, - )( + const data = this._ethersInterface.functions.{{this.name}}( {{> params inputs=inputs}} - txDataWithDefaults, + ).data + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { + ...txData, + data, + } ); + const gas = await this._web3Wrapper.estimateGasAsync(txDataWithDefaults); return gas; }, getABIEncodedTransactionData( @@ -45,7 +49,9 @@ public {{this.name}} = { txData: TxData = {}, ): string { const self = this as {{contractName}}Contract; - const abiEncodedTransactionData = self._web3ContractInstance.{{this.name}}.getData(); + const abiEncodedTransactionData = this._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ).data return abiEncodedTransactionData; }, }; diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 4fb0eb6ac..6a0a84cfc 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -17,7 +17,7 @@ "build": "run-p build:umd:prod build:commonjs; exit 0;", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated && prettier --write 'src/contract_wrappers/generated/**.ts'", "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", "test:circleci": "run-s test:coverage report_test_coverage", "test": "run-s clean test:commonjs", @@ -91,6 +91,7 @@ "ethereumjs-abi": "^0.6.4", "ethereumjs-blockstream": "^2.0.6", "ethereumjs-util": "^5.1.1", + "ethers-contracts": "^2.2.1", "js-sha3": "^0.7.0", "lodash": "^4.17.4", "uuid": "^3.1.0", diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts index b313273b5..ad7727de5 100644 --- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts @@ -108,10 +108,10 @@ export class ContractWrapper { const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log); return logWithDecodedArgs; } - protected async _instantiateContractIfExistsAsync( + protected async _getContractAbiAndAddressFromArtifactsAsync( artifact: Artifact, addressIfExists?: string, - ): Promise { + ): Promise<[Web3.ContractAbi, string]> { let contractAddress: string; if (_.isUndefined(addressIfExists)) { if (_.isUndefined(artifact.networks[this._networkId])) { @@ -125,8 +125,8 @@ export class ContractWrapper { if (!doesContractExist) { throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]); } - const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress); - return contractInstance; + const abiAndAddress: [Web3.ContractAbi, string] = [artifact.abi, contractAddress]; + return abiAndAddress; } protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string { if (_.isUndefined(addressIfExists)) { diff --git a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts index 4807eff33..42f8213a2 100644 --- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts @@ -187,11 +187,11 @@ export class EtherTokenWrapper extends ContractWrapper { if (!_.isUndefined(etherTokenContract)) { return etherTokenContract; } - const web3ContractInstance = await this._instantiateContractIfExistsAsync( + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( artifacts.EtherTokenArtifact, etherTokenAddress, ); - const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults()); + const contractInstance = new EtherTokenContract(this._web3Wrapper, abi, address); etherTokenContract = contractInstance; this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract; return etherTokenContract; diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index 6bafc84c1..e0f6bd539 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -858,7 +858,7 @@ export class ExchangeWrapper extends ContractWrapper { }); if (!_.isUndefined(errLog)) { const logArgs = (errLog as LogWithDecodedArgs).args; - const errCode = logArgs.errorId.toNumber(); + const errCode = logArgs.errorId; const errMessage = this._exchangeContractErrCodesToMsg[errCode]; throw new Error(errMessage); } @@ -906,11 +906,11 @@ export class ExchangeWrapper extends ContractWrapper { if (!_.isUndefined(this._exchangeContractIfExists)) { return this._exchangeContractIfExists; } - const web3ContractInstance = await this._instantiateContractIfExistsAsync( + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( artifacts.ExchangeArtifact, this._contractAddressIfExists, ); - const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults()); + const contractInstance = new ExchangeContract(this._web3Wrapper, abi, address); this._exchangeContractIfExists = contractInstance; return this._exchangeContractIfExists; } diff --git a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts index d8fac7eea..a62c785bc 100644 --- a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts +++ b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts @@ -1,11 +1,45 @@ -import {TxData, TxDataPayable} from '@0xproject/types'; +import { TxData, TxDataPayable } from '@0xproject/types'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as ethersContracts from 'ethers-contracts'; import * as _ from 'lodash'; import * as Web3 from 'web3'; export class BaseContract { - protected _web3ContractInstance: Web3.ContractInstance; - protected _defaults: Partial; - protected async _applyDefaultsToTxDataAsync( + protected _ethersInterface: ethersContracts.Interface; + protected _web3Wrapper: Web3Wrapper; + protected _abi: Web3.ContractAbi; + protected _address: string; + protected static _transformABIData( + abis: Web3.DataItem[], + values: any[], + transformation: (type: string, value: any) => any, + ): any { + return _.map(values, (value: any, i: number) => + BaseContract._transformTypedData(abis[i].type, value, transformation), + ); + } + protected static _lowercaseAddress(type: string, value: string): string { + return type === 'address' ? value.toLowerCase() : value; + } + protected static _bigNumberToString(type: string, value: string): string { + return _.isObject(value) && (value as any).isBigNumber ? value.toString() : value; + } + private static _transformTypedData( + type: string, + values: any, + transformation: (type: string, value: any) => any, + ): any { + const trailingArrayRegex = /\[\d*\]$/; + if (type.match(trailingArrayRegex)) { + const arrayItemType = type.replace(trailingArrayRegex, ''); + return _.map(values, (value: any, i: number) => + this._transformTypedData(arrayItemType, value, transformation), + ); + } else { + return transformation(type, values); + } + } + protected async _applyDefaultsToTxDataAsync>( txData: T, estimateGasAsync?: (txData: T) => Promise, ): Promise { @@ -15,7 +49,8 @@ export class BaseContract { // 3. Gas estimate calculation + safety margin const removeUndefinedProperties = _.pickBy; const txDataWithDefaults = { - ...removeUndefinedProperties(this._defaults), + to: this._address, + ...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()), ...removeUndefinedProperties(txData as any), // HACK: TS can't prove that T is spreadable. // Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged @@ -26,8 +61,10 @@ export class BaseContract { } return txDataWithDefaults; } - constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial) { - this._web3ContractInstance = web3ContractInstance; - this._defaults = defaults; + constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { + this._web3Wrapper = web3Wrapper; + this._abi = abi; + this._address = address; + this._ethersInterface = new ethersContracts.Interface(abi); } } diff --git a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts index f0ae5f33c..e1806c6f2 100644 --- a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts @@ -23,7 +23,7 @@ export class TokenRegistryWrapper extends ContractWrapper { address: metadata[0], name: metadata[1], symbol: metadata[2], - decimals: metadata[3].toNumber(), + decimals: metadata[3], }; return token; } @@ -50,7 +50,8 @@ export class TokenRegistryWrapper extends ContractWrapper { public async getTokenAddressesAsync(): Promise { const tokenRegistryContract = await this._getTokenRegistryContractAsync(); const addresses = await tokenRegistryContract.getTokenAddresses.callAsync(); - return addresses; + const lowerCaseAddresses = _.map(addresses, address => address.toLowerCase()); + return lowerCaseAddresses; } /** * Retrieves a token by address currently listed in the Token Registry smart contract @@ -116,14 +117,11 @@ export class TokenRegistryWrapper extends ContractWrapper { if (!_.isUndefined(this._tokenRegistryContractIfExists)) { return this._tokenRegistryContractIfExists; } - const web3ContractInstance = await this._instantiateContractIfExistsAsync( + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( artifacts.TokenRegistryArtifact, this._contractAddressIfExists, ); - const contractInstance = new TokenRegistryContract( - web3ContractInstance, - this._web3Wrapper.getContractDefaults(), - ); + const contractInstance = new TokenRegistryContract(this._web3Wrapper, abi, address); this._tokenRegistryContractIfExists = contractInstance; return this._tokenRegistryContractIfExists; } diff --git a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts index f0cbf364d..211c7dfb4 100644 --- a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts @@ -59,14 +59,11 @@ export class TokenTransferProxyWrapper extends ContractWrapper { if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) { return this._tokenTransferProxyContractIfExists; } - const web3ContractInstance = await this._instantiateContractIfExistsAsync( + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( artifacts.TokenTransferProxyArtifact, this._contractAddressIfExists, ); - const contractInstance = new TokenTransferProxyContract( - web3ContractInstance, - this._web3Wrapper.getContractDefaults(), - ); + const contractInstance = new TokenTransferProxyContract(this._web3Wrapper, abi, address); this._tokenTransferProxyContractIfExists = contractInstance; return this._tokenTransferProxyContractIfExists; } diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts index 11a7670c0..0ec9ad707 100644 --- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts @@ -419,11 +419,11 @@ export class TokenWrapper extends ContractWrapper { if (!_.isUndefined(tokenContract)) { return tokenContract; } - const web3ContractInstance = await this._instantiateContractIfExistsAsync( + const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync( artifacts.TokenArtifact, normalizedTokenAddress, ); - const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults()); + const contractInstance = new TokenContract(this._web3Wrapper, abi, address); tokenContract = contractInstance; this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract; return tokenContract; diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts index 0e103d057..702f35149 100644 --- a/packages/0x.js/src/globals.d.ts +++ b/packages/0x.js/src/globals.d.ts @@ -41,3 +41,31 @@ declare module 'truffle-hdwallet-provider' { } export = HDWalletProvider; } + +declare module 'ethers-contracts' { + export interface TransactionDescription { + name: string; + signature: string; + sighash: string; + data: string; + } + export interface CallDescription extends TransactionDescription { + parse: (...args: any[]) => any; + } + export interface FunctionDescription { + (...params: any[]): TransactionDescription | CallDescription; + inputs: { names: string[]; types: string[] }; + outputs: { names: string[]; types: string[] }; + } + export interface EventDescription { + inputs: { names: string[]; types: string[] }; + signature: string; + topic: string; + } + // tslint:disable-next-line:max-classes-per-file + export class Interface { + public functions: { [functionName: string]: FunctionDescription }; + public events: { [eventName: string]: EventDescription }; + constructor(abi: any); + } +} diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index 0a3037258..2f17e30c2 100644 --- a/packages/0x.js/src/types.ts +++ b/packages/0x.js/src/types.ts @@ -127,7 +127,7 @@ export interface SignedOrder extends Order { } // [address, name, symbol, decimals, ipfsHash, swarmHash] -export type TokenMetadata = [string, string, string, BigNumber, string, string]; +export type TokenMetadata = [string, string, string, number, string, string]; export interface Token { name: string; diff --git a/packages/0x.js/test/utils/fill_scenarios.ts b/packages/0x.js/test/utils/fill_scenarios.ts index 1a61487f4..8b1308298 100644 --- a/packages/0x.js/test/utils/fill_scenarios.ts +++ b/packages/0x.js/test/utils/fill_scenarios.ts @@ -35,12 +35,8 @@ export class FillScenarios { const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper; for (const token of this._tokens) { if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') { - const contractInstance = web3Wrapper.getContractInstance( - artifacts.DummyTokenArtifact.abi, - token.address, - ); const defaults = {}; - const dummyToken = new DummyTokenContract(contractInstance, defaults); + const dummyToken = new DummyTokenContract(web3Wrapper, artifacts.DummyTokenArtifact.abi, token.address); const tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals); const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, { from: this._coinbase, diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index c86d6fb55..7e589551e 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.2.3 - _TBD, 2018_ + + * Add a `backend` parameter that allows you to specify your backend (web3 or ethers). Ethers auto-converts small ints to numbers (#TBD) + ## v0.2.1 - _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index bc5a974a9..d34d74cdf 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -11,13 +11,14 @@ import * as yargs from 'yargs'; import toSnakeCase = require('to-snake-case'); import * as Web3 from 'web3'; -import { ContextData, ParamKind } from './types'; +import { ContextData, ContractsBackend, ParamKind } from './types'; import { utils } from './utils'; const ABI_TYPE_CONSTRUCTOR = 'constructor'; const ABI_TYPE_METHOD = 'function'; const ABI_TYPE_EVENT = 'event'; const DEFAULT_NETWORK_ID = 50; +const DEFAULT_BACKEND = 'web3'; const args = yargs .option('abis', { @@ -43,6 +44,12 @@ const args = yargs demandOption: true, normalize: true, }) + .option('backend', { + describe: 'Which backend do you plan to use. Either web3 or ethers', + type: 'string', + choices: [ContractsBackend.Web3, ContractsBackend.Ethers], + default: DEFAULT_BACKEND, + }) .option('network-id', { describe: 'ID of the network where contract ABIs are nested in artifacts', type: 'number', @@ -73,8 +80,8 @@ function writeOutputFile(name: string, renderedTsCode: string): void { utils.log(`Created: ${chalk.bold(filePath)}`); } -Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input)); -Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output)); +Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend)); +Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend)); if (args.partials) { registerPartials(args.partials); diff --git a/packages/abi-gen/src/types.ts b/packages/abi-gen/src/types.ts index e82ab824b..402e0105e 100644 --- a/packages/abi-gen/src/types.ts +++ b/packages/abi-gen/src/types.ts @@ -12,6 +12,11 @@ export enum AbiType { Fallback = 'fallback', } +export enum ContractsBackend { + Web3 = 'web3', + Ethers = 'ethers', +} + export interface Method extends Web3.MethodAbi { singleReturnValue: boolean; } diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts index 14255643a..dc2c5390e 100644 --- a/packages/abi-gen/src/utils.ts +++ b/packages/abi-gen/src/utils.ts @@ -3,14 +3,14 @@ import * as _ from 'lodash'; import * as path from 'path'; import * as Web3 from 'web3'; -import { AbiType, ParamKind } from './types'; +import { AbiType, ContractsBackend, ParamKind } from './types'; export const utils = { - solTypeToTsType(paramKind: ParamKind, solType: string): string { + solTypeToTsType(paramKind: ParamKind, backend: ContractsBackend, solType: string): string { const trailingArrayRegex = /\[\d*\]$/; if (solType.match(trailingArrayRegex)) { const arrayItemSolType = solType.replace(trailingArrayRegex, ''); - const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType); + const arrayItemTsType = utils.solTypeToTsType(paramKind, backend, arrayItemSolType); const arrayTsType = utils.isUnionType(arrayItemTsType) ? `Array<${arrayItemTsType}>` : `${arrayItemTsType}[]`; @@ -24,13 +24,21 @@ export const utils = { { regex: '^bytes\\d*$', tsType: 'string' }, ]; if (paramKind === ParamKind.Input) { - // web3 allows to pass those an non-bignumbers and that's nice - // but it always returns stuff as BigNumbers + // web3 and ethers allow to pass those as numbers instead of bignumbers solTypeRegexToTsType.unshift({ regex: '^u?int(8|16|32)?$', tsType: 'number|BigNumber', }); } + if (backend === ContractsBackend.Ethers) { + if (paramKind === ParamKind.Output) { + // ethers-contracts automatically converts small BigNumbers to numbers + solTypeRegexToTsType.unshift({ + regex: '^u?int(8|16|32|48)?$', + tsType: 'number', + }); + } + } for (const regexAndTxType of solTypeRegexToTsType) { const { regex, tsType } = regexAndTxType; if (solType.match(regex)) { diff --git a/yarn.lock b/yarn.lock index 7c7dcd76b..f48310c91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,6 +10,12 @@ version "4.0.3" resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-4.0.3.tgz#e8ce5f28c3025a01c6af7fc6d944494903a9e348" +"@types/bignumber.js@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" + dependencies: + bignumber.js "*" + "@types/bintrees@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/bintrees/-/bintrees-1.0.2.tgz#0dfdce4eeebdf90427bd35b0e79dc248b3d157a6" @@ -1283,6 +1289,10 @@ big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" +bignumber.js@*, bignumber.js@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002" + "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9" @@ -3227,6 +3237,21 @@ ethereumjs-wallet@^0.6.0: utf8 "^2.1.1" uuid "^2.0.1" +ethers-contracts@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ethers-contracts/-/ethers-contracts-2.2.1.tgz#e2bf5dd5e157313ba454b50c646c8472fcd0a8b3" + dependencies: + ethers-utils "^2.1.0" + +ethers-utils@^2.1.0: + version "2.1.11" + resolved "https://registry.yarnpkg.com/ethers-utils/-/ethers-utils-2.1.11.tgz#b27535ca3226118be300211c39c896b1e5e21641" + dependencies: + bn.js "^4.4.0" + hash.js "^1.0.0" + js-sha3 "0.5.7" + xmlhttprequest "1.8.0" + ethjs-abi@0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/ethjs-abi/-/ethjs-abi-0.1.8.tgz#cd288583ed628cdfadaf8adefa3ba1dbcbca6c18" @@ -4970,6 +4995,10 @@ js-sha3@0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a" +js-sha3@0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" + js-sha3@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" @@ -9811,7 +9840,7 @@ xml-js@^1.3.2: dependencies: sax "^1.2.4" -xmlhttprequest@*: +xmlhttprequest@*, xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" -- cgit v1.2.3 From fe8f2d8d898e9909636366c9ceee37a5e9481573 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 12:20:59 -0800 Subject: Add support for ABIv2 to abi-gen --- .../contract_templates/partials/event.handlebars | 2 +- .../partials/return_type.handlebars | 4 +-- .../partials/typed_params.handlebars | 2 +- packages/0x.js/package.json | 2 +- packages/abi-gen/CHANGELOG.md | 1 + packages/abi-gen/src/utils.ts | 34 ++++++++++++++++++---- 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/0x.js/contract_templates/partials/event.handlebars b/packages/0x.js/contract_templates/partials/event.handlebars index 6d68d4c0f..3c6100e4f 100644 --- a/packages/0x.js/contract_templates/partials/event.handlebars +++ b/packages/0x.js/contract_templates/partials/event.handlebars @@ -1,5 +1,5 @@ export interface {{name}}ContractEventArgs { {{#each inputs}} - {{name}}: {{#returnType type}}{{/returnType}}; + {{name}}: {{#returnType type components}}{{/returnType}}; {{/each}} } diff --git a/packages/0x.js/contract_templates/partials/return_type.handlebars b/packages/0x.js/contract_templates/partials/return_type.handlebars index 383961a40..268ad15f7 100644 --- a/packages/0x.js/contract_templates/partials/return_type.handlebars +++ b/packages/0x.js/contract_templates/partials/return_type.handlebars @@ -1,6 +1,6 @@ {{#singleReturnValue}} -{{#returnType outputs.0.type}}{{/returnType}} +{{#returnType outputs.0.type outputs.0.components}}{{/returnType}} {{/singleReturnValue}} {{^singleReturnValue}} -[{{#each outputs}}{{#returnType type}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}] +[{{#each outputs}}{{#returnType type components}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}] {{/singleReturnValue}} diff --git a/packages/0x.js/contract_templates/partials/typed_params.handlebars b/packages/0x.js/contract_templates/partials/typed_params.handlebars index 3ea4b2e95..c100e58f7 100644 --- a/packages/0x.js/contract_templates/partials/typed_params.handlebars +++ b/packages/0x.js/contract_templates/partials/typed_params.handlebars @@ -1,3 +1,3 @@ {{#each inputs}} - {{name}}: {{#parameterType type}}{{/parameterType}}, + {{name}}: {{#parameterType type components}}{{/parameterType}}, {{/each}} diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 6a0a84cfc..78cba529a 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -17,7 +17,7 @@ "build": "run-p build:umd:prod build:commonjs; exit 0;", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated && prettier --write 'src/contract_wrappers/generated/**.ts'", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", "test:circleci": "run-s test:coverage report_test_coverage", "test": "run-s clean test:commonjs", diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index 7e589551e..17186570e 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -3,6 +3,7 @@ ## v0.2.3 - _TBD, 2018_ * Add a `backend` parameter that allows you to specify your backend (web3 or ethers). Ethers auto-converts small ints to numbers (#TBD) + * Add support for ABIv2 (#TBD) ## v0.2.1 - _February 9, 2018_ diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts index dc2c5390e..349604aec 100644 --- a/packages/abi-gen/src/utils.ts +++ b/packages/abi-gen/src/utils.ts @@ -6,14 +6,20 @@ import * as Web3 from 'web3'; import { AbiType, ContractsBackend, ParamKind } from './types'; export const utils = { - solTypeToTsType(paramKind: ParamKind, backend: ContractsBackend, solType: string): string { + solTypeToTsType( + paramKind: ParamKind, + backend: ContractsBackend, + solType: string, + components?: Web3.DataItem[], + ): string { const trailingArrayRegex = /\[\d*\]$/; if (solType.match(trailingArrayRegex)) { const arrayItemSolType = solType.replace(trailingArrayRegex, ''); - const arrayItemTsType = utils.solTypeToTsType(paramKind, backend, arrayItemSolType); - const arrayTsType = utils.isUnionType(arrayItemTsType) - ? `Array<${arrayItemTsType}>` - : `${arrayItemTsType}[]`; + const arrayItemTsType = utils.solTypeToTsType(paramKind, backend, arrayItemSolType, components); + const arrayTsType = + utils.isUnionType(arrayItemTsType) || utils.isObjectType(arrayItemTsType) + ? `Array<${arrayItemTsType}>` + : `${arrayItemTsType}[]`; return arrayTsType; } else { const solTypeRegexToTsType = [ @@ -45,12 +51,30 @@ export const utils = { return tsType; } } + const TUPLE_TYPE_REGEX = '^tuple$'; + if (solType.match(TUPLE_TYPE_REGEX)) { + const componentsType = _.map(components, component => { + const componentValueType = utils.solTypeToTsType( + paramKind, + backend, + component.type, + component.components, + ); + const componentType = `${component.name}: ${componentValueType}`; + return componentType; + }); + const tsType = `{${componentsType}}`; + return tsType; + } throw new Error(`Unknown Solidity type found: ${solType}`); } }, isUnionType(tsType: string): boolean { return tsType === 'number|BigNumber'; }, + isObjectType(tsType: string): boolean { + return /^{.*}$/.test(tsType); + }, log(...args: any[]): void { console.log(...args); // tslint:disable-line:no-console }, -- cgit v1.2.3 From 9d9cab1711f2d5c77376056affc1d7287211c18d Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 12:53:27 -0800 Subject: Fix build by using local events types --- .../contract_templates/contract.handlebars | 18 ++++++++++++++ .../contract_templates/partials/event.handlebars | 5 ++++ packages/contracts/globals.d.ts | 28 ++++++++++++++++++++++ packages/contracts/package.json | 3 ++- packages/contracts/test/exchange/core.ts | 17 ++++++------- packages/contracts/test/exchange/helpers.ts | 7 +++++- packages/contracts/test/exchange/wrapper.ts | 7 +++++- yarn.lock | 10 -------- 8 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 packages/contracts/contract_templates/partials/event.handlebars diff --git a/packages/contracts/contract_templates/contract.handlebars b/packages/contracts/contract_templates/contract.handlebars index afb9708e9..84b0696b1 100644 --- a/packages/contracts/contract_templates/contract.handlebars +++ b/packages/contracts/contract_templates/contract.handlebars @@ -10,6 +10,24 @@ import * as Web3 from 'web3'; import {BaseContract} from './base_contract'; +{{#if events}} +export type {{contractName}}ContractEventArgs = +{{#each events}} + | {{name}}ContractEventArgs{{#if @last}};{{/if}} +{{/each}} + +export enum {{contractName}}Events { + {{#each events}} + {{name}} = '{{name}}', + {{/each}} +} + +{{#each events}} +{{> event}} + +{{/each}} +{{/if}} + export class {{contractName}}Contract extends BaseContract { {{#each methods}} {{#this.constant}} diff --git a/packages/contracts/contract_templates/partials/event.handlebars b/packages/contracts/contract_templates/partials/event.handlebars new file mode 100644 index 000000000..3c6100e4f --- /dev/null +++ b/packages/contracts/contract_templates/partials/event.handlebars @@ -0,0 +1,5 @@ +export interface {{name}}ContractEventArgs { + {{#each inputs}} + {{name}}: {{#returnType type components}}{{/returnType}}; + {{/each}} +} diff --git a/packages/contracts/globals.d.ts b/packages/contracts/globals.d.ts index 0e6586a4b..fe39fb11d 100644 --- a/packages/contracts/globals.d.ts +++ b/packages/contracts/globals.d.ts @@ -32,3 +32,31 @@ declare module 'ethereumjs-abi' { const soliditySHA3: (argTypes: string[], args: any[]) => Buffer; const methodID: (name: string, types: string[]) => Buffer; } + +declare module 'ethers-contracts' { + export interface TransactionDescription { + name: string; + signature: string; + sighash: string; + data: string; + } + export interface CallDescription extends TransactionDescription { + parse: (...args: any[]) => any; + } + export interface FunctionDescription { + (...params: any[]): TransactionDescription | CallDescription; + inputs: { names: string[]; types: string[] }; + outputs: { names: string[]; types: string[] }; + } + export interface EventDescription { + inputs: { names: string[]; types: string[] }; + signature: string; + topic: string; + } + // tslint:disable-next-line:max-classes-per-file + export class Interface { + public functions: { [functionName: string]: FunctionDescription }; + public events: { [eventName: string]: EventDescription }; + constructor(abi: any); + } +} diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 0a3a6fc84..f35ba73c2 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -17,7 +17,7 @@ "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", "compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir src/artifacts", "clean": "shx rm -rf ./lib", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend web3", "migrate": "node ../deployer/lib/src/cli.js migrate", "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'", "test:circleci": "yarn test" @@ -72,6 +72,7 @@ "bn.js": "^4.11.8", "ethereumjs-abi": "^0.6.4", "ethereumjs-util": "^5.1.1", + "ethers-contracts": "^2.2.1", "isomorphic-fetch": "^2.2.1", "lodash": "^4.17.4", "request": "^2.81.0", diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 9cfc68418..1997a1f11 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -1,12 +1,4 @@ -import { - LogCancelContractEventArgs, - LogErrorContractEventArgs, - LogFillContractEventArgs, - LogWithDecodedArgs, - SignedOrder, - TransactionReceiptWithDecodedLogs, - ZeroEx, -} from '0x.js'; +import { LogWithDecodedArgs, SignedOrder, TransactionReceiptWithDecodedLogs, ZeroEx } from '0x.js'; import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; @@ -15,7 +7,12 @@ import ethUtil = require('ethereumjs-util'); import * as Web3 from 'web3'; import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token'; -import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange'; +import { + ExchangeContract, + LogCancelContractEventArgs, + LogErrorContractEventArgs, + LogFillContractEventArgs, +} from '../../src/contract_wrappers/generated/exchange'; import { TokenTransferProxyContract } from '../../src/contract_wrappers/generated/token_transfer_proxy'; import { Balances } from '../../util/balances'; import { constants } from '../../util/constants'; diff --git a/packages/contracts/test/exchange/helpers.ts b/packages/contracts/test/exchange/helpers.ts index 5fe00225e..9030af4c6 100644 --- a/packages/contracts/test/exchange/helpers.ts +++ b/packages/contracts/test/exchange/helpers.ts @@ -5,7 +5,12 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); -import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange'; +import { + ExchangeContract, + LogCancelContractEventArgs, + LogErrorContractEventArgs, + LogFillContractEventArgs, +} from '../../src/contract_wrappers/generated/exchange'; import { constants } from '../../util/constants'; import { ExchangeWrapper } from '../../util/exchange_wrapper'; import { OrderFactory } from '../../util/order_factory'; diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index bf5a89222..5b1b76deb 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -7,7 +7,12 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token'; -import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange'; +import { + ExchangeContract, + LogCancelContractEventArgs, + LogErrorContractEventArgs, + LogFillContractEventArgs, +} from '../../src/contract_wrappers/generated/exchange'; import { TokenRegistryContract } from '../../src/contract_wrappers/generated/token_registry'; import { TokenTransferProxyContract } from '../../src/contract_wrappers/generated/token_transfer_proxy'; import { Balances } from '../../util/balances'; diff --git a/yarn.lock b/yarn.lock index f48310c91..ddcaa3f9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,12 +10,6 @@ version "4.0.3" resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-4.0.3.tgz#e8ce5f28c3025a01c6af7fc6d944494903a9e348" -"@types/bignumber.js@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" - dependencies: - bignumber.js "*" - "@types/bintrees@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/bintrees/-/bintrees-1.0.2.tgz#0dfdce4eeebdf90427bd35b0e79dc248b3d157a6" @@ -1289,10 +1283,6 @@ big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" -bignumber.js@*, bignumber.js@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002" - "bignumber.js@git+https://github.com/debris/bignumber.js#master": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9" -- cgit v1.2.3 From ddc30cc2c0a81e1c459bf2bd7eb6623f9262a801 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 13:00:26 -0800 Subject: Add CHANGELOG entry --- packages/0x.js/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index 2710788e0..b882a1b31 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -4,6 +4,7 @@ * Validate and lowercase all addresses in public methods (#373) * Improve validation to force passing contract addresses on private networks (#385) + * Change `LogErrorContractEventArgs.errorId` type from `BigNumber` to `number` (#413) * Rename all public `_unsubscribeAll` methods to `unsubscribeAll` (#415) ## v0.32.2 - _February 9, 2018_ -- cgit v1.2.3 From fa822caa626f6bca6d7960f9f0cddd8376b63157 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 13:05:23 -0800 Subject: Apply prettier after generating contracts --- packages/contracts/package.json | 2 +- packages/contracts/src/contract_wrappers/generated/base_contract.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/contracts/package.json b/packages/contracts/package.json index f35ba73c2..ddd8ade55 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -17,7 +17,7 @@ "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", "compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir src/artifacts", "clean": "shx rm -rf ./lib", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend web3", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend web3 && prettier --write 'src/contract_wrappers/generated/**.ts'", "migrate": "node ../deployer/lib/src/cli.js migrate", "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'", "test:circleci": "yarn test" diff --git a/packages/contracts/src/contract_wrappers/generated/base_contract.ts b/packages/contracts/src/contract_wrappers/generated/base_contract.ts index 2d77b3ab1..d492bd325 100644 --- a/packages/contracts/src/contract_wrappers/generated/base_contract.ts +++ b/packages/contracts/src/contract_wrappers/generated/base_contract.ts @@ -1,4 +1,4 @@ -import {TxData, TxDataPayable} from '@0xproject/types'; +import { TxData, TxDataPayable } from '@0xproject/types'; import * as _ from 'lodash'; import * as Web3 from 'web3'; @@ -6,7 +6,7 @@ export class BaseContract { public address: string; protected _web3ContractInstance: Web3.ContractInstance; protected _defaults: Partial; - protected async _applyDefaultsToTxDataAsync( + protected async _applyDefaultsToTxDataAsync( txData: T, estimateGasAsync?: (txData: T) => Promise, ): Promise { -- cgit v1.2.3 From 34274a10428bbc07a4f075bcf4a3ccafe0c04f5e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 13:24:20 -0800 Subject: Pass components to parameterType --- packages/contracts/contract_templates/partials/typed_params.handlebars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/contract_templates/partials/typed_params.handlebars b/packages/contracts/contract_templates/partials/typed_params.handlebars index 3ea4b2e95..c100e58f7 100644 --- a/packages/contracts/contract_templates/partials/typed_params.handlebars +++ b/packages/contracts/contract_templates/partials/typed_params.handlebars @@ -1,3 +1,3 @@ {{#each inputs}} - {{name}}: {{#parameterType type}}{{/parameterType}}, + {{name}}: {{#parameterType type components}}{{/parameterType}}, {{/each}} -- cgit v1.2.3 From 93b2736d6533f983aeb74005004de7f40eb35851 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 14:13:35 -0800 Subject: Use the same templates as 0x.js --- .../0x.js/contract_templates/contract.handlebars | 48 ------------- .../contract_templates/partials/call.handlebars | 23 ------ .../contract_templates/partials/event.handlebars | 5 -- .../contract_templates/partials/params.handlebars | 3 - .../partials/return_type.handlebars | 6 -- .../contract_templates/partials/tx.handlebars | 57 --------------- .../partials/typed_params.handlebars | 3 - packages/0x.js/package.json | 2 +- packages/contract_templates/contract.handlebars | 48 +++++++++++++ .../contract_templates/partials/call.handlebars | 23 ++++++ .../contract_templates/partials/event.handlebars | 5 ++ .../contract_templates/partials/params.handlebars | 3 + .../partials/return_type.handlebars | 10 +++ packages/contract_templates/partials/tx.handlebars | 83 ++++++++++++++++++++++ .../partials/typed_params.handlebars | 3 + .../contract_templates/contract.handlebars | 44 ------------ .../contract_templates/partials/call.handlebars | 10 --- .../contract_templates/partials/event.handlebars | 5 -- .../contract_templates/partials/params.handlebars | 3 - .../partials/return_type.handlebars | 10 --- .../contract_templates/partials/tx.handlebars | 36 ---------- .../partials/typed_params.handlebars | 3 - packages/contracts/package.json | 2 +- .../contract_wrappers/generated/base_contract.ts | 51 ++++++++++--- packages/contracts/test/exchange/core.ts | 18 +++-- packages/contracts/test/exchange/helpers.ts | 2 +- packages/contracts/test/exchange/wrapper.ts | 20 ++++-- .../contracts/test/multi_sig_with_time_lock.ts | 22 ++++-- ...i_sig_with_time_lock_except_remove_auth_addr.ts | 30 +++++--- packages/contracts/test/token_registry.ts | 2 +- .../contracts/test/token_transfer_proxy/auth.ts | 16 +++-- .../test/token_transfer_proxy/transfer_from.ts | 8 ++- .../contracts/test/unlimited_allowance_token.ts | 2 +- packages/contracts/test/zrx_token.ts | 12 ++-- packages/contracts/util/balances.ts | 2 +- packages/contracts/util/exchange_wrapper.ts | 10 +-- packages/contracts/util/token_registry_wrapper.ts | 6 +- 37 files changed, 315 insertions(+), 321 deletions(-) delete mode 100644 packages/0x.js/contract_templates/contract.handlebars delete mode 100644 packages/0x.js/contract_templates/partials/call.handlebars delete mode 100644 packages/0x.js/contract_templates/partials/event.handlebars delete mode 100644 packages/0x.js/contract_templates/partials/params.handlebars delete mode 100644 packages/0x.js/contract_templates/partials/return_type.handlebars delete mode 100644 packages/0x.js/contract_templates/partials/tx.handlebars delete mode 100644 packages/0x.js/contract_templates/partials/typed_params.handlebars create mode 100644 packages/contract_templates/contract.handlebars create mode 100644 packages/contract_templates/partials/call.handlebars create mode 100644 packages/contract_templates/partials/event.handlebars create mode 100644 packages/contract_templates/partials/params.handlebars create mode 100644 packages/contract_templates/partials/return_type.handlebars create mode 100644 packages/contract_templates/partials/tx.handlebars create mode 100644 packages/contract_templates/partials/typed_params.handlebars delete mode 100644 packages/contracts/contract_templates/contract.handlebars delete mode 100644 packages/contracts/contract_templates/partials/call.handlebars delete mode 100644 packages/contracts/contract_templates/partials/event.handlebars delete mode 100644 packages/contracts/contract_templates/partials/params.handlebars delete mode 100644 packages/contracts/contract_templates/partials/return_type.handlebars delete mode 100644 packages/contracts/contract_templates/partials/tx.handlebars delete mode 100644 packages/contracts/contract_templates/partials/typed_params.handlebars diff --git a/packages/0x.js/contract_templates/contract.handlebars b/packages/0x.js/contract_templates/contract.handlebars deleted file mode 100644 index 2954145a7..000000000 --- a/packages/0x.js/contract_templates/contract.handlebars +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file is auto-generated using abi-gen. Don't edit directly. - * Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates. - */ -// tslint:disable:no-consecutive-blank-lines -// tslint:disable-next-line:no-unused-variable -import { TxData, TxDataPayable } from '@0xproject/types'; -import { BigNumber, classUtils, promisify } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as ethersContracts from 'ethers-contracts'; -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -import {BaseContract} from './base_contract'; - -{{#if events}} -export type {{contractName}}ContractEventArgs = -{{#each events}} - | {{name}}ContractEventArgs{{#if @last}};{{/if}} -{{/each}} - -export enum {{contractName}}Events { - {{#each events}} - {{name}} = '{{name}}', - {{/each}} -} - -{{#each events}} -{{> event}} - -{{/each}} -{{/if}} - -// tslint:disable:no-parameter-reassignment -export class {{contractName}}Contract extends BaseContract { -{{#each methods}} - {{#this.constant}} - {{> call contractName=../contractName}} - {{/this.constant}} - {{^this.constant}} - {{> tx contractName=../contractName}} - {{/this.constant}} -{{/each}} - constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { - super(web3Wrapper, abi, address); - classUtils.bindAll(this, ['_ethersInterface', '_address', '_abi', '_web3Wrapper']); - } -} // tslint:disable:max-file-line-count diff --git a/packages/0x.js/contract_templates/partials/call.handlebars b/packages/0x.js/contract_templates/partials/call.handlebars deleted file mode 100644 index c533712b7..000000000 --- a/packages/0x.js/contract_templates/partials/call.handlebars +++ /dev/null @@ -1,23 +0,0 @@ -public {{this.name}} = { - async callAsync( - {{> typed_params inputs=inputs}} - defaultBlock?: Web3.BlockParam, - ): Promise<{{> return_type outputs=outputs}}> { - const self = this as {{contractName}}Contract; - const inputAbi = _.find(this._abi, {name: '{{this.name}}'}).inputs; - [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); - const callDescription = self._ethersInterface.functions.{{this.name}}( - {{> params inputs=inputs}} - ) as ethersContracts.CallDescription; - const callData = await self._applyDefaultsToTxDataAsync( - { - data: callDescription.data, - } - ) - const rawCallResult = await self._web3Wrapper.callAsync(callData); - let resultArray = callDescription.parse(rawCallResult); - const outputAbi = _.find(this._abi, {name: '{{this.name}}'}).outputs; - resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); - return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; - }, -}; diff --git a/packages/0x.js/contract_templates/partials/event.handlebars b/packages/0x.js/contract_templates/partials/event.handlebars deleted file mode 100644 index 3c6100e4f..000000000 --- a/packages/0x.js/contract_templates/partials/event.handlebars +++ /dev/null @@ -1,5 +0,0 @@ -export interface {{name}}ContractEventArgs { - {{#each inputs}} - {{name}}: {{#returnType type components}}{{/returnType}}; - {{/each}} -} diff --git a/packages/0x.js/contract_templates/partials/params.handlebars b/packages/0x.js/contract_templates/partials/params.handlebars deleted file mode 100644 index ac5d4ae85..000000000 --- a/packages/0x.js/contract_templates/partials/params.handlebars +++ /dev/null @@ -1,3 +0,0 @@ -{{#each inputs}} -{{name}}, -{{/each}} diff --git a/packages/0x.js/contract_templates/partials/return_type.handlebars b/packages/0x.js/contract_templates/partials/return_type.handlebars deleted file mode 100644 index 268ad15f7..000000000 --- a/packages/0x.js/contract_templates/partials/return_type.handlebars +++ /dev/null @@ -1,6 +0,0 @@ -{{#singleReturnValue}} -{{#returnType outputs.0.type outputs.0.components}}{{/returnType}} -{{/singleReturnValue}} -{{^singleReturnValue}} -[{{#each outputs}}{{#returnType type components}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}] -{{/singleReturnValue}} diff --git a/packages/0x.js/contract_templates/partials/tx.handlebars b/packages/0x.js/contract_templates/partials/tx.handlebars deleted file mode 100644 index aae9aa404..000000000 --- a/packages/0x.js/contract_templates/partials/tx.handlebars +++ /dev/null @@ -1,57 +0,0 @@ -public {{this.name}} = { - async sendTransactionAsync( - {{> typed_params inputs=inputs}} - {{#this.payable}} - txData: TxDataPayable = {}, - {{/this.payable}} - {{^this.payable}} - txData: TxData = {}, - {{/this.payable}} - ): Promise { - const self = this as {{contractName}}Contract; - const inputAbi = _.find(this._abi, {name: '{{this.name}}'}).inputs; - [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); - const data = this._ethersInterface.functions.{{this.name}}( - {{> params inputs=inputs}} - ).data - const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( - { - ...txData, - data, - }, - self.{{this.name}}.estimateGasAsync.bind( - self, - {{> params inputs=inputs}} - ), - ); - const txHash = await this._web3Wrapper.sendTransactionAsync(txDataWithDefaults); - return txHash; - }, - async estimateGasAsync( - {{> typed_params inputs=inputs}} - txData: TxData = {}, - ): Promise { - const self = this as {{contractName}}Contract; - const data = this._ethersInterface.functions.{{this.name}}( - {{> params inputs=inputs}} - ).data - const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( - { - ...txData, - data, - } - ); - const gas = await this._web3Wrapper.estimateGasAsync(txDataWithDefaults); - return gas; - }, - getABIEncodedTransactionData( - {{> typed_params inputs=inputs}} - txData: TxData = {}, - ): string { - const self = this as {{contractName}}Contract; - const abiEncodedTransactionData = this._ethersInterface.functions.{{this.name}}( - {{> params inputs=inputs}} - ).data - return abiEncodedTransactionData; - }, -}; diff --git a/packages/0x.js/contract_templates/partials/typed_params.handlebars b/packages/0x.js/contract_templates/partials/typed_params.handlebars deleted file mode 100644 index c100e58f7..000000000 --- a/packages/0x.js/contract_templates/partials/typed_params.handlebars +++ /dev/null @@ -1,3 +0,0 @@ -{{#each inputs}} - {{name}}: {{#parameterType type components}}{{/parameterType}}, -{{/each}} diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 78cba529a..0ea60fde8 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -17,7 +17,7 @@ "build": "run-p build:umd:prod build:commonjs; exit 0;", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", "test:circleci": "run-s test:coverage report_test_coverage", "test": "run-s clean test:commonjs", diff --git a/packages/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars new file mode 100644 index 000000000..2954145a7 --- /dev/null +++ b/packages/contract_templates/contract.handlebars @@ -0,0 +1,48 @@ +/** + * This file is auto-generated using abi-gen. Don't edit directly. + * Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates. + */ +// tslint:disable:no-consecutive-blank-lines +// tslint:disable-next-line:no-unused-variable +import { TxData, TxDataPayable } from '@0xproject/types'; +import { BigNumber, classUtils, promisify } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as ethersContracts from 'ethers-contracts'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import {BaseContract} from './base_contract'; + +{{#if events}} +export type {{contractName}}ContractEventArgs = +{{#each events}} + | {{name}}ContractEventArgs{{#if @last}};{{/if}} +{{/each}} + +export enum {{contractName}}Events { + {{#each events}} + {{name}} = '{{name}}', + {{/each}} +} + +{{#each events}} +{{> event}} + +{{/each}} +{{/if}} + +// tslint:disable:no-parameter-reassignment +export class {{contractName}}Contract extends BaseContract { +{{#each methods}} + {{#this.constant}} + {{> call contractName=../contractName}} + {{/this.constant}} + {{^this.constant}} + {{> tx contractName=../contractName}} + {{/this.constant}} +{{/each}} + constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { + super(web3Wrapper, abi, address); + classUtils.bindAll(this, ['_ethersInterface', '_address', '_abi', '_web3Wrapper']); + } +} // tslint:disable:max-file-line-count diff --git a/packages/contract_templates/partials/call.handlebars b/packages/contract_templates/partials/call.handlebars new file mode 100644 index 000000000..7ac3e1ee3 --- /dev/null +++ b/packages/contract_templates/partials/call.handlebars @@ -0,0 +1,23 @@ +public {{this.name}} = { + async callAsync( + {{> typed_params inputs=inputs}} + defaultBlock?: Web3.BlockParam, + ): Promise<{{> return_type outputs=outputs}}> { + const self = this as {{contractName}}Contract; + const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; + [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); + const callDescription = self._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ) as ethersContracts.CallDescription; + const callData = await self._applyDefaultsToTxDataAsync( + { + data: callDescription.data, + } + ) + const rawCallResult = await self._web3Wrapper.callAsync(callData); + let resultArray = callDescription.parse(rawCallResult); + const outputAbi = _.find(this.abi, {name: '{{this.name}}'}).outputs; + resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); + return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; + }, +}; diff --git a/packages/contract_templates/partials/event.handlebars b/packages/contract_templates/partials/event.handlebars new file mode 100644 index 000000000..3c6100e4f --- /dev/null +++ b/packages/contract_templates/partials/event.handlebars @@ -0,0 +1,5 @@ +export interface {{name}}ContractEventArgs { + {{#each inputs}} + {{name}}: {{#returnType type components}}{{/returnType}}; + {{/each}} +} diff --git a/packages/contract_templates/partials/params.handlebars b/packages/contract_templates/partials/params.handlebars new file mode 100644 index 000000000..ac5d4ae85 --- /dev/null +++ b/packages/contract_templates/partials/params.handlebars @@ -0,0 +1,3 @@ +{{#each inputs}} +{{name}}, +{{/each}} diff --git a/packages/contract_templates/partials/return_type.handlebars b/packages/contract_templates/partials/return_type.handlebars new file mode 100644 index 000000000..9dd509953 --- /dev/null +++ b/packages/contract_templates/partials/return_type.handlebars @@ -0,0 +1,10 @@ +{{#if outputs.length}} +{{#singleReturnValue}} +{{#returnType outputs.0.type components}}{{/returnType}} +{{/singleReturnValue}} +{{^singleReturnValue}} +[{{#each outputs}}{{#returnType type components}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}] +{{/singleReturnValue}} +{{else}} +void +{{/if}} diff --git a/packages/contract_templates/partials/tx.handlebars b/packages/contract_templates/partials/tx.handlebars new file mode 100644 index 000000000..5026dac20 --- /dev/null +++ b/packages/contract_templates/partials/tx.handlebars @@ -0,0 +1,83 @@ +public {{this.name}} = { + async sendTransactionAsync( + {{> typed_params inputs=inputs}} + {{#this.payable}} + txData: TxDataPayable = {}, + {{/this.payable}} + {{^this.payable}} + txData: TxData = {}, + {{/this.payable}} + ): Promise { + const self = this as {{contractName}}Contract; + const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; + [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); + const encodedData = this._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ).data + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { + ...txData, + data: encodedData, + }, + self.{{this.name}}.estimateGasAsync.bind( + self, + {{> params inputs=inputs}} + ), + ); + const txHash = await this._web3Wrapper.sendTransactionAsync(txDataWithDefaults); + return txHash; + }, + async estimateGasAsync( + {{> typed_params inputs=inputs}} + txData: TxData = {}, + ): Promise { + const self = this as {{contractName}}Contract; + const encodedData = this._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ).data + const txDataWithDefaults = await self._applyDefaultsToTxDataAsync( + { + ...txData, + data: encodedData, + } + ); + const gas = await this._web3Wrapper.estimateGasAsync(txDataWithDefaults); + return gas; + }, + getABIEncodedTransactionData( + {{> typed_params inputs=inputs}} + txData: TxData = {}, + ): string { + const self = this as {{contractName}}Contract; + const abiEncodedTransactionData = this._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ).data + return abiEncodedTransactionData; + }, + async callAsync( + {{> typed_params inputs=inputs}} + {{#this.payable}} + txData: TxDataPayable = {}, + {{/this.payable}} + {{^this.payable}} + txData: TxData = {}, + {{/this.payable}} + ): Promise<{{> return_type outputs=outputs}}> { + const self = this as {{contractName}}Contract; + const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; + [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); + const callDescription = self._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ) as ethersContracts.CallDescription; + const callData = await self._applyDefaultsToTxDataAsync( + { + data: callDescription.data, + } + ) + const rawCallResult = await self._web3Wrapper.callAsync(callData); + let resultArray = callDescription.parse(rawCallResult); + const outputAbi = _.find(this.abi, {name: '{{this.name}}'}).outputs; + resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); + return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; + }, +}; diff --git a/packages/contract_templates/partials/typed_params.handlebars b/packages/contract_templates/partials/typed_params.handlebars new file mode 100644 index 000000000..c100e58f7 --- /dev/null +++ b/packages/contract_templates/partials/typed_params.handlebars @@ -0,0 +1,3 @@ +{{#each inputs}} + {{name}}: {{#parameterType type components}}{{/parameterType}}, +{{/each}} diff --git a/packages/contracts/contract_templates/contract.handlebars b/packages/contracts/contract_templates/contract.handlebars deleted file mode 100644 index 84b0696b1..000000000 --- a/packages/contracts/contract_templates/contract.handlebars +++ /dev/null @@ -1,44 +0,0 @@ -/** - * This file is auto-generated using abi-gen. Don't edit directly. - * Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/abi-gen-templates. - */ -// tslint:disable:async-suffix member-ordering no-consecutive-blank-lines -// tslint:disable-next-line:no-unused-variable -import { TxData, TxDataPayable } from '@0xproject/types'; -import { BigNumber, classUtils, promisify } from '@0xproject/utils'; -import * as Web3 from 'web3'; - -import {BaseContract} from './base_contract'; - -{{#if events}} -export type {{contractName}}ContractEventArgs = -{{#each events}} - | {{name}}ContractEventArgs{{#if @last}};{{/if}} -{{/each}} - -export enum {{contractName}}Events { - {{#each events}} - {{name}} = '{{name}}', - {{/each}} -} - -{{#each events}} -{{> event}} - -{{/each}} -{{/if}} - -export class {{contractName}}Contract extends BaseContract { -{{#each methods}} - {{#this.constant}} - {{> call contractName=../contractName}} - {{/this.constant}} - {{^this.constant}} - {{> tx contractName=../contractName}} - {{/this.constant}} -{{/each}} - constructor(web3ContractInstance: Web3.ContractInstance, defaults?: Partial) { - super(web3ContractInstance, defaults); - classUtils.bindAll(this, ['_web3ContractInstance', '_defaults']); - } -} // tslint:disable:max-file-line-count diff --git a/packages/contracts/contract_templates/partials/call.handlebars b/packages/contracts/contract_templates/partials/call.handlebars deleted file mode 100644 index 82a45b40e..000000000 --- a/packages/contracts/contract_templates/partials/call.handlebars +++ /dev/null @@ -1,10 +0,0 @@ -public async {{this.name}}( -{{> typed_params inputs=inputs}} - defaultBlock?: Web3.BlockParam, -): Promise<{{> return_type outputs=outputs}}> { - const self = this as {{contractName}}Contract; - const result = await self._web3ContractInstance.{{this.name}}.call( - {{> params inputs=inputs}} - ); - return result; -} diff --git a/packages/contracts/contract_templates/partials/event.handlebars b/packages/contracts/contract_templates/partials/event.handlebars deleted file mode 100644 index 3c6100e4f..000000000 --- a/packages/contracts/contract_templates/partials/event.handlebars +++ /dev/null @@ -1,5 +0,0 @@ -export interface {{name}}ContractEventArgs { - {{#each inputs}} - {{name}}: {{#returnType type components}}{{/returnType}}; - {{/each}} -} diff --git a/packages/contracts/contract_templates/partials/params.handlebars b/packages/contracts/contract_templates/partials/params.handlebars deleted file mode 100644 index ac5d4ae85..000000000 --- a/packages/contracts/contract_templates/partials/params.handlebars +++ /dev/null @@ -1,3 +0,0 @@ -{{#each inputs}} -{{name}}, -{{/each}} diff --git a/packages/contracts/contract_templates/partials/return_type.handlebars b/packages/contracts/contract_templates/partials/return_type.handlebars deleted file mode 100644 index 40a5dd8b0..000000000 --- a/packages/contracts/contract_templates/partials/return_type.handlebars +++ /dev/null @@ -1,10 +0,0 @@ -{{#if outputs.length}} -{{#singleReturnValue}} -{{#returnType outputs.0.type}}{{/returnType}} -{{/singleReturnValue}} -{{^singleReturnValue}} -[{{#each outputs}}{{#returnType type}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}] -{{/singleReturnValue}} -{{else}} -void -{{/if}} diff --git a/packages/contracts/contract_templates/partials/tx.handlebars b/packages/contracts/contract_templates/partials/tx.handlebars deleted file mode 100644 index 69ae982d6..000000000 --- a/packages/contracts/contract_templates/partials/tx.handlebars +++ /dev/null @@ -1,36 +0,0 @@ -public {{this.name}} = { - async sendTransactionAsync( - {{> typed_params inputs=inputs}} - {{#this.payable}} - txData: TxDataPayable = {}, - {{/this.payable}} - {{^this.payable}} - txData: TxData = {}, - {{/this.payable}} - ): Promise { - const self = this as {{contractName}}Contract; - const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(txData); - const txHash = await self._web3ContractInstance.{{this.name}}( - {{> params inputs=inputs}} - txDataWithDefaults, - ); - return txHash; - }, - async callAsync( - {{> typed_params inputs=inputs}} - {{#this.payable}} - txData: TxDataPayable = {}, - {{/this.payable}} - {{^this.payable}} - txData: TxData = {}, - {{/this.payable}} - ): Promise<{{> return_type outputs=outputs}}> { - const self = this as {{contractName}}Contract; - const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(txData); - const returnValue = await self._web3ContractInstance.{{this.name}}.call( - {{> params inputs=inputs}} - txDataWithDefaults, - ); - return returnValue; - }, -}; diff --git a/packages/contracts/contract_templates/partials/typed_params.handlebars b/packages/contracts/contract_templates/partials/typed_params.handlebars deleted file mode 100644 index c100e58f7..000000000 --- a/packages/contracts/contract_templates/partials/typed_params.handlebars +++ /dev/null @@ -1,3 +0,0 @@ -{{#each inputs}} - {{name}}: {{#parameterType type components}}{{/parameterType}}, -{{/each}} diff --git a/packages/contracts/package.json b/packages/contracts/package.json index ddd8ade55..f41d7786d 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -17,7 +17,7 @@ "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", "compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir src/artifacts", "clean": "shx rm -rf ./lib", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template contract_templates/contract.handlebars --partials 'contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend web3 && prettier --write 'src/contract_wrappers/generated/**.ts'", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend web3 && prettier --write 'src/contract_wrappers/generated/**.ts'", "migrate": "node ../deployer/lib/src/cli.js migrate", "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'", "test:circleci": "yarn test" diff --git a/packages/contracts/src/contract_wrappers/generated/base_contract.ts b/packages/contracts/src/contract_wrappers/generated/base_contract.ts index d492bd325..a465ddc38 100644 --- a/packages/contracts/src/contract_wrappers/generated/base_contract.ts +++ b/packages/contracts/src/contract_wrappers/generated/base_contract.ts @@ -1,12 +1,45 @@ import { TxData, TxDataPayable } from '@0xproject/types'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as ethersContracts from 'ethers-contracts'; import * as _ from 'lodash'; import * as Web3 from 'web3'; export class BaseContract { + protected _ethersInterface: ethersContracts.Interface; + protected _web3Wrapper: Web3Wrapper; + public abi: Web3.ContractAbi; public address: string; - protected _web3ContractInstance: Web3.ContractInstance; - protected _defaults: Partial; - protected async _applyDefaultsToTxDataAsync( + protected static _transformABIData( + abis: Web3.DataItem[], + values: any[], + transformation: (type: string, value: any) => any, + ): any { + return _.map(values, (value: any, i: number) => + BaseContract._transformTypedData(abis[i].type, value, transformation), + ); + } + protected static _lowercaseAddress(type: string, value: string): string { + return type === 'address' ? value.toLowerCase() : value; + } + protected static _bigNumberToString(type: string, value: string): string { + return _.isObject(value) && (value as any).isBigNumber ? value.toString() : value; + } + private static _transformTypedData( + type: string, + values: any, + transformation: (type: string, value: any) => any, + ): any { + const trailingArrayRegex = /\[\d*\]$/; + if (type.match(trailingArrayRegex)) { + const arrayItemType = type.replace(trailingArrayRegex, ''); + return _.map(values, (value: any, i: number) => + this._transformTypedData(arrayItemType, value, transformation), + ); + } else { + return transformation(type, values); + } + } + protected async _applyDefaultsToTxDataAsync>( txData: T, estimateGasAsync?: (txData: T) => Promise, ): Promise { @@ -16,7 +49,8 @@ export class BaseContract { // 3. Gas estimate calculation + safety margin const removeUndefinedProperties = _.pickBy; const txDataWithDefaults = { - ...removeUndefinedProperties(this._defaults), + to: this.address, + ...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()), ...removeUndefinedProperties(txData as any), // HACK: TS can't prove that T is spreadable. // Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged @@ -27,9 +61,10 @@ export class BaseContract { } return txDataWithDefaults; } - constructor(web3ContractInstance: Web3.ContractInstance, defaults?: Partial) { - this.address = web3ContractInstance.address; - this._web3ContractInstance = web3ContractInstance; - this._defaults = defaults || {}; + constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { + this._web3Wrapper = web3Wrapper; + this.abi = abi; + this.address = address; + this._ethersInterface = new ethersContracts.Interface(abi); } } diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 1997a1f11..7d191aa99 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -60,16 +60,20 @@ describe('Exchange', () => { deployer.deployAsync(ContractName.DummyToken), deployer.deployAsync(ContractName.DummyToken), ]); - rep = new DummyTokenContract(repInstance); - dgd = new DummyTokenContract(dgdInstance); - zrx = new DummyTokenContract(zrxInstance); + rep = new DummyTokenContract(web3Wrapper, repInstance.abi, repInstance.address); + dgd = new DummyTokenContract(web3Wrapper, dgdInstance.abi, dgdInstance.address); + zrx = new DummyTokenContract(web3Wrapper, zrxInstance.abi, zrxInstance.address); const tokenTransferProxyInstance = await deployer.deployAsync(ContractName.TokenTransferProxy); - tokenTransferProxy = new TokenTransferProxyContract(tokenTransferProxyInstance); + tokenTransferProxy = new TokenTransferProxyContract( + web3Wrapper, + tokenTransferProxyInstance.abi, + tokenTransferProxyInstance.address, + ); const exchangeInstance = await deployer.deployAsync(ContractName.Exchange, [ zrx.address, tokenTransferProxy.address, ]); - exchange = new ExchangeContract(exchangeInstance); + exchange = new ExchangeContract(web3Wrapper, exchangeInstance.abi, exchangeInstance.address); await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: accounts[0] }); zeroEx = new ZeroEx(web3.currentProvider, { exchangeContractAddress: exchange.address, @@ -647,7 +651,7 @@ describe('Exchange', () => { it('should not change balances if makerTokenAddress is ZRX, makerTokenAmount + makerFee > maker allowance, \ and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const makerZRXAllowance = await zrx.allowance(maker, tokenTransferProxy.address); + const makerZRXAllowance = await zrx.allowance.callAsync(maker, tokenTransferProxy.address); signedOrder = await orderFactory.newSignedOrderAsync({ makerTokenAddress: zrx.address, makerTokenAmount: new BigNumber(makerZRXAllowance), @@ -673,7 +677,7 @@ describe('Exchange', () => { it('should not change balances if takerTokenAddress is ZRX, takerTokenAmount + takerFee > taker allowance, \ and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => { - const takerZRXAllowance = await zrx.allowance(taker, tokenTransferProxy.address); + const takerZRXAllowance = await zrx.allowance.callAsync(taker, tokenTransferProxy.address); signedOrder = await orderFactory.newSignedOrderAsync({ takerTokenAddress: zrx.address, takerTokenAmount: new BigNumber(takerZRXAllowance), diff --git a/packages/contracts/test/exchange/helpers.ts b/packages/contracts/test/exchange/helpers.ts index 9030af4c6..497193e8b 100644 --- a/packages/contracts/test/exchange/helpers.ts +++ b/packages/contracts/test/exchange/helpers.ts @@ -47,7 +47,7 @@ describe('Exchange', () => { zrx.address, tokenTransferProxy.address, ]); - const exchange = new ExchangeContract(exchangeInstance); + const exchange = new ExchangeContract(web3Wrapper, exchangeInstance.abi, exchangeInstance.address); await tokenTransferProxy.addAuthorizedAddress(exchange.address, { from: accounts[0] }); const zeroEx = new ZeroEx(web3.currentProvider, { networkId: constants.TESTRPC_NETWORK_ID }); exchangeWrapper = new ExchangeWrapper(exchange, zeroEx); diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index 5b1b76deb..4ea40cb59 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -60,18 +60,26 @@ describe('Exchange', () => { deployer.deployAsync(ContractName.DummyToken), deployer.deployAsync(ContractName.DummyToken), ]); - rep = new DummyTokenContract(repInstance); - dgd = new DummyTokenContract(dgdInstance); - zrx = new DummyTokenContract(zrxInstance); + rep = new DummyTokenContract(web3Wrapper, repInstance.abi, repInstance.address); + dgd = new DummyTokenContract(web3Wrapper, dgdInstance.abi, dgdInstance.address); + zrx = new DummyTokenContract(web3Wrapper, zrxInstance.abi, zrxInstance.address); const tokenRegistryInstance = await deployer.deployAsync(ContractName.TokenRegistry); - tokenRegistry = new TokenRegistryContract(tokenRegistryInstance); + tokenRegistry = new TokenRegistryContract( + web3Wrapper, + tokenRegistryInstance.abi, + tokenRegistryInstance.address, + ); const tokenTransferProxyInstance = await deployer.deployAsync(ContractName.TokenTransferProxy); - tokenTransferProxy = new TokenTransferProxyContract(tokenTransferProxyInstance); + tokenTransferProxy = new TokenTransferProxyContract( + web3Wrapper, + tokenTransferProxyInstance.abi, + tokenTransferProxyInstance.address, + ); const exchangeInstance = await deployer.deployAsync(ContractName.Exchange, [ zrx.address, tokenTransferProxy.address, ]); - exchange = new ExchangeContract(exchangeInstance); + exchange = new ExchangeContract(web3Wrapper, exchangeInstance.abi, exchangeInstance.address); await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(exchange.address, { from: accounts[0] }); const zeroEx = new ZeroEx(web3.currentProvider, { networkId: constants.TESTRPC_NETWORK_ID }); exWrapper = new ExchangeWrapper(exchange, zeroEx); diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts index 6812cb09f..a726814e4 100644 --- a/packages/contracts/test/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -59,10 +59,14 @@ describe('MultiSigWalletWithTimeLock', () => { SIGNATURES_REQUIRED, 0, ]); - multiSig = new MultiSigWalletWithTimeLockContract(multiSigInstance); + multiSig = new MultiSigWalletWithTimeLockContract( + web3Wrapper, + multiSigInstance.abi, + multiSigInstance.address, + ); multiSigWrapper = new MultiSigWrapper((multiSig as any) as MultiSigWalletContract); - const secondsTimeLocked = await multiSig.secondsTimeLocked(); + const secondsTimeLocked = await multiSig.secondsTimeLocked.callAsync(); initialSecondsTimeLocked = secondsTimeLocked.toNumber(); }); it('should throw when not called by wallet', async () => { @@ -113,7 +117,7 @@ describe('MultiSigWalletWithTimeLock', () => { const blockNum = await web3Wrapper.getBlockNumberAsync(); const blockInfo = await web3Wrapper.getBlockAsync(blockNum); const timestamp = new BigNumber(blockInfo.timestamp); - const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes(txId)); + const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.callAsync(txId)); expect(timestamp).to.be.bignumber.equal(confirmationTimeBigNum); }); @@ -141,7 +145,7 @@ describe('MultiSigWalletWithTimeLock', () => { const res = await zeroEx.awaitTransactionMinedAsync(txHash); expect(res.logs).to.have.length(2); - const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked()); + const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.callAsync()); expect(secondsTimeLocked).to.be.bignumber.equal(SECONDS_TIME_LOCKED); }); }); @@ -152,10 +156,14 @@ describe('MultiSigWalletWithTimeLock', () => { SIGNATURES_REQUIRED, SECONDS_TIME_LOCKED, ]); - multiSig = new MultiSigWalletWithTimeLockContract(multiSigInstance); + multiSig = new MultiSigWalletWithTimeLockContract( + web3Wrapper, + multiSigInstance.abi, + multiSigInstance.address, + ); multiSigWrapper = new MultiSigWrapper((multiSig as any) as MultiSigWalletContract); - const secondsTimeLocked = await multiSig.secondsTimeLocked(); + const secondsTimeLocked = await multiSig.secondsTimeLocked.callAsync(); initialSecondsTimeLocked = secondsTimeLocked.toNumber(); const destination = multiSig.address; const from = owners[0]; @@ -187,7 +195,7 @@ describe('MultiSigWalletWithTimeLock', () => { await rpc.increaseTimeAsync(SECONDS_TIME_LOCKED.toNumber()); await multiSig.executeTransaction.sendTransactionAsync(txId, { from: owners[0] }); - const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked()); + const secondsTimeLocked = new BigNumber(await multiSig.secondsTimeLocked.callAsync()); expect(secondsTimeLocked).to.be.bignumber.equal(newSecondsTimeLocked); }); }); diff --git a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts index 7e9d44730..c0299e1e1 100644 --- a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts +++ b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts @@ -49,7 +49,11 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { [authorizedAddress, unauthorizedAddress] = accounts; const initialOwner = accounts[0]; const tokenTransferProxyInstance = await deployer.deployAsync(ContractName.TokenTransferProxy); - tokenTransferProxy = new TokenTransferProxyContract(tokenTransferProxyInstance); + tokenTransferProxy = new TokenTransferProxyContract( + web3Wrapper, + tokenTransferProxyInstance.abi, + tokenTransferProxyInstance.address, + ); await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(authorizedAddress, { from: initialOwner, }); @@ -57,7 +61,11 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { ContractName.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress, [owners, requiredApprovals, SECONDS_TIME_LOCKED, tokenTransferProxy.address], ); - multiSig = new MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract(multiSigInstance); + multiSig = new MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract( + web3Wrapper, + multiSigInstance.abi, + multiSigInstance.address, + ); await tokenTransferProxy.transferOwnership.sendTransactionAsync(multiSig.address, { from: initialOwner, }); @@ -74,12 +82,14 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { describe('isFunctionRemoveAuthorizedAddress', () => { it('should throw if data is not for removeAuthorizedAddress', async () => { const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]); - return expect(multiSig.isFunctionRemoveAuthorizedAddress(data)).to.be.rejectedWith(constants.REVERT); + return expect(multiSig.isFunctionRemoveAuthorizedAddress.callAsync(data)).to.be.rejectedWith( + constants.REVERT, + ); }); it('should return true if data is for removeAuthorizedAddress', async () => { const data = MultiSigWrapper.encodeFnArgs('removeAuthorizedAddress', PROXY_ABI, [owners[0]]); - const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress(data); + const isFunctionRemoveAuthorizedAddress = await multiSig.isFunctionRemoveAuthorizedAddress.callAsync(data); expect(isFunctionRemoveAuthorizedAddress).to.be.true(); }); }); @@ -114,7 +124,7 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs; const txId = log.args.transactionId; await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed(txId); + const isConfirmed = await multiSig.isConfirmed.callAsync(txId); expect(isConfirmed).to.be.true(); return expect( @@ -133,7 +143,7 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs; const txId = log.args.transactionId; await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed(txId); + const isConfirmed = await multiSig.isConfirmed.callAsync(txId); expect(isConfirmed).to.be.true(); return expect( @@ -152,10 +162,10 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs; const txId = log.args.transactionId; await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed(txId); + const isConfirmed = await multiSig.isConfirmed.callAsync(txId); expect(isConfirmed).to.be.true(); await multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }); - const isAuthorized = await tokenTransferProxy.authorized(authorizedAddress); + const isAuthorized = await tokenTransferProxy.authorized.callAsync(authorizedAddress); expect(isAuthorized).to.be.false(); }); @@ -170,10 +180,10 @@ describe('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', () => { const log = abiDecoder.tryToDecodeLogOrNoop(res.logs[0]) as LogWithDecodedArgs; const txId = log.args.transactionId; await multiSig.confirmTransaction.sendTransactionAsync(txId, { from: owners[1] }); - const isConfirmed = await multiSig.isConfirmed(txId); + const isConfirmed = await multiSig.isConfirmed.callAsync(txId); expect(isConfirmed).to.be.true(); await multiSig.executeRemoveAuthorizedAddress.sendTransactionAsync(txId, { from: owners[1] }); - const tx = await multiSig.transactions(txId); + const tx = await multiSig.transactions.callAsync(txId); const isExecuted = tx[3]; expect(isExecuted).to.be.true(); return expect( diff --git a/packages/contracts/test/token_registry.ts b/packages/contracts/test/token_registry.ts index 867282d2c..eee14ad9f 100644 --- a/packages/contracts/test/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -31,7 +31,7 @@ describe('TokenRegistry', () => { owner = accounts[0]; notOwner = accounts[1]; const tokenRegInstance = await deployer.deployAsync(ContractName.TokenRegistry); - tokenReg = new TokenRegistryContract(tokenRegInstance); + tokenReg = new TokenRegistryContract(web3Wrapper, tokenRegInstance.abi, tokenRegInstance.address); tokenRegWrapper = new TokenRegWrapper(tokenReg); }); beforeEach(async () => { diff --git a/packages/contracts/test/token_transfer_proxy/auth.ts b/packages/contracts/test/token_transfer_proxy/auth.ts index 9d453b079..4f497dd0d 100644 --- a/packages/contracts/test/token_transfer_proxy/auth.ts +++ b/packages/contracts/test/token_transfer_proxy/auth.ts @@ -25,7 +25,11 @@ describe('TokenTransferProxy', () => { owner = address = accounts[0]; notOwner = accounts[1]; const tokenTransferProxyInstance = await deployer.deployAsync(ContractName.TokenTransferProxy); - tokenTransferProxy = new TokenTransferProxyContract(tokenTransferProxyInstance); + tokenTransferProxy = new TokenTransferProxyContract( + web3Wrapper, + tokenTransferProxyInstance.abi, + tokenTransferProxyInstance.address, + ); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -41,7 +45,7 @@ describe('TokenTransferProxy', () => { }); it('should allow owner to add an authorized address', async () => { await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(address, { from: owner }); - const isAuthorized = await tokenTransferProxy.authorized(address); + const isAuthorized = await tokenTransferProxy.authorized.callAsync(address); expect(isAuthorized).to.be.true(); }); it('should throw if owner attempts to authorize a duplicate address', async () => { @@ -67,7 +71,7 @@ describe('TokenTransferProxy', () => { await tokenTransferProxy.removeAuthorizedAddress.sendTransactionAsync(address, { from: owner, }); - const isAuthorized = await tokenTransferProxy.authorized(address); + const isAuthorized = await tokenTransferProxy.authorized.callAsync(address); expect(isAuthorized).to.be.false(); }); @@ -82,19 +86,19 @@ describe('TokenTransferProxy', () => { describe('getAuthorizedAddresses', () => { it('should return all authorized addresses', async () => { - const initial = await tokenTransferProxy.getAuthorizedAddresses(); + const initial = await tokenTransferProxy.getAuthorizedAddresses.callAsync(); expect(initial).to.have.length(0); await tokenTransferProxy.addAuthorizedAddress.sendTransactionAsync(address, { from: owner, }); - const afterAdd = await tokenTransferProxy.getAuthorizedAddresses(); + const afterAdd = await tokenTransferProxy.getAuthorizedAddresses.callAsync(); expect(afterAdd).to.have.length(1); expect(afterAdd).to.include(address); await tokenTransferProxy.removeAuthorizedAddress.sendTransactionAsync(address, { from: owner, }); - const afterRemove = await tokenTransferProxy.getAuthorizedAddresses(); + const afterRemove = await tokenTransferProxy.getAuthorizedAddresses.callAsync(); expect(afterRemove).to.have.length(0); }); }); diff --git a/packages/contracts/test/token_transfer_proxy/transfer_from.ts b/packages/contracts/test/token_transfer_proxy/transfer_from.ts index c35a7276a..6b86a0e97 100644 --- a/packages/contracts/test/token_transfer_proxy/transfer_from.ts +++ b/packages/contracts/test/token_transfer_proxy/transfer_from.ts @@ -33,9 +33,13 @@ describe('TokenTransferProxy', () => { accounts = await web3Wrapper.getAvailableAddressesAsync(); owner = notAuthorized = accounts[0]; const tokenTransferProxyInstance = await deployer.deployAsync(ContractName.TokenTransferProxy); - tokenTransferProxy = new TokenTransferProxyContract(tokenTransferProxyInstance); + tokenTransferProxy = new TokenTransferProxyContract( + web3Wrapper, + tokenTransferProxyInstance.abi, + tokenTransferProxyInstance.address, + ); const repInstance = await deployer.deployAsync(ContractName.DummyToken); - rep = new DummyTokenContract(repInstance); + rep = new DummyTokenContract(web3Wrapper, repInstance.abi, repInstance.address); dmyBalances = new Balances([rep], [accounts[0], accounts[1]]); await Promise.all([ diff --git a/packages/contracts/test/unlimited_allowance_token.ts b/packages/contracts/test/unlimited_allowance_token.ts index f0a66e76b..03eb581ad 100644 --- a/packages/contracts/test/unlimited_allowance_token.ts +++ b/packages/contracts/test/unlimited_allowance_token.ts @@ -35,7 +35,7 @@ describe('UnlimitedAllowanceToken', () => { owner = accounts[0]; spender = accounts[1]; const tokenInstance = await deployer.deployAsync(ContractName.DummyToken); - token = new DummyTokenContract(tokenInstance); + token = new DummyTokenContract(web3Wrapper, tokenInstance.abi, tokenInstance.address); await token.mint.sendTransactionAsync(MAX_MINT_VALUE, { from: owner }); tokenAddress = token.address; }); diff --git a/packages/contracts/test/zrx_token.ts b/packages/contracts/test/zrx_token.ts index 1610ada12..4ccc66b36 100644 --- a/packages/contracts/test/zrx_token.ts +++ b/packages/contracts/test/zrx_token.ts @@ -36,7 +36,7 @@ describe('ZRXToken', () => { networkId: constants.TESTRPC_NETWORK_ID, }); const zrxInstance = await deployer.deployAsync(ContractName.ZRXToken); - zrx = new ZRXTokenContract(zrxInstance); + zrx = new ZRXTokenContract(web3Wrapper, zrxInstance.abi, zrxInstance.address); zrxAddress = zrx.address; MAX_UINT = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; }); @@ -48,25 +48,25 @@ describe('ZRXToken', () => { }); describe('constants', () => { it('should have 18 decimals', async () => { - const decimals = new BigNumber(await zrx.decimals()); + const decimals = new BigNumber(await zrx.decimals.callAsync()); const expectedDecimals = 18; expect(decimals).to.be.bignumber.equal(expectedDecimals); }); it('should have a total supply of 1 billion tokens', async () => { - const totalSupply = new BigNumber(await zrx.totalSupply()); + const totalSupply = new BigNumber(await zrx.totalSupply.callAsync()); const expectedTotalSupply = 1000000000; expect(ZeroEx.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply); }); it('should be named 0x Protocol Token', async () => { - const name = await zrx.name(); + const name = await zrx.name.callAsync(); const expectedName = '0x Protocol Token'; expect(name).to.be.equal(expectedName); }); it('should have the symbol ZRX', async () => { - const symbol = await zrx.symbol(); + const symbol = await zrx.symbol.callAsync(); const expectedSymbol = 'ZRX'; expect(symbol).to.be.equal(expectedSymbol); }); @@ -75,7 +75,7 @@ describe('ZRXToken', () => { describe('constructor', () => { it('should initialize owner balance to totalSupply', async () => { const ownerBalance = await zeroEx.token.getBalanceAsync(zrxAddress, owner); - const totalSupply = new BigNumber(await zrx.totalSupply()); + const totalSupply = new BigNumber(await zrx.totalSupply.callAsync()); expect(totalSupply).to.be.bignumber.equal(ownerBalance); }); }); diff --git a/packages/contracts/util/balances.ts b/packages/contracts/util/balances.ts index 0abc305d8..d03d4b3c5 100644 --- a/packages/contracts/util/balances.ts +++ b/packages/contracts/util/balances.ts @@ -17,7 +17,7 @@ export class Balances { const balancesByOwner: BalancesByOwner = {}; for (const tokenContractInstance of this._tokenContractInstances) { for (const ownerAddress of this._ownerAddresses) { - let balance = await tokenContractInstance.balanceOf(ownerAddress); + let balance = await tokenContractInstance.balanceOf.callAsync(ownerAddress); balance = new BigNumber(balance); if (_.isUndefined(balancesByOwner[ownerAddress])) { balancesByOwner[ownerAddress] = {}; diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts index 03d04629d..f016067fe 100644 --- a/packages/contracts/util/exchange_wrapper.ts +++ b/packages/contracts/util/exchange_wrapper.ts @@ -186,11 +186,11 @@ export class ExchangeWrapper { public async getOrderHashAsync(signedOrder: SignedOrder): Promise { const shouldThrowOnInsufficientBalanceOrAllowance = false; const params = signedOrderUtils.getOrderAddressesAndValues(signedOrder); - const orderHash = await this._exchange.getOrderHash(params.orderAddresses, params.orderValues); + const orderHash = await this._exchange.getOrderHash.callAsync(params.orderAddresses, params.orderValues); return orderHash; } public async isValidSignatureAsync(signedOrder: SignedOrder): Promise { - const isValidSignature = await this._exchange.isValidSignature( + const isValidSignature = await this._exchange.isValidSignature.callAsync( signedOrder.maker, ZeroEx.getOrderHashHex(signedOrder), signedOrder.ecSignature.v, @@ -204,7 +204,7 @@ export class ExchangeWrapper { denominator: BigNumber, target: BigNumber, ): Promise { - const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target); + const isRoundingError = await this._exchange.isRoundingError.callAsync(numerator, denominator, target); return isRoundingError; } public async getPartialAmountAsync( @@ -212,7 +212,9 @@ export class ExchangeWrapper { denominator: BigNumber, target: BigNumber, ): Promise { - const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target)); + const partialAmount = new BigNumber( + await this._exchange.getPartialAmount.callAsync(numerator, denominator, target), + ); return partialAmount; } } diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts index d0af17103..ba0fe8af0 100644 --- a/packages/contracts/util/token_registry_wrapper.ts +++ b/packages/contracts/util/token_registry_wrapper.ts @@ -22,7 +22,7 @@ export class TokenRegWrapper { return tx; } public async getTokenMetaDataAsync(tokenAddress: string) { - const data = await this._tokenReg.getTokenMetaData(tokenAddress); + const data = await this._tokenReg.getTokenMetaData.callAsync(tokenAddress); const token: Token = { address: data[0], name: data[1], @@ -34,7 +34,7 @@ export class TokenRegWrapper { return token; } public async getTokenByNameAsync(tokenName: string) { - const data = await this._tokenReg.getTokenByName(tokenName); + const data = await this._tokenReg.getTokenByName.callAsync(tokenName); const token: Token = { address: data[0], name: data[1], @@ -46,7 +46,7 @@ export class TokenRegWrapper { return token; } public async getTokenBySymbolAsync(tokenSymbol: string) { - const data = await this._tokenReg.getTokenBySymbol(tokenSymbol); + const data = await this._tokenReg.getTokenBySymbol.callAsync(tokenSymbol); const token: Token = { address: data[0], name: data[1], -- cgit v1.2.3 From 4e451479f8db6ef459f4d4c6f7935c20f9d6ea09 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 14:56:05 -0800 Subject: Fix build --- .../0x.js/src/contract_wrappers/generated/base_contract.ts | 10 +++++----- packages/contract_templates/contract.handlebars | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts index a62c785bc..a465ddc38 100644 --- a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts +++ b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts @@ -7,8 +7,8 @@ import * as Web3 from 'web3'; export class BaseContract { protected _ethersInterface: ethersContracts.Interface; protected _web3Wrapper: Web3Wrapper; - protected _abi: Web3.ContractAbi; - protected _address: string; + public abi: Web3.ContractAbi; + public address: string; protected static _transformABIData( abis: Web3.DataItem[], values: any[], @@ -49,7 +49,7 @@ export class BaseContract { // 3. Gas estimate calculation + safety margin const removeUndefinedProperties = _.pickBy; const txDataWithDefaults = { - to: this._address, + to: this.address, ...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()), ...removeUndefinedProperties(txData as any), // HACK: TS can't prove that T is spreadable. @@ -63,8 +63,8 @@ export class BaseContract { } constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { this._web3Wrapper = web3Wrapper; - this._abi = abi; - this._address = address; + this.abi = abi; + this.address = address; this._ethersInterface = new ethersContracts.Interface(abi); } } diff --git a/packages/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars index 2954145a7..4b8b30056 100644 --- a/packages/contract_templates/contract.handlebars +++ b/packages/contract_templates/contract.handlebars @@ -43,6 +43,6 @@ export class {{contractName}}Contract extends BaseContract { {{/each}} constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { super(web3Wrapper, abi, address); - classUtils.bindAll(this, ['_ethersInterface', '_address', '_abi', '_web3Wrapper']); + classUtils.bindAll(this, ['_ethersInterface', 'address', 'abi', '_web3Wrapper']); } } // tslint:disable:max-file-line-count -- cgit v1.2.3 From 39c6bc11061301e0aa37cc0edd64bab4fed0564b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 23 Feb 2018 18:14:54 -0800 Subject: Add PR number --- packages/abi-gen/CHANGELOG.md | 4 ++-- packages/types/CHANGELOG.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index 17186570e..c6f1ad37f 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -2,8 +2,8 @@ ## v0.2.3 - _TBD, 2018_ - * Add a `backend` parameter that allows you to specify your backend (web3 or ethers). Ethers auto-converts small ints to numbers (#TBD) - * Add support for ABIv2 (#TBD) + * Add a `backend` parameter that allows you to specify your backend (web3 or ethers). Ethers auto-converts small ints to numbers (#413) + * Add support for ABIv2 (#413) ## v0.2.1 - _February 9, 2018_ diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index bea6f07bc..eff253f7a 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -2,7 +2,7 @@ ## v0.2.4 - _TBD, 2018_ - * Add `data` to `TxData` (#TBD) + * Add `data` to `TxData` (#413) ## v0.2.1 - _February 9, 2018_ -- cgit v1.2.3 From 2aec1501d03085e85fc5a73da3a44481de2dc6b3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 09:54:00 -0800 Subject: Update template link --- packages/contract_templates/contract.handlebars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars index 4b8b30056..f03bdb504 100644 --- a/packages/contract_templates/contract.handlebars +++ b/packages/contract_templates/contract.handlebars @@ -1,6 +1,6 @@ /** * This file is auto-generated using abi-gen. Don't edit directly. - * Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates. + * Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/contract_templates. */ // tslint:disable:no-consecutive-blank-lines // tslint:disable-next-line:no-unused-variable -- cgit v1.2.3 From 747732118ca7375012545629139f47bad8290056 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 14:10:41 -0800 Subject: Fix namings --- packages/contracts/test/exchange/helpers.ts | 4 ++-- packages/contracts/util/types.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/contracts/test/exchange/helpers.ts b/packages/contracts/test/exchange/helpers.ts index 497193e8b..9869c2155 100644 --- a/packages/contracts/test/exchange/helpers.ts +++ b/packages/contracts/test/exchange/helpers.ts @@ -55,8 +55,8 @@ describe('Exchange', () => { exchangeContractAddress: exchange.address, maker, feeRecipient, - makerToken: rep.address, - takerToken: dgd.address, + makerTokenAddress: rep.address, + takerTokenAddress: dgd.address, makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18), takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18), makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18), diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts index 65bc26f79..d6e4c587d 100644 --- a/packages/contracts/util/types.ts +++ b/packages/contracts/util/types.ts @@ -41,8 +41,8 @@ export interface DefaultOrderParams { exchangeContractAddress: string; maker: string; feeRecipient: string; - makerToken: string; - takerToken: string; + makerTokenAddress: string; + takerTokenAddress: string; makerTokenAmount: BigNumber; takerTokenAmount: BigNumber; makerFee: BigNumber; -- cgit v1.2.3 From 0bb0bff0b31bb40da7edd7bb25e8fdf67a11622a Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 14:31:09 -0800 Subject: Change backend for contracts contracts --- packages/contracts/package.json | 2 +- packages/contracts/test/exchange/core.ts | 8 ++++---- packages/contracts/util/token_registry_wrapper.ts | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/contracts/package.json b/packages/contracts/package.json index f41d7786d..9bb0cc2d2 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -17,7 +17,7 @@ "compile:comment": "Yarn workspaces do not link binaries correctly so we need to reference them directly https://github.com/yarnpkg/yarn/issues/3846", "compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir src/artifacts", "clean": "shx rm -rf ./lib", - "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend web3 && prettier --write 'src/contract_wrappers/generated/**.ts'", + "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(DummyToken|TokenTransferProxy|Exchange|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'", "migrate": "node ../deployer/lib/src/cli.js migrate", "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'", "test:circleci": "yarn test" diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 7d191aa99..303d745aa 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -724,7 +724,7 @@ describe('Exchange', () => { const res = await exWrapper.fillOrderAsync(signedOrder, taker); expect(res.logs).to.have.length(1); const log = res.logs[0] as LogWithDecodedArgs; - const errCode = log.args.errorId.toNumber(); + const errCode = log.args.errorId; expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED); }); @@ -735,7 +735,7 @@ describe('Exchange', () => { const res = await exWrapper.fillOrderAsync(signedOrder, taker); expect(res.logs).to.have.length(1); const log = res.logs[0] as LogWithDecodedArgs; - const errCode = log.args.errorId.toNumber(); + const errCode = log.args.errorId; expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED); }); }); @@ -863,7 +863,7 @@ describe('Exchange', () => { const res = await exWrapper.cancelOrderAsync(signedOrder, maker); expect(res.logs).to.have.length(1); const log = res.logs[0] as LogWithDecodedArgs; - const errCode = log.args.errorId.toNumber(); + const errCode = log.args.errorId; expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED); }); @@ -875,7 +875,7 @@ describe('Exchange', () => { const res = await exWrapper.cancelOrderAsync(signedOrder, maker); expect(res.logs).to.have.length(1); const log = res.logs[0] as LogWithDecodedArgs; - const errCode = log.args.errorId.toNumber(); + const errCode = log.args.errorId; expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED); }); }); diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts index ba0fe8af0..d78c8a64e 100644 --- a/packages/contracts/util/token_registry_wrapper.ts +++ b/packages/contracts/util/token_registry_wrapper.ts @@ -27,7 +27,7 @@ export class TokenRegWrapper { address: data[0], name: data[1], symbol: data[2], - decimals: data[3].toNumber(), + decimals: data[3], ipfsHash: data[4], swarmHash: data[5], }; @@ -39,7 +39,7 @@ export class TokenRegWrapper { address: data[0], name: data[1], symbol: data[2], - decimals: data[3].toNumber(), + decimals: data[3], ipfsHash: data[4], swarmHash: data[5], }; @@ -51,7 +51,7 @@ export class TokenRegWrapper { address: data[0], name: data[1], symbol: data[2], - decimals: data[3].toNumber(), + decimals: data[3], ipfsHash: data[4], swarmHash: data[5], }; -- cgit v1.2.3 From 1657451f37a74e772c10d26d94ce950b7092816e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 16:33:12 -0800 Subject: Add as an option to --- packages/types/CHANGELOG.md | 1 + packages/types/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index eff253f7a..a4f293d60 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -3,6 +3,7 @@ ## v0.2.4 - _TBD, 2018_ * Add `data` to `TxData` (#413) + * Add `number` as an option to `ContractEventArg` (#413) ## v0.2.1 - _February 9, 2018_ diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 484faa93d..6242d4268 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -39,7 +39,7 @@ export enum AbiType { Fallback = 'fallback', } -export type ContractEventArg = string | BigNumber; +export type ContractEventArg = string | BigNumber | number; export interface DecodedLogArgs { [argName: string]: ContractEventArg; -- cgit v1.2.3 From 42063f785ec565ae5b7f61c2c56a8eabace60d84 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 16:33:51 -0800 Subject: Use as a backend to decode event args --- packages/utils/CHANGELOG.md | 4 ++++ packages/utils/package.json | 1 + packages/utils/src/abi_decoder.ts | 27 ++++++++++++++------------- packages/utils/src/globals.d.ts | 29 +++++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 19ee80e4f..81792bee8 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.4.0 - _TBD, 2018_ + + * Use `ethers-contracts` as a backend to decode event args (#413) + ## v0.3.2 - _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/utils/package.json b/packages/utils/package.json index 14ccabcf4..2a2088920 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -31,6 +31,7 @@ "dependencies": { "@0xproject/types": "^0.2.3", "bignumber.js": "~4.1.0", + "ethers-contracts": "^2.2.1", "js-sha3": "^0.7.0", "lodash": "^4.17.4", "web3": "^0.20.0" diff --git a/packages/utils/src/abi_decoder.ts b/packages/utils/src/abi_decoder.ts index 368973b1b..024da3741 100644 --- a/packages/utils/src/abi_decoder.ts +++ b/packages/utils/src/abi_decoder.ts @@ -1,7 +1,7 @@ import { AbiType, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '@0xproject/types'; +import * as ethersContracts from 'ethers-contracts'; import * as _ from 'lodash'; import * as Web3 from 'web3'; -import * as SolidityCoder from 'web3/lib/solidity/coder'; import { BigNumber } from './configured_bignumber'; @@ -27,31 +27,29 @@ export class AbiDecoder { if (_.isUndefined(event)) { return log; } + const ethersInterface = new ethersContracts.Interface([event]); const logData = log.data; const decodedParams: DecodedLogArgs = {}; - let dataIndex = 0; let topicsIndex = 1; const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed); const dataTypes = _.map(nonIndexedInputs, input => input.type); - const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice('0x'.length)); + const decodedData = ethersInterface.events[event.name].parse(log.data); let failedToDecode = false; - _.forEach(event.inputs, (param: Web3.EventParameter) => { + _.forEach(event.inputs, (param: Web3.EventParameter, idx: number) => { // Indexed parameters are stored in topics. Non-indexed ones in decodedData - let value: BigNumber | string = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; + let value: BigNumber | string | number = param.indexed ? log.topics[topicsIndex++] : decodedData[idx]; if (_.isUndefined(value)) { failedToDecode = true; return; } if (param.type === SolidityTypes.Address) { value = AbiDecoder._padZeros(new BigNumber(value).toString(16)); - } else if ( - param.type === SolidityTypes.Uint256 || - param.type === SolidityTypes.Uint8 || - param.type === SolidityTypes.Uint - ) { + } else if (param.type === SolidityTypes.Uint256 || param.type === SolidityTypes.Uint) { value = new BigNumber(value); + } else if (param.type === SolidityTypes.Uint8) { + value = new BigNumber(value).toNumber(); } decodedParams[param.name] = value; }); @@ -67,11 +65,14 @@ export class AbiDecoder { } } private _addABI(abiArray: Web3.AbiDefinition[]): void { + if (_.isUndefined(abiArray)) { + return; + } + const ethersInterface = new ethersContracts.Interface(abiArray); _.map(abiArray, (abi: Web3.AbiDefinition) => { if (abi.type === AbiType.Event) { - const signature = `${abi.name}(${_.map(abi.inputs, input => input.type).join(',')})`; - const signatureHash = new Web3().sha3(signature); - this._methodIds[signatureHash] = abi; + const topic = ethersInterface.events[abi.name].topic; + this._methodIds[topic] = abi; } }); this._savedABIs = this._savedABIs.concat(abiArray); diff --git a/packages/utils/src/globals.d.ts b/packages/utils/src/globals.d.ts index ade9e59db..951ef6ea2 100644 --- a/packages/utils/src/globals.d.ts +++ b/packages/utils/src/globals.d.ts @@ -1,3 +1,28 @@ -declare module 'web3/lib/solidity/coder' { - const decodeParams: (types: string[], data: string) => any[]; +declare module 'ethers-contracts' { + export interface TransactionDescription { + name: string; + signature: string; + sighash: string; + data: string; + } + export interface CallDescription extends TransactionDescription { + parse: (...args: any[]) => any; + } + export interface FunctionDescription { + (...params: any[]): TransactionDescription | CallDescription; + inputs: { names: string[]; types: string[] }; + outputs: { names: string[]; types: string[] }; + } + export interface EventDescription { + parse: (...args: any[]) => any; + inputs: { names: string[]; types: string[] }; + signature: string; + topic: string; + } + // tslint:disable-next-line:max-classes-per-file + export class Interface { + public functions: { [functionName: string]: FunctionDescription }; + public events: { [eventName: string]: EventDescription }; + constructor(abi: any); + } } -- cgit v1.2.3 From 748ed403215b685c6aa3da36ab89ad02e2550c71 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 16:35:44 -0800 Subject: Add to context data --- packages/abi-gen/CHANGELOG.md | 1 + packages/abi-gen/src/index.ts | 1 + packages/abi-gen/src/types.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index c6f1ad37f..f04eb93cf 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -4,6 +4,7 @@ * Add a `backend` parameter that allows you to specify your backend (web3 or ethers). Ethers auto-converts small ints to numbers (#413) * Add support for ABIv2 (#413) + * Add `hasReturnValue` to context data (#413) ## v0.2.1 - _February 9, 2018_ diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index d34d74cdf..49ff0fe20 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -136,6 +136,7 @@ for (const abiFileName of abiFileNames) { const methodData = { ...methodAbi, singleReturnValue: methodAbi.outputs.length === 1, + hasReturnValue: methodAbi.outputs.length !== 0, }; return methodData; }); diff --git a/packages/abi-gen/src/types.ts b/packages/abi-gen/src/types.ts index 402e0105e..deddb1857 100644 --- a/packages/abi-gen/src/types.ts +++ b/packages/abi-gen/src/types.ts @@ -19,6 +19,7 @@ export enum ContractsBackend { export interface Method extends Web3.MethodAbi { singleReturnValue: boolean; + hasReturnValue: boolean; } export interface ContextData { -- cgit v1.2.3 From a5ef1db0c56e4166641c19b46641921a3b1e509f Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 16:36:56 -0800 Subject: Rewrite templates to decode call data on transactions --- packages/0x.js/src/globals.d.ts | 1 + .../contract_templates/partials/call.handlebars | 22 +--------------- .../partials/callAsync.handlebars | 29 ++++++++++++++++++++++ packages/contract_templates/partials/tx.handlebars | 27 +------------------- packages/contracts/globals.d.ts | 1 + 5 files changed, 33 insertions(+), 47 deletions(-) create mode 100644 packages/contract_templates/partials/callAsync.handlebars diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts index 702f35149..505f9b933 100644 --- a/packages/0x.js/src/globals.d.ts +++ b/packages/0x.js/src/globals.d.ts @@ -66,6 +66,7 @@ declare module 'ethers-contracts' { export class Interface { public functions: { [functionName: string]: FunctionDescription }; public events: { [eventName: string]: EventDescription }; + public static decodeParams(types: string[], data: string): any[]; constructor(abi: any); } } diff --git a/packages/contract_templates/partials/call.handlebars b/packages/contract_templates/partials/call.handlebars index 7ac3e1ee3..cfb9bea82 100644 --- a/packages/contract_templates/partials/call.handlebars +++ b/packages/contract_templates/partials/call.handlebars @@ -1,23 +1,3 @@ public {{this.name}} = { - async callAsync( - {{> typed_params inputs=inputs}} - defaultBlock?: Web3.BlockParam, - ): Promise<{{> return_type outputs=outputs}}> { - const self = this as {{contractName}}Contract; - const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; - [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); - const callDescription = self._ethersInterface.functions.{{this.name}}( - {{> params inputs=inputs}} - ) as ethersContracts.CallDescription; - const callData = await self._applyDefaultsToTxDataAsync( - { - data: callDescription.data, - } - ) - const rawCallResult = await self._web3Wrapper.callAsync(callData); - let resultArray = callDescription.parse(rawCallResult); - const outputAbi = _.find(this.abi, {name: '{{this.name}}'}).outputs; - resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); - return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; - }, + {{> callAsync}} }; diff --git a/packages/contract_templates/partials/callAsync.handlebars b/packages/contract_templates/partials/callAsync.handlebars new file mode 100644 index 000000000..88cc49ffa --- /dev/null +++ b/packages/contract_templates/partials/callAsync.handlebars @@ -0,0 +1,29 @@ +{{#hasReturnValue}} +async callAsync( +{{> typed_params inputs=inputs}} +{{#this.payable}} + txData: TxDataPayable = {}, +{{/this.payable}} +{{^this.payable}} + txData: TxData = {}, +{{/this.payable}} +): Promise<{{> return_type outputs=outputs}}> { + const self = this as {{contractName}}Contract; + const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; + [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); + const encodedData = self._ethersInterface.functions.{{this.name}}( + {{> params inputs=inputs}} + ).data; + const callData = await self._applyDefaultsToTxDataAsync( + { + data: encodedData, + } + ) + const rawCallResult = await self._web3Wrapper.callAsync(callData); + const outputAbi = _.find(this.abi, {name: '{{this.name}}'}).outputs as Web3.DataItem[]; + const outputParamsTypes = _.map(outputAbi, 'type'); + let resultArray = ethersContracts.Interface.decodeParams(outputParamsTypes, rawCallResult) as any; + resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); + return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; +}, +{{/hasReturnValue}} diff --git a/packages/contract_templates/partials/tx.handlebars b/packages/contract_templates/partials/tx.handlebars index 5026dac20..347a482d6 100644 --- a/packages/contract_templates/partials/tx.handlebars +++ b/packages/contract_templates/partials/tx.handlebars @@ -54,30 +54,5 @@ public {{this.name}} = { ).data return abiEncodedTransactionData; }, - async callAsync( - {{> typed_params inputs=inputs}} - {{#this.payable}} - txData: TxDataPayable = {}, - {{/this.payable}} - {{^this.payable}} - txData: TxData = {}, - {{/this.payable}} - ): Promise<{{> return_type outputs=outputs}}> { - const self = this as {{contractName}}Contract; - const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; - [{{> params inputs=inputs}}] = BaseContract._transformABIData(inputAbi, [{{> params inputs=inputs}}], BaseContract._bigNumberToString.bind(this)); - const callDescription = self._ethersInterface.functions.{{this.name}}( - {{> params inputs=inputs}} - ) as ethersContracts.CallDescription; - const callData = await self._applyDefaultsToTxDataAsync( - { - data: callDescription.data, - } - ) - const rawCallResult = await self._web3Wrapper.callAsync(callData); - let resultArray = callDescription.parse(rawCallResult); - const outputAbi = _.find(this.abi, {name: '{{this.name}}'}).outputs; - resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this)); - return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}}; - }, + {{> callAsync}} }; diff --git a/packages/contracts/globals.d.ts b/packages/contracts/globals.d.ts index fe39fb11d..beb3bfd8c 100644 --- a/packages/contracts/globals.d.ts +++ b/packages/contracts/globals.d.ts @@ -57,6 +57,7 @@ declare module 'ethers-contracts' { export class Interface { public functions: { [functionName: string]: FunctionDescription }; public events: { [eventName: string]: EventDescription }; + public static decodeParams(types: string[], data: string): any[]; constructor(abi: any); } } -- cgit v1.2.3 From 34c1134b55c202b47ac4672a4c9025e4be9e21b4 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 17:03:09 -0800 Subject: Create ethers-typescript-typings --- packages/0x.js/src/globals.d.ts | 29 ------------- packages/contracts/globals.d.ts | 29 ------------- packages/ethers-typescript-typings/.npmignore | 3 ++ packages/ethers-typescript-typings/CHANGELOG.md | 5 +++ packages/ethers-typescript-typings/README.md | 49 ++++++++++++++++++++++ packages/ethers-typescript-typings/index.d.ts | 29 +++++++++++++ packages/ethers-typescript-typings/package.json | 28 +++++++++++++ .../scripts/postpublish.js | 5 +++ packages/ethers-typescript-typings/tslint.json | 3 ++ packages/utils/src/globals.d.ts | 28 ------------- 10 files changed, 122 insertions(+), 86 deletions(-) create mode 100644 packages/ethers-typescript-typings/.npmignore create mode 100644 packages/ethers-typescript-typings/CHANGELOG.md create mode 100644 packages/ethers-typescript-typings/README.md create mode 100644 packages/ethers-typescript-typings/index.d.ts create mode 100644 packages/ethers-typescript-typings/package.json create mode 100644 packages/ethers-typescript-typings/scripts/postpublish.js create mode 100644 packages/ethers-typescript-typings/tslint.json delete mode 100644 packages/utils/src/globals.d.ts diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts index 505f9b933..0e103d057 100644 --- a/packages/0x.js/src/globals.d.ts +++ b/packages/0x.js/src/globals.d.ts @@ -41,32 +41,3 @@ declare module 'truffle-hdwallet-provider' { } export = HDWalletProvider; } - -declare module 'ethers-contracts' { - export interface TransactionDescription { - name: string; - signature: string; - sighash: string; - data: string; - } - export interface CallDescription extends TransactionDescription { - parse: (...args: any[]) => any; - } - export interface FunctionDescription { - (...params: any[]): TransactionDescription | CallDescription; - inputs: { names: string[]; types: string[] }; - outputs: { names: string[]; types: string[] }; - } - export interface EventDescription { - inputs: { names: string[]; types: string[] }; - signature: string; - topic: string; - } - // tslint:disable-next-line:max-classes-per-file - export class Interface { - public functions: { [functionName: string]: FunctionDescription }; - public events: { [eventName: string]: EventDescription }; - public static decodeParams(types: string[], data: string): any[]; - constructor(abi: any); - } -} diff --git a/packages/contracts/globals.d.ts b/packages/contracts/globals.d.ts index beb3bfd8c..0e6586a4b 100644 --- a/packages/contracts/globals.d.ts +++ b/packages/contracts/globals.d.ts @@ -32,32 +32,3 @@ declare module 'ethereumjs-abi' { const soliditySHA3: (argTypes: string[], args: any[]) => Buffer; const methodID: (name: string, types: string[]) => Buffer; } - -declare module 'ethers-contracts' { - export interface TransactionDescription { - name: string; - signature: string; - sighash: string; - data: string; - } - export interface CallDescription extends TransactionDescription { - parse: (...args: any[]) => any; - } - export interface FunctionDescription { - (...params: any[]): TransactionDescription | CallDescription; - inputs: { names: string[]; types: string[] }; - outputs: { names: string[]; types: string[] }; - } - export interface EventDescription { - inputs: { names: string[]; types: string[] }; - signature: string; - topic: string; - } - // tslint:disable-next-line:max-classes-per-file - export class Interface { - public functions: { [functionName: string]: FunctionDescription }; - public events: { [eventName: string]: EventDescription }; - public static decodeParams(types: string[], data: string): any[]; - constructor(abi: any); - } -} diff --git a/packages/ethers-typescript-typings/.npmignore b/packages/ethers-typescript-typings/.npmignore new file mode 100644 index 000000000..104d718ed --- /dev/null +++ b/packages/ethers-typescript-typings/.npmignore @@ -0,0 +1,3 @@ +.* +yarn-error.log +/scripts/ diff --git a/packages/ethers-typescript-typings/CHANGELOG.md b/packages/ethers-typescript-typings/CHANGELOG.md new file mode 100644 index 000000000..d67d5c73d --- /dev/null +++ b/packages/ethers-typescript-typings/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## v0.0.1 - _TBD, 2018_ + + * Initial types (#413) diff --git a/packages/ethers-typescript-typings/README.md b/packages/ethers-typescript-typings/README.md new file mode 100644 index 000000000..56ce5f138 --- /dev/null +++ b/packages/ethers-typescript-typings/README.md @@ -0,0 +1,49 @@ +## ethers-typescript-typings + +There currently isn't an official [Ethers][ethers] +type definition included in the [DefinitelyTyped][definitelytyped] project. +Until that happens, we will continue to improve our own type definition. +If it get's close to comprehensive, we'll add it to [DefinitelyTyped][definitelytyped]. + +[ethers]: https://github.com/ethers-io/ethers.js +[definitelytyped]: https://github.com/DefinitelyTyped/DefinitelyTyped + +## Installation + +```bash +yarn add -D ethers-typescript-typings +``` + +## Usage + +Add the following line within an `include` section of your `tsconfig.json` + +```json +"./node_modules/ethers-typescript-typings/index.d.ts" +``` + +## Contributing + +We strongly encourage that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository. + +Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. + +### Install Dependencies + +If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: + +```bash +yarn config set workspaces-experimental true +``` + +Then install dependencies + +```bash +yarn install +``` + +### Lint + +```bash +yarn lint +``` diff --git a/packages/ethers-typescript-typings/index.d.ts b/packages/ethers-typescript-typings/index.d.ts new file mode 100644 index 000000000..f4f99b890 --- /dev/null +++ b/packages/ethers-typescript-typings/index.d.ts @@ -0,0 +1,29 @@ +declare module 'ethers-contracts' { + export interface TransactionDescription { + name: string; + signature: string; + sighash: string; + data: string; + } + export interface CallDescription extends TransactionDescription { + parse: (...args: any[]) => any; + } + export interface FunctionDescription { + (...params: any[]): TransactionDescription | CallDescription; + inputs: { names: string[]; types: string[] }; + outputs: { names: string[]; types: string[] }; + } + export interface EventDescription { + parse: (...args: any[]) => any; + inputs: { names: string[]; types: string[] }; + signature: string; + topic: string; + } + // tslint:disable-next-line:max-classes-per-file + export class Interface { + public functions: { [functionName: string]: FunctionDescription }; + public events: { [eventName: string]: EventDescription }; + public static decodeParams(types: string[], data: string): any[]; + constructor(abi: any); + } +} diff --git a/packages/ethers-typescript-typings/package.json b/packages/ethers-typescript-typings/package.json new file mode 100644 index 000000000..0e6f517c8 --- /dev/null +++ b/packages/ethers-typescript-typings/package.json @@ -0,0 +1,28 @@ +{ + "name": "ethers-typescript-typings", + "version": "0.0.1", + "description": "Typescript type definitions for ethers.js", + "main": "index.d.ts", + "types": "index.d.ts", + "scripts": { + "lint": "tslint index.d.ts" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/0xProject/0x.js.git" + }, + "author": "Fabio Berger", + "contributors": [ + "Leonid Logvinov " + ], + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/0xProject/0x.js/issues" + }, + "homepage": "https://github.com/0xProject/0x.js/packages/ethers-typescript-typings#readme", + "devDependencies": { + "tslint": "5.8.0", + "tslint-config-0xproject": "^0.0.2", + "typescript": "2.7.1" + } +} diff --git a/packages/ethers-typescript-typings/scripts/postpublish.js b/packages/ethers-typescript-typings/scripts/postpublish.js new file mode 100644 index 000000000..b3e5407c8 --- /dev/null +++ b/packages/ethers-typescript-typings/scripts/postpublish.js @@ -0,0 +1,5 @@ +const postpublish_utils = require('../../../scripts/postpublish_utils'); +const packageJSON = require('../package.json'); + +const subPackageName = packageJSON.name; +postpublish_utils.standardPostPublishAsync(subPackageName); \ No newline at end of file diff --git a/packages/ethers-typescript-typings/tslint.json b/packages/ethers-typescript-typings/tslint.json new file mode 100644 index 000000000..9a93a1f74 --- /dev/null +++ b/packages/ethers-typescript-typings/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["tslint-config-0xproject"] +} diff --git a/packages/utils/src/globals.d.ts b/packages/utils/src/globals.d.ts deleted file mode 100644 index 951ef6ea2..000000000 --- a/packages/utils/src/globals.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -declare module 'ethers-contracts' { - export interface TransactionDescription { - name: string; - signature: string; - sighash: string; - data: string; - } - export interface CallDescription extends TransactionDescription { - parse: (...args: any[]) => any; - } - export interface FunctionDescription { - (...params: any[]): TransactionDescription | CallDescription; - inputs: { names: string[]; types: string[] }; - outputs: { names: string[]; types: string[] }; - } - export interface EventDescription { - parse: (...args: any[]) => any; - inputs: { names: string[]; types: string[] }; - signature: string; - topic: string; - } - // tslint:disable-next-line:max-classes-per-file - export class Interface { - public functions: { [functionName: string]: FunctionDescription }; - public events: { [eventName: string]: EventDescription }; - constructor(abi: any); - } -} -- cgit v1.2.3 From 758604fc1ab1fecf1303eef9dfb81192957e495e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 17:04:06 -0800 Subject: Include ethers types --- packages/0x.js/package.json | 1 + packages/0x.js/tsconfig.json | 1 + packages/contracts/package.json | 1 + packages/contracts/tsconfig.json | 1 + packages/utils/package.json | 1 + packages/utils/tsconfig.json | 6 +++++- 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 0ea60fde8..92710ad2d 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -77,6 +77,7 @@ "types-bn": "^0.0.1", "typescript": "2.7.1", "web3-provider-engine": "^13.0.1", + "ethers-typescript-typings": "^0.0.1", "web3-typescript-typings": "^0.9.11", "webpack": "^3.1.0" }, diff --git a/packages/0x.js/tsconfig.json b/packages/0x.js/tsconfig.json index 117f51e83..a6b5c71c2 100644 --- a/packages/0x.js/tsconfig.json +++ b/packages/0x.js/tsconfig.json @@ -9,6 +9,7 @@ "./test/**/*", "../../node_modules/types-bn/index.d.ts", "../../node_modules/types-ethereumjs-util/index.d.ts", + "../../node_modules/ethers-typescript-typings/index.d.ts", "../../node_modules/web3-typescript-typings/index.d.ts", "../../node_modules/chai-typescript-typings/index.d.ts", "../../node_modules/chai-as-promised-typescript-typings/index.d.ts" diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 9bb0cc2d2..8159ba244 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -58,6 +58,7 @@ "types-bn": "^0.0.1", "types-ethereumjs-util": "0xProject/types-ethereumjs-util", "typescript": "2.7.1", + "ethers-typescript-typings": "^0.0.1", "web3-typescript-typings": "^0.9.11", "yargs": "^10.0.3" }, diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json index b618ca4e7..490531eeb 100644 --- a/packages/contracts/tsconfig.json +++ b/packages/contracts/tsconfig.json @@ -11,6 +11,7 @@ "../../node_modules/types-ethereumjs-util/index.d.ts", "../../node_modules/chai-typescript-typings/index.d.ts", "../../node_modules/web3-typescript-typings/index.d.ts", + "../../node_modules/ethers-typescript-typings/index.d.ts", "../../node_modules/chai-as-promised-typescript-typings/index.d.ts", "../../node_modules/types-ethereumjs-util/index.d.ts", "../../node_modules/types-bn/index.d.ts", diff --git a/packages/utils/package.json b/packages/utils/package.json index 2a2088920..4f63aa4ce 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -26,6 +26,7 @@ "shx": "^0.2.2", "tslint": "5.8.0", "typescript": "2.7.1", + "ethers-typescript-typings": "^0.0.1", "web3-typescript-typings": "^0.9.11" }, "dependencies": { diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 3d967d05f..8114d99cd 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -3,5 +3,9 @@ "compilerOptions": { "outDir": "lib" }, - "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"] + "include": [ + "./src/**/*", + "../../node_modules/web3-typescript-typings/index.d.ts", + "../../node_modules/ethers-typescript-typings/index.d.ts" + ] } -- cgit v1.2.3 From ef40cb96876cb77e897be441ceff1ca1521dc682 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 26 Feb 2018 17:04:19 -0800 Subject: Add txData to async calls --- packages/0x.js/src/contract_wrappers/exchange_wrapper.ts | 8 ++++++-- packages/0x.js/src/contract_wrappers/token_wrapper.ts | 5 ++++- packages/contract_templates/partials/callAsync.handlebars | 3 ++- packages/web3-wrapper/src/index.ts | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index e0f6bd539..20b46c6bc 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -108,8 +108,10 @@ export class ExchangeWrapper extends ContractWrapper { const exchangeContract = await this._getExchangeContractAsync(); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync( orderHash, + txData, defaultBlock, ); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber @@ -127,7 +129,8 @@ export class ExchangeWrapper extends ContractWrapper { const exchangeContract = await this._getExchangeContractAsync(); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let fillAmountInBaseUnits = await exchangeContract.filled.callAsync(orderHash, defaultBlock); + const txData = {}; + let fillAmountInBaseUnits = await exchangeContract.filled.callAsync(orderHash, txData, defaultBlock); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber fillAmountInBaseUnits = new BigNumber(fillAmountInBaseUnits); return fillAmountInBaseUnits; @@ -144,7 +147,8 @@ export class ExchangeWrapper extends ContractWrapper { const exchangeContract = await this._getExchangeContractAsync(); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let cancelledAmountInBaseUnits = await exchangeContract.cancelled.callAsync(orderHash, defaultBlock); + const txData = {}; + let cancelledAmountInBaseUnits = await exchangeContract.cancelled.callAsync(orderHash, txData, defaultBlock); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber cancelledAmountInBaseUnits = new BigNumber(cancelledAmountInBaseUnits); return cancelledAmountInBaseUnits; diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts index 0ec9ad707..0f688cb71 100644 --- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts @@ -51,7 +51,8 @@ export class TokenWrapper extends ContractWrapper { const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, defaultBlock); + const txData = {}; + let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, defaultBlock); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber balance = new BigNumber(balance); return balance; @@ -146,9 +147,11 @@ export class TokenWrapper extends ContractWrapper { const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; + const txData = {}; let allowanceInBaseUnits = await tokenContract.allowance.callAsync( normalizedOwnerAddress, normalizedSpenderAddress, + txData, defaultBlock, ); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber diff --git a/packages/contract_templates/partials/callAsync.handlebars b/packages/contract_templates/partials/callAsync.handlebars index 88cc49ffa..93d347145 100644 --- a/packages/contract_templates/partials/callAsync.handlebars +++ b/packages/contract_templates/partials/callAsync.handlebars @@ -7,6 +7,7 @@ async callAsync( {{^this.payable}} txData: TxData = {}, {{/this.payable}} + defaultBlock?: Web3.BlockParam, ): Promise<{{> return_type outputs=outputs}}> { const self = this as {{contractName}}Contract; const inputAbi = _.find(this.abi, {name: '{{this.name}}'}).inputs; @@ -19,7 +20,7 @@ async callAsync( data: encodedData, } ) - const rawCallResult = await self._web3Wrapper.callAsync(callData); + const rawCallResult = await self._web3Wrapper.callAsync(callData, defaultBlock); const outputAbi = _.find(this.abi, {name: '{{this.name}}'}).outputs as Web3.DataItem[]; const outputParamsTypes = _.map(outputAbi, 'type'); let resultArray = ethersContracts.Interface.decodeParams(outputParamsTypes, rawCallResult) as any; diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts index e7c875430..a07805344 100644 --- a/packages/web3-wrapper/src/index.ts +++ b/packages/web3-wrapper/src/index.ts @@ -132,8 +132,8 @@ export class Web3Wrapper { const gas = await promisify(this._web3.eth.estimateGas)(txData); return gas; } - public async callAsync(callData: Web3.CallData): Promise { - const rawCalllResult = await promisify(this._web3.eth.call)(callData); + public async callAsync(callData: Web3.CallData, defaultBlock?: Web3.BlockParam): Promise { + const rawCalllResult = await promisify(this._web3.eth.call)(callData, defaultBlock); return rawCalllResult; } public async sendTransactionAsync(txData: Web3.TxData): Promise { -- cgit v1.2.3 From 10e2d4b99cc9d06ff9aa22dbff1050edf47a593e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 10:38:12 -0800 Subject: Remove unused param --- packages/0x.js/src/contract_wrappers/generated/base_contract.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts index a465ddc38..9086fe7b3 100644 --- a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts +++ b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts @@ -32,7 +32,7 @@ export class BaseContract { const trailingArrayRegex = /\[\d*\]$/; if (type.match(trailingArrayRegex)) { const arrayItemType = type.replace(trailingArrayRegex, ''); - return _.map(values, (value: any, i: number) => + return _.map(values, value => this._transformTypedData(arrayItemType, value, transformation), ); } else { -- cgit v1.2.3 From 06e28947504e267727abba3215399945ef22d91d Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 10:39:27 -0800 Subject: Improve CHANGELOG entry --- packages/abi-gen/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index f04eb93cf..ce76a37bb 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -2,7 +2,7 @@ ## v0.2.3 - _TBD, 2018_ - * Add a `backend` parameter that allows you to specify your backend (web3 or ethers). Ethers auto-converts small ints to numbers (#413) + * Add a `backend` parameter that allows you to specify the Ethereum library you use in your templates (`web3` or `ethers`). Ethers auto-converts small ints to numbers whereas Web3 doesn't. Defaults to `web3` (#413) * Add support for ABIv2 (#413) * Add `hasReturnValue` to context data (#413) -- cgit v1.2.3 From 0ef372e531c8c86f0ec8b48db6ee4395fdc9e378 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 10:41:32 -0800 Subject: Add link to the docs --- packages/abi-gen/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index ce76a37bb..d9198d3ed 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -3,7 +3,7 @@ ## v0.2.3 - _TBD, 2018_ * Add a `backend` parameter that allows you to specify the Ethereum library you use in your templates (`web3` or `ethers`). Ethers auto-converts small ints to numbers whereas Web3 doesn't. Defaults to `web3` (#413) - * Add support for ABIv2 (#413) + * Add support for [tuple types](https://solidity.readthedocs.io/en/develop/abi-spec.html#handling-tuple-types) (#413) * Add `hasReturnValue` to context data (#413) ## v0.2.1 - _February 9, 2018_ -- cgit v1.2.3 From 4f1e6296ca221c801d476345c491a0372f0af5b3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 10:42:31 -0800 Subject: Fix an option description --- packages/abi-gen/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/abi-gen/src/index.ts b/packages/abi-gen/src/index.ts index 49ff0fe20..7c29f7d1d 100644 --- a/packages/abi-gen/src/index.ts +++ b/packages/abi-gen/src/index.ts @@ -45,7 +45,7 @@ const args = yargs normalize: true, }) .option('backend', { - describe: 'Which backend do you plan to use. Either web3 or ethers', + describe: `The backing Ethereum library your app uses. Either 'web3' or 'ethers'. Ethers auto-converts small ints to numbers whereas Web3 doesn't.`, type: 'string', choices: [ContractsBackend.Web3, ContractsBackend.Ethers], default: DEFAULT_BACKEND, -- cgit v1.2.3 From a0390956a91b2e15052d1b5ca43ef6d85d64234e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 10:43:42 -0800 Subject: Merge ifs --- packages/abi-gen/src/utils.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts index 349604aec..3e4ff619a 100644 --- a/packages/abi-gen/src/utils.ts +++ b/packages/abi-gen/src/utils.ts @@ -36,14 +36,12 @@ export const utils = { tsType: 'number|BigNumber', }); } - if (backend === ContractsBackend.Ethers) { - if (paramKind === ParamKind.Output) { - // ethers-contracts automatically converts small BigNumbers to numbers - solTypeRegexToTsType.unshift({ - regex: '^u?int(8|16|32|48)?$', - tsType: 'number', - }); - } + if (backend === ContractsBackend.Ethers && paramKind === ParamKind.Output) { + // ethers-contracts automatically converts small BigNumbers to numbers + solTypeRegexToTsType.unshift({ + regex: '^u?int(8|16|32|48)?$', + tsType: 'number', + }); } for (const regexAndTxType of solTypeRegexToTsType) { const { regex, tsType } = regexAndTxType; -- cgit v1.2.3 From 8fe844bcc9e4298cc3ced58c1abcee78de4193b3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 12:01:12 -0800 Subject: Move BaseContract to web3Wrapper --- packages/0x.js/package.json | 1 - .../src/contract_wrappers/generated/.gitignore | 7 +- .../contract_wrappers/generated/base_contract.ts | 70 -------- packages/contract_templates/contract.handlebars | 4 +- .../src/contract_wrappers/generated/.gitignore | 9 +- .../contract_wrappers/generated/base_contract.ts | 70 -------- packages/web3-wrapper/package.json | 2 + packages/web3-wrapper/src/base_contract.ts | 69 ++++++++ packages/web3-wrapper/src/index.ts | 181 +-------------------- packages/web3-wrapper/src/web3_wrapper.ts | 179 ++++++++++++++++++++ packages/web3-wrapper/tsconfig.json | 6 +- 11 files changed, 260 insertions(+), 338 deletions(-) delete mode 100644 packages/0x.js/src/contract_wrappers/generated/base_contract.ts delete mode 100644 packages/contracts/src/contract_wrappers/generated/base_contract.ts create mode 100644 packages/web3-wrapper/src/base_contract.ts create mode 100644 packages/web3-wrapper/src/web3_wrapper.ts diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 92710ad2d..f8f4f064c 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -92,7 +92,6 @@ "ethereumjs-abi": "^0.6.4", "ethereumjs-blockstream": "^2.0.6", "ethereumjs-util": "^5.1.1", - "ethers-contracts": "^2.2.1", "js-sha3": "^0.7.0", "lodash": "^4.17.4", "uuid": "^3.1.0", diff --git a/packages/0x.js/src/contract_wrappers/generated/.gitignore b/packages/0x.js/src/contract_wrappers/generated/.gitignore index 834808b48..72e8ffc0d 100644 --- a/packages/0x.js/src/contract_wrappers/generated/.gitignore +++ b/packages/0x.js/src/contract_wrappers/generated/.gitignore @@ -1,6 +1 @@ -dummy_token.ts -ether_token.ts -exchange.ts -token_registry.ts -token_transfer_proxy.ts -token.ts +* diff --git a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts b/packages/0x.js/src/contract_wrappers/generated/base_contract.ts deleted file mode 100644 index 9086fe7b3..000000000 --- a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { TxData, TxDataPayable } from '@0xproject/types'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as ethersContracts from 'ethers-contracts'; -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -export class BaseContract { - protected _ethersInterface: ethersContracts.Interface; - protected _web3Wrapper: Web3Wrapper; - public abi: Web3.ContractAbi; - public address: string; - protected static _transformABIData( - abis: Web3.DataItem[], - values: any[], - transformation: (type: string, value: any) => any, - ): any { - return _.map(values, (value: any, i: number) => - BaseContract._transformTypedData(abis[i].type, value, transformation), - ); - } - protected static _lowercaseAddress(type: string, value: string): string { - return type === 'address' ? value.toLowerCase() : value; - } - protected static _bigNumberToString(type: string, value: string): string { - return _.isObject(value) && (value as any).isBigNumber ? value.toString() : value; - } - private static _transformTypedData( - type: string, - values: any, - transformation: (type: string, value: any) => any, - ): any { - const trailingArrayRegex = /\[\d*\]$/; - if (type.match(trailingArrayRegex)) { - const arrayItemType = type.replace(trailingArrayRegex, ''); - return _.map(values, value => - this._transformTypedData(arrayItemType, value, transformation), - ); - } else { - return transformation(type, values); - } - } - protected async _applyDefaultsToTxDataAsync>( - txData: T, - estimateGasAsync?: (txData: T) => Promise, - ): Promise { - // Gas amount sourced with the following priorities: - // 1. Optional param passed in to public method call - // 2. Global config passed in at library instantiation - // 3. Gas estimate calculation + safety margin - const removeUndefinedProperties = _.pickBy; - const txDataWithDefaults = { - to: this.address, - ...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()), - ...removeUndefinedProperties(txData as any), - // HACK: TS can't prove that T is spreadable. - // Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged - }; - if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) { - const estimatedGas = await estimateGasAsync(txData); - txDataWithDefaults.gas = estimatedGas; - } - return txDataWithDefaults; - } - constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { - this._web3Wrapper = web3Wrapper; - this.abi = abi; - this.address = address; - this._ethersInterface = new ethersContracts.Interface(abi); - } -} diff --git a/packages/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars index f03bdb504..b5c2dd9f2 100644 --- a/packages/contract_templates/contract.handlebars +++ b/packages/contract_templates/contract.handlebars @@ -6,13 +6,11 @@ // tslint:disable-next-line:no-unused-variable import { TxData, TxDataPayable } from '@0xproject/types'; import { BigNumber, classUtils, promisify } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { BaseContract, Web3Wrapper } from '@0xproject/web3-wrapper'; import * as ethersContracts from 'ethers-contracts'; import * as _ from 'lodash'; import * as Web3 from 'web3'; -import {BaseContract} from './base_contract'; - {{#if events}} export type {{contractName}}ContractEventArgs = {{#each events}} diff --git a/packages/contracts/src/contract_wrappers/generated/.gitignore b/packages/contracts/src/contract_wrappers/generated/.gitignore index b976a8737..72e8ffc0d 100644 --- a/packages/contracts/src/contract_wrappers/generated/.gitignore +++ b/packages/contracts/src/contract_wrappers/generated/.gitignore @@ -1,8 +1 @@ -dummy_token.ts -exchange.ts -multi_sig_wallet_with_time_lock_except_remove_authorized_address.ts -multi_sig_wallet_with_time_lock.ts -multi_sig_wallet.ts -token_registry.ts -token_transfer_proxy.ts -zrx_token.ts +* diff --git a/packages/contracts/src/contract_wrappers/generated/base_contract.ts b/packages/contracts/src/contract_wrappers/generated/base_contract.ts deleted file mode 100644 index a465ddc38..000000000 --- a/packages/contracts/src/contract_wrappers/generated/base_contract.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { TxData, TxDataPayable } from '@0xproject/types'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as ethersContracts from 'ethers-contracts'; -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -export class BaseContract { - protected _ethersInterface: ethersContracts.Interface; - protected _web3Wrapper: Web3Wrapper; - public abi: Web3.ContractAbi; - public address: string; - protected static _transformABIData( - abis: Web3.DataItem[], - values: any[], - transformation: (type: string, value: any) => any, - ): any { - return _.map(values, (value: any, i: number) => - BaseContract._transformTypedData(abis[i].type, value, transformation), - ); - } - protected static _lowercaseAddress(type: string, value: string): string { - return type === 'address' ? value.toLowerCase() : value; - } - protected static _bigNumberToString(type: string, value: string): string { - return _.isObject(value) && (value as any).isBigNumber ? value.toString() : value; - } - private static _transformTypedData( - type: string, - values: any, - transformation: (type: string, value: any) => any, - ): any { - const trailingArrayRegex = /\[\d*\]$/; - if (type.match(trailingArrayRegex)) { - const arrayItemType = type.replace(trailingArrayRegex, ''); - return _.map(values, (value: any, i: number) => - this._transformTypedData(arrayItemType, value, transformation), - ); - } else { - return transformation(type, values); - } - } - protected async _applyDefaultsToTxDataAsync>( - txData: T, - estimateGasAsync?: (txData: T) => Promise, - ): Promise { - // Gas amount sourced with the following priorities: - // 1. Optional param passed in to public method call - // 2. Global config passed in at library instantiation - // 3. Gas estimate calculation + safety margin - const removeUndefinedProperties = _.pickBy; - const txDataWithDefaults = { - to: this.address, - ...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()), - ...removeUndefinedProperties(txData as any), - // HACK: TS can't prove that T is spreadable. - // Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged - }; - if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) { - const estimatedGas = await estimateGasAsync(txData); - txDataWithDefaults.gas = estimatedGas; - } - return txDataWithDefaults; - } - constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { - this._web3Wrapper = web3Wrapper; - this.abi = abi; - this.address = address; - this._ethersInterface = new ethersContracts.Interface(abi); - } -} diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index 8f87bb118..e827842b0 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -26,11 +26,13 @@ "shx": "^0.2.2", "tslint": "5.8.0", "typescript": "2.7.1", + "ethers-typescript-typings": "^0.0.1", "web3-typescript-typings": "^0.9.11" }, "dependencies": { "@0xproject/types": "^0.2.3", "@0xproject/utils": "^0.3.4", + "ethers-contracts": "^2.2.1", "lodash": "^4.17.4", "web3": "^0.20.0" } diff --git a/packages/web3-wrapper/src/base_contract.ts b/packages/web3-wrapper/src/base_contract.ts new file mode 100644 index 000000000..997ce97d3 --- /dev/null +++ b/packages/web3-wrapper/src/base_contract.ts @@ -0,0 +1,69 @@ +import { TxData, TxDataPayable } from '@0xproject/types'; +import * as ethersContracts from 'ethers-contracts'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import { Web3Wrapper } from './web3_wrapper'; + +export class BaseContract { + protected _ethersInterface: ethersContracts.Interface; + protected _web3Wrapper: Web3Wrapper; + public abi: Web3.ContractAbi; + public address: string; + protected static _transformABIData( + abis: Web3.DataItem[], + values: any[], + transformation: (type: string, value: any) => any, + ): any { + return _.map(values, (value: any, i: number) => + BaseContract._transformTypedData(abis[i].type, value, transformation), + ); + } + protected static _lowercaseAddress(type: string, value: string): string { + return type === 'address' ? value.toLowerCase() : value; + } + protected static _bigNumberToString(type: string, value: string): string { + return _.isObject(value) && (value as any).isBigNumber ? value.toString() : value; + } + private static _transformTypedData( + type: string, + values: any, + transformation: (type: string, value: any) => any, + ): any { + const trailingArrayRegex = /\[\d*\]$/; + if (type.match(trailingArrayRegex)) { + const arrayItemType = type.replace(trailingArrayRegex, ''); + return _.map(values, value => this._transformTypedData(arrayItemType, value, transformation)); + } else { + return transformation(type, values); + } + } + protected async _applyDefaultsToTxDataAsync>( + txData: T, + estimateGasAsync?: (txData: T) => Promise, + ): Promise { + // Gas amount sourced with the following priorities: + // 1. Optional param passed in to public method call + // 2. Global config passed in at library instantiation + // 3. Gas estimate calculation + safety margin + const removeUndefinedProperties = _.pickBy; + const txDataWithDefaults = { + to: this.address, + ...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()), + ...removeUndefinedProperties(txData as any), + // HACK: TS can't prove that T is spreadable. + // Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged + }; + if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) { + const estimatedGas = await estimateGasAsync(txData); + txDataWithDefaults.gas = estimatedGas; + } + return txDataWithDefaults; + } + constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) { + this._web3Wrapper = web3Wrapper; + this.abi = abi; + this.address = address; + this._ethersInterface = new ethersContracts.Interface(abi); + } +} diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts index a07805344..56dfa227c 100644 --- a/packages/web3-wrapper/src/index.ts +++ b/packages/web3-wrapper/src/index.ts @@ -1,179 +1,2 @@ -import { TransactionReceipt, TxData } from '@0xproject/types'; -import { BigNumber, promisify } from '@0xproject/utils'; -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -interface RawLogEntry { - logIndex: string | null; - transactionIndex: string | null; - transactionHash: string; - blockHash: string | null; - blockNumber: string | null; - address: string; - data: string; - topics: string[]; -} - -export class Web3Wrapper { - private _web3: Web3; - private _defaults: Partial; - private _jsonRpcRequestId: number; - constructor(provider: Web3.Provider, defaults?: Partial) { - if (_.isUndefined((provider as any).sendAsync)) { - // Web3@1.0 provider doesn't support synchronous http requests, - // so it only has an async `send` method, instead of a `send` and `sendAsync` in web3@0.x.x` - // We re-assign the send method so that Web3@1.0 providers work with 0x.js - (provider as any).sendAsync = (provider as any).send; - } - this._web3 = new Web3(); - this._web3.setProvider(provider); - this._defaults = defaults || {}; - this._jsonRpcRequestId = 0; - } - public getContractDefaults(): Partial { - return this._defaults; - } - public setProvider(provider: Web3.Provider) { - this._web3.setProvider(provider); - } - public isAddress(address: string): boolean { - return this._web3.isAddress(address); - } - public async isSenderAddressAvailableAsync(senderAddress: string): Promise { - const addresses = await this.getAvailableAddressesAsync(); - const normalizedAddress = senderAddress.toLowerCase(); - return _.includes(addresses, normalizedAddress); - } - public async getNodeVersionAsync(): Promise { - const nodeVersion = await promisify(this._web3.version.getNode)(); - return nodeVersion; - } - public async getNetworkIdAsync(): Promise { - const networkIdStr = await promisify(this._web3.version.getNetwork)(); - const networkId = _.parseInt(networkIdStr); - return networkId; - } - public async getTransactionReceiptAsync(txHash: string): Promise { - const transactionReceipt = await promisify(this._web3.eth.getTransactionReceipt)(txHash); - if (!_.isNull(transactionReceipt)) { - transactionReceipt.status = this._normalizeTxReceiptStatus(transactionReceipt.status); - } - return transactionReceipt; - } - public getCurrentProvider(): Web3.Provider { - return this._web3.currentProvider; - } - public toWei(ethAmount: BigNumber): BigNumber { - const balanceWei = this._web3.toWei(ethAmount, 'ether'); - return balanceWei; - } - public async getBalanceInWeiAsync(owner: string): Promise { - let balanceInWei = await promisify(this._web3.eth.getBalance)(owner); - // Rewrap in a new BigNumber - balanceInWei = new BigNumber(balanceInWei); - return balanceInWei; - } - public async doesContractExistAtAddressAsync(address: string): Promise { - const code = await promisify(this._web3.eth.getCode)(address); - // Regex matches 0x0, 0x00, 0x in order to accommodate poorly implemented clients - const codeIsEmpty = /^0x0{0,40}$/i.test(code); - return !codeIsEmpty; - } - public async signTransactionAsync(address: string, message: string): Promise { - const signData = await promisify(this._web3.eth.sign)(address, message); - return signData; - } - public async getBlockNumberAsync(): Promise { - const blockNumber = await promisify(this._web3.eth.getBlockNumber)(); - return blockNumber; - } - public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise { - const block = await promisify(this._web3.eth.getBlock)(blockParam); - return block; - } - public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise { - const { timestamp } = await this.getBlockAsync(blockParam); - return timestamp; - } - public async getAvailableAddressesAsync(): Promise { - const addresses = await promisify(this._web3.eth.getAccounts)(); - const normalizedAddresses = _.map(addresses, address => address.toLowerCase()); - return normalizedAddresses; - } - public async getLogsAsync(filter: Web3.FilterObject): Promise { - let fromBlock = filter.fromBlock; - if (_.isNumber(fromBlock)) { - fromBlock = this._web3.toHex(fromBlock); - } - let toBlock = filter.toBlock; - if (_.isNumber(toBlock)) { - toBlock = this._web3.toHex(toBlock); - } - const serializedFilter = { - ...filter, - fromBlock, - toBlock, - }; - const payload = { - jsonrpc: '2.0', - id: this._jsonRpcRequestId++, - method: 'eth_getLogs', - params: [serializedFilter], - }; - const rawLogs = await this._sendRawPayloadAsync(payload); - const formattedLogs = _.map(rawLogs, this._formatLog.bind(this)); - return formattedLogs; - } - public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract { - const web3Contract = this._web3.eth.contract(abi); - return web3Contract; - } - public async estimateGasAsync(txData: Partial): Promise { - const gas = await promisify(this._web3.eth.estimateGas)(txData); - return gas; - } - public async callAsync(callData: Web3.CallData, defaultBlock?: Web3.BlockParam): Promise { - const rawCalllResult = await promisify(this._web3.eth.call)(callData, defaultBlock); - return rawCalllResult; - } - public async sendTransactionAsync(txData: Web3.TxData): Promise { - const txHash = await promisify(this._web3.eth.sendTransaction)(txData); - return txHash; - } - private async _sendRawPayloadAsync(payload: Web3.JSONRPCRequestPayload): Promise { - const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider); - const response = await promisify(sendAsync)(payload); - const result = response.result; - return result; - } - private _normalizeTxReceiptStatus(status: undefined | null | string | 0 | 1): null | 0 | 1 { - // Transaction status might have four values - // undefined - Testrpc and other old clients - // null - New clients on old transactions - // number - Parity - // hex - Geth - if (_.isString(status)) { - return this._web3.toDecimal(status) as 0 | 1; - } else if (_.isUndefined(status)) { - return null; - } else { - return status; - } - } - private _formatLog(rawLog: RawLogEntry): Web3.LogEntry { - const formattedLog = { - ...rawLog, - logIndex: this._hexToDecimal(rawLog.logIndex), - blockNumber: this._hexToDecimal(rawLog.blockNumber), - transactionIndex: this._hexToDecimal(rawLog.transactionIndex), - }; - return formattedLog; - } - private _hexToDecimal(hex: string | null): number | null { - if (_.isNull(hex)) { - return null; - } - const decimal = this._web3.toDecimal(hex); - return decimal; - } -} +export { Web3Wrapper } from './web3_wrapper'; +export { BaseContract } from './base_contract'; diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts new file mode 100644 index 000000000..a07805344 --- /dev/null +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -0,0 +1,179 @@ +import { TransactionReceipt, TxData } from '@0xproject/types'; +import { BigNumber, promisify } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +interface RawLogEntry { + logIndex: string | null; + transactionIndex: string | null; + transactionHash: string; + blockHash: string | null; + blockNumber: string | null; + address: string; + data: string; + topics: string[]; +} + +export class Web3Wrapper { + private _web3: Web3; + private _defaults: Partial; + private _jsonRpcRequestId: number; + constructor(provider: Web3.Provider, defaults?: Partial) { + if (_.isUndefined((provider as any).sendAsync)) { + // Web3@1.0 provider doesn't support synchronous http requests, + // so it only has an async `send` method, instead of a `send` and `sendAsync` in web3@0.x.x` + // We re-assign the send method so that Web3@1.0 providers work with 0x.js + (provider as any).sendAsync = (provider as any).send; + } + this._web3 = new Web3(); + this._web3.setProvider(provider); + this._defaults = defaults || {}; + this._jsonRpcRequestId = 0; + } + public getContractDefaults(): Partial { + return this._defaults; + } + public setProvider(provider: Web3.Provider) { + this._web3.setProvider(provider); + } + public isAddress(address: string): boolean { + return this._web3.isAddress(address); + } + public async isSenderAddressAvailableAsync(senderAddress: string): Promise { + const addresses = await this.getAvailableAddressesAsync(); + const normalizedAddress = senderAddress.toLowerCase(); + return _.includes(addresses, normalizedAddress); + } + public async getNodeVersionAsync(): Promise { + const nodeVersion = await promisify(this._web3.version.getNode)(); + return nodeVersion; + } + public async getNetworkIdAsync(): Promise { + const networkIdStr = await promisify(this._web3.version.getNetwork)(); + const networkId = _.parseInt(networkIdStr); + return networkId; + } + public async getTransactionReceiptAsync(txHash: string): Promise { + const transactionReceipt = await promisify(this._web3.eth.getTransactionReceipt)(txHash); + if (!_.isNull(transactionReceipt)) { + transactionReceipt.status = this._normalizeTxReceiptStatus(transactionReceipt.status); + } + return transactionReceipt; + } + public getCurrentProvider(): Web3.Provider { + return this._web3.currentProvider; + } + public toWei(ethAmount: BigNumber): BigNumber { + const balanceWei = this._web3.toWei(ethAmount, 'ether'); + return balanceWei; + } + public async getBalanceInWeiAsync(owner: string): Promise { + let balanceInWei = await promisify(this._web3.eth.getBalance)(owner); + // Rewrap in a new BigNumber + balanceInWei = new BigNumber(balanceInWei); + return balanceInWei; + } + public async doesContractExistAtAddressAsync(address: string): Promise { + const code = await promisify(this._web3.eth.getCode)(address); + // Regex matches 0x0, 0x00, 0x in order to accommodate poorly implemented clients + const codeIsEmpty = /^0x0{0,40}$/i.test(code); + return !codeIsEmpty; + } + public async signTransactionAsync(address: string, message: string): Promise { + const signData = await promisify(this._web3.eth.sign)(address, message); + return signData; + } + public async getBlockNumberAsync(): Promise { + const blockNumber = await promisify(this._web3.eth.getBlockNumber)(); + return blockNumber; + } + public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise { + const block = await promisify(this._web3.eth.getBlock)(blockParam); + return block; + } + public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise { + const { timestamp } = await this.getBlockAsync(blockParam); + return timestamp; + } + public async getAvailableAddressesAsync(): Promise { + const addresses = await promisify(this._web3.eth.getAccounts)(); + const normalizedAddresses = _.map(addresses, address => address.toLowerCase()); + return normalizedAddresses; + } + public async getLogsAsync(filter: Web3.FilterObject): Promise { + let fromBlock = filter.fromBlock; + if (_.isNumber(fromBlock)) { + fromBlock = this._web3.toHex(fromBlock); + } + let toBlock = filter.toBlock; + if (_.isNumber(toBlock)) { + toBlock = this._web3.toHex(toBlock); + } + const serializedFilter = { + ...filter, + fromBlock, + toBlock, + }; + const payload = { + jsonrpc: '2.0', + id: this._jsonRpcRequestId++, + method: 'eth_getLogs', + params: [serializedFilter], + }; + const rawLogs = await this._sendRawPayloadAsync(payload); + const formattedLogs = _.map(rawLogs, this._formatLog.bind(this)); + return formattedLogs; + } + public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract { + const web3Contract = this._web3.eth.contract(abi); + return web3Contract; + } + public async estimateGasAsync(txData: Partial): Promise { + const gas = await promisify(this._web3.eth.estimateGas)(txData); + return gas; + } + public async callAsync(callData: Web3.CallData, defaultBlock?: Web3.BlockParam): Promise { + const rawCalllResult = await promisify(this._web3.eth.call)(callData, defaultBlock); + return rawCalllResult; + } + public async sendTransactionAsync(txData: Web3.TxData): Promise { + const txHash = await promisify(this._web3.eth.sendTransaction)(txData); + return txHash; + } + private async _sendRawPayloadAsync(payload: Web3.JSONRPCRequestPayload): Promise { + const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider); + const response = await promisify(sendAsync)(payload); + const result = response.result; + return result; + } + private _normalizeTxReceiptStatus(status: undefined | null | string | 0 | 1): null | 0 | 1 { + // Transaction status might have four values + // undefined - Testrpc and other old clients + // null - New clients on old transactions + // number - Parity + // hex - Geth + if (_.isString(status)) { + return this._web3.toDecimal(status) as 0 | 1; + } else if (_.isUndefined(status)) { + return null; + } else { + return status; + } + } + private _formatLog(rawLog: RawLogEntry): Web3.LogEntry { + const formattedLog = { + ...rawLog, + logIndex: this._hexToDecimal(rawLog.logIndex), + blockNumber: this._hexToDecimal(rawLog.blockNumber), + transactionIndex: this._hexToDecimal(rawLog.transactionIndex), + }; + return formattedLog; + } + private _hexToDecimal(hex: string | null): number | null { + if (_.isNull(hex)) { + return null; + } + const decimal = this._web3.toDecimal(hex); + return decimal; + } +} diff --git a/packages/web3-wrapper/tsconfig.json b/packages/web3-wrapper/tsconfig.json index 3d967d05f..7bae7f9f0 100644 --- a/packages/web3-wrapper/tsconfig.json +++ b/packages/web3-wrapper/tsconfig.json @@ -3,5 +3,9 @@ "compilerOptions": { "outDir": "lib" }, - "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"] + "include": [ + "./src/**/*", + "../../node_modules/ethers-typescript-typings/index.d.ts", + "../../node_modules/web3-typescript-typings/index.d.ts" + ] } -- cgit v1.2.3 From c07e3a76bb443641246b05c42f7a05bceb28bc88 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 12:02:11 -0800 Subject: Remove tslint disable --- packages/ethers-typescript-typings/index.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ethers-typescript-typings/index.d.ts b/packages/ethers-typescript-typings/index.d.ts index f4f99b890..e5d38819e 100644 --- a/packages/ethers-typescript-typings/index.d.ts +++ b/packages/ethers-typescript-typings/index.d.ts @@ -19,7 +19,6 @@ declare module 'ethers-contracts' { signature: string; topic: string; } - // tslint:disable-next-line:max-classes-per-file export class Interface { public functions: { [functionName: string]: FunctionDescription }; public events: { [eventName: string]: EventDescription }; -- cgit v1.2.3 From c07d64c6ff3c5d8a127d6bbcbc5e0f0d71070908 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 12:02:40 -0800 Subject: Rename idx to i --- packages/utils/src/abi_decoder.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/abi_decoder.ts b/packages/utils/src/abi_decoder.ts index 024da3741..2b496eb17 100644 --- a/packages/utils/src/abi_decoder.ts +++ b/packages/utils/src/abi_decoder.ts @@ -37,9 +37,9 @@ export class AbiDecoder { const decodedData = ethersInterface.events[event.name].parse(log.data); let failedToDecode = false; - _.forEach(event.inputs, (param: Web3.EventParameter, idx: number) => { + _.forEach(event.inputs, (param: Web3.EventParameter, i: number) => { // Indexed parameters are stored in topics. Non-indexed ones in decodedData - let value: BigNumber | string | number = param.indexed ? log.topics[topicsIndex++] : decodedData[idx]; + let value: BigNumber | string | number = param.indexed ? log.topics[topicsIndex++] : decodedData[i]; if (_.isUndefined(value)) { failedToDecode = true; return; -- cgit v1.2.3 From 425a519f97f5e6bdf0934007faa73b8349e7dd6b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 12:18:52 -0800 Subject: Include types for ethers-contracts --- packages/deployer/package.json | 1 + packages/deployer/tsconfig.json | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/deployer/package.json b/packages/deployer/package.json index f969e4eda..7222966f6 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -36,6 +36,7 @@ "tslint": "5.8.0", "types-bn": "^0.0.1", "typescript": "2.7.1", + "ethers-typescript-typings": "^0.9.11", "web3-typescript-typings": "^0.9.11" }, "dependencies": { diff --git a/packages/deployer/tsconfig.json b/packages/deployer/tsconfig.json index 4e1edb510..897446b66 100644 --- a/packages/deployer/tsconfig.json +++ b/packages/deployer/tsconfig.json @@ -11,6 +11,7 @@ "../../node_modules/types-bn/index.d.ts", "../../node_modules/types-ethereumjs-util/index.d.ts", "../../node_modules/chai-typescript-typings/index.d.ts", + "../../node_modules/ethers-typescript-typings/index.d.ts", "../../node_modules/web3-typescript-typings/index.d.ts" ] } -- cgit v1.2.3 From cdea6184570668592a46e3af7fe9bef1c33a7b79 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 12:20:44 -0800 Subject: Fix the version --- packages/deployer/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/deployer/package.json b/packages/deployer/package.json index 7222966f6..2a6668fa6 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -36,7 +36,7 @@ "tslint": "5.8.0", "types-bn": "^0.0.1", "typescript": "2.7.1", - "ethers-typescript-typings": "^0.9.11", + "ethers-typescript-typings": "^0.0.1", "web3-typescript-typings": "^0.9.11" }, "dependencies": { -- cgit v1.2.3 From 29c5ba56396906472b97f0d09ab5ba1be2799c88 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 12:50:58 -0800 Subject: Include types for ethers-contracts --- packages/dev-utils/tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dev-utils/tsconfig.json b/packages/dev-utils/tsconfig.json index ace978fea..1ed3fbc9c 100644 --- a/packages/dev-utils/tsconfig.json +++ b/packages/dev-utils/tsconfig.json @@ -8,6 +8,7 @@ "./test/**/*", "../../node_modules/types-bn/index.d.ts", "../../node_modules/chai-typescript-typings/index.d.ts", + "../../node_modules/ethers-typescript-typings/index.d.ts", "../../node_modules/web3-typescript-typings/index.d.ts", "../../node_modules/types-ethereumjs-util/index.d.ts" ] -- cgit v1.2.3 From ce0b92d681cfb510ede09296b60260637781f875 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 27 Feb 2018 13:19:17 -0800 Subject: Add ethers-contracts as a dependency --- packages/0x.js/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index f8f4f064c..96ba28b75 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -89,6 +89,7 @@ "@0xproject/web3-wrapper": "^0.1.14", "bintrees": "^1.0.2", "bn.js": "^4.11.8", + "ethers-contracts": "^2.2.1", "ethereumjs-abi": "^0.6.4", "ethereumjs-blockstream": "^2.0.6", "ethereumjs-util": "^5.1.1", -- cgit v1.2.3