aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2018-02-28 06:41:59 +0800
committerGitHub <noreply@github.com>2018-02-28 06:41:59 +0800
commit7aa070f9eaef734274df6e6eaa4590fe30d52899 (patch)
tree454cc4800db190b664d65609c62048a989e2d933 /packages
parentc2ec2291e8243266f52a3b89f38ba67ce1215c22 (diff)
parentce0b92d681cfb510ede09296b60260637781f875 (diff)
downloaddexon-sol-tools-7aa070f9eaef734274df6e6eaa4590fe30d52899.tar.gz
dexon-sol-tools-7aa070f9eaef734274df6e6eaa4590fe30d52899.tar.zst
dexon-sol-tools-7aa070f9eaef734274df6e6eaa4590fe30d52899.zip
Merge pull request #413 from 0xProject/feature/ethers-contracts
abi-gen V2 abi and ethers-contracts
Diffstat (limited to 'packages')
-rw-r--r--packages/0x.js/CHANGELOG.md1
-rw-r--r--packages/0x.js/contract_templates/partials/call.handlebars15
-rw-r--r--packages/0x.js/contract_templates/partials/return_type.handlebars6
-rw-r--r--packages/0x.js/contract_templates/partials/typed_params.handlebars3
-rw-r--r--packages/0x.js/package.json4
-rw-r--r--packages/0x.js/src/contract_wrappers/contract_wrapper.ts8
-rw-r--r--packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts4
-rw-r--r--packages/0x.js/src/contract_wrappers/exchange_wrapper.ts14
-rw-r--r--packages/0x.js/src/contract_wrappers/generated/.gitignore7
-rw-r--r--packages/0x.js/src/contract_wrappers/generated/base_contract.ts33
-rw-r--r--packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts12
-rw-r--r--packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts7
-rw-r--r--packages/0x.js/src/contract_wrappers/token_wrapper.ts9
-rw-r--r--packages/0x.js/src/types.ts2
-rw-r--r--packages/0x.js/test/utils/fill_scenarios.ts6
-rw-r--r--packages/0x.js/tsconfig.json1
-rw-r--r--packages/abi-gen/CHANGELOG.md6
-rw-r--r--packages/abi-gen/src/index.ts14
-rw-r--r--packages/abi-gen/src/types.ts6
-rw-r--r--packages/abi-gen/src/utils.ts46
-rw-r--r--packages/contract_templates/contract.handlebars (renamed from packages/0x.js/contract_templates/contract.handlebars)14
-rw-r--r--packages/contract_templates/partials/call.handlebars3
-rw-r--r--packages/contract_templates/partials/callAsync.handlebars30
-rw-r--r--packages/contract_templates/partials/event.handlebars (renamed from packages/0x.js/contract_templates/partials/event.handlebars)2
-rw-r--r--packages/contract_templates/partials/params.handlebars (renamed from packages/0x.js/contract_templates/partials/params.handlebars)0
-rw-r--r--packages/contract_templates/partials/return_type.handlebars10
-rw-r--r--packages/contract_templates/partials/tx.handlebars (renamed from packages/0x.js/contract_templates/partials/tx.handlebars)37
-rw-r--r--packages/contract_templates/partials/typed_params.handlebars3
-rw-r--r--packages/contracts/contract_templates/contract.handlebars26
-rw-r--r--packages/contracts/contract_templates/partials/call.handlebars10
-rw-r--r--packages/contracts/contract_templates/partials/params.handlebars3
-rw-r--r--packages/contracts/contract_templates/partials/return_type.handlebars10
-rw-r--r--packages/contracts/contract_templates/partials/tx.handlebars36
-rw-r--r--packages/contracts/contract_templates/partials/typed_params.handlebars3
-rw-r--r--packages/contracts/package.json4
-rw-r--r--packages/contracts/src/contract_wrappers/generated/.gitignore9
-rw-r--r--packages/contracts/src/contract_wrappers/generated/base_contract.ts35
-rw-r--r--packages/contracts/test/exchange/core.ts43
-rw-r--r--packages/contracts/test/exchange/helpers.ts13
-rw-r--r--packages/contracts/test/exchange/wrapper.ts27
-rw-r--r--packages/contracts/test/multi_sig_with_time_lock.ts22
-rw-r--r--packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts30
-rw-r--r--packages/contracts/test/token_registry.ts2
-rw-r--r--packages/contracts/test/token_transfer_proxy/auth.ts16
-rw-r--r--packages/contracts/test/token_transfer_proxy/transfer_from.ts8
-rw-r--r--packages/contracts/test/unlimited_allowance_token.ts2
-rw-r--r--packages/contracts/test/zrx_token.ts12
-rw-r--r--packages/contracts/tsconfig.json1
-rw-r--r--packages/contracts/util/balances.ts2
-rw-r--r--packages/contracts/util/exchange_wrapper.ts10
-rw-r--r--packages/contracts/util/token_registry_wrapper.ts12
-rw-r--r--packages/contracts/util/types.ts4
-rw-r--r--packages/deployer/package.json1
-rw-r--r--packages/deployer/src/cli.ts7
-rw-r--r--packages/deployer/src/deployer.ts2
-rw-r--r--packages/deployer/tsconfig.json1
-rw-r--r--packages/dev-utils/tsconfig.json1
-rw-r--r--packages/ethers-typescript-typings/.npmignore3
-rw-r--r--packages/ethers-typescript-typings/CHANGELOG.md5
-rw-r--r--packages/ethers-typescript-typings/README.md49
-rw-r--r--packages/ethers-typescript-typings/index.d.ts28
-rw-r--r--packages/ethers-typescript-typings/package.json28
-rw-r--r--packages/ethers-typescript-typings/scripts/postpublish.js5
-rw-r--r--packages/ethers-typescript-typings/tslint.json3
-rw-r--r--packages/types/CHANGELOG.md5
-rw-r--r--packages/types/src/index.ts3
-rw-r--r--packages/utils/CHANGELOG.md4
-rw-r--r--packages/utils/package.json2
-rw-r--r--packages/utils/src/abi_decoder.ts27
-rw-r--r--packages/utils/src/globals.d.ts3
-rw-r--r--packages/utils/tsconfig.json6
-rw-r--r--packages/web3-wrapper/CHANGELOG.md9
-rw-r--r--packages/web3-wrapper/package.json2
-rw-r--r--packages/web3-wrapper/src/base_contract.ts69
-rw-r--r--packages/web3-wrapper/src/index.ts181
-rw-r--r--packages/web3-wrapper/src/web3_wrapper.ts179
-rw-r--r--packages/web3-wrapper/tsconfig.json6
77 files changed, 729 insertions, 543 deletions
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_
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 0475136f0..000000000
--- a/packages/0x.js/contract_templates/partials/call.handlebars
+++ /dev/null
@@ -1,15 +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 result = await promisify<{{> return_type outputs=outputs}}>(
- self._web3ContractInstance.{{this.name}}.call,
- self._web3ContractInstance,
- )(
- {{> params inputs=inputs}}
- );
- return result;
- },
-};
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 383961a40..000000000
--- a/packages/0x.js/contract_templates/partials/return_type.handlebars
+++ /dev/null
@@ -1,6 +0,0 @@
-{{#singleReturnValue}}
-{{#returnType outputs.0.type}}{{/returnType}}
-{{/singleReturnValue}}
-{{^singleReturnValue}}
-[{{#each outputs}}{{#returnType type}}{{/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
deleted file mode 100644
index 3ea4b2e95..000000000
--- a/packages/0x.js/contract_templates/partials/typed_params.handlebars
+++ /dev/null
@@ -1,3 +0,0 @@
-{{#each inputs}}
- {{name}}: {{#parameterType type}}{{/parameterType}},
-{{/each}}
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 4fb0eb6ac..96ba28b75 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 --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",
@@ -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"
},
@@ -88,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",
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<Web3.ContractInstance> {
+ ): 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..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;
@@ -858,7 +862,7 @@ export class ExchangeWrapper extends ContractWrapper {
});
if (!_.isUndefined(errLog)) {
const logArgs = (errLog as LogWithDecodedArgs<LogErrorContractEventArgs>).args;
- const errCode = logArgs.errorId.toNumber();
+ const errCode = logArgs.errorId;
const errMessage = this._exchangeContractErrCodesToMsg[errCode];
throw new Error(errMessage);
}
@@ -906,11 +910,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/.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 d8fac7eea..000000000
--- a/packages/0x.js/src/contract_wrappers/generated/base_contract.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import {TxData, TxDataPayable} from '@0xproject/types';
-import * as _ from 'lodash';
-import * as Web3 from 'web3';
-
-export class BaseContract {
- protected _web3ContractInstance: Web3.ContractInstance;
- protected _defaults: Partial<TxData>;
- protected async _applyDefaultsToTxDataAsync<T extends TxData|TxDataPayable>(
- txData: T,
- estimateGasAsync?: (txData: T) => Promise<number>,
- ): Promise<TxData> {
- // 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 = {
- ...removeUndefinedProperties(this._defaults),
- ...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(web3ContractInstance: Web3.ContractInstance, defaults: Partial<TxData>) {
- this._web3ContractInstance = web3ContractInstance;
- this._defaults = defaults;
- }
-}
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<string[]> {
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..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
@@ -419,11 +422,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/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/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/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md
index c86d6fb55..d9198d3ed 100644
--- a/packages/abi-gen/CHANGELOG.md
+++ b/packages/abi-gen/CHANGELOG.md
@@ -1,5 +1,11 @@
# CHANGELOG
+## 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 [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_
* 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..7c29f7d1d 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: `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,
+ })
.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);
@@ -129,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 e82ab824b..deddb1857 100644
--- a/packages/abi-gen/src/types.ts
+++ b/packages/abi-gen/src/types.ts
@@ -12,8 +12,14 @@ export enum AbiType {
Fallback = 'fallback',
}
+export enum ContractsBackend {
+ Web3 = 'web3',
+ Ethers = 'ethers',
+}
+
export interface Method extends Web3.MethodAbi {
singleReturnValue: boolean;
+ hasReturnValue: boolean;
}
export interface ContextData {
diff --git a/packages/abi-gen/src/utils.ts b/packages/abi-gen/src/utils.ts
index 14255643a..3e4ff619a 100644
--- a/packages/abi-gen/src/utils.ts
+++ b/packages/abi-gen/src/utils.ts
@@ -3,17 +3,23 @@ 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,
+ components?: Web3.DataItem[],
+ ): string {
const trailingArrayRegex = /\[\d*\]$/;
if (solType.match(trailingArrayRegex)) {
const arrayItemSolType = solType.replace(trailingArrayRegex, '');
- const arrayItemTsType = utils.solTypeToTsType(paramKind, 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 = [
@@ -24,25 +30,49 @@ 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 && 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)) {
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
},
diff --git a/packages/0x.js/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars
index 33699b8a7..b5c2dd9f2 100644
--- a/packages/0x.js/contract_templates/contract.handlebars
+++ b/packages/contract_templates/contract.handlebars
@@ -1,15 +1,16 @@
/**
* 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
import { TxData, TxDataPayable } from '@0xproject/types';
import { BigNumber, classUtils, promisify } from '@0xproject/utils';
+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}}
@@ -28,6 +29,7 @@ export enum {{contractName}}Events {
{{/each}}
{{/if}}
+// tslint:disable:no-parameter-reassignment
export class {{contractName}}Contract extends BaseContract {
{{#each methods}}
{{#this.constant}}
@@ -37,8 +39,8 @@ export class {{contractName}}Contract extends BaseContract {
{{> tx contractName=../contractName}}
{{/this.constant}}
{{/each}}
- constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial<TxData>) {
- 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/contract_templates/partials/call.handlebars b/packages/contract_templates/partials/call.handlebars
new file mode 100644
index 000000000..cfb9bea82
--- /dev/null
+++ b/packages/contract_templates/partials/call.handlebars
@@ -0,0 +1,3 @@
+public {{this.name}} = {
+ {{> callAsync}}
+};
diff --git a/packages/contract_templates/partials/callAsync.handlebars b/packages/contract_templates/partials/callAsync.handlebars
new file mode 100644
index 000000000..93d347145
--- /dev/null
+++ b/packages/contract_templates/partials/callAsync.handlebars
@@ -0,0 +1,30 @@
+{{#hasReturnValue}}
+async callAsync(
+{{> typed_params inputs=inputs}}
+{{#this.payable}}
+ txData: TxDataPayable = {},
+{{/this.payable}}
+{{^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;
+ [{{> 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, 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;
+ resultArray = BaseContract._transformABIData(outputAbi, resultArray, BaseContract._lowercaseAddress.bind(this));
+ return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}};
+},
+{{/hasReturnValue}}
diff --git a/packages/0x.js/contract_templates/partials/event.handlebars b/packages/contract_templates/partials/event.handlebars
index 6d68d4c0f..3c6100e4f 100644
--- a/packages/0x.js/contract_templates/partials/event.handlebars
+++ b/packages/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/params.handlebars b/packages/contract_templates/partials/params.handlebars
index ac5d4ae85..ac5d4ae85 100644
--- a/packages/0x.js/contract_templates/partials/params.handlebars
+++ b/packages/contract_templates/partials/params.handlebars
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/0x.js/contract_templates/partials/tx.handlebars b/packages/contract_templates/partials/tx.handlebars
index 9df83266a..347a482d6 100644
--- a/packages/0x.js/contract_templates/partials/tx.handlebars
+++ b/packages/contract_templates/partials/tx.handlebars
@@ -9,19 +9,22 @@ public {{this.name}} = {
{{/this.payable}}
): Promise<string> {
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,
+ {
+ ...txData,
+ data: encodedData,
+ },
self.{{this.name}}.estimateGasAsync.bind(
self,
{{> params inputs=inputs}}
),
);
- const txHash = await promisify<string>(
- 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<number> {
const self = this as {{contractName}}Contract;
- const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
- txData,
- );
- const gas = await promisify<number>(
- self._web3ContractInstance.{{this.name}}.estimateGas, self._web3ContractInstance,
- )(
+ const encodedData = this._ethersInterface.functions.{{this.name}}(
{{> params inputs=inputs}}
- txDataWithDefaults,
+ ).data
+ const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
+ {
+ ...txData,
+ data: encodedData,
+ }
);
+ const gas = await this._web3Wrapper.estimateGasAsync(txDataWithDefaults);
return gas;
},
getABIEncodedTransactionData(
@@ -45,7 +49,10 @@ 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;
},
+ {{> callAsync}}
};
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 afb9708e9..000000000
--- a/packages/contracts/contract_templates/contract.handlebars
+++ /dev/null
@@ -1,26 +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';
-
-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<TxData>) {
- 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/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<string> {
- 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 3ea4b2e95..000000000
--- a/packages/contracts/contract_templates/partials/typed_params.handlebars
+++ /dev/null
@@ -1,3 +0,0 @@
-{{#each inputs}}
- {{name}}: {{#parameterType type}}{{/parameterType}},
-{{/each}}
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index 0a3a6fc84..8159ba244 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 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"
@@ -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"
},
@@ -72,6 +73,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/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 2d77b3ab1..000000000
--- a/packages/contracts/src/contract_wrappers/generated/base_contract.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import {TxData, TxDataPayable} from '@0xproject/types';
-import * as _ from 'lodash';
-import * as Web3 from 'web3';
-
-export class BaseContract {
- public address: string;
- protected _web3ContractInstance: Web3.ContractInstance;
- protected _defaults: Partial<TxData>;
- protected async _applyDefaultsToTxDataAsync<T extends TxData|TxDataPayable>(
- txData: T,
- estimateGasAsync?: (txData: T) => Promise<number>,
- ): Promise<TxData> {
- // 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 = {
- ...removeUndefinedProperties(this._defaults),
- ...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(web3ContractInstance: Web3.ContractInstance, defaults?: Partial<TxData>) {
- this.address = web3ContractInstance.address;
- this._web3ContractInstance = web3ContractInstance;
- this._defaults = defaults || {};
- }
-}
diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts
index 9cfc68418..303d745aa 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';
@@ -63,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,
@@ -650,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),
@@ -676,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),
@@ -723,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<LogErrorContractEventArgs>;
- const errCode = log.args.errorId.toNumber();
+ const errCode = log.args.errorId;
expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_EXPIRED);
});
@@ -734,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<LogErrorContractEventArgs>;
- const errCode = log.args.errorId.toNumber();
+ const errCode = log.args.errorId;
expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
});
});
@@ -862,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<LogErrorContractEventArgs>;
- const errCode = log.args.errorId.toNumber();
+ const errCode = log.args.errorId;
expect(errCode).to.be.equal(ExchangeContractErrs.ERROR_ORDER_FULLY_FILLED_OR_CANCELLED);
});
@@ -874,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<LogErrorContractEventArgs>;
- 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/test/exchange/helpers.ts b/packages/contracts/test/exchange/helpers.ts
index 5fe00225e..9869c2155 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';
@@ -42,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);
@@ -50,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/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts
index bf5a89222..4ea40cb59 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';
@@ -55,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<SubmissionContractEventArgs>;
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<SubmissionContractEventArgs>;
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<SubmissionContractEventArgs>;
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<SubmissionContractEventArgs>;
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/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/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<string> {
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<boolean> {
- 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<boolean> {
- 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<BigNumber> {
- 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..d78c8a64e 100644
--- a/packages/contracts/util/token_registry_wrapper.ts
+++ b/packages/contracts/util/token_registry_wrapper.ts
@@ -22,36 +22,36 @@ 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],
symbol: data[2],
- decimals: data[3].toNumber(),
+ decimals: data[3],
ipfsHash: data[4],
swarmHash: data[5],
};
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],
symbol: data[2],
- decimals: data[3].toNumber(),
+ decimals: data[3],
ipfsHash: data[4],
swarmHash: data[5],
};
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],
symbol: data[2],
- decimals: data[3].toNumber(),
+ decimals: data[3],
ipfsHash: data[4],
swarmHash: data[5],
};
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;
diff --git a/packages/deployer/package.json b/packages/deployer/package.json
index f969e4eda..2a6668fa6 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.0.1",
"web3-typescript-typings": "^0.9.11"
},
"dependencies": {
diff --git a/packages/deployer/src/cli.ts b/packages/deployer/src/cli.ts
index ba156ac20..c976e8f97 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();
@@ -100,6 +100,9 @@ async function onDeployCommand(argv: CliOptions): Promise<void> {
*/
function getContractsSetFromList(contracts: string): Set<string> {
const specifiedContracts = new Set();
+ if (contracts === '*') {
+ return new Set(['*']);
+ }
const contractsArray = contracts.split(',');
_.forEach(contractsArray, contractName => {
const fileName = `${contractName}${constants.SOLIDITY_FILE_EXTENSION}`;
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;
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"
]
}
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"
]
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..e5d38819e
--- /dev/null
+++ b/packages/ethers-typescript-typings/index.d.ts
@@ -0,0 +1,28 @@
+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;
+ }
+ 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 <logvinov.leon@gmail.com>"
+ ],
+ "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/types/CHANGELOG.md b/packages/types/CHANGELOG.md
index b1cb721d2..a4f293d60 100644
--- a/packages/types/CHANGELOG.md
+++ b/packages/types/CHANGELOG.md
@@ -1,5 +1,10 @@
# CHANGELOG
+## v0.2.4 - _TBD, 2018_
+
+ * Add `data` to `TxData` (#413)
+ * Add `number` as an option to `ContractEventArg` (#413)
+
## 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..6242d4268 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;
@@ -38,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;
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..4f63aa4ce 100644
--- a/packages/utils/package.json
+++ b/packages/utils/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",
"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..2b496eb17 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, i: 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[i];
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
deleted file mode 100644
index ade9e59db..000000000
--- a/packages/utils/src/globals.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-declare module 'web3/lib/solidity/coder' {
- const decodeParams: (types: string[], data: string) => any[];
-}
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"
+ ]
}
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/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<T extends Partial<TxData | TxDataPayable>>(
+ txData: T,
+ estimateGasAsync?: (txData: T) => Promise<number>,
+ ): Promise<TxData> {
+ // 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 7f3452c98..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<TxData>;
- private _jsonRpcRequestId: number;
- constructor(provider: Web3.Provider, defaults?: Partial<TxData>) {
- 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<TxData> {
- 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<boolean> {
- const addresses = await this.getAvailableAddressesAsync();
- const normalizedAddress = senderAddress.toLowerCase();
- return _.includes(addresses, normalizedAddress);
- }
- public async getNodeVersionAsync(): Promise<string> {
- const nodeVersion = await promisify<string>(this._web3.version.getNode)();
- return nodeVersion;
- }
- public async getNetworkIdAsync(): Promise<number> {
- const networkIdStr = await promisify<string>(this._web3.version.getNetwork)();
- const networkId = _.parseInt(networkIdStr);
- return networkId;
- }
- public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
- const transactionReceipt = await promisify<TransactionReceipt>(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<BigNumber> {
- let balanceInWei = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
- // Rewrap in a new BigNumber
- balanceInWei = new BigNumber(balanceInWei);
- return balanceInWei;
- }
- public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
- const code = await promisify<string>(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<string> {
- const signData = await promisify<string>(this._web3.eth.sign)(address, message);
- return signData;
- }
- public async getBlockNumberAsync(): Promise<number> {
- const blockNumber = await promisify<number>(this._web3.eth.getBlockNumber)();
- return blockNumber;
- }
- public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise<Web3.BlockWithoutTransactionData> {
- const block = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam);
- return block;
- }
- public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise<number> {
- const { timestamp } = await this.getBlockAsync(blockParam);
- return timestamp;
- }
- public async getAvailableAddressesAsync(): Promise<string[]> {
- const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
- const normalizedAddresses = _.map(addresses, address => address.toLowerCase());
- return normalizedAddresses;
- }
- public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
- 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<RawLogEntry[]>(payload);
- const formattedLogs = _.map(rawLogs, this._formatLog.bind(this));
- return formattedLogs;
- }
- public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract<any> {
- 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<number> {
- const gas = await promisify<number>(this._web3.eth.estimateGas)({ data });
- return gas;
- }
- public async sendTransactionAsync(txData: Web3.TxData): Promise<string> {
- const txHash = await promisify<string>(this._web3.eth.sendTransaction)(txData);
- return txHash;
- }
- private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> {
- const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
- const response = await promisify<Web3.JSONRPCResponsePayload>(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<TxData>;
+ private _jsonRpcRequestId: number;
+ constructor(provider: Web3.Provider, defaults?: Partial<TxData>) {
+ 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<TxData> {
+ 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<boolean> {
+ const addresses = await this.getAvailableAddressesAsync();
+ const normalizedAddress = senderAddress.toLowerCase();
+ return _.includes(addresses, normalizedAddress);
+ }
+ public async getNodeVersionAsync(): Promise<string> {
+ const nodeVersion = await promisify<string>(this._web3.version.getNode)();
+ return nodeVersion;
+ }
+ public async getNetworkIdAsync(): Promise<number> {
+ const networkIdStr = await promisify<string>(this._web3.version.getNetwork)();
+ const networkId = _.parseInt(networkIdStr);
+ return networkId;
+ }
+ public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
+ const transactionReceipt = await promisify<TransactionReceipt>(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<BigNumber> {
+ let balanceInWei = await promisify<BigNumber>(this._web3.eth.getBalance)(owner);
+ // Rewrap in a new BigNumber
+ balanceInWei = new BigNumber(balanceInWei);
+ return balanceInWei;
+ }
+ public async doesContractExistAtAddressAsync(address: string): Promise<boolean> {
+ const code = await promisify<string>(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<string> {
+ const signData = await promisify<string>(this._web3.eth.sign)(address, message);
+ return signData;
+ }
+ public async getBlockNumberAsync(): Promise<number> {
+ const blockNumber = await promisify<number>(this._web3.eth.getBlockNumber)();
+ return blockNumber;
+ }
+ public async getBlockAsync(blockParam: string | Web3.BlockParam): Promise<Web3.BlockWithoutTransactionData> {
+ const block = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockParam);
+ return block;
+ }
+ public async getBlockTimestampAsync(blockParam: string | Web3.BlockParam): Promise<number> {
+ const { timestamp } = await this.getBlockAsync(blockParam);
+ return timestamp;
+ }
+ public async getAvailableAddressesAsync(): Promise<string[]> {
+ const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
+ const normalizedAddresses = _.map(addresses, address => address.toLowerCase());
+ return normalizedAddresses;
+ }
+ public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
+ 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<RawLogEntry[]>(payload);
+ const formattedLogs = _.map(rawLogs, this._formatLog.bind(this));
+ return formattedLogs;
+ }
+ public getContractFromAbi(abi: Web3.ContractAbi): Web3.Contract<any> {
+ const web3Contract = this._web3.eth.contract(abi);
+ return web3Contract;
+ }
+ public async estimateGasAsync(txData: Partial<Web3.TxData>): Promise<number> {
+ const gas = await promisify<number>(this._web3.eth.estimateGas)(txData);
+ return gas;
+ }
+ public async callAsync(callData: Web3.CallData, defaultBlock?: Web3.BlockParam): Promise<string> {
+ const rawCalllResult = await promisify<string>(this._web3.eth.call)(callData, defaultBlock);
+ return rawCalllResult;
+ }
+ public async sendTransactionAsync(txData: Web3.TxData): Promise<string> {
+ const txHash = await promisify<string>(this._web3.eth.sendTransaction)(txData);
+ return txHash;
+ }
+ private async _sendRawPayloadAsync<A>(payload: Web3.JSONRPCRequestPayload): Promise<A> {
+ const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
+ const response = await promisify<Web3.JSONRPCResponsePayload>(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"
+ ]
}