aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.prettierignore1
-rw-r--r--CONTRIBUTING.md14
-rw-r--r--PULL_REQUEST_TEMPLATE.md18
-rw-r--r--README.md8
-rw-r--r--package.json2
-rw-r--r--packages/0x.js/CHANGELOG.md3
-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.json5
-rw-r--r--packages/0x.js/src/0x.ts10
-rw-r--r--packages/0x.js/src/contract_wrappers/contract_wrapper.ts8
-rw-r--r--packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts35
-rw-r--r--packages/0x.js/src/contract_wrappers/exchange_wrapper.ts59
-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.ts15
-rw-r--r--packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts14
-rw-r--r--packages/0x.js/src/contract_wrappers/token_wrapper.ts125
-rw-r--r--packages/0x.js/src/types.ts2
-rw-r--r--packages/0x.js/test/ether_token_wrapper_test.ts2
-rw-r--r--packages/0x.js/test/exchange_wrapper_test.ts2
-rw-r--r--packages/0x.js/test/subscription_test.ts4
-rw-r--r--packages/0x.js/test/token_wrapper_test.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/assert/CHANGELOG.md1
-rw-r--r--packages/assert/src/index.ts5
-rw-r--r--packages/base-contract/.npmignore5
-rw-r--r--packages/base-contract/CHANGELOG.md5
-rw-r--r--packages/base-contract/README.md53
-rw-r--r--packages/base-contract/package.json39
-rw-r--r--packages/base-contract/src/index.ts68
-rw-r--r--packages/base-contract/tsconfig.json11
-rw-r--r--packages/base-contract/tslint.json3
-rw-r--r--packages/connect/README.md4
-rw-r--r--packages/contract_templates/contract.handlebars (renamed from packages/0x.js/contract_templates/contract.handlebars)15
-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/README.md10
-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.json5
-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/json-schemas/CHANGELOG.md2
-rw-r--r--packages/subproviders/README.md8
-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.md7
-rw-r--r--packages/web3-wrapper/package.json2
-rw-r--r--packages/web3-wrapper/src/index.ts18
-rw-r--r--packages/web3-wrapper/tsconfig.json6
-rw-r--r--packages/website/README.md10
-rw-r--r--packages/website/md/docs/smart_contracts/introduction.md8
-rw-r--r--packages/website/package.json1
-rw-r--r--packages/website/ts/blockchain.ts2
-rw-r--r--packages/website/ts/components/top_bar/top_bar.tsx1
-rw-r--r--packages/website/ts/containers/connect_documentation.tsx21
-rw-r--r--packages/website/ts/containers/smart_contracts_documentation.tsx51
-rw-r--r--packages/website/ts/containers/zero_ex_js_documentation.tsx23
-rw-r--r--packages/website/ts/pages/documentation/doc_page.tsx132
-rw-r--r--packages/website/ts/pages/documentation/docs_info.ts22
-rw-r--r--packages/website/ts/pages/documentation/documentation.tsx146
-rw-r--r--packages/website/ts/pages/documentation/method_block.tsx4
-rw-r--r--packages/website/ts/pages/documentation/source_link.tsx13
-rw-r--r--packages/website/ts/pages/shared/nested_sidebar_menu.tsx10
-rw-r--r--packages/website/ts/pages/shared/version_drop_down.tsx15
-rw-r--r--packages/website/ts/types.ts25
-rw-r--r--packages/website/ts/utils/configs.ts37
-rw-r--r--packages/website/ts/utils/constants.ts1
-rw-r--r--packages/website/ts/utils/doxity_utils.ts16
-rw-r--r--packages/website/ts/utils/typedoc_utils.ts68
-rw-r--r--packages/website/tsconfig.json6
-rw-r--r--yarn.lock27
120 files changed, 1230 insertions, 752 deletions
diff --git a/.prettierignore b/.prettierignore
index c3738481a..385c15654 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,5 +1,4 @@
lib
-generated
.nyc_output
/packages/contracts/src/artifacts
package.json
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e8828ff6b..2bb71e855 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,9 +8,9 @@ If you'd like to contribute to 0x protocol, please fork the repo, fix, commit an
We encourage a “PR early” approach so create the PR as early as possible even without the fix/feature ready, so that devs and other contributors know you have picked up the issue. These early PRs should indicate an 'in progress' status by adding the '[WIP]' prefix to the PR title. Please make sure your contributions adhere to our coding guidelines:
-* Pull requests adding features or refactoring should be opened against the `development` branch
-* Pull requests fixing bugs in the latest release version should be opened again the `master` branch
-* Write [good commit messages](https://chris.beams.io/posts/git-commit/)
+* Pull requests adding features or refactoring should be opened against the `development` branch
+* Pull requests fixing bugs in the latest release version should be opened again the `master` branch
+* Write [good commit messages](https://chris.beams.io/posts/git-commit/)
### Code quality
@@ -31,10 +31,10 @@ We also use [Prettier](https://prettier.io/) to auto-format our code. Be sure to
If using the Atom text editor, we recommend you install the following packages:
-* [atom-typescript](https://atom.io/packages/atom-typescript)
-* [linter-tslint](https://atom.io/packages/linter-tslint)
-* [prettier-atom](https://atom.io/packages/prettier-atom)
-* [language-ethereum](https://atom.io/packages/language-ethereum)
+* [atom-typescript](https://atom.io/packages/atom-typescript)
+* [linter-tslint](https://atom.io/packages/linter-tslint)
+* [prettier-atom](https://atom.io/packages/prettier-atom)
+* [language-ethereum](https://atom.io/packages/language-ethereum)
Our CI will also run TSLint and Prettier as a part of the test run when you submit your PR. Make sure that the CI tests pass for your contribution.
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 96eae1691..481b1d536 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -24,9 +24,9 @@
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
-* [ ] Bug fix (non-breaking change which fixes an issue)
-* [ ] New feature (non-breaking change which adds functionality)
-* [ ] Breaking change (fix or feature that would cause existing functionality to change)
+* [ ] Bug fix (non-breaking change which fixes an issue)
+* [ ] New feature (non-breaking change which adds functionality)
+* [ ] Breaking change (fix or feature that would cause existing functionality to change)
## Checklist:
@@ -34,9 +34,9 @@
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
-* [ ] Change requires a change to the documentation.
-* [ ] Added tests to cover my changes.
-* [ ] Added new entries to the relevant CHANGELOGs.
-* [ ] Updated the new versions of the changed packages in the relevant CHANGELOGs.
-* [ ] Labeled this PR with the 'WIP' label if it is a work in progress.
-* [ ] Labeled this PR with the labels corresponding to the changed package.
+* [ ] Change requires a change to the documentation.
+* [ ] Added tests to cover my changes.
+* [ ] Added new entries to the relevant CHANGELOGs.
+* [ ] Updated the new versions of the changed packages in the relevant CHANGELOGs.
+* [ ] Labeled this PR with the 'WIP' label if it is a work in progress.
+* [ ] Labeled this PR with the labels corresponding to the changed package.
diff --git a/README.md b/README.md
index 775f7cdf3..8ade618b5 100644
--- a/README.md
+++ b/README.md
@@ -48,10 +48,10 @@ This repository contains all the 0x developer tools written in TypeScript. Our h
Dedicated documentation pages:
-* [0x.js Library](https://0xproject.com/docs/0xjs)
-* [0x Connect](https://0xproject.com/docs/connect)
-* [Smart contracts](https://0xproject.com/docs/contracts)
-* [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
+* [0x.js Library](https://0xproject.com/docs/0xjs)
+* [0x Connect](https://0xproject.com/docs/connect)
+* [Smart contracts](https://0xproject.com/docs/contracts)
+* [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
## Contributing
diff --git a/package.json b/package.json
index 9c3825822..e130cbcc8 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
"async-child-process": "^1.1.1",
"ethereumjs-testrpc": "^6.0.3",
"lerna": "^2.5.1",
- "prettier": "1.9.2",
+ "prettier": "^1.11.0",
"publish-release": "0xproject/publish-release",
"semver-sort": "^0.0.4"
}
diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md
index 57cd381ee..b882a1b31 100644
--- a/packages/0x.js/CHANGELOG.md
+++ b/packages/0x.js/CHANGELOG.md
@@ -2,7 +2,10 @@
## v0.33.0 - _TBD, 2018_
+ * 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..20af430d6 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,17 +77,20 @@
"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"
},
"dependencies": {
"@0xproject/assert": "^0.0.20",
+ "@0xproject/base-contract": "^0.0.1",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
"@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/0x.ts b/packages/0x.js/src/0x.ts
index c578478d8..22a5fee10 100644
--- a/packages/0x.js/src/0x.ts
+++ b/packages/0x.js/src/0x.ts
@@ -76,8 +76,9 @@ export class ZeroEx {
assert.isHexString('data', data);
assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
assert.isETHAddressHex('signerAddress', signerAddress);
+ const normalizedSignerAddress = signerAddress.toLowerCase();
- const isValidSignature = signatureUtils.isValidSignature(data, signature, signerAddress);
+ const isValidSignature = signatureUtils.isValidSignature(data, signature, normalizedSignerAddress);
return isValidSignature;
}
/**
@@ -250,6 +251,7 @@ export class ZeroEx {
): Promise<ECSignature> {
assert.isHexString('orderHash', orderHash);
await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
+ const normalizedSignerAddress = signerAddress.toLowerCase();
let msgHashHex = orderHash;
if (shouldAddPersonalMessagePrefix) {
@@ -258,7 +260,7 @@ export class ZeroEx {
msgHashHex = ethUtil.bufferToHex(msgHashBuff);
}
- const signature = await this._web3Wrapper.signTransactionAsync(signerAddress, msgHashHex);
+ const signature = await this._web3Wrapper.signTransactionAsync(normalizedSignerAddress, msgHashHex);
// HACK: There is no consensus on whether the signatureHex string should be formatted as
// v + r + s OR r + s + v, and different clients (even different versions of the same client)
@@ -267,7 +269,7 @@ export class ZeroEx {
const validVParamValues = [27, 28];
const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature);
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
- const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, signerAddress);
+ const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
if (isValidVRSSignature) {
return ecSignatureVRS;
}
@@ -275,7 +277,7 @@ export class ZeroEx {
const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature);
if (_.includes(validVParamValues, ecSignatureRSV.v)) {
- const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, signerAddress);
+ const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
if (isValidRSVSignature) {
return ecSignatureRSV;
}
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 db7cdee43..42f8213a2 100644
--- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts
@@ -41,15 +41,18 @@ export class EtherTokenWrapper extends ContractWrapper {
depositor: string,
txOpts: TransactionOpts = {},
): Promise<string> {
+ assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
+ const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
+ const normalizedDepositorAddress = depositor.toLowerCase();
- const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor);
+ const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(normalizedDepositorAddress);
assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit);
- const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
+ const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
const txHash = await wethContract.deposit.sendTransactionAsync({
- from: depositor,
+ from: normalizedDepositorAddress,
value: amountInWei,
gas: txOpts.gasLimit,
gasPrice: txOpts.gasPrice,
@@ -72,14 +75,20 @@ export class EtherTokenWrapper extends ContractWrapper {
txOpts: TransactionOpts = {},
): Promise<string> {
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
+ assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
+ const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
+ const normalizedWithdrawerAddress = withdrawer.toLowerCase();
- const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer);
+ const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(
+ normalizedEtherTokenAddress,
+ normalizedWithdrawerAddress,
+ );
assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
- const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
+ const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
- from: withdrawer,
+ from: normalizedWithdrawerAddress,
gas: txOpts.gasLimit,
gasPrice: txOpts.gasPrice,
});
@@ -101,11 +110,12 @@ export class EtherTokenWrapper extends ContractWrapper {
indexFilterValues: IndexedFilterValues,
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
+ const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
const logs = await this._getLogsAsync<ArgsType>(
- etherTokenAddress,
+ normalizedEtherTokenAddress,
eventName,
blockRange,
indexFilterValues,
@@ -129,11 +139,12 @@ export class EtherTokenWrapper extends ContractWrapper {
callback: EventCallback<ArgsType>,
): string {
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
+ const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
assert.isFunction('callback', callback);
const subscriptionToken = this._subscribe<ArgsType>(
- etherTokenAddress,
+ normalizedEtherTokenAddress,
eventName,
indexFilterValues,
artifacts.EtherTokenArtifact.abi,
@@ -151,7 +162,7 @@ export class EtherTokenWrapper extends ContractWrapper {
/**
* Cancels all existing subscriptions
*/
- public _unsubscribeAll(): void {
+ public unsubscribeAll(): void {
super._unsubscribeAll();
}
/**
@@ -168,7 +179,7 @@ export class EtherTokenWrapper extends ContractWrapper {
return contractAddressIfExists;
}
private _invalidateContractInstance(): void {
- this._unsubscribeAll();
+ this.unsubscribeAll();
this._etherTokenContractsByAddress = {};
}
private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
@@ -176,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 c82b7ecf5..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;
@@ -180,6 +184,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
const exchangeInstance = await this._getExchangeContractAsync();
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
@@ -192,7 +197,7 @@ export class ExchangeWrapper extends ContractWrapper {
exchangeTradeEmulator,
signedOrder,
fillTakerTokenAmount,
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
}
@@ -208,7 +213,7 @@ export class ExchangeWrapper extends ContractWrapper {
signedOrder.ecSignature.r,
signedOrder.ecSignature.s,
{
- from: takerAddress,
+ from: normalizedTakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -254,6 +259,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
? SHOULD_VALIDATE_BY_DEFAULT
@@ -267,7 +273,7 @@ export class ExchangeWrapper extends ContractWrapper {
exchangeTradeEmulator,
signedOrder,
fillTakerTokenAmount.minus(filledTakerTokenAmount),
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
@@ -301,7 +307,7 @@ export class ExchangeWrapper extends ContractWrapper {
rArray,
sArray,
{
- from: takerAddress,
+ from: normalizedTakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -345,6 +351,7 @@ export class ExchangeWrapper extends ContractWrapper {
);
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
? SHOULD_VALIDATE_BY_DEFAULT
: orderTransactionOpts.shouldValidate;
@@ -356,7 +363,7 @@ export class ExchangeWrapper extends ContractWrapper {
exchangeTradeEmulator,
orderFillRequest.signedOrder,
orderFillRequest.takerTokenFillAmount,
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
}
@@ -389,7 +396,7 @@ export class ExchangeWrapper extends ContractWrapper {
rArray,
sArray,
{
- from: takerAddress,
+ from: normalizedTakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -417,6 +424,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
const exchangeInstance = await this._getExchangeContractAsync();
@@ -430,7 +438,7 @@ export class ExchangeWrapper extends ContractWrapper {
exchangeTradeEmulator,
signedOrder,
fillTakerTokenAmount,
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
}
@@ -444,7 +452,7 @@ export class ExchangeWrapper extends ContractWrapper {
signedOrder.ecSignature.r,
signedOrder.ecSignature.s,
{
- from: takerAddress,
+ from: normalizedTakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -476,6 +484,7 @@ export class ExchangeWrapper extends ContractWrapper {
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
if (_.isEmpty(orderFillRequests)) {
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
}
@@ -492,7 +501,7 @@ export class ExchangeWrapper extends ContractWrapper {
exchangeTradeEmulator,
orderFillRequest.signedOrder,
orderFillRequest.takerTokenFillAmount,
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
}
@@ -520,7 +529,7 @@ export class ExchangeWrapper extends ContractWrapper {
rParams,
sParams,
{
- from: takerAddress,
+ from: normalizedTakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -544,6 +553,7 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('order', order, schemas.orderSchema);
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
+ const normalizedMakerAddress = order.maker.toLowerCase();
const exchangeInstance = await this._getExchangeContractAsync();
@@ -566,7 +576,7 @@ export class ExchangeWrapper extends ContractWrapper {
orderValues,
cancelTakerTokenAmount,
{
- from: order.maker,
+ from: normalizedMakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -603,6 +613,8 @@ export class ExchangeWrapper extends ContractWrapper {
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
const maker = makers[0];
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
+ const normalizedMakerAddress = maker.toLowerCase();
+
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
? SHOULD_VALIDATE_BY_DEFAULT
: orderTransactionOpts.shouldValidate;
@@ -636,7 +648,7 @@ export class ExchangeWrapper extends ContractWrapper {
orderValues,
cancelTakerTokenAmounts,
{
- from: maker,
+ from: normalizedMakerAddress,
gas: orderTransactionOpts.gasLimit,
gasPrice: orderTransactionOpts.gasPrice,
},
@@ -679,7 +691,7 @@ export class ExchangeWrapper extends ContractWrapper {
/**
* Cancels all existing subscriptions
*/
- public _unsubscribeAll(): void {
+ public unsubscribeAll(): void {
super._unsubscribeAll();
}
/**
@@ -757,13 +769,14 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
const zrxTokenAddress = this.getZRXTokenAddress();
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
exchangeTradeEmulator,
signedOrder,
fillTakerTokenAmount,
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
}
@@ -803,13 +816,14 @@ export class ExchangeWrapper extends ContractWrapper {
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
const zrxTokenAddress = this.getZRXTokenAddress();
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
exchangeTradeEmulator,
signedOrder,
fillTakerTokenAmount,
- takerAddress,
+ normalizedTakerAddress,
zrxTokenAddress,
);
}
@@ -848,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);
}
@@ -862,7 +876,7 @@ export class ExchangeWrapper extends ContractWrapper {
return contractAddress;
}
private _invalidateContractInstances(): void {
- this._unsubscribeAll();
+ this.unsubscribeAll();
delete this._exchangeContractIfExists;
}
private async _isValidSignatureUsingContractCallAsync(
@@ -873,11 +887,12 @@ export class ExchangeWrapper extends ContractWrapper {
assert.isHexString('dataHex', dataHex);
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
+ const normalizedSignerAddress = signerAddressHex.toLowerCase();
const exchangeInstance = await this._getExchangeContractAsync();
const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
- signerAddressHex,
+ normalizedSignerAddress,
dataHex,
ecSignature.v,
ecSignature.r,
@@ -895,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 f54aaf0f8..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
@@ -58,9 +59,10 @@ export class TokenRegistryWrapper extends ContractWrapper {
*/
public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> {
assert.isETHAddressHex('address', address);
+ const normalizedAddress = address.toLowerCase();
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
- const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
+ const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress);
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
return token;
}
@@ -115,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 f5d9d108a..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
@@ -2,6 +2,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
import { artifacts } from '../artifacts';
+import { assert } from '../utils/assert';
import { ContractWrapper } from './contract_wrapper';
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
@@ -22,8 +23,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
* @return Whether the exchangeContractAddress is authorized.
*/
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
+ assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress);
+ const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase();
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
- const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(exchangeContractAddress);
+ const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(
+ normalizedExchangeContractAddress,
+ );
return isAuthorized;
}
/**
@@ -54,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 a018006b8..0f688cb71 100644
--- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts
+++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts
@@ -46,10 +46,13 @@ export class TokenWrapper extends ContractWrapper {
): Promise<BigNumber> {
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
- const tokenContract = await this._getTokenContractAsync(tokenAddress);
+ const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
- let balance = await tokenContract.balanceOf.callAsync(ownerAddress, 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;
@@ -72,14 +75,17 @@ export class TokenWrapper extends ContractWrapper {
amountInBaseUnits: BigNumber,
txOpts: TransactionOpts = {},
): Promise<string> {
- await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
assert.isETHAddressHex('spenderAddress', spenderAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedSpenderAddress = spenderAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
- const tokenContract = await this._getTokenContractAsync(tokenAddress);
- const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
- from: ownerAddress,
+ const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
+ const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, {
+ from: normalizedOwnerAddress,
gas: txOpts.gasLimit,
gasPrice: txOpts.gasPrice,
});
@@ -103,10 +109,16 @@ export class TokenWrapper extends ContractWrapper {
spenderAddress: string,
txOpts: TransactionOpts = {},
): Promise<string> {
+ assert.isETHAddressHex('ownerAddress', ownerAddress);
+ assert.isETHAddressHex('tokenAddress', tokenAddress);
+ assert.isETHAddressHex('spenderAddress', spenderAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
+ const normalizedSpenderAddress = spenderAddress.toLowerCase();
const txHash = await this.setAllowanceAsync(
- tokenAddress,
- ownerAddress,
- spenderAddress,
+ normalizedTokenAddress,
+ normalizedOwnerAddress,
+ normalizedSpenderAddress,
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
txOpts,
);
@@ -128,10 +140,20 @@ export class TokenWrapper extends ContractWrapper {
): Promise<BigNumber> {
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ assert.isETHAddressHex('spenderAddress', spenderAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
+ const normalizedSpenderAddress = spenderAddress.toLowerCase();
- const tokenContract = await this._getTokenContractAsync(tokenAddress);
+ const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
- let allowanceInBaseUnits = await tokenContract.allowance.callAsync(ownerAddress, spenderAddress, 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
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
return allowanceInBaseUnits;
@@ -149,9 +171,16 @@ export class TokenWrapper extends ContractWrapper {
): Promise<BigNumber> {
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
- const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts);
+ const allowanceInBaseUnits = await this.getAllowanceAsync(
+ normalizedTokenAddress,
+ normalizedOwnerAddress,
+ proxyAddress,
+ methodOpts,
+ );
return allowanceInBaseUnits;
}
/**
@@ -172,12 +201,14 @@ export class TokenWrapper extends ContractWrapper {
): Promise<string> {
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
const txHash = await this.setAllowanceAsync(
- tokenAddress,
- ownerAddress,
+ normalizedTokenAddress,
+ normalizedOwnerAddress,
proxyAddress,
amountInBaseUnits,
txOpts,
@@ -200,9 +231,13 @@ export class TokenWrapper extends ContractWrapper {
ownerAddress: string,
txOpts: TransactionOpts = {},
): Promise<string> {
+ assert.isETHAddressHex('ownerAddress', ownerAddress);
+ assert.isETHAddressHex('tokenAddress', tokenAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedOwnerAddress = ownerAddress.toLowerCase();
const txHash = await this.setProxyAllowanceAsync(
- tokenAddress,
- ownerAddress,
+ normalizedTokenAddress,
+ normalizedOwnerAddress,
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
txOpts,
);
@@ -225,19 +260,22 @@ export class TokenWrapper extends ContractWrapper {
txOpts: TransactionOpts = {},
): Promise<string> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
- await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
assert.isETHAddressHex('toAddress', toAddress);
+ await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedFromAddress = fromAddress.toLowerCase();
+ const normalizedToAddress = toAddress.toLowerCase();
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
- const tokenContract = await this._getTokenContractAsync(tokenAddress);
+ const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
+ const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress);
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
}
- const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
- from: fromAddress,
+ const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, {
+ from: normalizedFromAddress,
gas: txOpts.gasLimit,
gasPrice: txOpts.gasPrice,
});
@@ -265,30 +303,38 @@ export class TokenWrapper extends ContractWrapper {
amountInBaseUnits: BigNumber,
txOpts: TransactionOpts = {},
): Promise<string> {
- assert.isETHAddressHex('tokenAddress', tokenAddress);
- assert.isETHAddressHex('fromAddress', fromAddress);
assert.isETHAddressHex('toAddress', toAddress);
+ assert.isETHAddressHex('fromAddress', fromAddress);
+ assert.isETHAddressHex('tokenAddress', tokenAddress);
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
+ const normalizedToAddress = toAddress.toLowerCase();
+ const normalizedFromAddress = fromAddress.toLowerCase();
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ const normalizedSenderAddress = senderAddress.toLowerCase();
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
- const tokenContract = await this._getTokenContractAsync(tokenAddress);
+ const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress);
+ const fromAddressAllowance = await this.getAllowanceAsync(
+ normalizedTokenAddress,
+ normalizedFromAddress,
+ normalizedSenderAddress,
+ );
if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
}
- const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
+ const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress);
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
}
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
- fromAddress,
- toAddress,
+ normalizedFromAddress,
+ normalizedToAddress,
amountInBaseUnits,
{
- from: senderAddress,
+ from: normalizedSenderAddress,
gas: txOpts.gasLimit,
gasPrice: txOpts.gasPrice,
},
@@ -311,11 +357,12 @@ export class TokenWrapper extends ContractWrapper {
callback: EventCallback<ArgsType>,
): string {
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
assert.isFunction('callback', callback);
const subscriptionToken = this._subscribe<ArgsType>(
- tokenAddress,
+ normalizedTokenAddress,
eventName,
indexFilterValues,
artifacts.TokenArtifact.abi,
@@ -333,7 +380,7 @@ export class TokenWrapper extends ContractWrapper {
/**
* Cancels all existing subscriptions
*/
- public _unsubscribeAll(): void {
+ public unsubscribeAll(): void {
super._unsubscribeAll();
}
/**
@@ -352,11 +399,12 @@ export class TokenWrapper extends ContractWrapper {
indexFilterValues: IndexedFilterValues,
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
const logs = await this._getLogsAsync<ArgsType>(
- tokenAddress,
+ normalizedTokenAddress,
eventName,
blockRange,
indexFilterValues,
@@ -365,21 +413,22 @@ export class TokenWrapper extends ContractWrapper {
return logs;
}
private _invalidateContractInstances(): void {
- this._unsubscribeAll();
+ this.unsubscribeAll();
this._tokenContractsByAddress = {};
}
private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
- let tokenContract = this._tokenContractsByAddress[tokenAddress];
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
+ let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress];
if (!_.isUndefined(tokenContract)) {
return tokenContract;
}
- const web3ContractInstance = await this._instantiateContractIfExistsAsync(
+ const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
artifacts.TokenArtifact,
- tokenAddress,
+ normalizedTokenAddress,
);
- const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
+ const contractInstance = new TokenContract(this._web3Wrapper, abi, address);
tokenContract = contractInstance;
- this._tokenContractsByAddress[tokenAddress] = tokenContract;
+ 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/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts
index 72086dff0..68f2c6f66 100644
--- a/packages/0x.js/test/ether_token_wrapper_test.ts
+++ b/packages/0x.js/test/ether_token_wrapper_test.ts
@@ -158,7 +158,7 @@ describe('EtherTokenWrapper', () => {
etherTokenAddress = etherToken.address;
});
afterEach(() => {
- zeroEx.etherToken._unsubscribeAll();
+ zeroEx.etherToken.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts
index 325426438..688be628f 100644
--- a/packages/0x.js/test/exchange_wrapper_test.ts
+++ b/packages/0x.js/test/exchange_wrapper_test.ts
@@ -922,7 +922,7 @@ describe('ExchangeWrapper', () => {
);
});
afterEach(async () => {
- zeroEx.exchange._unsubscribeAll();
+ zeroEx.exchange.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
diff --git a/packages/0x.js/test/subscription_test.ts b/packages/0x.js/test/subscription_test.ts
index 337e2effa..f485bf84b 100644
--- a/packages/0x.js/test/subscription_test.ts
+++ b/packages/0x.js/test/subscription_test.ts
@@ -49,7 +49,7 @@ describe('SubscriptionTest', () => {
tokenAddress = token.address;
});
afterEach(() => {
- zeroEx.token._unsubscribeAll();
+ zeroEx.token.unsubscribeAll();
_.each(stubs, s => s.restore());
stubs = [];
});
@@ -76,7 +76,7 @@ describe('SubscriptionTest', () => {
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
- zeroEx.token._unsubscribeAll();
+ zeroEx.token.unsubscribeAll();
done();
})().catch(done);
});
diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts
index 34ebe30c2..070d6ec47 100644
--- a/packages/0x.js/test/token_wrapper_test.ts
+++ b/packages/0x.js/test/token_wrapper_test.ts
@@ -377,7 +377,7 @@ describe('TokenWrapper', () => {
tokenAddress = token.address;
});
afterEach(() => {
- zeroEx.token._unsubscribeAll();
+ zeroEx.token.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
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/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md
index f512f7b10..6721c4cb6 100644
--- a/packages/assert/CHANGELOG.md
+++ b/packages/assert/CHANGELOG.md
@@ -2,6 +2,7 @@
## v0.1.0 - _TBD, 2018_
+ * Remove isETHAddressHex checksum address check and assume address will be lowercased (#373)
* Add an optional parameter `subSchemas` to `doesConformToSchema` method (#385)
## v0.0.18 - _February 9, 2017_
diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts
index 4d090e493..40d083cb6 100644
--- a/packages/assert/src/index.ts
+++ b/packages/assert/src/index.ts
@@ -33,11 +33,8 @@ export const assert = {
);
},
isETHAddressHex(variableName: string, value: string): void {
+ this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
- this.assert(
- addressUtils.isAddress(value) && value.toLowerCase() === value,
- `Checksummed addresses are not supported. Convert ${variableName} to lower case before passing`,
- );
},
doesBelongToStringEnum(
variableName: string,
diff --git a/packages/base-contract/.npmignore b/packages/base-contract/.npmignore
new file mode 100644
index 000000000..ad5ffcd56
--- /dev/null
+++ b/packages/base-contract/.npmignore
@@ -0,0 +1,5 @@
+.*
+yarn-error.log
+/scripts/
+/src/
+tsconfig.json
diff --git a/packages/base-contract/CHANGELOG.md b/packages/base-contract/CHANGELOG.md
new file mode 100644
index 000000000..74e983f1c
--- /dev/null
+++ b/packages/base-contract/CHANGELOG.md
@@ -0,0 +1,5 @@
+# CHANGELOG
+
+## v0.0.1 - _TBD, 2018_
+
+ * Initial release (#TBD)
diff --git a/packages/base-contract/README.md b/packages/base-contract/README.md
new file mode 100644
index 000000000..ff0d4d303
--- /dev/null
+++ b/packages/base-contract/README.md
@@ -0,0 +1,53 @@
+## @0xproject/base-contract
+
+BaseContract to derive all auto-generated wrappers from
+
+## Installation
+
+```bash
+yarn add @0xproject/base-contract
+```
+
+## Usage
+
+```javascript
+import { BaseContract } from '@0xproject/base-contract';
+```
+
+## Contributing
+
+We strongly recommend 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
+```
+
+### Build
+
+```bash
+yarn build
+```
+
+or
+
+```bash
+yarn build:watch
+```
+
+### Lint
+
+```bash
+yarn lint
+```
diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json
new file mode 100644
index 000000000..6edbed161
--- /dev/null
+++ b/packages/base-contract/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "@0xproject/base-contract",
+ "version": "0.0.1",
+ "description": "0x Base TS contract",
+ "main": "lib/index.js",
+ "types": "lib/index.d.ts",
+ "scripts": {
+ "build:watch": "tsc -w",
+ "build": "tsc",
+ "clean": "shx rm -rf lib",
+ "lint": "tslint --project . 'src/**/*.ts'"
+ },
+ "license": "Apache-2.0",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/0xProject/0x.js.git"
+ },
+ "bugs": {
+ "url": "https://github.com/0xProject/0x.js/issues"
+ },
+ "homepage": "https://github.com/0xProject/0x.js/packages/base-contract/README.md",
+ "devDependencies": {
+ "@0xproject/tslint-config": "^0.4.9",
+ "@types/lodash": "^4.14.86",
+ "npm-run-all": "^4.1.2",
+ "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/web3-wrapper": "^0.1.14",
+ "ethers-contracts": "^2.2.1",
+ "lodash": "^4.17.4",
+ "web3": "^0.20.0"
+ }
+}
diff --git a/packages/base-contract/src/index.ts b/packages/base-contract/src/index.ts
new file mode 100644
index 000000000..cc1e16a13
--- /dev/null
+++ b/packages/base-contract/src/index.ts
@@ -0,0 +1,68 @@
+import { TxData, TxDataPayable } from '@0xproject/types';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as ethersContracts from 'ethers-contracts';
+import * as _ from 'lodash';
+import * as Web3 from 'web3';
+
+export class BaseContract {
+ protected _ethersInterface: ethersContracts.Interface;
+ protected _web3Wrapper: Web3Wrapper;
+ public abi: Web3.ContractAbi;
+ public address: string;
+ protected static _transformABIData(
+ abis: Web3.DataItem[],
+ values: any[],
+ transformation: (type: string, value: any) => any,
+ ): any {
+ return _.map(values, (value: any, i: number) =>
+ BaseContract._transformTypedData(abis[i].type, value, transformation),
+ );
+ }
+ protected static _lowercaseAddress(type: string, value: string): string {
+ return type === 'address' ? value.toLowerCase() : value;
+ }
+ protected static _bigNumberToString(type: string, value: string): string {
+ return _.isObject(value) && (value as any).isBigNumber ? value.toString() : value;
+ }
+ private static _transformTypedData(
+ type: string,
+ values: any,
+ transformation: (type: string, value: any) => any,
+ ): any {
+ const trailingArrayRegex = /\[\d*\]$/;
+ if (type.match(trailingArrayRegex)) {
+ const arrayItemType = type.replace(trailingArrayRegex, '');
+ return _.map(values, value => this._transformTypedData(arrayItemType, value, transformation));
+ } else {
+ return transformation(type, values);
+ }
+ }
+ protected async _applyDefaultsToTxDataAsync<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/base-contract/tsconfig.json b/packages/base-contract/tsconfig.json
new file mode 100644
index 000000000..8114d99cd
--- /dev/null
+++ b/packages/base-contract/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "outDir": "lib"
+ },
+ "include": [
+ "./src/**/*",
+ "../../node_modules/web3-typescript-typings/index.d.ts",
+ "../../node_modules/ethers-typescript-typings/index.d.ts"
+ ]
+}
diff --git a/packages/base-contract/tslint.json b/packages/base-contract/tslint.json
new file mode 100644
index 000000000..ffaefe83a
--- /dev/null
+++ b/packages/base-contract/tslint.json
@@ -0,0 +1,3 @@
+{
+ "extends": ["@0xproject/tslint-config"]
+}
diff --git a/packages/connect/README.md b/packages/connect/README.md
index 63faf5271..7302322e6 100644
--- a/packages/connect/README.md
+++ b/packages/connect/README.md
@@ -10,8 +10,8 @@ yarn add @0xproject/connect
## Usage
-* [Docs](https://0xproject.com/docs/connect)
-* [Tutorials](https://0xproject.com/wiki#connect)
+* [Docs](https://0xproject.com/docs/connect)
+* [Tutorials](https://0xproject.com/wiki#connect)
## Contributing
diff --git a/packages/0x.js/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars
index 33699b8a7..2e8ac3f06 100644
--- a/packages/0x.js/contract_templates/contract.handlebars
+++ b/packages/contract_templates/contract.handlebars
@@ -1,15 +1,17 @@
/**
* 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 { BaseContract } from '@0xproject/base-contract';
import { TxData, TxDataPayable } from '@0xproject/types';
import { BigNumber, classUtils, promisify } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as ethersContracts from 'ethers-contracts';
+import * as _ from 'lodash';
import * as Web3 from 'web3';
-import {BaseContract} from './base_contract';
-
{{#if events}}
export type {{contractName}}ContractEventArgs =
{{#each events}}
@@ -28,6 +30,7 @@ export enum {{contractName}}Events {
{{/each}}
{{/if}}
+// tslint:disable:no-parameter-reassignment
export class {{contractName}}Contract extends BaseContract {
{{#each methods}}
{{#this.constant}}
@@ -37,8 +40,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/README.md b/packages/contracts/README.md
index 11b9e5056..c209edf02 100644
--- a/packages/contracts/README.md
+++ b/packages/contracts/README.md
@@ -4,11 +4,11 @@ Smart contracts that implement the 0x protocol.
## Usage
-* [Docs](https://0xproject.com/docs/contracts)
-* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
-* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
-* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
-* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
+* [Docs](https://0xproject.com/docs/contracts)
+* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
+* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
+* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
+* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
## Contributing
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..7cac30069 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,11 +58,13 @@
"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"
},
"dependencies": {
"0x.js": "^0.32.4",
+ "@0xproject/web3-wrapper": "^0.1.14",
"@0xproject/deployer": "^0.1.0",
"@0xproject/json-schemas": "^0.7.12",
"@0xproject/types": "^0.2.3",
@@ -72,6 +74,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/json-schemas/CHANGELOG.md b/packages/json-schemas/CHANGELOG.md
index 9a9fc12de..7fdae6cf3 100644
--- a/packages/json-schemas/CHANGELOG.md
+++ b/packages/json-schemas/CHANGELOG.md
@@ -2,7 +2,7 @@
## v0.7.10 - _February 9, 2018_
-* Fix publishing issue where .npmignore was not properly excluding undesired content (#389)
+* Fix publishing issue where .npmignore was not properly excluding undesired content (#389)
## v0.7.0 - _December 20, 2017_
diff --git a/packages/subproviders/README.md b/packages/subproviders/README.md
index 954729713..39e4a46e7 100644
--- a/packages/subproviders/README.md
+++ b/packages/subproviders/README.md
@@ -96,10 +96,10 @@ yarn run test:unit
In order to run the integration tests, make sure you have a Ledger Nano S available.
-* Plug it into your computer
-* Unlock the device
-* Open the on-device Ethereum app
-* Make sure "browser support" is disabled
+* Plug it into your computer
+* Unlock the device
+* Open the on-device Ethereum app
+* Make sure "browser support" is disabled
Then run:
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 eb31f7e3c..eef665d24 100644
--- a/packages/web3-wrapper/CHANGELOG.md
+++ b/packages/web3-wrapper/CHANGELOG.md
@@ -1,5 +1,12 @@
# CHANGELOG
+## v0.2.0 _TBD, 2018_
+
+ * 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_
* 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..55f1ffff0 100644
--- a/packages/web3-wrapper/package.json
+++ b/packages/web3-wrapper/package.json
@@ -31,6 +31,8 @@
"dependencies": {
"@0xproject/types": "^0.2.3",
"@0xproject/utils": "^0.3.4",
+ "ethers-contracts": "^2.2.1",
+ "ethers-typescript-typings": "^0.0.1",
"lodash": "^4.17.4",
"web3": "^0.20.0"
}
diff --git a/packages/web3-wrapper/src/index.ts b/packages/web3-wrapper/src/index.ts
index a2878fc2a..a07805344 100644
--- a/packages/web3-wrapper/src/index.ts
+++ b/packages/web3-wrapper/src/index.ts
@@ -41,7 +41,8 @@ export class Web3Wrapper {
}
public async isSenderAddressAvailableAsync(senderAddress: string): Promise<boolean> {
const addresses = await this.getAvailableAddressesAsync();
- return _.includes(addresses, senderAddress);
+ const normalizedAddress = senderAddress.toLowerCase();
+ return _.includes(addresses, normalizedAddress);
}
public async getNodeVersionAsync(): Promise<string> {
const nodeVersion = await promisify<string>(this._web3.version.getNode)();
@@ -96,7 +97,8 @@ export class Web3Wrapper {
}
public async getAvailableAddressesAsync(): Promise<string[]> {
const addresses = await promisify<string[]>(this._web3.eth.getAccounts)();
- return addresses;
+ const normalizedAddresses = _.map(addresses, address => address.toLowerCase());
+ return normalizedAddresses;
}
public async getLogsAsync(filter: Web3.FilterObject): Promise<Web3.LogEntry[]> {
let fromBlock = filter.fromBlock;
@@ -126,14 +128,14 @@ export class Web3Wrapper {
const web3Contract = this._web3.eth.contract(abi);
return web3Contract;
}
- public getContractInstance(abi: Web3.ContractAbi, address: string): Web3.ContractInstance {
- const web3ContractInstance = this.getContractFromAbi(abi).at(address);
- return web3ContractInstance;
- }
- public async estimateGasAsync(data: string): Promise<number> {
- const gas = await promisify<number>(this._web3.eth.estimateGas)({ data });
+ 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;
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"
+ ]
}
diff --git a/packages/website/README.md b/packages/website/README.md
index 7d3187781..042df52de 100644
--- a/packages/website/README.md
+++ b/packages/website/README.md
@@ -58,11 +58,11 @@ yarn lint
##### Toolkit
-* [Material Design Icon Font](http://zavoloklom.github.io/material-design-iconic-font/icons.html#directional)
-* [BassCSS toolkit](http://basscss.com/)
-* [Material-UI component library](http://www.material-ui.com/#/)
+* [Material Design Icon Font](http://zavoloklom.github.io/material-design-iconic-font/icons.html#directional)
+* [BassCSS toolkit](http://basscss.com/)
+* [Material-UI component library](http://www.material-ui.com/#/)
##### Recommended Atom packages:
-* [atom-typescript](https://atom.io/packages/atom-typescript)
-* [linter-tslint](https://atom.io/packages/linter-tslint)
+* [atom-typescript](https://atom.io/packages/atom-typescript)
+* [linter-tslint](https://atom.io/packages/linter-tslint)
diff --git a/packages/website/md/docs/smart_contracts/introduction.md b/packages/website/md/docs/smart_contracts/introduction.md
index 20396289b..566a573b6 100644
--- a/packages/website/md/docs/smart_contracts/introduction.md
+++ b/packages/website/md/docs/smart_contracts/introduction.md
@@ -2,7 +2,7 @@ Welcome to the [0x smart contracts](https://github.com/0xProject/contracts) docu
### Helpful wiki articles:
-* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
-* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
-* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
-* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
+* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
+* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
+* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
+* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
diff --git a/packages/website/package.json b/packages/website/package.json
index 1d313390a..ceb3853f9 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -87,6 +87,7 @@
"copy-webpack-plugin": "^4.0.1",
"copyfiles": "^1.2.0",
"css-loader": "0.23.x",
+ "ethers-typescript-typings": "^0.0.1",
"exports-loader": "0.6.x",
"imports-loader": "0.6.x",
"json-loader": "^0.5.4",
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index db3872a32..85b4e892f 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -672,7 +672,7 @@ export class Blockchain {
}
}
private _stopWatchingExchangeLogFillEvents(): void {
- this._zeroEx.exchange._unsubscribeAll();
+ this._zeroEx.exchange.unsubscribeAll();
}
private async _getTokenRegistryTokensByAddressAsync(): Promise<TokenByAddress> {
utils.assert(!_.isUndefined(this._zeroEx), 'ZeroEx must be instantiated.');
diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx
index 2723c2218..b2b2d2ebd 100644
--- a/packages/website/ts/components/top_bar/top_bar.tsx
+++ b/packages/website/ts/components/top_bar/top_bar.tsx
@@ -319,7 +319,6 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
shouldDisplaySectionHeaders={false}
onMenuItemClick={this._onMenuButtonClick.bind(this)}
selectedVersion={this.props.docsVersion}
- docPath={this.props.docsInfo.websitePath}
versions={this.props.availableDocVersions}
/>
</div>
diff --git a/packages/website/ts/containers/connect_documentation.tsx b/packages/website/ts/containers/connect_documentation.tsx
index 5c5d26b44..464bdcd74 100644
--- a/packages/website/ts/containers/connect_documentation.tsx
+++ b/packages/website/ts/containers/connect_documentation.tsx
@@ -2,15 +2,14 @@ import * as _ from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
+import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
-import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
-import { DocsInfoConfig, Environments, WebsitePaths } from 'ts/types';
+import { DocPackages, DocsInfoConfig, Environments, SupportedDocJson, WebsitePaths } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';
-import { typeDocUtils } from 'ts/utils/typedoc_utils';
/* tslint:disable:no-var-requires */
const IntroMarkdown = require('md/docs/connect/introduction');
@@ -25,16 +24,11 @@ const connectDocSections = {
types: constants.TYPES_SECTION_NAME,
};
-const s3BucketName =
- configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-connect-docs-jsons' : 'connect-docs-jsons';
-const docsJsonRoot = `https://s3.amazonaws.com/${s3BucketName}`;
-
const docsInfoConfig: DocsInfoConfig = {
+ id: DocPackages.Connect,
+ type: SupportedDocJson.TypeDoc,
displayName: '0x Connect',
- subPackageName: 'connect',
packageUrl: 'https://github.com/0xProject/0x.js',
- websitePath: WebsitePaths.Connect,
- docsJsonRoot,
menu: {
introduction: [connectDocSections.introduction],
install: [connectDocSections.installation],
@@ -77,7 +71,6 @@ const docsInfoConfig: DocsInfoConfig = {
menuSubsectionToVersionWhenIntroduced: {},
sections: connectDocSections,
visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel],
- convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
};
const docsInfo = new DocsInfo(docsInfoConfig);
@@ -92,7 +85,7 @@ interface ConnectedDispatch {
dispatcher: Dispatcher;
}
-const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
+const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
docsVersion: state.docsVersion,
availableDocVersions: state.availableDocVersions,
translate: state.translate,
@@ -103,6 +96,6 @@ const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
dispatcher: new Dispatcher(dispatch),
});
-export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
- DocumentationComponent,
+export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
+ DocPageComponent,
);
diff --git a/packages/website/ts/containers/smart_contracts_documentation.tsx b/packages/website/ts/containers/smart_contracts_documentation.tsx
index c4731f929..a839529aa 100644
--- a/packages/website/ts/containers/smart_contracts_documentation.tsx
+++ b/packages/website/ts/containers/smart_contracts_documentation.tsx
@@ -2,12 +2,18 @@ import * as _ from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
+import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
-import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
-import { DocsInfoConfig, SmartContractDocSections as Sections, WebsitePaths } from 'ts/types';
-import { doxityUtils } from 'ts/utils/doxity_utils';
+import {
+ DocPackages,
+ DocsInfoConfig,
+ Networks,
+ SmartContractDocSections as Sections,
+ SupportedDocJson,
+ WebsitePaths,
+} from 'ts/types';
import { Translate } from 'ts/utils/translate';
/* tslint:disable:no-var-requires */
@@ -15,10 +21,10 @@ const IntroMarkdown = require('md/docs/smart_contracts/introduction');
/* tslint:enable:no-var-requires */
const docsInfoConfig: DocsInfoConfig = {
+ id: DocPackages.SmartContracts,
+ type: SupportedDocJson.Doxity,
displayName: '0x Smart Contracts',
packageUrl: 'https://github.com/0xProject/contracts',
- websitePath: WebsitePaths.SmartContracts,
- docsJsonRoot: 'https://s3.amazonaws.com/smart-contracts-docs-json',
menu: {
introduction: [Sections.Introduction],
contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
@@ -34,7 +40,34 @@ const docsInfoConfig: DocsInfoConfig = {
ZRXToken: Sections.ZRXToken,
},
visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
- convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils),
+ contractsByVersionByNetworkId: {
+ '1.0.0': {
+ [Networks.Mainnet]: {
+ [Sections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
+ [Sections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
+ [Sections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
+ [Sections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
+ },
+ [Networks.Ropsten]: {
+ [Sections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
+ [Sections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
+ [Sections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
+ [Sections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
+ },
+ [Networks.Kovan]: {
+ [Sections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
+ [Sections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
+ [Sections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
+ [Sections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
+ },
+ [Networks.Rinkeby]: {
+ [Sections.Exchange]: '0x1d16ef40fac01cec8adac2ac49427b9384192c05',
+ [Sections.TokenTransferProxy]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
+ [Sections.ZRXToken]: '0x00f58d6d585f84b2d7267940cede30ce2fe6eae8',
+ [Sections.TokenRegistry]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
+ },
+ },
+ },
};
const docsInfo = new DocsInfo(docsInfoConfig);
@@ -49,7 +82,7 @@ interface ConnectedDispatch {
docsInfo: DocsInfo;
}
-const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
+const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
docsVersion: state.docsVersion,
availableDocVersions: state.availableDocVersions,
translate: state.translate,
@@ -60,6 +93,6 @@ const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
docsInfo,
});
-export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
- DocumentationComponent,
+export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
+ DocPageComponent,
);
diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.tsx
index a32a87f7f..500bf8d96 100644
--- a/packages/website/ts/containers/zero_ex_js_documentation.tsx
+++ b/packages/website/ts/containers/zero_ex_js_documentation.tsx
@@ -2,15 +2,14 @@ import * as _ from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
+import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
-import { Documentation as DocumentationComponent, DocumentationAllProps } from 'ts/pages/documentation/documentation';
import { Dispatcher } from 'ts/redux/dispatcher';
import { State } from 'ts/redux/reducer';
-import { DocsInfoConfig, Environments, WebsitePaths } from 'ts/types';
+import { DocPackages, DocsInfoConfig, Environments, SupportedDocJson, WebsitePaths } from 'ts/types';
import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';
-import { typeDocUtils } from 'ts/utils/typedoc_utils';
/* tslint:disable:no-var-requires */
const IntroMarkdown = require('md/docs/0xjs/introduction');
@@ -37,15 +36,11 @@ const zeroExJsDocSections = {
types: constants.TYPES_SECTION_NAME,
};
-const s3BucketName = configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-0xjs-docs-jsons' : '0xjs-docs-jsons';
-const docsJsonRoot = `https://s3.amazonaws.com/${s3BucketName}`;
-
const docsInfoConfig: DocsInfoConfig = {
+ id: DocPackages.ZeroExJs,
+ type: SupportedDocJson.TypeDoc,
displayName: '0x.js',
packageUrl: 'https://github.com/0xProject/0x.js',
- subPackageName: '0x.js',
- websitePath: WebsitePaths.ZeroExJs,
- docsJsonRoot,
menu: {
introduction: [zeroExJsDocSections.introduction],
install: [zeroExJsDocSections.installation],
@@ -69,7 +64,8 @@ const docsInfoConfig: DocsInfoConfig = {
[zeroExJsDocSections.versioning]: versioningMarkdown,
},
// Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is
- // currently no way to extract the re-exported types from index.ts via TypeDoc :(
+ // currently no way to extract the re-exported types from index.ts via TypeDoc :( Make sure to only
+ // ADD types here, DO NOT REMOVE types since they might still be needed for older supported versions
publicTypes: [
'Order',
'SignedOrder',
@@ -147,7 +143,6 @@ const docsInfoConfig: DocsInfoConfig = {
},
sections: zeroExJsDocSections,
visibleConstructors: [zeroExJsDocSections.zeroEx],
- convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils),
};
const docsInfo = new DocsInfo(docsInfoConfig);
@@ -162,7 +157,7 @@ interface ConnectedDispatch {
dispatcher: Dispatcher;
}
-const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({
+const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({
docsVersion: state.docsVersion,
availableDocVersions: state.availableDocVersions,
docsInfo,
@@ -173,6 +168,6 @@ const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
dispatcher: new Dispatcher(dispatch),
});
-export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)(
- DocumentationComponent,
+export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)(
+ DocPageComponent,
);
diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx
new file mode 100644
index 000000000..2c8f1c103
--- /dev/null
+++ b/packages/website/ts/pages/documentation/doc_page.tsx
@@ -0,0 +1,132 @@
+import findVersions = require('find-versions');
+import * as _ from 'lodash';
+import * as React from 'react';
+import DocumentTitle = require('react-document-title');
+import semverSort = require('semver-sort');
+import { TopBar } from 'ts/components/top_bar/top_bar';
+import { DocsInfo } from 'ts/pages/documentation/docs_info';
+import { Documentation } from 'ts/pages/documentation/documentation';
+import { Dispatcher } from 'ts/redux/dispatcher';
+import { DocAgnosticFormat, DocPackages, DoxityDocObj, Environments, MenuSubsectionsBySection } from 'ts/types';
+import { configs } from 'ts/utils/configs';
+import { constants } from 'ts/utils/constants';
+import { docUtils } from 'ts/utils/doc_utils';
+import { Translate } from 'ts/utils/translate';
+
+const docIdToS3BucketName: { [id: string]: string } = {
+ [DocPackages.ZeroExJs]: '0xjs-docs-jsons',
+ [DocPackages.SmartContracts]: 'smart-contracts-docs-json',
+ [DocPackages.Connect]:
+ configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-connect-docs-jsons' : 'connect-docs-jsons',
+};
+
+const docIdToSubpackageName: { [id: string]: string } = {
+ [DocPackages.ZeroExJs]: '0x.js',
+ [DocPackages.Connect]: 'connect',
+ [DocPackages.SmartContracts]: 'contracts',
+};
+
+export interface DocPageProps {
+ location: Location;
+ dispatcher: Dispatcher;
+ docsVersion: string;
+ availableDocVersions: string[];
+ docsInfo: DocsInfo;
+ translate: Translate;
+}
+
+interface DocPageState {
+ docAgnosticFormat?: DocAgnosticFormat;
+}
+
+export class DocPage extends React.Component<DocPageProps, DocPageState> {
+ private _isUnmounted: boolean;
+ constructor(props: DocPageProps) {
+ super(props);
+ this._isUnmounted = false;
+ this.state = {
+ docAgnosticFormat: undefined,
+ };
+ }
+ public componentWillMount() {
+ const pathName = this.props.location.pathname;
+ const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
+ const versions = findVersions(lastSegment);
+ const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
+ // tslint:disable-next-line:no-floating-promises
+ this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
+ }
+ public componentWillUnmount() {
+ this._isUnmounted = true;
+ }
+
+ public render() {
+ const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
+ ? {}
+ : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
+ const sourceUrl = this._getSourceUrl();
+ return (
+ <div>
+ <DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
+ <TopBar
+ blockchainIsLoaded={false}
+ location={this.props.location}
+ docsVersion={this.props.docsVersion}
+ availableDocVersions={this.props.availableDocVersions}
+ menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+ menuSubsectionsBySection={menuSubsectionsBySection}
+ docsInfo={this.props.docsInfo}
+ translate={this.props.translate}
+ />
+ <Documentation
+ location={this.props.location}
+ docsVersion={this.props.docsVersion}
+ availableDocVersions={this.props.availableDocVersions}
+ docsInfo={this.props.docsInfo}
+ docAgnosticFormat={this.state.docAgnosticFormat}
+ menuSubsectionsBySection={menuSubsectionsBySection}
+ sourceUrl={sourceUrl}
+ />
+ </div>
+ );
+ }
+ private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
+ const s3BucketName = docIdToS3BucketName[this.props.docsInfo.id];
+ const docsJsonRoot = `${constants.S3_BUCKET_ROOT}/${s3BucketName}`;
+ const versionToFileName = await docUtils.getVersionToFileNameAsync(docsJsonRoot);
+ const versions = _.keys(versionToFileName);
+ this.props.dispatcher.updateAvailableDocVersions(versions);
+ const sortedVersions = semverSort.desc(versions);
+ const latestVersion = sortedVersions[0];
+
+ let versionToFetch = latestVersion;
+ if (!_.isUndefined(preferredVersionIfExists)) {
+ const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
+ if (!_.isUndefined(preferredVersionFileNameIfExists)) {
+ versionToFetch = preferredVersionIfExists;
+ }
+ }
+ this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
+
+ const versionFileNameToFetch = versionToFileName[versionToFetch];
+ const versionDocObj = await docUtils.getJSONDocFileAsync(versionFileNameToFetch, docsJsonRoot);
+ const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
+
+ if (!this._isUnmounted) {
+ this.setState({
+ docAgnosticFormat,
+ });
+ }
+ }
+ private _getSourceUrl() {
+ const url = this.props.docsInfo.packageUrl;
+ const pkg = docIdToSubpackageName[this.props.docsInfo.id];
+ let tagPrefix = pkg;
+ const packagesWithNamespace = ['connect'];
+ if (_.includes(packagesWithNamespace, pkg)) {
+ tagPrefix = `@0xproject/${pkg}`;
+ }
+ const sourceUrl = `${url}/blob/${tagPrefix}%40${this.props.docsVersion}/packages/${pkg}`;
+ return sourceUrl;
+ }
+}
diff --git a/packages/website/ts/pages/documentation/docs_info.ts b/packages/website/ts/pages/documentation/docs_info.ts
index 4b1ec122a..31e151fe8 100644
--- a/packages/website/ts/pages/documentation/docs_info.ts
+++ b/packages/website/ts/pages/documentation/docs_info.ts
@@ -1,33 +1,37 @@
import compareVersions = require('compare-versions');
import * as _ from 'lodash';
import {
+ ContractsByVersionByNetworkId,
DocAgnosticFormat,
DocsInfoConfig,
DocsMenu,
DoxityDocObj,
MenuSubsectionsBySection,
SectionsMap,
+ SupportedDocJson,
TypeDocNode,
} from 'ts/types';
+import { doxityUtils } from 'ts/utils/doxity_utils';
+import { typeDocUtils } from 'ts/utils/typedoc_utils';
export class DocsInfo {
+ public id: string;
+ public type: SupportedDocJson;
public displayName: string;
public packageUrl: string;
- public subPackageName?: string;
- public websitePath: string;
- public docsJsonRoot: string;
public menu: DocsMenu;
public sections: SectionsMap;
public sectionNameToMarkdown: { [sectionName: string]: string };
+ public contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
private _docsInfo: DocsInfoConfig;
constructor(config: DocsInfoConfig) {
+ this.id = config.id;
+ this.type = config.type;
this.displayName = config.displayName;
this.packageUrl = config.packageUrl;
- this.subPackageName = config.subPackageName;
- this.websitePath = config.websitePath;
- this.docsJsonRoot = config.docsJsonRoot;
this.sections = config.sections;
this.sectionNameToMarkdown = config.sectionNameToMarkdown;
+ this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId;
this._docsInfo = config;
}
public isPublicType(typeName: string): boolean {
@@ -106,6 +110,10 @@ export class DocsInfo {
return _.includes(this._docsInfo.visibleConstructors, sectionName);
}
public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
- return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
+ if (this.type === SupportedDocJson.Doxity) {
+ return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
+ } else {
+ return typeDocUtils.convertToDocAgnosticFormat(docObj as TypeDocNode, this);
+ }
}
}
diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx
index 285471166..7eed78fc3 100644
--- a/packages/website/ts/pages/documentation/documentation.tsx
+++ b/packages/website/ts/pages/documentation/documentation.tsx
@@ -1,11 +1,7 @@
-import findVersions = require('find-versions');
import * as _ from 'lodash';
import CircularProgress from 'material-ui/CircularProgress';
import * as React from 'react';
-import DocumentTitle = require('react-document-title');
import { scroller } from 'react-scroll';
-import semverSort = require('semver-sort');
-import { TopBar } from 'ts/components/top_bar/top_bar';
import { Badge } from 'ts/components/ui/badge';
import { Comment } from 'ts/pages/documentation/comment';
import { DocsInfo } from 'ts/pages/documentation/docs_info';
@@ -17,25 +13,23 @@ import { TypeDefinition } from 'ts/pages/documentation/type_definition';
import { MarkdownSection } from 'ts/pages/shared/markdown_section';
import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu';
import { SectionHeader } from 'ts/pages/shared/section_header';
-import { Dispatcher } from 'ts/redux/dispatcher';
import {
AddressByContractName,
DocAgnosticFormat,
DoxityDocObj,
EtherscanLinkSuffixes,
Event,
+ MenuSubsectionsBySection,
Networks,
Property,
SolidityMethod,
Styles,
+ SupportedDocJson,
TypeDefinitionByName,
TypescriptMethod,
} from 'ts/types';
import { colors } from 'ts/utils/colors';
-import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
-import { docUtils } from 'ts/utils/doc_utils';
-import { Translate } from 'ts/utils/translate';
import { utils } from 'ts/utils/utils';
const TOP_BAR_HEIGHT = 60;
@@ -48,20 +42,18 @@ const networkNameToColor: { [network: string]: string } = {
[Networks.Rinkeby]: colors.darkYellow,
};
-export interface DocumentationAllProps {
- source: string;
+export interface DocumentationProps {
location: Location;
- dispatcher: Dispatcher;
docsVersion: string;
availableDocVersions: string[];
docsInfo: DocsInfo;
- translate: Translate;
-}
-
-interface DocumentationState {
docAgnosticFormat?: DocAgnosticFormat;
+ menuSubsectionsBySection: MenuSubsectionsBySection;
+ sourceUrl: string;
}
+interface DocumentationState {}
+
const styles: Styles = {
mainContainers: {
position: 'absolute',
@@ -81,57 +73,17 @@ const styles: Styles = {
},
};
-export class Documentation extends React.Component<DocumentationAllProps, DocumentationState> {
- private _isUnmounted: boolean;
- constructor(props: DocumentationAllProps) {
- super(props);
- this._isUnmounted = false;
- this.state = {
- docAgnosticFormat: undefined,
- };
- }
- public componentWillMount() {
- const pathName = this.props.location.pathname;
- const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
- const versions = findVersions(lastSegment);
- const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
- // tslint:disable-next-line:no-floating-promises
- this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
- }
- public componentWillUnmount() {
- this._isUnmounted = true;
+export class Documentation extends React.Component<DocumentationProps, DocumentationState> {
+ public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) {
+ if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) {
+ this._scrollToHash();
+ }
}
public render() {
- const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
- ? {}
- : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
return (
<div>
- <DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- docsVersion={this.props.docsVersion}
- availableDocVersions={this.props.availableDocVersions}
- menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
- menuSubsectionsBySection={menuSubsectionsBySection}
- docsInfo={this.props.docsInfo}
- translate={this.props.translate}
- />
- {_.isUndefined(this.state.docAgnosticFormat) ? (
- <div className="col col-12" style={styles.mainContainers}>
- <div
- className="relative sm-px2 sm-pt2 sm-m1"
- style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
- >
- <div className="center pb2">
- <CircularProgress size={40} thickness={5} />
- </div>
- <div className="center pt2" style={{ paddingBottom: 11 }}>
- Loading documentation...
- </div>
- </div>
- </div>
+ {_.isUndefined(this.props.docAgnosticFormat) ? (
+ this._renderLoading()
) : (
<div style={{ width: '100%', height: '100%', backgroundColor: colors.gray40 }}>
<div
@@ -155,8 +107,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
versions={this.props.availableDocVersions}
title={this.props.docsInfo.displayName}
topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
- menuSubsectionsBySection={menuSubsectionsBySection}
- docPath={this.props.docsInfo.websitePath}
+ menuSubsectionsBySection={this.props.menuSubsectionsBySection}
/>
</div>
</div>
@@ -175,11 +126,28 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
</div>
);
}
+ private _renderLoading() {
+ return (
+ <div className="col col-12" style={styles.mainContainers}>
+ <div
+ className="relative sm-px2 sm-pt2 sm-m1"
+ style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+ >
+ <div className="center pb2">
+ <CircularProgress size={40} thickness={5} />
+ </div>
+ <div className="center pt2" style={{ paddingBottom: 11 }}>
+ Loading documentation...
+ </div>
+ </div>
+ </div>
+ );
+ }
private _renderDocumentation(): React.ReactNode {
const subMenus = _.values(this.props.docsInfo.getMenu());
const orderedSectionNames = _.flatten(subMenus);
- const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
+ const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat);
const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
return renderedSections;
@@ -196,7 +164,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
);
}
- const docSection = this.state.docAgnosticFormat[sectionName];
+ const docSection = this.props.docAgnosticFormat[sectionName];
if (_.isUndefined(docSection)) {
return null;
}
@@ -278,7 +246,13 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
);
}
private _renderNetworkBadgesIfExists(sectionName: string) {
- const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
+ if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
+ return null;
+ }
+
+ const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[
+ this.props.docsVersion
+ ];
const badges = _.map(
networkToAddressByContractName,
(addressByContractName: AddressByContractName, networkName: string) => {
@@ -326,8 +300,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
<SourceLink
version={this.props.docsVersion}
source={property.source}
- baseUrl={this.props.docsInfo.packageUrl}
- subPackageName={this.props.docsInfo.subPackageName}
+ sourceUrl={this.props.sourceUrl}
/>
)}
{property.comment && <Comment comment={property.comment} className="py2" />}
@@ -348,6 +321,7 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
typeDefinitionByName={typeDefinitionByName}
libraryVersion={this.props.docsVersion}
docsInfo={this.props.docsInfo}
+ sourceUrl={this.props.sourceUrl}
/>
);
}
@@ -364,38 +338,4 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume
containerId: 'documentation',
});
}
- private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
- const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
- const versions = _.keys(versionToFileName);
- this.props.dispatcher.updateAvailableDocVersions(versions);
- const sortedVersions = semverSort.desc(versions);
- const latestVersion = sortedVersions[0];
-
- let versionToFetch = latestVersion;
- if (!_.isUndefined(preferredVersionIfExists)) {
- const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
- if (!_.isUndefined(preferredVersionFileNameIfExists)) {
- versionToFetch = preferredVersionIfExists;
- }
- }
- this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
-
- const versionFileNameToFetch = versionToFileName[versionToFetch];
- const versionDocObj = await docUtils.getJSONDocFileAsync(
- versionFileNameToFetch,
- this.props.docsInfo.docsJsonRoot,
- );
- const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
-
- if (!this._isUnmounted) {
- this.setState(
- {
- docAgnosticFormat,
- },
- () => {
- this._scrollToHash();
- },
- );
- }
- }
}
diff --git a/packages/website/ts/pages/documentation/method_block.tsx b/packages/website/ts/pages/documentation/method_block.tsx
index 1bc6aa4f4..d2c96bf8c 100644
--- a/packages/website/ts/pages/documentation/method_block.tsx
+++ b/packages/website/ts/pages/documentation/method_block.tsx
@@ -15,6 +15,7 @@ interface MethodBlockProps {
libraryVersion: string;
typeDefinitionByName: TypeDefinitionByName;
docsInfo: DocsInfo;
+ sourceUrl: string;
}
interface MethodBlockState {
@@ -80,8 +81,7 @@ export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockSt
<SourceLink
version={this.props.libraryVersion}
source={(method as TypescriptMethod).source}
- baseUrl={this.props.docsInfo.packageUrl}
- subPackageName={this.props.docsInfo.subPackageName}
+ sourceUrl={this.props.sourceUrl}
/>
)}
{method.comment && <Comment comment={method.comment} className="py2" />}
diff --git a/packages/website/ts/pages/documentation/source_link.tsx b/packages/website/ts/pages/documentation/source_link.tsx
index 6588ee39e..31f80aba3 100644
--- a/packages/website/ts/pages/documentation/source_link.tsx
+++ b/packages/website/ts/pages/documentation/source_link.tsx
@@ -5,22 +5,13 @@ import { colors } from 'ts/utils/colors';
interface SourceLinkProps {
source: Source;
- baseUrl: string;
+ sourceUrl: string;
version: string;
- subPackageName: string;
}
-const packagesWithNamespace = ['connect'];
-
export function SourceLink(props: SourceLinkProps) {
const src = props.source;
- const url = props.baseUrl;
- const pkg = props.subPackageName;
- let tagPrefix = pkg;
- if (_.includes(packagesWithNamespace, pkg)) {
- tagPrefix = `@0xproject/${pkg}`;
- }
- const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${src.fileName}#L${src.line}`;
+ const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`;
return (
<div className="pt2" style={{ fontSize: 14 }}>
<a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
index ba794ee9f..1a08ca9f9 100644
--- a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
+++ b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
@@ -16,7 +16,6 @@ interface NestedSidebarMenuProps {
onMenuItemClick?: () => void;
selectedVersion?: string;
versions?: string[];
- docPath?: string;
}
interface NestedSidebarMenuState {}
@@ -69,13 +68,8 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
<div>
{this._renderEmblem()}
{!_.isUndefined(this.props.versions) &&
- !_.isUndefined(this.props.selectedVersion) &&
- !_.isUndefined(this.props.docPath) && (
- <VersionDropDown
- selectedVersion={this.props.selectedVersion}
- versions={this.props.versions}
- docPath={this.props.docPath}
- />
+ !_.isUndefined(this.props.selectedVersion) && (
+ <VersionDropDown selectedVersion={this.props.selectedVersion} versions={this.props.versions} />
)}
<div className="pl1">{navigation}</div>
</div>
diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx
index b922e1048..3b331af9b 100644
--- a/packages/website/ts/pages/shared/version_drop_down.tsx
+++ b/packages/website/ts/pages/shared/version_drop_down.tsx
@@ -6,7 +6,6 @@ import * as React from 'react';
interface VersionDropDownProps {
selectedVersion: string;
versions: string[];
- docPath: string;
}
interface VersionDropDownState {}
@@ -31,7 +30,17 @@ export class VersionDropDown extends React.Component<VersionDropDownProps, Versi
});
return items;
}
- private _updateSelectedVersion(e: any, index: number, value: string) {
- window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
+ private _updateSelectedVersion(e: any, index: number, semver: string) {
+ const port = window.location.port;
+ const hasPort = !_.isUndefined(port);
+ let path = window.location.pathname;
+ const lastChar = path[path.length - 1];
+ if (_.isFinite(_.parseInt(lastChar))) {
+ const pathSections = path.split('/');
+ pathSections.pop();
+ path = pathSections.join('/');
+ }
+ const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}${path}`;
+ window.location.href = `${baseUrl}/${semver}${window.location.hash}`;
}
}
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index f6413eec5..f0db537e6 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -627,20 +627,39 @@ export interface SectionsMap {
[sectionName: string]: string;
}
+export enum DocPackages {
+ Connect = 'CONNECT',
+ ZeroExJs = 'ZERO_EX_JS',
+ SmartContracts = 'SMART_CONTRACTS',
+}
+
+export enum SupportedDocJson {
+ Doxity = 'DOXITY',
+ TypeDoc = 'TYPEDOC',
+}
+
+export interface ContractsByVersionByNetworkId {
+ [version: string]: {
+ [networkName: string]: {
+ [contractName: string]: string;
+ };
+ };
+}
+
export interface DocsInfoConfig {
+ id: string;
+ type: SupportedDocJson;
displayName: string;
packageUrl: string;
- websitePath: string;
- docsJsonRoot: string;
menu: DocsMenu;
sections: SectionsMap;
sectionNameToMarkdown: { [sectionName: string]: string };
visibleConstructors: string[];
- convertToDocAgnosticFormatFn: (docObj: DoxityDocObj | TypeDocNode, docsInfo?: any) => DocAgnosticFormat;
subPackageName?: string;
publicTypes?: string[];
sectionNameToModulePath?: { [sectionName: string]: string[] };
menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
+ contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
}
export interface TimestampMsRange {
diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts
index 8e359f8bd..7e9ba69de 100644
--- a/packages/website/ts/utils/configs.ts
+++ b/packages/website/ts/utils/configs.ts
@@ -1,12 +1,5 @@
import * as _ from 'lodash';
-import {
- ContractAddresses,
- Environments,
- Networks,
- OutdatedWrappedEtherByNetworkId,
- PublicNodeUrlsByNetworkId,
- SmartContractDocSections,
-} from 'ts/types';
+import { ContractAddresses, Environments, OutdatedWrappedEtherByNetworkId, PublicNodeUrlsByNetworkId } from 'ts/types';
const BASE_URL = window.location.origin;
const isDevelopment = _.includes(
@@ -19,34 +12,6 @@ export const configs = {
BACKEND_BASE_URL: 'https://website-api.0xproject.com',
BASE_URL,
BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
- CONTRACT_ADDRESS: {
- '1.0.0': {
- [Networks.Mainnet]: {
- [SmartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093',
- [SmartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4',
- [SmartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498',
- [SmartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c',
- },
- [Networks.Ropsten]: {
- [SmartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac',
- [SmartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
- [SmartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
- [SmartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed',
- },
- [Networks.Kovan]: {
- [SmartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364',
- [SmartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4',
- [SmartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
- [SmartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f',
- },
- [Networks.Rinkeby]: {
- [SmartContractDocSections.Exchange]: '0x1d16ef40fac01cec8adac2ac49427b9384192c05',
- [SmartContractDocSections.TokenTransferProxy]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d',
- [SmartContractDocSections.ZRXToken]: '0x00f58d6d585f84b2d7267940cede30ce2fe6eae8',
- [SmartContractDocSections.TokenRegistry]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6',
- },
- },
- } as ContractAddresses,
DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
// WARNING: ZRX & WETH MUST always be default trackedTokens
DEFAULT_TRACKED_TOKEN_SYMBOLS: ['WETH', 'ZRX'],
diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts
index 6af821dbe..3476b7375 100644
--- a/packages/website/ts/utils/constants.ts
+++ b/packages/website/ts/utils/constants.ts
@@ -42,6 +42,7 @@ export const constants = {
PROVIDER_NAME_GENERIC: 'Injected Web3',
PROVIDER_NAME_PUBLIC: '0x Public',
ROLLBAR_ACCESS_TOKEN: 'a6619002b51c4464928201e6ea94de65',
+ S3_BUCKET_ROOT: 'https://s3.amazonaws.com',
SUCCESS_STATUS: 200,
UNAVAILABLE_STATUS: 503,
TAKER_FEE: new BigNumber(0),
diff --git a/packages/website/ts/utils/doxity_utils.ts b/packages/website/ts/utils/doxity_utils.ts
index 5f1d02132..35ce05672 100644
--- a/packages/website/ts/utils/doxity_utils.ts
+++ b/packages/website/ts/utils/doxity_utils.ts
@@ -45,11 +45,17 @@ export const doxityUtils = {
const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
doxityMethods,
(doxityMethod: DoxityAbiDoc) => {
- // We assume that none of our functions returns more then a single value
- const outputIfExists = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs[0] : undefined;
- const returnTypeIfExists = !_.isUndefined(outputIfExists)
- ? this._convertType(outputIfExists.type)
- : undefined;
+ const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : [];
+ let returnTypeIfExists: Type;
+ if (outputs.length === 0) {
+ // no-op. It's already undefined
+ } else if (outputs.length === 1) {
+ const outputsType = outputs[0].type;
+ returnTypeIfExists = this._convertType(outputsType);
+ } else {
+ const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`;
+ returnTypeIfExists = this._convertType(outputsType);
+ }
// For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
const callPath =
contractName !== 'ZRXToken'
diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts
index 11ec8da58..992475911 100644
--- a/packages/website/ts/utils/typedoc_utils.ts
+++ b/packages/website/ts/utils/typedoc_utils.ts
@@ -4,6 +4,7 @@ import {
CustomType,
CustomTypeChild,
DocAgnosticFormat,
+ DocPackages,
DocSection,
IndexSignature,
KindString,
@@ -108,7 +109,7 @@ export const typeDocUtils = {
isConstructor,
docsInfo.sections,
sectionName,
- docsInfo.subPackageName,
+ docsInfo.id,
);
docSection.constructors.push(constructor);
break;
@@ -121,7 +122,7 @@ export const typeDocUtils = {
isConstructor,
docsInfo.sections,
sectionName,
- docsInfo.subPackageName,
+ docsInfo.id,
);
docSection.methods.push(method);
}
@@ -133,7 +134,7 @@ export const typeDocUtils = {
entity,
docsInfo.sections,
sectionName,
- docsInfo.subPackageName,
+ docsInfo.id,
);
docSection.properties.push(property);
}
@@ -149,7 +150,7 @@ export const typeDocUtils = {
entity,
docsInfo.sections,
sectionName,
- docsInfo.subPackageName,
+ docsInfo.id,
);
docSection.types.push(customType);
}
@@ -161,21 +162,16 @@ export const typeDocUtils = {
});
return docSection;
},
- _convertCustomType(
- entity: TypeDocNode,
- sections: SectionsMap,
- sectionName: string,
- subPackageName: string,
- ): CustomType {
+ _convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): CustomType {
const typeIfExists = !_.isUndefined(entity.type)
- ? typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName)
+ ? typeDocUtils._convertType(entity.type, sections, sectionName, docId)
: undefined;
const isConstructor = false;
const methodIfExists = !_.isUndefined(entity.declaration)
- ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
+ ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
: undefined;
const indexSignatureIfExists = !_.isUndefined(entity.indexSignature)
- ? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, subPackageName)
+ ? typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName, docId)
: undefined;
const commentIfExists =
!_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
@@ -185,7 +181,7 @@ export const typeDocUtils = {
const childrenIfExist = !_.isUndefined(entity.children)
? _.map(entity.children, (child: TypeDocNode) => {
const childTypeIfExists = !_.isUndefined(child.type)
- ? typeDocUtils._convertType(child.type, sections, sectionName, subPackageName)
+ ? typeDocUtils._convertType(child.type, sections, sectionName, docId)
: undefined;
const c: CustomTypeChild = {
name: child.name,
@@ -212,27 +208,22 @@ export const typeDocUtils = {
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
- subPackageName: string,
+ docId: string,
): IndexSignature {
const key = entity.parameters[0];
const indexSignature = {
keyName: key.name,
- keyType: typeDocUtils._convertType(key.type, sections, sectionName, subPackageName),
+ keyType: typeDocUtils._convertType(key.type, sections, sectionName, docId),
valueName: entity.type.name,
};
return indexSignature;
},
- _convertProperty(
- entity: TypeDocNode,
- sections: SectionsMap,
- sectionName: string,
- subPackageName: string,
- ): Property {
+ _convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Property {
const source = entity.sources[0];
const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
const property = {
name: entity.name,
- type: typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName),
+ type: typeDocUtils._convertType(entity.type, sections, sectionName, docId),
source: {
fileName: source.fileName,
line: source.line,
@@ -246,7 +237,7 @@ export const typeDocUtils = {
isConstructor: boolean,
sections: SectionsMap,
sectionName: string,
- subPackageName: string,
+ docId: string,
): TypescriptMethod {
const signature = entity.signatures[0];
const source = entity.sources[0];
@@ -258,7 +249,7 @@ export const typeDocUtils = {
let callPath;
if (isConstructor || entity.name === '__type') {
callPath = '';
- } else if (subPackageName === '0x.js') {
+ } else if (docId === DocPackages.ZeroExJs) {
const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
callPath =
!_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
@@ -269,12 +260,12 @@ export const typeDocUtils = {
}
const parameters = _.map(signature.parameters, param => {
- return typeDocUtils._convertParameter(param, sections, sectionName, subPackageName);
+ return typeDocUtils._convertParameter(param, sections, sectionName, docId);
});
- const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, subPackageName);
+ const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId);
const typeParameter = _.isUndefined(signature.typeParameter)
? undefined
- : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, subPackageName);
+ : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId);
const method = {
isConstructor,
@@ -297,21 +288,16 @@ export const typeDocUtils = {
entity: TypeDocNode,
sections: SectionsMap,
sectionName: string,
- subPackageName: string,
+ docId: string,
): TypeParameter {
- const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
+ const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
const parameter = {
name: entity.name,
type,
};
return parameter;
},
- _convertParameter(
- entity: TypeDocNode,
- sections: SectionsMap,
- sectionName: string,
- subPackageName: string,
- ): Parameter {
+ _convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Parameter {
let comment = '<No comment>';
if (entity.comment && entity.comment.shortText) {
comment = entity.comment.shortText;
@@ -321,7 +307,7 @@ export const typeDocUtils = {
const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
- const type = typeDocUtils._convertType(entity.type, sections, sectionName, subPackageName);
+ const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
const parameter = {
name: entity.name,
@@ -331,17 +317,17 @@ export const typeDocUtils = {
};
return parameter;
},
- _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, subPackageName: string): Type {
+ _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, docId: string): Type {
const typeArguments = _.map(entity.typeArguments, typeArgument => {
- return typeDocUtils._convertType(typeArgument, sections, sectionName, subPackageName);
+ return typeDocUtils._convertType(typeArgument, sections, sectionName, docId);
});
const types = _.map(entity.types, t => {
- return typeDocUtils._convertType(t, sections, sectionName, subPackageName);
+ return typeDocUtils._convertType(t, sections, sectionName, docId);
});
const isConstructor = false;
const methodIfExists = !_.isUndefined(entity.declaration)
- ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, subPackageName)
+ ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
: undefined;
const elementTypeIfExists = !_.isUndefined(entity.elementType)
diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json
index 38b177d0b..99f465bc2 100644
--- a/packages/website/tsconfig.json
+++ b/packages/website/tsconfig.json
@@ -13,5 +13,9 @@
"*": ["node_modules/@types/*", "*"]
}
},
- "include": ["./ts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+ "include": [
+ "./ts/**/*",
+ "../../node_modules/web3-typescript-typings/index.d.ts",
+ "../../node_modules/ethers-typescript-typings/index.d.ts"
+ ]
}
diff --git a/yarn.lock b/yarn.lock
index 7c7dcd76b..a334b14e5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3227,6 +3227,21 @@ ethereumjs-wallet@^0.6.0:
utf8 "^2.1.1"
uuid "^2.0.1"
+ethers-contracts@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ethers-contracts/-/ethers-contracts-2.2.1.tgz#e2bf5dd5e157313ba454b50c646c8472fcd0a8b3"
+ dependencies:
+ ethers-utils "^2.1.0"
+
+ethers-utils@^2.1.0:
+ version "2.1.11"
+ resolved "https://registry.yarnpkg.com/ethers-utils/-/ethers-utils-2.1.11.tgz#b27535ca3226118be300211c39c896b1e5e21641"
+ dependencies:
+ bn.js "^4.4.0"
+ hash.js "^1.0.0"
+ js-sha3 "0.5.7"
+ xmlhttprequest "1.8.0"
+
ethjs-abi@0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/ethjs-abi/-/ethjs-abi-0.1.8.tgz#cd288583ed628cdfadaf8adefa3ba1dbcbca6c18"
@@ -4970,6 +4985,10 @@ js-sha3@0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a"
+js-sha3@0.5.7:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7"
+
js-sha3@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243"
@@ -6948,9 +6967,9 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
-prettier@1.9.2:
- version "1.9.2"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827"
+prettier@^1.11.0:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.0.tgz#c024f70cab158c993f50fc0c25ffe738cb8b0f85"
pretty-bytes@^1.0.4:
version "1.0.4"
@@ -9811,7 +9830,7 @@ xml-js@^1.3.2:
dependencies:
sax "^1.2.4"
-xmlhttprequest@*:
+xmlhttprequest@*, xmlhttprequest@1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc"