diff options
author | Brandon Millman <brandon.millman@gmail.com> | 2018-03-09 02:47:13 +0800 |
---|---|---|
committer | Brandon Millman <brandon.millman@gmail.com> | 2018-03-09 02:47:13 +0800 |
commit | 260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423 (patch) | |
tree | b9b943e46f93c4c61f29b31e69bd932b920134db | |
parent | 9286dc284ca56cbaa5b4015b3b9549eb710977ce (diff) | |
parent | a691de7d55d2f712a9601dd2440f155fcb0a9a14 (diff) | |
download | dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.tar dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.tar.gz dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.tar.bz2 dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.tar.lz dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.tar.xz dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.tar.zst dexon-0x-contracts-260bb8218f8207bcc9f1f7d0d9ddf2d4356fd423.zip |
Merge branch 'master' of github.com:0xProject/0x-monorepo
* 'master' of github.com:0xProject/0x-monorepo: (171 commits)
Fix bugs in postpublish_utils.js
Update @0xproject/utils in top-level package.json
Changelog tweaks
Publish
Updated CHANGELOGS
Fix typo
Add PR number to changelog entry
Add changelog update to subproviders package
Add `numberOfAccounts` param to `LedgerSubprovider` method `getAccountsAsync` and add tests
Remove unnecessary type assertion
Fix comments
Add comments
Don't need any external packages for 0x connect docs yet
Instead of adding `@0xproject/types` to tsconfig.json, let's only add it when calling TypeDoc
Fix styling
Make prettier ignore postpublish_utils
Update yarn.lock
Update yarn.lock
Update all mentions of the repo name being `0x.js` to `0x-monorepo`
Add hack comment
...
222 files changed, 3960 insertions, 5946 deletions
diff --git a/.gitignore b/.gitignore index 24b8d044f..49d0604ea 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,6 @@ packages/website/public/bundle* # generated binaries bin/ + +# generated contract artifacts +packages/contracts/src/artifacts diff --git a/.prettierignore b/.prettierignore index b2dee5c88..5b8003c95 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,5 @@ lib -generated .nyc_output -/packages/contracts/build/contracts +/packages/contracts/src/artifacts package.json +scripts/postpublish_utils.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e8828ff6b..39c3239eb 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 @@ -23,7 +23,7 @@ If the sub-package you are modifying has a `CHANGELOG.md` file, make sure to add ### Styleguide -We use [TSLint](https://palantir.github.io/tslint/) with [custom configs](https://github.com/0xProject/0x.js/tree/development/packages/tslint-config) to keep our code style consistent. +We use [TSLint](https://palantir.github.io/tslint/) with [custom configs](https://github.com/0xProject/0x-monorepo/tree/development/packages/tslint-config) to keep our code style consistent. To lint your code just run: `yarn lint` @@ -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. @@ -4,17 +4,17 @@ [0x][website-url] is an open protocol that facilitates trustless, low friction exchange of Ethereum-based assets. A full description of the protocol may be found in our [whitepaper][whitepaper-url]. -This repository contains all the 0x developer tools written in TypeScript. Our hope is that these tools make it easy to build Relayers and other DApps that use the 0x protocol. +This repository is a monorepo including the 0x protocol smart contracts and numerous developer tools. Each public sub-package is independently published to NPM. [website-url]: https://0xproject.com/ [whitepaper-url]: https://0xproject.com/pdfs/0x_white_paper.pdf -[](https://circleci.com/gh/0xProject/0x.js) -[](https://coveralls.io/github/0xProject/0x.js?branch=master) +[](https://circleci.com/gh/0xProject/0x-monorepo) +[](https://coveralls.io/github/0xProject/0x-monorepo?branch=master) [](https://chat.0xproject.com) [](https://gitter.im/0xProject/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://opensource.org/licenses/Apache-2.0) -[](https://greenkeeper.io/) +[](https://greenkeeper.io/) ### Published Packages @@ -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/lerna.json b/lerna.json index dbe42bcb1..5f975fff9 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,11 @@ { "lerna": "2.5.1", "packages": ["packages/*"], + "commands": { + "publish": { + "allowBranch": "development" + } + }, "version": "independent", "commands": { "publish": { diff --git a/package.json b/package.json index 9c3825822..9519fd40d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "name": "0x.js", + "name": "0x-monorepo", "workspaces": ["packages/*"], "scripts": { "dev": "lerna run --parallel build:watch", @@ -16,11 +16,11 @@ "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic" }, "devDependencies": { - "@0xproject/utils": "^0.3.4", + "@0xproject/utils": "^0.4.0", "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 0af474c74..f0377160b 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGELOG +## v0.33.0 - _March 4, 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) + * Move web3 typings from devDep to dep since cannot use this package without it (#429) + ## v0.32.2 - _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/0x.js/README.md b/packages/0x.js/README.md index bac4fa5d8..18c771234 100644 --- a/packages/0x.js/README.md +++ b/packages/0x.js/README.md @@ -22,7 +22,7 @@ import { ZeroEx } from '0x.js'; **Install** -Download the UMD module from our [releases page](https://github.com/0xProject/0x.js/releases) and add it to your project. +Download the UMD module from our [releases page](https://github.com/0xProject/0x-monorepo/releases) and add it to your project. **Import** 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..18bf20ee3 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "0.32.4", + "version": "0.33.0", "description": "A javascript library for interacting with the 0x protocol", "keywords": [ "0x.js", @@ -15,9 +15,9 @@ "build:watch": "tsc -w", "prebuild": "run-s clean generate_contract_wrappers", "build": "run-p build:umd:prod build:commonjs; exit 0;", - "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES", "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", @@ -35,16 +35,16 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js" + "url": "https://github.com/0xProject/0x-monorepo" }, "license": "Apache-2.0", "engines": { "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^0.2.3", - "@0xproject/dev-utils": "^0.1.0", - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/abi-gen": "^0.2.4", + "@0xproject/dev-utils": "^0.2.0", + "@0xproject/tslint-config": "^0.4.10", "@types/bintrees": "^1.0.2", "@types/jsonschema": "^1.1.1", "@types/lodash": "^4.14.86", @@ -55,12 +55,13 @@ "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", - "chai-as-promised-typescript-typings": "^0.0.9", + "chai-as-promised-typescript-typings": "^0.0.10", "chai-bignumber": "^2.0.1", - "chai-typescript-typings": "^0.0.3", + "chai-typescript-typings": "^0.0.4", "copyfiles": "^1.2.0", "coveralls": "^3.0.0", "dirty-chai": "^2.0.1", + "ethers-typescript-typings": "^0.0.2", "json-loader": "^0.5.4", "mocha": "^4.0.1", "npm-run-all": "^4.1.2", @@ -73,27 +74,29 @@ "source-map-support": "^0.5.0", "truffle-hdwallet-provider": "^0.0.3", "tslint": "5.8.0", - "typedoc": "~0.8.0", + "typedoc": "0xProject/typedoc", "types-bn": "^0.0.1", "typescript": "2.7.1", "web3-provider-engine": "^13.0.1", - "web3-typescript-typings": "^0.9.11", "webpack": "^3.1.0" }, "dependencies": { - "@0xproject/assert": "^0.0.20", - "@0xproject/json-schemas": "^0.7.12", - "@0xproject/types": "^0.2.3", - "@0xproject/utils": "^0.3.4", - "@0xproject/web3-wrapper": "^0.1.14", + "@0xproject/assert": "^0.1.0", + "@0xproject/base-contract": "^0.0.2", + "@0xproject/json-schemas": "^0.7.13", + "@0xproject/types": "^0.3.0", + "@0xproject/utils": "^0.4.0", + "@0xproject/web3-wrapper": "^0.2.0", "bintrees": "^1.0.2", "bn.js": "^4.11.8", "ethereumjs-abi": "^0.6.4", "ethereumjs-blockstream": "^2.0.6", "ethereumjs-util": "^5.1.1", + "ethers-contracts": "^2.2.1", "js-sha3": "^0.7.0", "lodash": "^4.17.4", "uuid": "^3.1.0", - "web3": "^0.20.0" + "web3": "^0.20.0", + "web3-typescript-typings": "^0.10.0" } } diff --git a/packages/0x.js/scripts/postpublish.js b/packages/0x.js/scripts/postpublish.js index 7cbabd8f6..1a9ab73ea 100644 --- a/packages/0x.js/scripts/postpublish.js +++ b/packages/0x.js/scripts/postpublish.js @@ -1,9 +1,16 @@ const execAsync = require('async-child-process').execAsync; const postpublish_utils = require('../../../scripts/postpublish_utils'); const packageJSON = require('../package.json'); +const tsConfig = require('../tsconfig.json'); const cwd = __dirname + '/..'; const subPackageName = packageJSON.name; +// Include any external packages that are part of the 0x.js public interface +// to this array so that TypeDoc picks it up and adds it to the Docs JSON +// So far, we only have @0xproject/types as part of 0x.js's public interface. +const fileIncludes = [...tsConfig.include, '../types/src/index.ts']; +const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname); +const projectFiles = fileIncludesAdjusted.join(' '); const S3BucketPath = 's3://0xjs-docs-jsons/'; let tag; @@ -20,7 +27,7 @@ postpublish_utils .then(function(release) { console.log('POSTPUBLISH: Release successful, generating docs...'); const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json'; - return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_DIR=' + __dirname + '/.. yarn docs:json', { + return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', { cwd, }); }) diff --git a/packages/0x.js/scripts/stagedocs.js b/packages/0x.js/scripts/stagedocs.js index b48c23851..f0ba55205 100644 --- a/packages/0x.js/scripts/stagedocs.js +++ b/packages/0x.js/scripts/stagedocs.js @@ -1,24 +1,31 @@ const execAsync = require('async-child-process').execAsync; const postpublish_utils = require('../../../scripts/postpublish_utils'); +const tsConfig = require('../tsconfig.json'); const cwd = __dirname + '/..'; const S3BucketPath = 's3://staging-0xjs-docs-jsons/'; +// Include any external packages that are part of the 0x.js public interface +// to this array so that TypeDoc picks it up and adds it to the Docs JSON +// So far, we only have @0xproject/types as part of 0x.js's public interface. +const fileIncludes = [...tsConfig.include, '../types/src/index.ts']; +const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname); +const projectFiles = fileIncludesAdjusted.join(' '); const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json'; const version = process.env.DOCS_VERSION; -execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_DIR=' + __dirname + '/.. yarn docs:json', { +execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', { cwd, }) -.then(function(result) { - if (result.stderr !== '') { - throw new Error(result.stderr); - } - const fileName = 'v' + version + '.json'; - const s3Url = S3BucketPath + fileName; - return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', { - cwd, + .then(function(result) { + if (result.stderr !== '') { + throw new Error(result.stderr); + } + const fileName = 'v' + version + '.json'; + const s3Url = S3BucketPath + fileName; + return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', { + cwd, + }); + }) + .catch(function(err) { + console.log(err); }); -}) -.catch(function(err) { - console.log(err); -}); diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts index 6cfa65cc2..22a5fee10 100644 --- a/packages/0x.js/src/0x.ts +++ b/packages/0x.js/src/0x.ts @@ -13,6 +13,8 @@ import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_pr import { TokenWrapper } from './contract_wrappers/token_wrapper'; import { OrderStateWatcher } from './order_watcher/order_state_watcher'; import { zeroExConfigSchema } from './schemas/zero_ex_config_schema'; +import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema'; +import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema'; import { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types'; import { assert } from './utils/assert'; import { constants } from './utils/constants'; @@ -74,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; } /** @@ -163,7 +166,10 @@ export class ZeroEx { */ constructor(provider: Web3Provider, config: ZeroExConfig) { assert.isWeb3Provider('provider', provider); - assert.doesConformToSchema('config', config, zeroExConfigSchema); + assert.doesConformToSchema('config', config, zeroExConfigSchema, [ + zeroExPrivateNetworkConfigSchema, + zeroExPublicNetworkConfigSchema, + ]); const artifactJSONs = _.values(artifacts); const abiArrays = _.map(artifactJSONs, artifact => artifact.abi); this._abiDecoder = new AbiDecoder(abiArrays); @@ -245,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) { @@ -253,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) @@ -262,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; } @@ -270,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/index.ts b/packages/0x.js/src/index.ts index 161945443..9879bbb56 100644 --- a/packages/0x.js/src/index.ts +++ b/packages/0x.js/src/index.ts @@ -34,6 +34,7 @@ export { BlockParam, ContractEventArg, LogWithDecodedArgs, + TransactionReceipt, TransactionReceiptWithDecodedLogs, } from '@0xproject/types'; @@ -58,5 +59,3 @@ export { ExchangeContractEventArgs, ExchangeEvents, } from './contract_wrappers/generated/exchange'; - -export { TransactionReceipt } from '@0xproject/types'; diff --git a/packages/0x.js/src/schemas/zero_ex_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_config_schema.ts index 546b1c2d0..a9c3c64fc 100644 --- a/packages/0x.js/src/schemas/zero_ex_config_schema.ts +++ b/packages/0x.js/src/schemas/zero_ex_config_schema.ts @@ -1,27 +1,5 @@ export const zeroExConfigSchema = { id: '/ZeroExConfig', - properties: { - networkId: { - type: 'number', - minimum: 0, - }, - gasPrice: { $ref: '/Number' }, - exchangeContractAddress: { $ref: '/Address' }, - tokenRegistryContractAddress: { $ref: '/Address' }, - orderWatcherConfig: { - type: 'object', - properties: { - pollingIntervalMs: { - type: 'number', - minimum: 0, - }, - numConfirmations: { - type: 'number', - minimum: 0, - }, - }, - }, - }, + oneOf: [{ $ref: '/ZeroExPrivateNetworkConfig' }, { $ref: '/ZeroExPublicNetworkConfig' }], type: 'object', - required: ['networkId'], }; diff --git a/packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts new file mode 100644 index 000000000..f7f649a6d --- /dev/null +++ b/packages/0x.js/src/schemas/zero_ex_private_network_config_schema.ts @@ -0,0 +1,35 @@ +export const zeroExPrivateNetworkConfigSchema = { + id: '/ZeroExPrivateNetworkConfig', + properties: { + networkId: { + type: 'number', + minimum: 1, + }, + gasPrice: { $ref: '/Number' }, + zrxContractAddress: { $ref: '/Address' }, + exchangeContractAddress: { $ref: '/Address' }, + tokenRegistryContractAddress: { $ref: '/Address' }, + tokenTransferProxyContractAddress: { $ref: '/Address' }, + orderWatcherConfig: { + type: 'object', + properties: { + pollingIntervalMs: { + type: 'number', + minimum: 0, + }, + numConfirmations: { + type: 'number', + minimum: 0, + }, + }, + }, + }, + type: 'object', + required: [ + 'networkId', + 'zrxContractAddress', + 'exchangeContractAddress', + 'tokenRegistryContractAddress', + 'tokenTransferProxyContractAddress', + ], +}; diff --git a/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts b/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts new file mode 100644 index 000000000..9da31481a --- /dev/null +++ b/packages/0x.js/src/schemas/zero_ex_public_network_config_schema.ts @@ -0,0 +1,29 @@ +export const zeroExPublicNetworkConfigSchema = { + id: '/ZeroExPublicNetworkConfig', + properties: { + networkId: { + type: 'number', + enum: [1, 3, 4, 42, 50], + }, + gasPrice: { $ref: '/Number' }, + zrxContractAddress: { $ref: '/Address' }, + exchangeContractAddress: { $ref: '/Address' }, + tokenRegistryContractAddress: { $ref: '/Address' }, + tokenTransferProxyContractAddress: { $ref: '/Address' }, + orderWatcherConfig: { + type: 'object', + properties: { + pollingIntervalMs: { + type: 'number', + minimum: 0, + }, + numConfirmations: { + type: 'number', + minimum: 0, + }, + }, + }, + }, + type: 'object', + required: ['networkId'], +}; diff --git a/packages/0x.js/src/types.ts b/packages/0x.js/src/types.ts index ab97f7775..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; @@ -196,7 +196,7 @@ export interface OrderStateWatcherConfig { } /* - * networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 42-kovan, 50-testrpc) + * networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc) * gasPrice: Gas price to use with every transaction * exchangeContractAddress: The address of an exchange contract to use * zrxContractAddress: The address of the ZRX contract to use diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts index da49ec467..68f2c6f66 100644 --- a/packages/0x.js/test/ether_token_wrapper_test.ts +++ b/packages/0x.js/test/ether_token_wrapper_test.ts @@ -75,11 +75,14 @@ describe('EtherTokenWrapper', () => { const contractAddressIfExists = zeroEx.etherToken.getContractAddressIfExists(); expect(contractAddressIfExists).to.not.be.undefined(); }); - it('should return undefined if connected to an unknown network', () => { + it('should throw if connected to a private network and contract addresses are not specified', () => { const UNKNOWN_NETWORK_NETWORK_ID = 10; - const unknownNetworkZeroEx = new ZeroEx(web3.currentProvider, { networkId: UNKNOWN_NETWORK_NETWORK_ID }); - const contractAddressIfExists = unknownNetworkZeroEx.etherToken.getContractAddressIfExists(); - expect(contractAddressIfExists).to.be.undefined(); + expect( + () => + new ZeroEx(web3.currentProvider, { + networkId: UNKNOWN_NETWORK_NETWORK_ID, + } as any), + ).to.throw(); }); }); describe('#depositAsync', () => { @@ -155,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/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts index b49dee8e5..7f79e3802 100644 --- a/packages/0x.js/test/expiration_watcher_test.ts +++ b/packages/0x.js/test/expiration_watcher_test.ts @@ -9,10 +9,10 @@ import * as Web3 from 'web3'; import { ZeroEx } from '../src/0x'; import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher'; import { DoneCallback, Token } from '../src/types'; -import { constants } from '../src/utils/constants'; import { utils } from '../src/utils/utils'; import { chaiSetup } from './utils/chai_setup'; +import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; import { reportNoErrorCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; 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..90e82c632 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## v0.2.4 - _March 4, 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/README.md b/packages/abi-gen/README.md index 1188bd437..5232e59ce 100644 --- a/packages/abi-gen/README.md +++ b/packages/abi-gen/README.md @@ -4,8 +4,8 @@ This package allows you to generate TypeScript contract wrappers from ABI files. It's heavily inspired by [Geth abigen](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) but takes a different approach. You can write your custom handlebars templates which will allow you to seamlessly integrate the generated code into your existing codebase with existing conventions. -For an example of the generated [wrapper files](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/src/contract_wrappers/generated) check out 0x.js. -[Here](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files. +For an example of the generated [wrapper files](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/src/contract_wrappers/generated) check out 0x.js. +[Here](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files. ## Installation @@ -36,14 +36,14 @@ The abi file should be either a [Truffle](http://truffleframework.com/) contract ## How to write custom templates? -The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) and start adjusting them for your needs. +The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) and start adjusting them for your needs. We use [handlebars](http://handlebarsjs.com/) template engine under the hood. You need to have a master template called `contract.mustache`. it will be used to generate each contract wrapper. Although - you don't need and probably shouldn't write all your logic in a single template file. You can write [partial templates](http://handlebarsjs.com/partials.html) and as long as they are within a partials folder - they will be registered and available. ## Which data/context do I get in my templates? For now you don't get much on top of methods abi, some useful helpers and a contract name because it was enough for our use-case, but if you need something else - create a PR. -See the [type definition](https://github.com/0xProject/0x.js/tree/development/packages/abi-gen/src/types.ts) of what we pass to the render method. +See the [type definition](https://github.com/0xProject/0x-monorepo/tree/development/packages/abi-gen/src/types.ts) of what we pass to the render method. ## Output files diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index 2506335a4..741cf3940 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/abi-gen", - "version": "0.2.3", + "version": "0.2.4", "description": "Generate contract wrappers from ABI and handlebars templates", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -15,15 +15,15 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md", "dependencies": { - "@0xproject/utils": "^0.3.4", + "@0xproject/utils": "^0.4.0", "chalk": "^2.3.0", "glob": "^7.1.2", "handlebars": "^4.0.11", @@ -34,7 +34,7 @@ "yargs": "^10.0.3" }, "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "@types/glob": "^5.0.33", "@types/handlebars": "^4.0.36", "@types/mkdirp": "^0.5.1", @@ -44,6 +44,6 @@ "shx": "^0.2.2", "tslint": "5.8.0", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11" + "web3-typescript-typings": "^0.10.0" } } 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 23c2c5e56..b37a810e3 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## v0.1.0 - _March 4, 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_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/assert/package.json b/packages/assert/package.json index 0a1659dd8..cfe019444 100644 --- a/packages/assert/package.json +++ b/packages/assert/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/assert", - "version": "0.0.20", + "version": "0.1.0", "description": "Provides a standard way of performing type and schema validation across 0x projects", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", @@ -17,19 +17,19 @@ "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "@types/lodash": "^4.14.86", "@types/mocha": "^2.2.42", "@types/valid-url": "^1.0.2", "chai": "^4.0.1", - "chai-typescript-typings": "^0.0.3", + "chai-typescript-typings": "^0.0.4", "dirty-chai": "^2.0.1", "mocha": "^4.0.1", "npm-run-all": "^4.1.2", @@ -38,8 +38,8 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/json-schemas": "^0.7.12", - "@0xproject/utils": "^0.3.4", + "@0xproject/json-schemas": "^0.7.13", + "@0xproject/utils": "^0.4.0", "lodash": "^4.17.4", "valid-url": "^1.0.9" } diff --git a/packages/assert/src/index.ts b/packages/assert/src/index.ts index 7ad574ec7..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, @@ -66,8 +63,11 @@ export const assert = { const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync); this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value)); }, - doesConformToSchema(variableName: string, value: any, schema: Schema): void { + doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void { const schemaValidator = new SchemaValidator(); + if (!_.isUndefined(subSchemas)) { + _.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator)); + } const validationResult = schemaValidator.validate(value, schema); const hasValidationErrors = validationResult.errors.length > 0; const msg = `Expected ${variableName} to conform to schema ${schema.id} 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..1942b3b3e --- /dev/null +++ b/packages/base-contract/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## v0.0.2 - _March 4, 2018_ + + * Initial release 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..8b31b8e12 --- /dev/null +++ b/packages/base-contract/package.json @@ -0,0 +1,39 @@ +{ + "name": "@0xproject/base-contract", + "version": "0.0.2", + "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-monorepo.git" + }, + "bugs": { + "url": "https://github.com/0xProject/0x-monorepo/issues" + }, + "homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md", + "devDependencies": { + "@0xproject/tslint-config": "^0.4.10", + "@types/lodash": "^4.14.86", + "npm-run-all": "^4.1.2", + "shx": "^0.2.2", + "tslint": "5.8.0", + "typescript": "2.7.1" + }, + "dependencies": { + "@0xproject/types": "^0.3.0", + "@0xproject/web3-wrapper": "^0.2.0", + "ethers-contracts": "^2.2.1", + "ethers-typescript-typings": "^0.0.2", + "lodash": "^4.17.4", + "web3": "^0.20.0", + "web3-typescript-typings": "^0.10.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/chai-as-promised-typescript-typings/package.json b/packages/chai-as-promised-typescript-typings/package.json index e1cbdd44f..18fdf438c 100644 --- a/packages/chai-as-promised-typescript-typings/package.json +++ b/packages/chai-as-promised-typescript-typings/package.json @@ -1,12 +1,12 @@ { "name": "chai-as-promised-typescript-typings", - "version": "0.0.9", + "version": "0.0.10", "description": "Typescript type definitions for chai-as-promised", "main": "index.d.ts", "types": "index.d.ts", "repository": { "type": "git", - "url": "git+https://github.com/0xProject/0x.js.git" + "url": "git+https://github.com/0xProject/0x-monorepo.git" }, "author": "Fabio Berger", "contributors": [ @@ -14,10 +14,10 @@ ], "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/chai-as-promised-typescript-typings#readme", "dependencies": { - "chai-typescript-typings": "^0.0.3" + "chai-typescript-typings": "^0.0.4" } } diff --git a/packages/chai-typescript-typings/package.json b/packages/chai-typescript-typings/package.json index 65103f76d..afd40df76 100644 --- a/packages/chai-typescript-typings/package.json +++ b/packages/chai-typescript-typings/package.json @@ -1,16 +1,16 @@ { "name": "chai-typescript-typings", - "version": "0.0.3", + "version": "0.0.4", "description": "Typescript type definitions for chai", "main": "index.d.ts", "types": "index.d.ts", "repository": { "type": "git", - "url": "git+https://github.com/0xProject/0x.js.git" + "url": "git+https://github.com/0xProject/0x-monorepo.git" }, "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/chai-typescript-typings#readme" + "homepage": "https://github.com/0xProject/0x-monorepo/packages/chai-typescript-typings#readme" } diff --git a/packages/connect/CHANGELOG.md b/packages/connect/CHANGELOG.md index 75ffb5274..e1fb7c795 100644 --- a/packages/connect/CHANGELOG.md +++ b/packages/connect/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## v0.6.1 - _February 16, 2018_ +## v0.6.2 - _February 16, 2018_ * Fix JSON parse empty response (#407) 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/connect/package.json b/packages/connect/package.json index c5c8f4ea0..f2eec9f00 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/connect", - "version": "0.6.1", + "version": "0.6.2", "description": "A javascript library for interacting with the standard relayer api", "keywords": [ "connect", @@ -15,7 +15,7 @@ "build:watch": "tsc -w", "build": "tsc", "clean": "shx rm -rf _bundles lib test_temp", - "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR", + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES", "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", "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures", "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", @@ -25,7 +25,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "author": "Brandon Millman", "license": "Apache-2.0", @@ -33,20 +33,20 @@ "node": ">=6.0.0" }, "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/connect/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md", "dependencies": { - "@0xproject/assert": "^0.0.20", - "@0xproject/json-schemas": "^0.7.12", - "@0xproject/utils": "^0.3.4", + "@0xproject/assert": "^0.1.0", + "@0xproject/json-schemas": "^0.7.13", + "@0xproject/utils": "^0.4.0", "isomorphic-fetch": "^2.2.1", "lodash": "^4.17.4", "query-string": "^5.0.1", "websocket": "^1.0.25" }, "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "@types/fetch-mock": "^5.12.1", "@types/lodash": "^4.14.86", "@types/mocha": "^2.2.42", @@ -54,8 +54,8 @@ "@types/websocket": "^0.0.34", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", - "chai-as-promised-typescript-typings": "^0.0.9", - "chai-typescript-typings": "^0.0.3", + "chai-as-promised-typescript-typings": "^0.0.10", + "chai-typescript-typings": "^0.0.4", "copyfiles": "^1.2.0", "dirty-chai": "^2.0.1", "fetch-mock": "^5.13.1", @@ -65,6 +65,6 @@ "tslint": "5.8.0", "typedoc": "~0.8.0", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11" + "web3-typescript-typings": "^0.10.0" } } diff --git a/packages/connect/scripts/postpublish.js b/packages/connect/scripts/postpublish.js index 869bad099..e447615f9 100644 --- a/packages/connect/scripts/postpublish.js +++ b/packages/connect/scripts/postpublish.js @@ -1,10 +1,16 @@ const execAsync = require('async-child-process').execAsync; const postpublish_utils = require('../../../scripts/postpublish_utils'); const packageJSON = require('../package.json'); +const tsConfig = require('../tsconfig.json'); const cwd = __dirname + '/..'; const subPackageName = packageJSON.name; const S3BucketPath = 's3://connect-docs-jsons/'; +// Include any external packages that are part of the @0xproject/connect public interface +// to this array so that TypeDoc picks it up and adds it to the Docs JSON +const fileIncludes = [...tsConfig.include]; +const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname); +const projectFiles = fileIncludesAdjusted.join(' '); let tag; let version; @@ -19,7 +25,7 @@ postpublish_utils .then(function(release) { console.log('POSTPUBLISH: Release successful, generating docs...'); const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json'; - return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_DIR=' + __dirname + '/.. yarn docs:json', { + return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', { cwd, }); }) diff --git a/packages/connect/scripts/stagedocs.js b/packages/connect/scripts/stagedocs.js index 868112a37..58272ab86 100644 --- a/packages/connect/scripts/stagedocs.js +++ b/packages/connect/scripts/stagedocs.js @@ -1,24 +1,30 @@ const execAsync = require('async-child-process').execAsync; const postpublish_utils = require('../../../scripts/postpublish_utils'); +const tsConfig = require('../tsconfig.json'); const cwd = __dirname + '/..'; const S3BucketPath = 's3://staging-connect-docs-jsons/'; const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json'; const version = process.env.DOCS_VERSION; +// Include any external packages that are part of the @0xproject/connect public interface +// to this array so that TypeDoc picks it up and adds it to the Docs JSON +const fileIncludes = [...tsConfig.include]; +const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname); +const projectFiles = fileIncludesAdjusted.join(' '); -execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_DIR=' + __dirname + '/.. yarn docs:json', { +execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', { cwd, }) -.then(function(result) { - if (result.stderr !== '') { - throw new Error(result.stderr); - } - const fileName = 'v' + version + '.json'; - const s3Url = S3BucketPath + fileName; - return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', { - cwd, + .then(function(result) { + if (result.stderr !== '') { + throw new Error(result.stderr); + } + const fileName = 'v' + version + '.json'; + const s3Url = S3BucketPath + fileName; + return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', { + cwd, + }); + }) + .catch(function(err) { + console.log(err); }); -}) -.catch(function(err) { - console.log(err); -}); diff --git a/packages/0x.js/contract_templates/contract.handlebars b/packages/contract_templates/contract.handlebars index 33699b8a7..132cd60cc 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-monorepo/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..7628b057b 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 @@ -60,7 +60,7 @@ yarn lint Before running the tests, you will need to spin up a [TestRPC](https://www.npmjs.com/package/ethereumjs-testrpc) instance. -In a separate terminal, start TestRPC (a convenience command is provided as part of the [0x.js monorepo](https://github.com/0xProject/0x.js)) +In a separate terminal, start TestRPC (a convenience command is provided as part of the [0x.js monorepo](https://github.com/0xProject/0x-monorepo)) ```bash cd ../.. 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/globals.d.ts b/packages/contracts/globals.d.ts index 0e6586a4b..c6597054a 100644 --- a/packages/contracts/globals.d.ts +++ b/packages/contracts/globals.d.ts @@ -30,5 +30,6 @@ declare module 'web3-eth-abi' { declare module 'ethereumjs-abi' { const soliditySHA3: (argTypes: string[], args: any[]) => Buffer; + const soliditySHA256: (argTypes: string[], args: any[]) => Buffer; const methodID: (name: string, types: string[]) => Buffer; } diff --git a/packages/contracts/package.json b/packages/contracts/package.json index b125697ae..0d084a542 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "contracts", - "version": "2.1.13", + "version": "2.1.14", "description": "Smart contract components of 0x protocol", "main": "index.js", "directories": { @@ -9,36 +9,35 @@ }, "scripts": { "build:watch": "tsc -w", - "prebuild": "run-s clean copy_artifacts generate_contract_wrappers", + "prebuild": "run-s clean compile copy_artifacts generate_contract_wrappers", "copy_artifacts": "copyfiles './src/artifacts/**/*' ./lib", "build": "tsc", - "test": "run-s compile build run_mocha", + "test": "run-s build run_mocha", "run_mocha": "mocha 'lib/test/**/*.js' --timeout 10000 --bail --exit", "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|Arbitrage|EtherDelta|AccountLevels).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" }, "config": { - "contracts": "Exchange,DummyToken,ZRXToken,Token,WETH9,TokenTransferProxy,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,MaliciousToken,TokenRegistry" + "contracts": "Exchange,DummyToken,ZRXToken,Token,WETH9,TokenTransferProxy,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,MaliciousToken,TokenRegistry,Arbitrage,EtherDelta,AccountLevels" }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "author": "Amir Bandeali", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/contracts/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md", "devDependencies": { - "@0xproject/dev-utils": "^0.1.0", - "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", + "@0xproject/dev-utils": "^0.2.0", + "@0xproject/tslint-config": "^0.4.10", "@types/bluebird": "^3.5.3", "@types/lodash": "^4.14.86", "@types/node": "^8.0.53", @@ -46,11 +45,12 @@ "@types/yargs": "^10.0.0", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", - "chai-as-promised-typescript-typings": "^0.0.9", + "chai-as-promised-typescript-typings": "^0.0.10", "chai-bignumber": "^2.0.1", - "chai-typescript-typings": "^0.0.3", + "chai-typescript-typings": "^0.0.4", "copyfiles": "^1.2.0", "dirty-chai": "^2.0.1", + "ethers-typescript-typings": "^0.0.2", "mocha": "^4.0.1", "npm-run-all": "^4.1.2", "shx": "^0.2.2", @@ -59,19 +59,21 @@ "types-bn": "^0.0.1", "types-ethereumjs-util": "0xProject/types-ethereumjs-util", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11", + "web3-typescript-typings": "^0.10.0", "yargs": "^10.0.3" }, "dependencies": { - "0x.js": "^0.32.4", - "@0xproject/deployer": "^0.1.0", - "@0xproject/json-schemas": "^0.7.12", - "@0xproject/utils": "^0.3.4", - "@0xproject/web3-wrapper": "^0.1.14", + "0x.js": "^0.33.0", + "@0xproject/deployer": "^0.2.0", + "@0xproject/json-schemas": "^0.7.13", + "@0xproject/types": "^0.3.0", + "@0xproject/utils": "^0.4.0", + "@0xproject/web3-wrapper": "^0.2.0", "bluebird": "^3.5.0", "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/artifacts/DummyToken.json b/packages/contracts/src/artifacts/DummyToken.json deleted file mode 100644 index aee8c794f..000000000 --- a/packages/contracts/src/artifacts/DummyToken.json +++ /dev/null @@ -1,313 +0,0 @@ -{ - "contract_name": "DummyToken", - "networks": { - "50": { - "solc_version": "0.4.18", - "keccak256": "0x457cd1abe6333f2131eb9663c76a52857bc3e37606b3997b8c6683267b2049e3", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_value", - "type": "uint256" - } - ], - "name": "mint", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_target", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "setBalance", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "name": "_name", - "type": "string" - }, - { - "name": "_symbol", - "type": "string" - }, - { - "name": "_decimals", - "type": "uint256" - }, - { - "name": "_totalSupply", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "unlinked_binary": - "0x606060405234156200001057600080fd5b60405162001200380380620012008339810160405280805182019190602001805182019190602001805190602001909190805190602001909190505033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360049080519060200190620000a59291906200011a565b508260059080519060200190620000be9291906200011a565b508160068190555080600281905550806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555050505050620001c9565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200015d57805160ff19168380011785556200018e565b828001600101855582156200018e579182015b828111156200018d57825182559160200191906001019062000170565b5b5090506200019d9190620001a1565b5090565b620001c691905b80821115620001c2576000816000905550600101620001a8565b5090565b90565b61102780620001d96000396000f3006060604052600436106100c5576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100ca578063095ea7b31461015857806318160ddd146101b257806323b872dd146101db578063313ce5671461025457806370a082311461027d5780638da5cb5b146102ca57806395d89b411461031f578063a0712d68146103ad578063a9059cbb146103d0578063dd62ed3e1461042a578063e30443bc14610496578063f2fde38b146104d8575b600080fd5b34156100d557600080fd5b6100dd610511565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561011d578082015181840152602081019050610102565b50505050905090810190601f16801561014a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561016357600080fd5b610198600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105af565b604051808215151515815260200191505060405180910390f35b34156101bd57600080fd5b6101c56106a1565b6040518082815260200191505060405180910390f35b34156101e657600080fd5b61023a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a7565b604051808215151515815260200191505060405180910390f35b341561025f57600080fd5b6102676109c8565b6040518082815260200191505060405180910390f35b341561028857600080fd5b6102b4600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109ce565b6040518082815260200191505060405180910390f35b34156102d557600080fd5b6102dd610a16565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032a57600080fd5b610332610a3c565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610372578082015181840152602081019050610357565b50505050905090810190601f16801561039f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103b857600080fd5b6103ce6004808035906020019091905050610ada565b005b34156103db57600080fd5b610410600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b91565b604051808215151515815260200191505060405180910390f35b341561043557600080fd5b610480600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d71565b6040518082815260200191505060405180910390f35b34156104a157600080fd5b6104d6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610df8565b005b34156104e357600080fd5b61050f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610eed565b005b60048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105a75780601f1061057c576101008083540402835291602001916105a7565b820191906000526020600020905b81548152906001019060200180831161058a57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60025481565b600080600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101580156107775750828110155b801561080157506000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054836000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b151561080c57600080fd5b826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156109575782600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b60065481565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ad25780601f10610aa757610100808354040283529160200191610ad2565b820191906000526020600020905b815481529060010190602001808311610ab557829003601f168201915b505050505081565b68056bc75e2d631000008111151515610af257600080fd5b610b3a816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610fc4565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b8860025482610fc4565b60028190555050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610c5f57506000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b1515610c6a57600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e5657600080fd5b610e5f836109ce565b905080821015610e8957610e7e600254610e798385610fe2565b610fe2565b600281905550610ea5565b610e9e600254610e998484610fe2565b610fc4565b6002819055505b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610f4957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610fc15780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610fd857fe5b8091505092915050565b6000828211151515610ff057fe5b8183039050929150505600a165627a7a723058209c3a37463b05ebd155665b4be7d56f40b7ff1ca3a86a33391b31f468e00b48480029", - "updated_at": 1518645860123 - } - } -} diff --git a/packages/contracts/src/artifacts/Exchange.json b/packages/contracts/src/artifacts/Exchange.json deleted file mode 100644 index 724793583..000000000 --- a/packages/contracts/src/artifacts/Exchange.json +++ /dev/null @@ -1,603 +0,0 @@ -{ - "contract_name": "Exchange", - "networks": { - "50": { - "solc_version": "0.4.14", - "keccak256": "0x50d9d5de7ea3f16b7e655c3ed280d1d7ff50422b4fc42ae609422eab5028d2ca", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "numerator", - "type": "uint256" - }, - { - "name": "denominator", - "type": "uint256" - }, - { - "name": "target", - "type": "uint256" - } - ], - "name": "isRoundingError", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "filled", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "name": "cancelled", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "fillOrdersUpTo", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "cancelTakerTokenAmount", - "type": "uint256" - } - ], - "name": "cancelOrder", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ZRX_TOKEN_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmounts", - "type": "uint256[]" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "batchFillOrKillOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "fillOrKillOrder", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "getUnavailableTakerTokenAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "signer", - "type": "address" - }, - { - "name": "hash", - "type": "bytes32" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "isValidSignature", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "numerator", - "type": "uint256" - }, - { - "name": "denominator", - "type": "uint256" - }, - { - "name": "target", - "type": "uint256" - } - ], - "name": "getPartialAmount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "TOKEN_TRANSFER_PROXY_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "fillTakerTokenAmounts", - "type": "uint256[]" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8[]" - }, - { - "name": "r", - "type": "bytes32[]" - }, - { - "name": "s", - "type": "bytes32[]" - } - ], - "name": "batchFillOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5][]" - }, - { - "name": "orderValues", - "type": "uint256[6][]" - }, - { - "name": "cancelTakerTokenAmounts", - "type": "uint256[]" - } - ], - "name": "batchCancelOrders", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - }, - { - "name": "fillTakerTokenAmount", - "type": "uint256" - }, - { - "name": "shouldThrowOnInsufficientBalanceOrAllowance", - "type": "bool" - }, - { - "name": "v", - "type": "uint8" - }, - { - "name": "r", - "type": "bytes32" - }, - { - "name": "s", - "type": "bytes32" - } - ], - "name": "fillOrder", - "outputs": [ - { - "name": "filledTakerTokenAmount", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "orderAddresses", - "type": "address[5]" - }, - { - "name": "orderValues", - "type": "uint256[6]" - } - ], - "name": "getOrderHash", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "EXTERNAL_QUERY_GAS_LIMIT", - "outputs": [ - { - "name": "", - "type": "uint16" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "VERSION", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_zrxToken", - "type": "address" - }, - { - "name": "_tokenTransferProxy", - "type": "address" - } - ], - "payable": false, - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": false, - "name": "taker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "filledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "filledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidMakerFee", - "type": "uint256" - }, - { - "indexed": false, - "name": "paidTakerFee", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogFill", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "maker", - "type": "address" - }, - { - "indexed": true, - "name": "feeRecipient", - "type": "address" - }, - { - "indexed": false, - "name": "makerToken", - "type": "address" - }, - { - "indexed": false, - "name": "takerToken", - "type": "address" - }, - { - "indexed": false, - "name": "cancelledMakerTokenAmount", - "type": "uint256" - }, - { - "indexed": false, - "name": "cancelledTakerTokenAmount", - "type": "uint256" - }, - { - "indexed": true, - "name": "tokens", - "type": "bytes32" - }, - { - "indexed": false, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogCancel", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "errorId", - "type": "uint8" - }, - { - "indexed": true, - "name": "orderHash", - "type": "bytes32" - } - ], - "name": "LogError", - "type": "event" - } - ], - "unlinked_binary": - "0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a723058200855a52575ade1fd6a84adab86cbbe615f88001d9f15f37dd43f7a0a279522940029", - "updated_at": 1518645850257 - } - } -} diff --git a/packages/contracts/src/artifacts/MaliciousToken.json b/packages/contracts/src/artifacts/MaliciousToken.json deleted file mode 100644 index e32c9d20b..000000000 --- a/packages/contracts/src/artifacts/MaliciousToken.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "contract_name": "MaliciousToken", - "networks": { - "50": { - "solc_version": "0.4.18", - "keccak256": "0x91d9300198fcb37383f39ae62bafd5a92b6def37f673c23b8ec37caca5bf9c69", - "optimizer_enabled": 0, - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "unlinked_binary": - "0x60606040526001600360006101000a81548160ff021916908360ff160217905550341561002b57600080fd5b6109968061003a6000396000f300606060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b31461007d57806318160ddd146100d757806323b872dd1461010057806370a0823114610179578063a9059cbb146101c6578063dd62ed3e14610220575b600080fd5b341561008857600080fd5b6100bd600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061028c565b604051808215151515815260200191505060405180910390f35b34156100e257600080fd5b6100ea61037e565b6040518082815260200191505060405180910390f35b341561010b57600080fd5b61015f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610384565b604051808215151515815260200191505060405180910390f35b341561018457600080fd5b6101b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610677565b6040518082815260200191505060405180910390f35b34156101d157600080fd5b610206600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106c7565b604051808215151515815260200191505060405180910390f35b341561022b57600080fd5b610276600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108a7565b6040518082815260200191505060405180910390f35b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60025481565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610450575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b80156104da57506000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b15156104e557600080fd5b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b6000610681610936565b6000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561079557506000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b15156107a057600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b60006108b1610936565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6003600081819054906101000a900460ff168092919060010191906101000a81548160ff021916908360ff160217905550505600a165627a7a723058206c519d7c969de1cb1e38dc98962c65b95b935b299072476ff618a37c783e977c0029", - "updated_at": 1518645860698 - } - } -} diff --git a/packages/contracts/src/artifacts/MultiSigWallet.json b/packages/contracts/src/artifacts/MultiSigWallet.json deleted file mode 100644 index b6524e8b4..000000000 --- a/packages/contracts/src/artifacts/MultiSigWallet.json +++ /dev/null @@ -1,523 +0,0 @@ -{ - "contract_name": "MultiSigWallet", - "networks": { - "50": { - "solc_version": "0.4.10", - "keccak256": "0xccb0952f9f74bdedc4c6aa09bdad61b3f2c0b66a3aeae0be209c74472b62e9c6", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "owners", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "removeOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "revokeConfirmation", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "isOwner", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "address" - } - ], - "name": "confirmations", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "pending", - "type": "bool" - }, - { - "name": "executed", - "type": "bool" - } - ], - "name": "getTransactionCount", - "outputs": [ - { - "name": "count", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "addOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "isConfirmed", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "getConfirmationCount", - "outputs": [ - { - "name": "count", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "transactions", - "outputs": [ - { - "name": "destination", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - }, - { - "name": "executed", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getOwners", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "from", - "type": "uint256" - }, - { - "name": "to", - "type": "uint256" - }, - { - "name": "pending", - "type": "bool" - }, - { - "name": "executed", - "type": "bool" - } - ], - "name": "getTransactionIds", - "outputs": [ - { - "name": "_transactionIds", - "type": "uint256[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "getConfirmations", - "outputs": [ - { - "name": "_confirmations", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "transactionCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_required", - "type": "uint256" - } - ], - "name": "changeRequirement", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "confirmTransaction", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "destination", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "submitTransaction", - "outputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_OWNER_COUNT", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "required", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "newOwner", - "type": "address" - } - ], - "name": "replaceOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "executeTransaction", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_owners", - "type": "address[]" - }, - { - "name": "_required", - "type": "uint256" - } - ], - "payable": false, - "type": "constructor" - }, - { - "payable": true, - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Confirmation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Revocation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Submission", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Execution", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "ExecutionFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - } - ], - "name": "OwnerAddition", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - } - ], - "name": "OwnerRemoval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "required", - "type": "uint256" - } - ], - "name": "RequirementChange", - "type": "event" - } - ], - "unlinked_binary": - "0x606060405234156200000d57fe5b604051620022e9380380620022e9833981016040528080518201919060200180519060200190919050505b600082518260328211806200004c57508181115b80620000585750600081145b80620000645750600082145b15620000705760006000fd5b600092505b8451831015620001a9576002600086858151811015156200009257fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16806200011e575060008584815181101515620000fc57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16145b156200012a5760006000fd5b60016002600087868151811015156200013f57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b828060010193505062000075565b8460039080519060200190620001c1929190620001d6565b50836004819055505b5b5050505050620002ab565b82805482825590600052602060002090810192821562000252579160200282015b82811115620002515782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190620001f7565b5b50905062000261919062000265565b5090565b620002a891905b80821115620002a457600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506001016200026c565b5090565b90565b61202e80620002bb6000396000f3006060604052361561011b576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c271461017c578063173825d9146101dc57806320ea8d86146102125780632f54bf6e146102325780633411c81c1461028057806354741525146102d75780637065cb4814610318578063784547a71461034e5780638b51d13f146103865780639ace38c2146103ba578063a0e67e2b146104b5578063a8abe69a1461052a578063b5dc40c3146105cc578063b77bf6001461064f578063ba51a6df14610675578063c01a8c8414610695578063c6427474146106b5578063d74f8edd1461074b578063dc8452cd14610771578063e20056e614610797578063ee22610b146107ec575b61017a5b6000341115610177573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b565b005b341561018457fe5b61019a600480803590602001909190505061080c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101e457fe5b610210600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061084c565b005b341561021a57fe5b6102306004808035906020019091905050610af4565b005b341561023a57fe5b610266600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610ca5565b604051808215151515815260200191505060405180910390f35b341561028857fe5b6102bd600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610cc5565b604051808215151515815260200191505060405180910390f35b34156102df57fe5b610302600480803515159060200190919080351515906020019091905050610cf4565b6040518082815260200191505060405180910390f35b341561032057fe5b61034c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d8b565b005b341561035657fe5b61036c6004808035906020019091905050610f8e565b604051808215151515815260200191505060405180910390f35b341561038e57fe5b6103a46004808035906020019091905050611078565b6040518082815260200191505060405180910390f35b34156103c257fe5b6103d86004808035906020019091905050611148565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001831515151581526020018281038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156104a35780601f10610478576101008083540402835291602001916104a3565b820191906000526020600020905b81548152906001019060200180831161048657829003601f168201915b50509550505050505060405180910390f35b34156104bd57fe5b6104c56111a4565b6040518080602001828103825283818151815260200191508051906020019060200280838360008314610517575b805182526020831115610517576020820191506020810190506020830392506104f3565b5050509050019250505060405180910390f35b341561053257fe5b610567600480803590602001909190803590602001909190803515159060200190919080351515906020019091905050611239565b60405180806020018281038252838181518152602001915080519060200190602002808383600083146105b9575b8051825260208311156105b957602082019150602081019050602083039250610595565b5050509050019250505060405180910390f35b34156105d457fe5b6105ea600480803590602001909190505061139d565b604051808060200182810382528381815181526020019150805190602001906020028083836000831461063c575b80518252602083111561063c57602082019150602081019050602083039250610618565b5050509050019250505060405180910390f35b341561065757fe5b61065f6115cf565b6040518082815260200191505060405180910390f35b341561067d57fe5b61069360048080359060200190919050506115d5565b005b341561069d57fe5b6106b3600480803590602001909190505061168c565b005b34156106bd57fe5b610735600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611871565b6040518082815260200191505060405180910390f35b341561075357fe5b61075b611891565b6040518082815260200191505060405180910390f35b341561077957fe5b610781611896565b6040518082815260200191505060405180910390f35b341561079f57fe5b6107ea600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061189c565b005b34156107f457fe5b61080a6004808035906020019091905050611bc1565b005b60038181548110151561081b57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156108895760006000fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156108e35760006000fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610a6f578273ffffffffffffffffffffffffffffffffffffffff1660038381548110151561097657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610a615760036001600380549050038154811015156109d657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a1257fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a6f565b5b8180600101925050610940565b6001600381818054905003915081610a879190611edd565b506003805490506004541115610aa657610aa56003805490506115d5565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405180905060405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610b4e5760006000fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610bba5760006000fd5b836000600082815260200190815260200160002060030160009054906101000a900460ff1615610bea5760006000fd5b60006001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405180905060405180910390a35b5b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60006000600090505b600554811015610d8357838015610d3557506000600082815260200190815260200160002060030160009054906101000a900460ff16155b80610d695750828015610d6857506000600082815260200190815260200160002060030160009054906101000a900460ff165b5b15610d75576001820191505b5b8080600101915050610cfd565b5b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dc65760006000fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610e1f5760006000fd5b8160008173ffffffffffffffffffffffffffffffffffffffff161415610e455760006000fd5b6001600380549050016004546032821180610e5f57508181115b80610e6a5750600081145b80610e755750600082145b15610e805760006000fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038054806001018281610eec9190611f09565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405180905060405180910390a25b5b50505b505b505b50565b60006000600060009150600090505b60038054905081101561107057600160008581526020019081526020016000206000600383815481101515610fce57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561104f576001820191505b6004548214156110625760019250611071565b5b8080600101915050610f9d565b5b5050919050565b60006000600090505b600380549050811015611141576001600084815260200190815260200160002060006003838154811015156110b257fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611133576001820191505b5b8080600101915050611081565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6111ac611f35565b600380548060200260200160405190810160405280929190818152602001828054801561122e57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116111e4575b505050505090505b90565b611241611f49565b611249611f49565b6000600060055460405180591061125d5750595b908082528060200260200182016040525b50925060009150600090505b60055481101561131d578580156112b257506000600082815260200190815260200160002060030160009054906101000a900460ff16155b806112e657508480156112e557506000600082815260200190815260200160002060030160009054906101000a900460ff165b5b1561130f578083838151811015156112fa57fe5b90602001906020020181815250506001820191505b5b808060010191505061127a565b87870360405180591061132d5750595b908082528060200260200182016040525b5093508790505b8681101561139157828181518110151561135b57fe5b906020019060200201518489830381518110151561137557fe5b90602001906020020181815250505b8080600101915050611345565b5b505050949350505050565b6113a5611f35565b6113ad611f35565b600060006003805490506040518059106113c45750595b908082528060200260200182016040525b50925060009150600090505b6003805490508110156115275760016000868152602001908152602001600020600060038381548110151561141257fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156115195760038181548110151561149b57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683838151811015156114d657fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b80806001019150506113e1565b816040518059106115355750595b908082528060200260200182016040525b509350600090505b818110156115c657828181518110151561156457fe5b90602001906020020151848281518110151561157c57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b808060010191505061154e565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116105760006000fd5b60038054905081603282118061162557508181115b806116305750600081145b8061163b5750600082145b156116465760006000fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156116e65760006000fd5b8160006000600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156117425760006000fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117ad5760006000fd5b60016001600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550843373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405180905060405180910390a361186685611bc1565b5b5b50505b505b5050565b600061187e848484611d86565b90506118898161168c565b5b9392505050565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156118d95760006000fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156119335760006000fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561198c5760006000fd5b600092505b600380549050831015611a7a578473ffffffffffffffffffffffffffffffffffffffff166003848154811015156119c457fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611a6c5783600384815481101515611a1d57fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611a7a565b5b8280600101935050611991565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405180905060405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405180905060405180910390a25b5b505b505b505050565b6000816000600082815260200190815260200160002060030160009054906101000a900460ff1615611bf35760006000fd5b611bfc83610f8e565b15611d7f5760006000848152602001908152602001600020915060018260030160006101000a81548160ff0219169083151502179055508160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260010154836002016040518082805460018160011615610100020316600290048015611cdc5780601f10611cb157610100808354040283529160200191611cdc565b820191906000526020600020905b815481529060010190602001808311611cbf57829003601f168201915b505091505060006040518083038185876185025a03f19250505015611d3057827f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405180905060405180910390a2611d7e565b827f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405180905060405180910390a260008260030160006101000a81548160ff0219169083151502179055505b5b5b5b505050565b60008360008173ffffffffffffffffffffffffffffffffffffffff161415611dae5760006000fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001600015158152506000600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002019080519060200190611e6e929190611f5d565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405180905060405180910390a25b5b509392505050565b815481835581811511611f0457818360005260206000209182019101611f039190611fdd565b5b505050565b815481835581811511611f3057818360005260206000209182019101611f2f9190611fdd565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611f9e57805160ff1916838001178555611fcc565b82800160010185558215611fcc579182015b82811115611fcb578251825591602001919060010190611fb0565b5b509050611fd99190611fdd565b5090565b611fff91905b80821115611ffb576000816000905550600101611fe3565b5090565b905600a165627a7a723058200a8e23793500b02c6ba5fd192656d8e75bd9e4479e5c539e0b34d50459bf3e560029", - "updated_at": 1518648330317 - } - } -} diff --git a/packages/contracts/src/artifacts/MultiSigWalletWithTimeLock.json b/packages/contracts/src/artifacts/MultiSigWalletWithTimeLock.json deleted file mode 100644 index c340ec1f1..000000000 --- a/packages/contracts/src/artifacts/MultiSigWalletWithTimeLock.json +++ /dev/null @@ -1,600 +0,0 @@ -{ - "contract_name": "MultiSigWalletWithTimeLock", - "networks": { - "50": { - "solc_version": "0.4.10", - "keccak256": "0x73f2aeb4c300248f7c2c851b085e41525007202decc34831880688f1aee6e126", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "owners", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "removeOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "revokeConfirmation", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "isOwner", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "address" - } - ], - "name": "confirmations", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "secondsTimeLocked", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "pending", - "type": "bool" - }, - { - "name": "executed", - "type": "bool" - } - ], - "name": "getTransactionCount", - "outputs": [ - { - "name": "count", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "addOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "isConfirmed", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_secondsTimeLocked", - "type": "uint256" - } - ], - "name": "changeTimeLock", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "getConfirmationCount", - "outputs": [ - { - "name": "count", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "transactions", - "outputs": [ - { - "name": "destination", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - }, - { - "name": "executed", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getOwners", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "from", - "type": "uint256" - }, - { - "name": "to", - "type": "uint256" - }, - { - "name": "pending", - "type": "bool" - }, - { - "name": "executed", - "type": "bool" - } - ], - "name": "getTransactionIds", - "outputs": [ - { - "name": "_transactionIds", - "type": "uint256[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "getConfirmations", - "outputs": [ - { - "name": "_confirmations", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "transactionCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_required", - "type": "uint256" - } - ], - "name": "changeRequirement", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "confirmTransaction", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "destination", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "submitTransaction", - "outputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "confirmationTimes", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_OWNER_COUNT", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "required", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "newOwner", - "type": "address" - } - ], - "name": "replaceOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "executeTransaction", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_owners", - "type": "address[]" - }, - { - "name": "_required", - "type": "uint256" - }, - { - "name": "_secondsTimeLocked", - "type": "uint256" - } - ], - "payable": false, - "type": "constructor" - }, - { - "payable": true, - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - }, - { - "indexed": false, - "name": "confirmationTime", - "type": "uint256" - } - ], - "name": "ConfirmationTimeSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "secondsTimeLocked", - "type": "uint256" - } - ], - "name": "TimeLockChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Confirmation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Revocation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Submission", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Execution", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "ExecutionFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - } - ], - "name": "OwnerAddition", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - } - ], - "name": "OwnerRemoval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "required", - "type": "uint256" - } - ], - "name": "RequirementChange", - "type": "event" - } - ], - "unlinked_binary": - "0x606060405234156200000d57fe5b6040516200250138038062002501833981016040528080518201919060200180519060200190919080519060200190919050505b82825b600082518260328211806200005857508181115b80620000645750600081145b80620000705750600082145b156200007c5760006000fd5b600092505b8451831015620001b5576002600086858151811015156200009e57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16806200012a5750600085848151811015156200010857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16145b15620001365760006000fd5b60016002600087868151811015156200014b57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b828060010193505062000081565b8460039080519060200190620001cd929190620001ed565b50836004819055505b5b5050505050806006819055505b505050620002c2565b82805482825590600052602060002090810192821562000269579160200282015b82811115620002685782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550916020019190600101906200020e565b5b5090506200027891906200027c565b5090565b620002bf91905b80821115620002bb57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555060010162000283565b5090565b90565b61222f80620002d26000396000f3006060604052361561013c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c271461019d578063173825d9146101fd57806320ea8d86146102335780632f54bf6e146102535780633411c81c146102a157806337bd78a0146102f8578063547415251461031e5780637065cb481461035f578063784547a7146103955780637ad28c51146103cd5780638b51d13f146103ed5780639ace38c214610421578063a0e67e2b1461051c578063a8abe69a14610591578063b5dc40c314610633578063b77bf600146106b6578063ba51a6df146106dc578063c01a8c84146106fc578063c64274741461071c578063d38f2d82146107b2578063d74f8edd146107e6578063dc8452cd1461080c578063e20056e614610832578063ee22610b14610887575b61019b5b6000341115610198573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b565b005b34156101a557fe5b6101bb60048080359060200190919050506108a7565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561020557fe5b610231600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108e7565b005b341561023b57fe5b6102516004808035906020019091905050610b8f565b005b341561025b57fe5b610287600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d59565b604051808215151515815260200191505060405180910390f35b34156102a957fe5b6102de600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d79565b604051808215151515815260200191505060405180910390f35b341561030057fe5b610308610da8565b6040518082815260200191505060405180910390f35b341561032657fe5b610349600480803515159060200190919080351515906020019091905050610dae565b6040518082815260200191505060405180910390f35b341561036757fe5b610393600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e45565b005b341561039d57fe5b6103b36004808035906020019091905050611048565b604051808215151515815260200191505060405180910390f35b34156103d557fe5b6103eb6004808035906020019091905050611132565b005b34156103f557fe5b61040b60048080359060200190919050506111b0565b6040518082815260200191505060405180910390f35b341561042957fe5b61043f6004808035906020019091905050611280565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018315151515815260200182810382528481815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561050a5780601f106104df5761010080835404028352916020019161050a565b820191906000526020600020905b8154815290600101906020018083116104ed57829003601f168201915b50509550505050505060405180910390f35b341561052457fe5b61052c6112dc565b604051808060200182810382528381815181526020019150805190602001906020028083836000831461057e575b80518252602083111561057e5760208201915060208101905060208303925061055a565b5050509050019250505060405180910390f35b341561059957fe5b6105ce600480803590602001909190803590602001909190803515159060200190919080351515906020019091905050611371565b6040518080602001828103825283818151815260200191508051906020019060200280838360008314610620575b805182526020831115610620576020820191506020810190506020830392506105fc565b5050509050019250505060405180910390f35b341561063b57fe5b61065160048080359060200190919050506114d5565b60405180806020018281038252838181518152602001915080519060200190602002808383600083146106a3575b8051825260208311156106a35760208201915060208101905060208303925061067f565b5050509050019250505060405180910390f35b34156106be57fe5b6106c6611707565b6040518082815260200191505060405180910390f35b34156106e457fe5b6106fa600480803590602001909190505061170d565b005b341561070457fe5b61071a60048080359060200190919050506117c4565b005b341561072457fe5b61079c600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506119d2565b6040518082815260200191505060405180910390f35b34156107ba57fe5b6107d060048080359060200190919050506119f2565b6040518082815260200191505060405180910390f35b34156107ee57fe5b6107f6611a0a565b6040518082815260200191505060405180910390f35b341561081457fe5b61081c611a0f565b6040518082815260200191505060405180910390f35b341561083a57fe5b610885600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611a15565b005b341561088f57fe5b6108a56004808035906020019091905050611d3a565b005b6003818154811015156108b657fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109245760006000fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561097e5760006000fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610b0a578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610a1157fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610afc576003600160038054905003815481101515610a7157fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610aad57fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610b0a565b5b81806001019250506109db565b6001600381818054905003915081610b2291906120de565b506003805490506004541115610b4157610b4060038054905061170d565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405180905060405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610be95760006000fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610c555760006000fd5b836000600082815260200190815260200160002060030160009054906101000a900460ff1615610c855760006000fd5b84610c8f81611048565b151515610c9c5760006000fd5b60006001600088815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550853373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405180905060405180910390a35b5b505b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60065481565b60006000600090505b600554811015610e3d57838015610def57506000600082815260200190815260200160002060030160009054906101000a900460ff16155b80610e235750828015610e2257506000600082815260200190815260200160002060030160009054906101000a900460ff165b5b15610e2f576001820191505b5b8080600101915050610db7565b5b5092915050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610e805760006000fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610ed95760006000fd5b8160008173ffffffffffffffffffffffffffffffffffffffff161415610eff5760006000fd5b6001600380549050016004546032821180610f1957508181115b80610f245750600081145b80610f2f5750600082145b15610f3a5760006000fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060038054806001018281610fa6919061210a565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405180905060405180910390a25b5b50505b505b505b50565b60006000600060009150600090505b60038054905081101561112a5760016000858152602001908152602001600020600060038381548110151561108857fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611109576001820191505b60045482141561111c576001925061112b565b5b8080600101915050611057565b5b5050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561116d5760006000fd5b806006819055507fd1c9101a34feff75cccef14a28785a0279cb0b49c1f321f21f5f422e746b4377816040518082815260200191505060405180910390a15b5b50565b60006000600090505b600380549050811015611279576001600084815260200190815260200160002060006003838154811015156111ea57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561126b576001820191505b5b80806001019150506111b9565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6112e4612136565b600380548060200260200160405190810160405280929190818152602001828054801561136657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161131c575b505050505090505b90565b61137961214a565b61138161214a565b600060006005546040518059106113955750595b908082528060200260200182016040525b50925060009150600090505b600554811015611455578580156113ea57506000600082815260200190815260200160002060030160009054906101000a900460ff16155b8061141e575084801561141d57506000600082815260200190815260200160002060030160009054906101000a900460ff165b5b156114475780838381518110151561143257fe5b90602001906020020181815250506001820191505b5b80806001019150506113b2565b8787036040518059106114655750595b908082528060200260200182016040525b5093508790505b868110156114c957828181518110151561149357fe5b90602001906020020151848983038151811015156114ad57fe5b90602001906020020181815250505b808060010191505061147d565b5b505050949350505050565b6114dd612136565b6114e5612136565b600060006003805490506040518059106114fc5750595b908082528060200260200182016040525b50925060009150600090505b60038054905081101561165f5760016000868152602001908152602001600020600060038381548110151561154a57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611651576003818154811015156115d357fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16838381518110151561160e57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b8080600101915050611519565b8160405180591061166d5750595b908082528060200260200182016040525b509350600090505b818110156116fe57828181518110151561169c57fe5b9060200190602002015184828151811015156116b457fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8080600101915050611686565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156117485760006000fd5b60038054905081603282118061175d57508181115b806117685750600081145b806117735750600082145b1561177e5760006000fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561181e5760006000fd5b8160006000600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561187a5760006000fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156118e55760006000fd5b846118ef81611048565b1515156118fc5760006000fd5b60016001600088815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550853373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405180905060405180910390a36119b586611048565b156119c5576119c48642611f32565b5b5b5b505b50505b505b5050565b60006119df848484611f87565b90506119ea816117c4565b5b9392505050565b60076020528060005260406000206000915090505481565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a525760006000fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611aac5760006000fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611b055760006000fd5b600092505b600380549050831015611bf3578473ffffffffffffffffffffffffffffffffffffffff16600384815481101515611b3d57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611be55783600384815481101515611b9657fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611bf3565b5b8280600101935050611b0a565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405180905060405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405180905060405180910390a25b5b505b505b505050565b6000816000600082815260200190815260200160002060030160009054906101000a900460ff1615611d6c5760006000fd5b82611d7681611048565b1515611d825760006000fd5b836006546007600083815260200190815260200160002054014210151515611daa5760006000fd5b60006000868152602001908152602001600020935060018460030160006101000a81548160ff0219169083151502179055508360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168460010154856002016040518082805460018160011615610100020316600290048015611e855780601f10611e5a57610100808354040283529160200191611e85565b820191906000526020600020905b815481529060010190602001808311611e6857829003601f168201915b505091505060006040518083038185876185025a03f19250505015611ed957847f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405180905060405180910390a2611f27565b847f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405180905060405180910390a260008460030160006101000a81548160ff0219169083151502179055505b5b5b505b505b505050565b806007600084815260200190815260200160002081905550817f0b237afe65f1514fd7ea3f923ea4fe792bdd07000a912b6cd1602a8e7f573c8d826040518082815260200191505060405180910390a25b5050565b60008360008173ffffffffffffffffffffffffffffffffffffffff161415611faf5760006000fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001600015158152506000600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010155604082015181600201908051906020019061206f92919061215e565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405180905060405180910390a25b5b509392505050565b8154818355818115116121055781836000526020600020918201910161210491906121de565b5b505050565b8154818355818115116121315781836000526020600020918201910161213091906121de565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061219f57805160ff19168380011785556121cd565b828001600101855582156121cd579182015b828111156121cc5782518255916020019190600101906121b1565b5b5090506121da91906121de565b5090565b61220091905b808211156121fc5760008160009055506001016121e4565b5090565b905600a165627a7a7230582038efb3dddde115c814a22908eeab5e492de8fc546bd0b86b0d1c01cde609b9640029", - "updated_at": 1518645841445 - } - } -} diff --git a/packages/contracts/src/artifacts/MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.json b/packages/contracts/src/artifacts/MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.json deleted file mode 100644 index 015efc95c..000000000 --- a/packages/contracts/src/artifacts/MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.json +++ /dev/null @@ -1,648 +0,0 @@ -{ - "contract_name": "MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress", - "networks": { - "50": { - "solc_version": "0.4.10", - "keccak256": "0xda08395db72af1130287a88849e0cf0c895eb7c98e41483df3a4d457ca832910", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "owners", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "removeOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "revokeConfirmation", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "isOwner", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - }, - { - "name": "", - "type": "address" - } - ], - "name": "confirmations", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "secondsTimeLocked", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "pending", - "type": "bool" - }, - { - "name": "executed", - "type": "bool" - } - ], - "name": "getTransactionCount", - "outputs": [ - { - "name": "count", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "data", - "type": "bytes" - } - ], - "name": "isFunctionRemoveAuthorizedAddress", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "executeRemoveAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - } - ], - "name": "addOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "isConfirmed", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_secondsTimeLocked", - "type": "uint256" - } - ], - "name": "changeTimeLock", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "getConfirmationCount", - "outputs": [ - { - "name": "count", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "transactions", - "outputs": [ - { - "name": "destination", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - }, - { - "name": "executed", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getOwners", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "from", - "type": "uint256" - }, - { - "name": "to", - "type": "uint256" - }, - { - "name": "pending", - "type": "bool" - }, - { - "name": "executed", - "type": "bool" - } - ], - "name": "getTransactionIds", - "outputs": [ - { - "name": "_transactionIds", - "type": "uint256[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "TOKEN_TRANSFER_PROXY_CONTRACT", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "getConfirmations", - "outputs": [ - { - "name": "_confirmations", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "transactionCount", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_required", - "type": "uint256" - } - ], - "name": "changeRequirement", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "confirmTransaction", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "destination", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - }, - { - "name": "data", - "type": "bytes" - } - ], - "name": "submitTransaction", - "outputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "confirmationTimes", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_OWNER_COUNT", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "required", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "owner", - "type": "address" - }, - { - "name": "newOwner", - "type": "address" - } - ], - "name": "replaceOwner", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "transactionId", - "type": "uint256" - } - ], - "name": "executeTransaction", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_owners", - "type": "address[]" - }, - { - "name": "_required", - "type": "uint256" - }, - { - "name": "_secondsTimeLocked", - "type": "uint256" - }, - { - "name": "_tokenTransferProxy", - "type": "address" - } - ], - "payable": false, - "type": "constructor" - }, - { - "payable": true, - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - }, - { - "indexed": false, - "name": "confirmationTime", - "type": "uint256" - } - ], - "name": "ConfirmationTimeSet", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "secondsTimeLocked", - "type": "uint256" - } - ], - "name": "TimeLockChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Confirmation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Revocation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Submission", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "Execution", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "transactionId", - "type": "uint256" - } - ], - "name": "ExecutionFailure", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "name": "value", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - } - ], - "name": "OwnerAddition", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "owner", - "type": "address" - } - ], - "name": "OwnerRemoval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "name": "required", - "type": "uint256" - } - ], - "name": "RequirementChange", - "type": "event" - } - ], - "unlinked_binary": - "0x606060405234156200000d57fe5b60405162002adb38038062002adb833981016040528080518201919060200180519060200190919080519060200190919080519060200190919050505b8383835b82825b600082518260328211806200006557508181115b80620000715750600081145b806200007d5750600082145b15620000895760006000fd5b600092505b8451831015620001c257600260008685815181101515620000ab57fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680620001375750600085848151811015156200011557fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff16145b15620001435760006000fd5b60016002600087868151811015156200015857fe5b9060200190602002015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505b82806001019350506200008e565b8460039080519060200190620001da92919062000240565b50836004819055505b5b5050505050806006819055505b50505080600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050505062000315565b828054828255906000526020600020908101928215620002bc579160200282015b82811115620002bb5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019062000261565b5b509050620002cb9190620002cf565b5090565b6200031291905b808211156200030e57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101620002d6565b5090565b90565b6127b680620003256000396000f3006060604052361561015d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063025e7c27146101be578063173825d91461021e57806320ea8d86146102545780632f54bf6e146102745780633411c81c146102c257806337bd78a014610319578063547415251461033f578063553a48fd146103805780635711b311146103f25780637065cb4814610412578063784547a7146104485780637ad28c51146104805780638b51d13f146104a05780639ace38c2146104d4578063a0e67e2b146105cf578063a8abe69a14610644578063add1cbc5146106e6578063b5dc40c314610738578063b77bf600146107bb578063ba51a6df146107e1578063c01a8c8414610801578063c642747414610821578063d38f2d82146108b7578063d74f8edd146108eb578063dc8452cd14610911578063e20056e614610937578063ee22610b1461098c575b6101bc5b60003411156101b9573373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a25b5b565b005b34156101c657fe5b6101dc60048080359060200190919050506109ac565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022657fe5b610252600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506109ec565b005b341561025c57fe5b6102726004808035906020019091905050610c94565b005b341561027c57fe5b6102a8600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e5e565b604051808215151515815260200191505060405180910390f35b34156102ca57fe5b6102ff600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e7e565b604051808215151515815260200191505060405180910390f35b341561032157fe5b610329610ead565b6040518082815260200191505060405180910390f35b341561034757fe5b61036a600480803515159060200190919080351515906020019091905050610eb3565b6040518082815260200191505060405180910390f35b341561038857fe5b6103d8600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610f4a565b604051808215151515815260200191505060405180910390f35b34156103fa57fe5b610410600480803590602001909190505061108b565b005b341561041a57fe5b610446600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506113a6565b005b341561045057fe5b61046660048080359060200190919050506115a9565b604051808215151515815260200191505060405180910390f35b341561048857fe5b61049e6004808035906020019091905050611693565b005b34156104a857fe5b6104be6004808035906020019091905050611711565b6040518082815260200191505060405180910390f35b34156104dc57fe5b6104f260048080359060200190919050506117e1565b604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200180602001831515151581526020018281038252848181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156105bd5780601f10610592576101008083540402835291602001916105bd565b820191906000526020600020905b8154815290600101906020018083116105a057829003601f168201915b50509550505050505060405180910390f35b34156105d757fe5b6105df61183d565b6040518080602001828103825283818151815260200191508051906020019060200280838360008314610631575b8051825260208311156106315760208201915060208101905060208303925061060d565b5050509050019250505060405180910390f35b341561064c57fe5b6106816004808035906020019091908035906020019091908035151590602001909190803515159060200190919050506118d2565b60405180806020018281038252838181518152602001915080519060200190602002808383600083146106d3575b8051825260208311156106d3576020820191506020810190506020830392506106af565b5050509050019250505060405180910390f35b34156106ee57fe5b6106f6611a36565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561074057fe5b6107566004808035906020019091905050611a5c565b60405180806020018281038252838181518152602001915080519060200190602002808383600083146107a8575b8051825260208311156107a857602082019150602081019050602083039250610784565b5050509050019250505060405180910390f35b34156107c357fe5b6107cb611c8e565b6040518082815260200191505060405180910390f35b34156107e957fe5b6107ff6004808035906020019091905050611c94565b005b341561080957fe5b61081f6004808035906020019091905050611d4b565b005b341561082957fe5b6108a1600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611f59565b6040518082815260200191505060405180910390f35b34156108bf57fe5b6108d56004808035906020019091905050611f79565b6040518082815260200191505060405180910390f35b34156108f357fe5b6108fb611f91565b6040518082815260200191505060405180910390f35b341561091957fe5b610921611f96565b6040518082815260200191505060405180910390f35b341561093f57fe5b61098a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611f9c565b005b341561099457fe5b6109aa60048080359060200190919050506122c1565b005b6003818154811015156109bb57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a295760006000fd5b81600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610a835760006000fd5b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600091505b600160038054905003821015610c0f578273ffffffffffffffffffffffffffffffffffffffff16600383815481101515610b1657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610c01576003600160038054905003815481101515610b7657fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600383815481101515610bb257fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610c0f565b5b8180600101925050610ae0565b6001600381818054905003915081610c279190612665565b506003805490506004541115610c4657610c45600380549050611c94565b5b8273ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405180905060405180910390a25b5b505b5050565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610cee5760006000fd5b81336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515610d5a5760006000fd5b836000600082815260200190815260200160002060030160009054906101000a900460ff1615610d8a5760006000fd5b84610d94816115a9565b151515610da15760006000fd5b60006001600088815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550853373ffffffffffffffffffffffffffffffffffffffff167ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e960405180905060405180910390a35b5b505b505b50505b5050565b60026020528060005260406000206000915054906101000a900460ff1681565b60016020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b60065481565b60006000600090505b600554811015610f4257838015610ef457506000600082815260200190815260200160002060030160009054906101000a900460ff16155b80610f285750828015610f2757506000600082815260200190815260200160002060030160009054906101000a900460ff165b5b15610f34576001820191505b5b8080600101915050610ebc565b5b5092915050565b60006000600060405180807f72656d6f7665417574686f72697a656441646472657373286164647265737329815250602001905060405180910390209150600090505b600481101561107f578181600481101515610fa457fe5b1a7f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168482815181101515610ff757fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415156110715760006000fd5b5b8080600101915050610f8d565b600192505b5050919050565b6000816000600082815260200190815260200160002060030160009054906101000a900460ff16156110bd5760006000fd5b826110c7816115a9565b15156110d35760006000fd5b836000600060008381526020019081526020016000209050600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561116c5760006000fd5b611211816002018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156112075780601f106111dc57610100808354040283529160200191611207565b820191906000526020600020905b8154815290600101906020018083116111ea57829003601f168201915b5050505050610f4a565b151561121d5760006000fd5b60006000878152602001908152602001600020945060018560030160006101000a81548160ff0219169083151502179055508460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1685600101548660020160405180828054600181600116156101000203166002900480156112f85780601f106112cd576101008083540402835291602001916112f8565b820191906000526020600020905b8154815290600101906020018083116112db57829003601f168201915b505091505060006040518083038185876185025a03f1925050501561134c57857f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405180905060405180910390a261139a565b857f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405180905060405180910390a260008560030160006101000a81548160ff0219169083151502179055505b5b5b50505b505b505050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e15760006000fd5b80600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561143a5760006000fd5b8160008173ffffffffffffffffffffffffffffffffffffffff1614156114605760006000fd5b600160038054905001600454603282118061147a57508181115b806114855750600081145b806114905750600082145b1561149b5760006000fd5b6001600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600380548060010182816115079190612691565b916000526020600020900160005b87909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550508473ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405180905060405180910390a25b5b50505b505b505b50565b60006000600060009150600090505b60038054905081101561168b576001600085815260200190815260200160002060006003838154811015156115e957fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561166a576001820191505b60045482141561167d576001925061168c565b5b80806001019150506115b8565b5b5050919050565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156116ce5760006000fd5b806006819055507fd1c9101a34feff75cccef14a28785a0279cb0b49c1f321f21f5f422e746b4377816040518082815260200191505060405180910390a15b5b50565b60006000600090505b6003805490508110156117da5760016000848152602001908152602001600020600060038381548110151561174b57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156117cc576001820191505b5b808060010191505061171a565b5b50919050565b60006020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169080600101549080600201908060030160009054906101000a900460ff16905084565b6118456126bd565b60038054806020026020016040519081016040528092919081815260200182805480156118c757602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001906001019080831161187d575b505050505090505b90565b6118da6126d1565b6118e26126d1565b600060006005546040518059106118f65750595b908082528060200260200182016040525b50925060009150600090505b6005548110156119b65785801561194b57506000600082815260200190815260200160002060030160009054906101000a900460ff16155b8061197f575084801561197e57506000600082815260200190815260200160002060030160009054906101000a900460ff165b5b156119a85780838381518110151561199357fe5b90602001906020020181815250506001820191505b5b8080600101915050611913565b8787036040518059106119c65750595b908082528060200260200182016040525b5093508790505b86811015611a2a5782818151811015156119f457fe5b9060200190602002015184898303815181101515611a0e57fe5b90602001906020020181815250505b80806001019150506119de565b5b505050949350505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b611a646126bd565b611a6c6126bd565b60006000600380549050604051805910611a835750595b908082528060200260200182016040525b50925060009150600090505b600380549050811015611be657600160008681526020019081526020016000206000600383815481101515611ad157fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611bd857600381815481101515611b5a57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168383815181101515611b9557fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001820191505b5b8080600101915050611aa0565b81604051805910611bf45750595b908082528060200260200182016040525b509350600090505b81811015611c85578281815181101515611c2357fe5b906020019060200201518482815181101515611c3b57fe5b9060200190602002019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250505b8080600101915050611c0d565b5b505050919050565b60055481565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611ccf5760006000fd5b600380549050816032821180611ce457508181115b80611cef5750600081145b80611cfa5750600082145b15611d055760006000fd5b826004819055507fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a836040518082815260200191505060405180910390a15b5b50505b50565b33600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515611da55760006000fd5b8160006000600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415611e015760006000fd5b82336001600083815260200190815260200160002060008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e6c5760006000fd5b84611e76816115a9565b151515611e835760006000fd5b60016001600088815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550853373ffffffffffffffffffffffffffffffffffffffff167f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef60405180905060405180910390a3611f3c866115a9565b15611f4c57611f4b86426124b9565b5b5b5b505b50505b505b5050565b6000611f6684848461250e565b9050611f7181611d4b565b5b9392505050565b60076020528060005260406000206000915090505481565b603281565b60045481565b60003073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611fd95760006000fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156120335760006000fd5b82600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561208c5760006000fd5b600092505b60038054905083101561217a578473ffffffffffffffffffffffffffffffffffffffff166003848154811015156120c457fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561216c578360038481548110151561211d57fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061217a565b5b8280600101935050612091565b6000600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508473ffffffffffffffffffffffffffffffffffffffff167f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9060405180905060405180910390a28373ffffffffffffffffffffffffffffffffffffffff167ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d60405180905060405180910390a25b5b505b505b505050565b6000816000600082815260200190815260200160002060030160009054906101000a900460ff16156122f35760006000fd5b826122fd816115a9565b15156123095760006000fd5b8360065460076000838152602001908152602001600020540142101515156123315760006000fd5b60006000868152602001908152602001600020935060018460030160006101000a81548160ff0219169083151502179055508360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16846001015485600201604051808280546001816001161561010002031660029004801561240c5780601f106123e15761010080835404028352916020019161240c565b820191906000526020600020905b8154815290600101906020018083116123ef57829003601f168201915b505091505060006040518083038185876185025a03f1925050501561246057847f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7560405180905060405180910390a26124ae565b847f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923660405180905060405180910390a260008460030160006101000a81548160ff0219169083151502179055505b5b5b505b505b505050565b806007600084815260200190815260200160002081905550817f0b237afe65f1514fd7ea3f923ea4fe792bdd07000a912b6cd1602a8e7f573c8d826040518082815260200191505060405180910390a25b5050565b60008360008173ffffffffffffffffffffffffffffffffffffffff1614156125365760006000fd5b60055491506080604051908101604052808673ffffffffffffffffffffffffffffffffffffffff168152602001858152602001848152602001600015158152506000600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020190805190602001906125f69291906126e5565b5060608201518160030160006101000a81548160ff0219169083151502179055509050506001600560008282540192505081905550817fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5160405180905060405180910390a25b5b509392505050565b81548183558181151161268c5781836000526020600020918201910161268b9190612765565b5b505050565b8154818355818115116126b8578183600052602060002091820191016126b79190612765565b5b505050565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061272657805160ff1916838001178555612754565b82800160010185558215612754579182015b82811115612753578251825591602001919060010190612738565b5b5090506127619190612765565b5090565b61278791905b8082111561278357600081600090555060010161276b565b5090565b905600a165627a7a72305820e460b58d5bd3a5224257358a24e4e34b192e61ef5ebd051c779a5117c38a2a060029", - "updated_at": 1518645843673 - } - } -} diff --git a/packages/contracts/src/artifacts/Token.json b/packages/contracts/src/artifacts/Token.json deleted file mode 100644 index d31ca60ba..000000000 --- a/packages/contracts/src/artifacts/Token.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "contract_name": "Token", - "networks": { - "50": { - "solc_version": "0.4.18", - "keccak256": "0xe43382be55ddb9c7a28567b4cc59e35072da198e6c49a90ff1396aa8399fd61e", - "optimizer_enabled": 0, - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "unlinked_binary": - "0x6060604052341561000f57600080fd5b6102ac8061001e6000396000f30060606040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b31461007257806323b872dd146100cc57806370a0823114610145578063a9059cbb14610192578063dd62ed3e146101ec575b600080fd5b341561007d57600080fd5b6100b2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610258565b604051808215151515815260200191505060405180910390f35b34156100d757600080fd5b61012b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610260565b604051808215151515815260200191505060405180910390f35b341561015057600080fd5b61017c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610269565b6040518082815260200191505060405180910390f35b341561019d57600080fd5b6101d2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610270565b604051808215151515815260200191505060405180910390f35b34156101f757600080fd5b610242600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610278565b6040518082815260200191505060405180910390f35b600092915050565b60009392505050565b6000919050565b600092915050565b6000929150505600a165627a7a723058201ef98a5ecc619c89a935fee340b114a09fe44aa51aa765f4037dd3423f49d42d0029", - "updated_at": 1518645860796 - } - } -} diff --git a/packages/contracts/src/artifacts/TokenRegistry.json b/packages/contracts/src/artifacts/TokenRegistry.json deleted file mode 100644 index 1bf5b53d0..000000000 --- a/packages/contracts/src/artifacts/TokenRegistry.json +++ /dev/null @@ -1,540 +0,0 @@ -{ - "contract_name": "TokenRegistry", - "networks": { - "50": { - "solc_version": "0.4.11", - "keccak256": "0xfaf2e3107cfafb9925c2ce51653c3f636bffff9e6528cc61c6341a3e27ca3c6b", - "optimizer_enabled": 0, - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_index", - "type": "uint256" - } - ], - "name": "removeToken", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_name", - "type": "string" - } - ], - "name": "getTokenAddressByName", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_symbol", - "type": "string" - } - ], - "name": "getTokenAddressBySymbol", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_swarmHash", - "type": "bytes" - } - ], - "name": "setTokenSwarmHash", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_token", - "type": "address" - } - ], - "name": "getTokenMetaData", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_name", - "type": "string" - }, - { - "name": "_symbol", - "type": "string" - }, - { - "name": "_decimals", - "type": "uint8" - }, - { - "name": "_ipfsHash", - "type": "bytes" - }, - { - "name": "_swarmHash", - "type": "bytes" - } - ], - "name": "addToken", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_name", - "type": "string" - } - ], - "name": "setTokenName", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "tokens", - "outputs": [ - { - "name": "token", - "type": "address" - }, - { - "name": "name", - "type": "string" - }, - { - "name": "symbol", - "type": "string" - }, - { - "name": "decimals", - "type": "uint8" - }, - { - "name": "ipfsHash", - "type": "bytes" - }, - { - "name": "swarmHash", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "tokenAddresses", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_name", - "type": "string" - } - ], - "name": "getTokenByName", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getTokenAddresses", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_ipfsHash", - "type": "bytes" - } - ], - "name": "setTokenIpfsHash", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_symbol", - "type": "string" - } - ], - "name": "getTokenBySymbol", - "outputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "string" - }, - { - "name": "", - "type": "uint8" - }, - { - "name": "", - "type": "bytes" - }, - { - "name": "", - "type": "bytes" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_token", - "type": "address" - }, - { - "name": "_symbol", - "type": "string" - } - ], - "name": "setTokenSymbol", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogAddToken", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "name", - "type": "string" - }, - { - "indexed": false, - "name": "symbol", - "type": "string" - }, - { - "indexed": false, - "name": "decimals", - "type": "uint8" - }, - { - "indexed": false, - "name": "ipfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "swarmHash", - "type": "bytes" - } - ], - "name": "LogRemoveToken", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldName", - "type": "string" - }, - { - "indexed": false, - "name": "newName", - "type": "string" - } - ], - "name": "LogTokenNameChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSymbol", - "type": "string" - }, - { - "indexed": false, - "name": "newSymbol", - "type": "string" - } - ], - "name": "LogTokenSymbolChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldIpfsHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newIpfsHash", - "type": "bytes" - } - ], - "name": "LogTokenIpfsHashChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "token", - "type": "address" - }, - { - "indexed": false, - "name": "oldSwarmHash", - "type": "bytes" - }, - { - "indexed": false, - "name": "newSwarmHash", - "type": "bytes" - } - ], - "name": "LogTokenSwarmHashChange", - "type": "event" - } - ], - "unlinked_binary": - "0x60606040525b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b613bf5806100576000396000f300606060405236156100e4576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806313baf1e6146100e65780632fbfeba9146101255780633550b6d9146101bf57806356318820146102595780637abccac9146102d25780638da5cb5b1461053d578063a880319d1461058f578063c370c86d146106dd578063e486033914610756578063e5df8b84146109fd578063e73fc0c314610a5d578063ee8c24b814610cec578063eef05f6514610d61578063efa74f1f14610dda578063f036417f14611069578063f2fde38b146110e2575bfe5b34156100ee57fe5b610123600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050611118565b005b341561012d57fe5b61017d600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611836565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101c757fe5b610217600480803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919050506118ca565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561026157fe5b6102d0600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061195e565b005b34156102da57fe5b610306600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611c0e565b604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a81815181526020019150805190602001908083836000831461039f575b80518252602083111561039f5760208201915060208101905060208303925061037b565b505050905090810190601f1680156103cb5780820380516001836020036101000a031916815260200191505b50858103845289818151815260200191508051906020019080838360008314610413575b805182526020831115610413576020820191506020810190506020830392506103ef565b505050905090810190601f16801561043f5780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360008314610487575b80518252602083111561048757602082019150602081019050602083039250610463565b505050905090810190601f1680156104b35780820380516001836020036101000a031916815260200191505b508581038252868181518152602001915080519060200190808383600083146104fb575b8051825260208311156104fb576020820191506020810190506020830392506104d7565b505050905090810190601f1680156105275780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b341561054557fe5b61054d611fc3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059757fe5b6106db600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803560ff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050611fe9565b005b34156106e557fe5b610754600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061281a565b005b341561075e57fe5b61078a600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050612cd1565b604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a81815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561085d5780601f106108325761010080835404028352916020019161085d565b820191906000526020600020905b81548152906001019060200180831161084057829003601f168201915b50508581038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156108e05780601f106108b5576101008083540402835291602001916108e0565b820191906000526020600020905b8154815290600101906020018083116108c357829003601f168201915b50508581038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156109635780601f1061093857610100808354040283529160200191610963565b820191906000526020600020905b81548152906001019060200180831161094657829003601f168201915b50508581038252868181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156109e65780601f106109bb576101008083540402835291602001916109e6565b820191906000526020600020905b8154815290600101906020018083116109c957829003601f168201915b50509a505050505050505050505060405180910390f35b3415610a0557fe5b610a1b6004808035906020019091905050612d36565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3415610a6557fe5b610ab5600480803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050612d76565b604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a818151815260200191508051906020019080838360008314610b4e575b805182526020831115610b4e57602082019150602081019050602083039250610b2a565b505050905090810190601f168015610b7a5780820380516001836020036101000a031916815260200191505b50858103845289818151815260200191508051906020019080838360008314610bc2575b805182526020831115610bc257602082019150602081019050602083039250610b9e565b505050905090810190601f168015610bee5780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360008314610c36575b805182526020831115610c3657602082019150602081019050602083039250610c12565b505050905090810190601f168015610c625780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360008314610caa575b805182526020831115610caa57602082019150602081019050602083039250610c86565b505050905090810190601f168015610cd65780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b3415610cf457fe5b610cfc612e48565b6040518080602001828103825283818151815260200191508051906020019060200280838360008314610d4e575b805182526020831115610d4e57602082019150602081019050602083039250610d2a565b5050509050019250505060405180910390f35b3415610d6957fe5b610dd8600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050612edd565b005b3415610de257fe5b610e32600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061318d565b604051808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200180602001806020018660ff1660ff168152602001806020018060200185810385528a818151815260200191508051906020019080838360008314610ecb575b805182526020831115610ecb57602082019150602081019050602083039250610ea7565b505050905090810190601f168015610ef75780820380516001836020036101000a031916815260200191505b50858103845289818151815260200191508051906020019080838360008314610f3f575b805182526020831115610f3f57602082019150602081019050602083039250610f1b565b505050905090810190601f168015610f6b5780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360008314610fb3575b805182526020831115610fb357602082019150602081019050602083039250610f8f565b505050905090810190601f168015610fdf5780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360008314611027575b80518252602083111561102757602082019150602081019050602083039250611003565b505050905090810190601f1680156110535780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390f35b341561107157fe5b6110e0600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061325f565b005b34156110ea57fe5b611116600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050613716565b005b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156111775760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515156112175760006000fd5b8373ffffffffffffffffffffffffffffffffffffffff1660048481548110151561123d57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561128d5760006000fd5b60046001600480549050038154811015156112a457fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166004848154811015156112e057fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160048181805490500391508161134291906137f0565b50600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091508160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f32c54f1e2ea75844ded7517e7dbcd3895da7cd0c28f9ab9f9cf6ecf5f83762c683600101846002018560030160009054906101000a900460ff1686600401876005016040518080602001806020018660ff1660ff168152602001806020018060200185810385528a8181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156114a35780601f10611478576101008083540402835291602001916114a3565b820191906000526020600020905b81548152906001019060200180831161148657829003601f168201915b50508581038452898181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156115265780601f106114fb57610100808354040283529160200191611526565b820191906000526020600020905b81548152906001019060200180831161150957829003601f168201915b50508581038352878181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156115a95780601f1061157e576101008083540402835291602001916115a9565b820191906000526020600020905b81548152906001019060200180831161158c57829003601f168201915b505085810382528681815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561162c5780601f106116015761010080835404028352916020019161162c565b820191906000526020600020905b81548152906001019060200180831161160f57829003601f168201915b5050995050505050505050505060405180910390a260028260020160405180828054600181600116156101000203166002900480156116a25780601f106116805761010080835404028352918201916116a2565b820191906000526020600020905b81548152906001019060200180831161168e575b5050915050908152602001604051809103902060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560038260010160405180828054600181600116156101000203166002900480156117395780601f10611717576101008083540402835291820191611739565b820191906000526020600020905b815481529060010190602001808311611725575b5050915050908152602001604051809103902060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160006117e7919061381c565b6002820160006117f7919061381c565b6003820160006101000a81549060ff021916905560048201600061181b9190613864565b60058201600061182b9190613864565b50505b5b505b505050565b60006003826040518082805190602001908083835b6020831061186e578051825260208201915060208101905060208303925061184b565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b60006002826040518082805190602001908083835b6020831061190257805182526020820191506020810190506020830392506118df565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690505b919050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156119bd5760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515611a5d5760006000fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091508373ffffffffffffffffffffffffffffffffffffffff167fc3168fdc13112e44a031057dbf6c609b33353addb4d8037d24543e22cbfe2acd8360050185604051808060200180602001838103835285818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015611b685780601f10611b3d57610100808354040283529160200191611b68565b820191906000526020600020905b815481529060010190602001808311611b4b57829003601f168201915b5050838103825284818151815260200191508051906020019080838360008314611bb1575b805182526020831115611bb157602082019150602081019050602083039250611b8d565b505050905090810190601f168015611bdd5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a282826005019080519060200190611c049291906138ac565b505b5b505b505050565b6000611c1861392c565b611c2061392c565b6000611c2a613940565b611c32613940565b611c3a613954565b600160008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060c060405190810160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d745780601f10611d4957610100808354040283529160200191611d74565b820191906000526020600020905b815481529060010190602001808311611d5757829003601f168201915b50505050508152602001600282018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611e165780601f10611deb57610100808354040283529160200191611e16565b820191906000526020600020905b815481529060010190602001808311611df957829003601f168201915b505050505081526020016003820160009054906101000a900460ff1660ff1660ff168152602001600482018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611ed55780601f10611eaa57610100808354040283529160200191611ed5565b820191906000526020600020905b815481529060010190602001808311611eb857829003601f168201915b50505050508152602001600582018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611f775780601f10611f4c57610100808354040283529160200191611f77565b820191906000526020600020905b815481529060010190602001808311611f5a57829003601f168201915b5050505050815250509050806000015181602001518260400151836060015184608001518560a001518494508393508191508090509650965096509650965096505b5091939550919395565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156120465760006000fd5b85600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156120e55760006000fd5b86600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156121235760006000fd5b85600073ffffffffffffffffffffffffffffffffffffffff166002826040518082805190602001908083835b60208310612172578051825260208201915060208101905060208303925061214f565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156121e95760006000fd5b87600073ffffffffffffffffffffffffffffffffffffffff166003826040518082805190602001908083835b602083106122385780518252602082019150602081019050602083039250612215565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156122af5760006000fd5b60c0604051908101604052808b73ffffffffffffffffffffffffffffffffffffffff1681526020018a81526020018981526020018860ff16815260200187815260200186815250600160008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190805190602001906123989291906139bc565b5060408201518160020190805190602001906123b59291906139bc565b5060608201518160030160006101000a81548160ff021916908360ff16021790555060808201518160040190805190602001906123f3929190613a3c565b5060a0820151816005019080519060200190612410929190613a3c565b50905050600480548060010182816124289190613abc565b916000526020600020900160005b8c909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050896002896040518082805190602001908083835b602083106124af578051825260208201915060208101905060208303925061248c565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508960038a6040518082805190602001908083835b602083106125575780518252602082019150602081019050602083039250612534565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508973ffffffffffffffffffffffffffffffffffffffff167fd8d928b0b50ca11d9dc273236b46f3526515b03602f71f3a6af4f45bd9fa91448a8a8a8a8a6040518080602001806020018660ff1660ff168152602001806020018060200185810385528a81815181526020019150805190602001908083836000831461266c575b80518252602083111561266c57602082019150602081019050602083039250612648565b505050905090810190601f1680156126985780820380516001836020036101000a031916815260200191505b508581038452898181518152602001915080519060200190808383600083146126e0575b8051825260208311156126e0576020820191506020810190506020830392506126bc565b505050905090810190601f16801561270c5780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360008314612754575b80518252602083111561275457602082019150602081019050602083039250612730565b505050905090810190601f1680156127805780820380516001836020036101000a031916815260200191505b508581038252868181518152602001915080519060200190808383600083146127c8575b8051825260208311156127c8576020820191506020810190506020830392506127a4565b505050905090810190601f1680156127f45780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390a25b5b505b505b505b505b505050505050565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156128795760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515156129195760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff166003826040518082805190602001908083835b602083106129685780518252602082019150602081019050602083039250612945565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156129df5760006000fd5b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002092508473ffffffffffffffffffffffffffffffffffffffff167f4a6dbfc867b179991dec22ff19960f0a94d8d9d891fc556f547764670340e8ae8460010186604051808060200180602001838103835285818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015612aea5780601f10612abf57610100808354040283529160200191612aea565b820191906000526020600020905b815481529060010190602001808311612acd57829003601f168201915b5050838103825284818151815260200191508051906020019080838360008314612b33575b805182526020831115612b3357602082019150602081019050602083039250612b0f565b505050905090810190601f168015612b5f5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26003836001016040518082805460018160011615610100020316600290048015612bcf5780601f10612bad576101008083540402835291820191612bcf565b820191906000526020600020905b815481529060010190602001808311612bbb575b5050915050908152602001604051809103902060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055846003856040518082805190602001908083835b60208310612c3c5780518252602082019150602081019050602083039250612c19565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083836001019080519060200190612cc5929190613ae8565b505b5b505b505b505050565b60016020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001019080600201908060030160009054906101000a900460ff1690806004019080600501905086565b600481815481101515612d4557fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000612d8061392c565b612d8861392c565b6000612d92613940565b612d9a613940565b60006003886040518082805190602001908083835b60208310612dd25780518252602082019150602081019050602083039250612daf565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050612e3181611c0e565b9650965096509650965096505b5091939550919395565b612e50613b68565b6004805480602002602001604051908101604052809291908181526020018280548015612ed257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311612e88575b505050505090505b90565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612f3c5760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515612fdc5760006000fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002091508373ffffffffffffffffffffffffffffffffffffffff167f5b19f79ac4e8cfa820815502e11615f1a449e28155dc289ec5cac1a11f90869483600401856040518080602001806020018381038352858181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156130e75780601f106130bc576101008083540402835291602001916130e7565b820191906000526020600020905b8154815290600101906020018083116130ca57829003601f168201915b5050838103825284818151815260200191508051906020019080838360008314613130575b8051825260208311156131305760208201915060208101905060208303925061310c565b505050905090810190601f16801561315c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2828260040190805190602001906131839291906138ac565b505b5b505b505050565b600061319761392c565b61319f61392c565b60006131a9613940565b6131b1613940565b60006002886040518082805190602001908083835b602083106131e957805182526020820191506020810190506020830392506131c6565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061324881611c0e565b9650965096509650965096505b5091939550919395565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156132be5760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff16600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415151561335e5760006000fd5b82600073ffffffffffffffffffffffffffffffffffffffff166002826040518082805190602001908083835b602083106133ad578051825260208201915060208101905060208303925061338a565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156134245760006000fd5b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002092508473ffffffffffffffffffffffffffffffffffffffff167f53d878a6530e56c9bc96548fa0a8cae4f1d1f49c86b0e934c086b992ebb6998f846002018660405180806020018060200183810383528581815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561352f5780601f106135045761010080835404028352916020019161352f565b820191906000526020600020905b81548152906001019060200180831161351257829003601f168201915b5050838103825284818151815260200191508051906020019080838360008314613578575b80518252602083111561357857602082019150602081019050602083039250613554565b505050905090810190601f1680156135a45780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a260028360020160405180828054600181600116156101000203166002900480156136145780601f106135f2576101008083540402835291820191613614565b820191906000526020600020905b815481529060010190602001808311613600575b5050915050908152602001604051809103902060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055846002856040518082805190602001908083835b60208310613681578051825260208201915060208101905060208303925061365e565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508383600201908051906020019061370a929190613ae8565b505b5b505b505b505050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156137735760006000fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156137eb5780600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b50565b815481835581811511613817578183600052602060002091820191016138169190613b7c565b5b505050565b50805460018160011615610100020316600290046000825580601f106138425750613861565b601f0160209004906000526020600020908101906138609190613b7c565b5b50565b50805460018160011615610100020316600290046000825580601f1061388a57506138a9565b601f0160209004906000526020600020908101906138a89190613b7c565b5b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106138ed57805160ff191683800117855561391b565b8280016001018555821561391b579182015b8281111561391a5782518255916020019190600101906138ff565b5b5090506139289190613b7c565b5090565b602060405190810160405280600081525090565b602060405190810160405280600081525090565b60c060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001613985613ba1565b8152602001613992613ba1565b8152602001600060ff1681526020016139a9613bb5565b81526020016139b6613bb5565b81525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106139fd57805160ff1916838001178555613a2b565b82800160010185558215613a2b579182015b82811115613a2a578251825591602001919060010190613a0f565b5b509050613a389190613b7c565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613a7d57805160ff1916838001178555613aab565b82800160010185558215613aab579182015b82811115613aaa578251825591602001919060010190613a8f565b5b509050613ab89190613b7c565b5090565b815481835581811511613ae357818360005260206000209182019101613ae29190613b7c565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613b2957805160ff1916838001178555613b57565b82800160010185558215613b57579182015b82811115613b56578251825591602001919060010190613b3b565b5b509050613b649190613b7c565b5090565b602060405190810160405280600081525090565b613b9e91905b80821115613b9a576000816000905550600101613b82565b5090565b90565b602060405190810160405280600081525090565b6020604051908101604052806000815250905600a165627a7a723058205f678f4c4175704443c6f7559c12ec6da458722d31ecf0b25fd93fee8b930a820029", - "updated_at": 1518645854885 - } - } -} diff --git a/packages/contracts/src/artifacts/TokenTransferProxy.json b/packages/contracts/src/artifacts/TokenTransferProxy.json deleted file mode 100644 index 23770df01..000000000 --- a/packages/contracts/src/artifacts/TokenTransferProxy.json +++ /dev/null @@ -1,180 +0,0 @@ -{ - "contract_name": "TokenTransferProxy", - "networks": { - "50": { - "solc_version": "0.4.11", - "keccak256": "0xf376b57d58b01cb4e9c70a03a1ab6b06bc61d7eb4714bc360dd063c08028453a", - "optimizer_enabled": 0, - "abi": [ - { - "constant": false, - "inputs": [ - { - "name": "token", - "type": "address" - }, - { - "name": "from", - "type": "address" - }, - { - "name": "to", - "type": "address" - }, - { - "name": "value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "target", - "type": "address" - } - ], - "name": "addAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "uint256" - } - ], - "name": "authorities", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "target", - "type": "address" - } - ], - "name": "removeAuthorizedAddress", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "owner", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "authorized", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getAuthorizedAddresses", - "outputs": [ - { - "name": "", - "type": "address[]" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "target", - "type": "address" - }, - { - "indexed": true, - "name": "caller", - "type": "address" - } - ], - "name": "LogAuthorizedAddressAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "target", - "type": "address" - }, - { - "indexed": true, - "name": "caller", - "type": "address" - } - ], - "name": "LogAuthorizedAddressRemoved", - "type": "event" - } - ], - "unlinked_binary": - "0x60606040525b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b610bd6806100576000396000f3006060604052361561008c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806315dacbea1461008e57806342f1181e14610123578063494503d41461015957806370712939146101b95780638da5cb5b146101ef578063b918161114610241578063d39de6e91461028f578063f2fde38b14610304575bfe5b341561009657fe5b610109600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061033a565b604051808215151515815260200191505060405180910390f35b341561012b57fe5b610157600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610495565b005b341561016157fe5b610177600480803590602001909190505061066d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101c157fe5b6101ed600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506106ad565b005b34156101f757fe5b6101ff610964565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561024957fe5b610275600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061098a565b604051808215151515815260200191505060405180910390f35b341561029757fe5b61029f6109aa565b60405180806020018281038252838181518152602001915080519060200190602002808383600083146102f1575b8051825260208311156102f1576020820191506020810190506020830392506102cd565b5050509050019250505060405180910390f35b341561030c57fe5b610338600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a3f565b005b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156103955760006000fd5b8473ffffffffffffffffffffffffffffffffffffffff166323b872dd8585856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b151561047157fe5b6102c65a03f1151561047f57fe5b5050506040518051905090505b5b949350505050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156104f25760006000fd5b80600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615151561054d5760006000fd5b6001600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600280548060010182816105b99190610b19565b916000526020600020900160005b84909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f94bb87f4c15c4587ff559a7584006fa01ddf9299359be6b512b94527aa961aca60405180905060405180910390a35b5b505b50565b60028181548110151561067c57fe5b906000526020600020900160005b915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561070c5760006000fd5b81600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615156107665760006000fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff0219169055600091505b6002805490508210156108ff578273ffffffffffffffffffffffffffffffffffffffff166002838154811015156107ed57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156108f157600260016002805490500381548110151561084d57fe5b906000526020600020900160005b9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660028381548110151561088957fe5b906000526020600020900160005b6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060016002818180549050039150816108eb9190610b45565b506108ff565b5b81806001019250506107ba565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ff5b347a1e40749dd050f5f07fbdbeb7e3efa9756903044dd29401fd1d4bb4a1c60405180905060405180910390a35b5b505b5050565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900460ff1681565b6109b2610b71565b6002805480602002602001604051908101604052809291908181526020018280548015610a3457602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116109ea575b505050505090505b90565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610a9c5760006000fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610b145780600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b5b50565b815481835581811511610b4057818360005260206000209182019101610b3f9190610b85565b5b505050565b815481835581811511610b6c57818360005260206000209182019101610b6b9190610b85565b5b505050565b602060405190810160405280600081525090565b610ba791905b80821115610ba3576000816000905550600101610b8b565b5090565b905600a165627a7a723058202a39ecce7fa8d2726ee124023aeec7f2d5ceb1ff5dbd623d87305279af329a530029", - "updated_at": 1518645855247 - } - } -} diff --git a/packages/contracts/src/artifacts/WETH9.json b/packages/contracts/src/artifacts/WETH9.json deleted file mode 100644 index ead5f644b..000000000 --- a/packages/contracts/src/artifacts/WETH9.json +++ /dev/null @@ -1,292 +0,0 @@ -{ - "contract_name": "WETH9", - "networks": { - "50": { - "solc_version": "0.4.18", - "keccak256": "0xce985174db1a24d312c0d544abb926a9b107bd9abd6424288a8e54a16d3e006b", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "guy", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "src", - "type": "address" - }, - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "wad", - "type": "uint256" - } - ], - "name": "withdraw", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "dst", - "type": "address" - }, - { - "name": "wad", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "deposit", - "outputs": [], - "payable": true, - "stateMutability": "payable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "payable": true, - "stateMutability": "payable", - "type": "fallback" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "guy", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "dst", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Deposit", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "src", - "type": "address" - }, - { - "indexed": false, - "name": "wad", - "type": "uint256" - } - ], - "name": "Withdrawal", - "type": "event" - } - ], - "unlinked_binary": - "0x60606040526040805190810160405280600d81526020017f57726170706564204574686572000000000000000000000000000000000000008152506000908051906020019061004f9291906100c8565b506040805190810160405280600481526020017f57455448000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100c8565b506012600260006101000a81548160ff021916908360ff16021790555034156100c357600080fd5b61016d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010957805160ff1916838001178555610137565b82800160010185558215610137579182015b8281111561013657825182559160200191906001019061011b565b5b5090506101449190610148565b5090565b61016a91905b8082111561016657600081600090555060010161014e565b5090565b90565b610c348061017c6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058205d39b84dc32db11788d365c5d4ad673648b645ce10963c48e4aad5da4909ab5e0029", - "updated_at": 1518645861261 - } - } -} diff --git a/packages/contracts/src/artifacts/ZRXToken.json b/packages/contracts/src/artifacts/ZRXToken.json deleted file mode 100644 index 0c353bc7e..000000000 --- a/packages/contracts/src/artifacts/ZRXToken.json +++ /dev/null @@ -1,226 +0,0 @@ -{ - "contract_name": "ZRXToken", - "networks": { - "50": { - "solc_version": "0.4.11", - "keccak256": "0x68278a8290a59fb66c378f7517c1029efe226d916e252deceb0a2799a6bc4e77", - "optimizer_enabled": 0, - "abi": [ - { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_spender", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_from", - "type": "address" - }, - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - { - "name": "", - "type": "uint8" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "symbol", - "outputs": [ - { - "name": "", - "type": "string" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "_to", - "type": "address" - }, - { - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "_owner", - "type": "address" - }, - { - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "inputs": [], - "payable": false, - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - } - ], - "unlinked_binary": - "0x60606040526b033b2e3c9fd0803ce8000000600355341561001c57fe5b5b600354600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5b610b82806100746000396000f30060606040523615610097576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde0314610099578063095ea7b31461013257806318160ddd1461018957806323b872dd146101af578063313ce5671461022557806370a082311461025157806395d89b411461029b578063a9059cbb14610334578063dd62ed3e1461038b575bfe5b34156100a157fe5b6100a96103f4565b60405180806020018281038252838181518152602001915080519060200190808383600083146100f8575b8051825260208311156100f8576020820191506020810190506020830392506100d4565b505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561013a57fe5b61016f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061042e565b604051808215151515815260200191505060405180910390f35b341561019157fe5b610199610521565b6040518082815260200191505060405180910390f35b34156101b757fe5b61020b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610527565b604051808215151515815260200191505060405180910390f35b341561022d57fe5b610235610857565b604051808260ff1660ff16815260200191505060405180910390f35b341561025957fe5b610285600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061085c565b6040518082815260200191505060405180910390f35b34156102a357fe5b6102ab6108a6565b60405180806020018281038252838181518152602001915080519060200190808383600083146102fa575b8051825260208311156102fa576020820191506020810190506020830392506102d6565b505050905090810190601f1680156103265780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561033c57fe5b610371600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506108e0565b604051808215151515815260200191505060405180910390f35b341561039357fe5b6103de600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610ace565b6040518082815260200191505060405180910390f35b604060405190810160405280601181526020017f30782050726f746f636f6c20546f6b656e00000000000000000000000000000081525081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a3600190505b92915050565b60035481565b60006000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082600060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101580156105f95750828110155b80156106855750600060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483600060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b156108455782600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555082600060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156107d75782600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a36001915061084f565b6000915061084f565b5b509392505050565b601281565b6000600060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b604060405190810160405280600381526020017f5a5258000000000000000000000000000000000000000000000000000000000081525081565b600081600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101580156109b15750600060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b15610abe5781600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610ac8565b60009050610ac8565b5b92915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b929150505600a165627a7a7230582055d3a76ea3e76a05371288f7870d0ec8251b0e3ce06877d2a8509c92c10c51420029", - "updated_at": 1518645862088 - } - } -} 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/src/contracts/current/tutorials/Arbitrage/Arbitrage.sol b/packages/contracts/src/contracts/current/tutorials/Arbitrage/Arbitrage.sol new file mode 100644 index 000000000..a9f3c22e6 --- /dev/null +++ b/packages/contracts/src/contracts/current/tutorials/Arbitrage/Arbitrage.sol @@ -0,0 +1,114 @@ +pragma solidity ^0.4.19; + +import { Exchange } from "../../protocol/Exchange/Exchange.sol"; +import { EtherDelta } from "../EtherDelta/EtherDelta.sol"; +import { Ownable } from "../../utils/Ownable/Ownable.sol"; +import { Token } from "../../tokens/Token/Token.sol"; + +/// @title Arbitrage - Facilitates atomic arbitrage of ERC20 tokens between EtherDelta and 0x Exchange contract. +/// @author Leonid Logvinov - <leo@0xProject.com> +contract Arbitrage is Ownable { + + Exchange exchange; + EtherDelta etherDelta; + address proxyAddress; + + uint256 constant MAX_UINT = 2**256 - 1; + + function Arbitrage(address _exchangeAddress, address _etherDeltaAddress, address _proxyAddress) { + exchange = Exchange(_exchangeAddress); + etherDelta = EtherDelta(_etherDeltaAddress); + proxyAddress = _proxyAddress; + } + + /* + * Makes token tradeable by setting an allowance for etherDelta and 0x proxy contract. + * Also sets an allowance for the owner of the contracts therefore allowing to withdraw tokens. + */ + function setAllowances(address tokenAddress) external onlyOwner { + Token token = Token(tokenAddress); + token.approve(address(etherDelta), MAX_UINT); + token.approve(proxyAddress, MAX_UINT); + token.approve(owner, MAX_UINT); + } + + /* + * Because of the limits on the number of local variables in Solidity we need to compress parameters while loosing + * readability. Scheme of the parameter layout: + * + * addresses + * 0..4 orderAddresses + * 5 user + * + * values + * 0..5 orderValues + * 6 fillTakerTokenAmount + * 7 amountGet + * 8 amountGive + * 9 expires + * 10 nonce + * 11 amount + + * signature + * exchange then etherDelta + */ + function makeAtomicTrade( + address[6] addresses, uint[12] values, + uint8[2] v, bytes32[2] r, bytes32[2] s + ) external onlyOwner { + makeExchangeTrade(addresses, values, v, r, s); + makeEtherDeltaTrade(addresses, values, v, r, s); + } + + function makeEtherDeltaTrade( + address[6] addresses, uint[12] values, + uint8[2] v, bytes32[2] r, bytes32[2] s + ) internal { + uint amount = values[11]; + etherDelta.depositToken( + addresses[2], // tokenGet === makerToken + values[7] // amountGet + ); + etherDelta.trade( + addresses[2], // tokenGet === makerToken + values[7], // amountGet + addresses[3], // tokenGive === takerToken + values[8], // amountGive + values[9], // expires + values[10], // nonce + addresses[5], // user + v[1], + r[1], + s[1], + amount + ); + etherDelta.withdrawToken( + addresses[3], // tokenGive === tokenToken + values[8] // amountGive + ); + } + + function makeExchangeTrade( + address[6] addresses, uint[12] values, + uint8[2] v, bytes32[2] r, bytes32[2] s + ) internal { + address[5] memory orderAddresses = [ + addresses[0], // maker + addresses[1], // taker + addresses[2], // makerToken + addresses[3], // takerToken + addresses[4] // feeRecepient + ]; + uint[6] memory orderValues = [ + values[0], // makerTokenAmount + values[1], // takerTokenAmount + values[2], // makerFee + values[3], // takerFee + values[4], // expirationTimestampInSec + values[5] // salt + ]; + uint fillTakerTokenAmount = values[6]; // fillTakerTokenAmount + // Execute Exchange trade. It either succeeds in full or fails and reverts all the changes. + exchange.fillOrKillOrder(orderAddresses, orderValues, fillTakerTokenAmount, v[0], r[0], s[0]); + } +} diff --git a/packages/contracts/src/contracts/current/tutorials/EtherDelta/AccountLevels.sol b/packages/contracts/src/contracts/current/tutorials/EtherDelta/AccountLevels.sol new file mode 100644 index 000000000..8d7a930d3 --- /dev/null +++ b/packages/contracts/src/contracts/current/tutorials/EtherDelta/AccountLevels.sol @@ -0,0 +1,11 @@ +pragma solidity ^0.4.19; + +contract AccountLevels { + //given a user, returns an account level + //0 = regular user (pays take fee and make fee) + //1 = market maker silver (pays take fee, no make fee, gets rebate) + //2 = market maker gold (pays take fee, no make fee, gets entire counterparty's take fee as rebate) + function accountLevel(address user) constant returns(uint) { + return 0; + } +} diff --git a/packages/contracts/src/contracts/current/tutorials/EtherDelta/EtherDelta.sol b/packages/contracts/src/contracts/current/tutorials/EtherDelta/EtherDelta.sol new file mode 100644 index 000000000..49847ab48 --- /dev/null +++ b/packages/contracts/src/contracts/current/tutorials/EtherDelta/EtherDelta.sol @@ -0,0 +1,168 @@ +pragma solidity ^0.4.19; + +import { SafeMath } from "../../utils/SafeMath/SafeMath.sol"; +import { AccountLevels } from "./AccountLevels.sol"; +import { Token } from "../../tokens/Token/Token.sol"; + +contract EtherDelta is SafeMath { + address public admin; //the admin address + address public feeAccount; //the account that will receive fees + address public accountLevelsAddr; //the address of the AccountLevels contract + uint public feeMake; //percentage times (1 ether) + uint public feeTake; //percentage times (1 ether) + uint public feeRebate; //percentage times (1 ether) + mapping (address => mapping (address => uint)) public tokens; //mapping of token addresses to mapping of account balances (token=0 means Ether) + mapping (address => mapping (bytes32 => bool)) public orders; //mapping of user accounts to mapping of order hashes to booleans (true = submitted by user, equivalent to offchain signature) + mapping (address => mapping (bytes32 => uint)) public orderFills; //mapping of user accounts to mapping of order hashes to uints (amount of order that has been filled) + + event Order(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user); + event Cancel(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s); + event Trade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, address get, address give); + event Deposit(address token, address user, uint amount, uint balance); + event Withdraw(address token, address user, uint amount, uint balance); + + function EtherDelta(address admin_, address feeAccount_, address accountLevelsAddr_, uint feeMake_, uint feeTake_, uint feeRebate_) { + admin = admin_; + feeAccount = feeAccount_; + accountLevelsAddr = accountLevelsAddr_; + feeMake = feeMake_; + feeTake = feeTake_; + feeRebate = feeRebate_; + } + + function() { + throw; + } + + function changeAdmin(address admin_) { + if (msg.sender != admin) throw; + admin = admin_; + } + + function changeAccountLevelsAddr(address accountLevelsAddr_) { + if (msg.sender != admin) throw; + accountLevelsAddr = accountLevelsAddr_; + } + + function changeFeeAccount(address feeAccount_) { + if (msg.sender != admin) throw; + feeAccount = feeAccount_; + } + + function changeFeeMake(uint feeMake_) { + if (msg.sender != admin) throw; + if (feeMake_ > feeMake) throw; + feeMake = feeMake_; + } + + function changeFeeTake(uint feeTake_) { + if (msg.sender != admin) throw; + if (feeTake_ > feeTake || feeTake_ < feeRebate) throw; + feeTake = feeTake_; + } + + function changeFeeRebate(uint feeRebate_) { + if (msg.sender != admin) throw; + if (feeRebate_ < feeRebate || feeRebate_ > feeTake) throw; + feeRebate = feeRebate_; + } + + function deposit() payable { + tokens[0][msg.sender] = safeAdd(tokens[0][msg.sender], msg.value); + Deposit(0, msg.sender, msg.value, tokens[0][msg.sender]); + } + + function withdraw(uint amount) { + if (tokens[0][msg.sender] < amount) throw; + tokens[0][msg.sender] = safeSub(tokens[0][msg.sender], amount); + if (!msg.sender.call.value(amount)()) throw; + Withdraw(0, msg.sender, amount, tokens[0][msg.sender]); + } + + function depositToken(address token, uint amount) { + //remember to call Token(address).approve(this, amount) or this contract will not be able to do the transfer on your behalf. + if (token==0) throw; + if (!Token(token).transferFrom(msg.sender, this, amount)) throw; + tokens[token][msg.sender] = safeAdd(tokens[token][msg.sender], amount); + Deposit(token, msg.sender, amount, tokens[token][msg.sender]); + } + + function withdrawToken(address token, uint amount) { + if (token==0) throw; + if (tokens[token][msg.sender] < amount) throw; + tokens[token][msg.sender] = safeSub(tokens[token][msg.sender], amount); + if (!Token(token).transfer(msg.sender, amount)) throw; + Withdraw(token, msg.sender, amount, tokens[token][msg.sender]); + } + + function balanceOf(address token, address user) constant returns (uint) { + return tokens[token][user]; + } + + function order(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce) { + bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); + orders[msg.sender][hash] = true; + Order(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender); + } + + function trade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount) { + //amount is in amountGet terms + bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); + if (!( + (orders[user][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) && + block.number <= expires && + safeAdd(orderFills[user][hash], amount) <= amountGet + )) throw; + tradeBalances(tokenGet, amountGet, tokenGive, amountGive, user, amount); + orderFills[user][hash] = safeAdd(orderFills[user][hash], amount); + Trade(tokenGet, amount, tokenGive, amountGive * amount / amountGet, user, msg.sender); + } + + function tradeBalances(address tokenGet, uint amountGet, address tokenGive, uint amountGive, address user, uint amount) private { + uint feeMakeXfer = safeMul(amount, feeMake) / (1 ether); + uint feeTakeXfer = safeMul(amount, feeTake) / (1 ether); + uint feeRebateXfer = 0; + if (accountLevelsAddr != 0x0) { + uint accountLevel = AccountLevels(accountLevelsAddr).accountLevel(user); + if (accountLevel==1) feeRebateXfer = safeMul(amount, feeRebate) / (1 ether); + if (accountLevel==2) feeRebateXfer = feeTakeXfer; + } + tokens[tokenGet][msg.sender] = safeSub(tokens[tokenGet][msg.sender], safeAdd(amount, feeTakeXfer)); + tokens[tokenGet][user] = safeAdd(tokens[tokenGet][user], safeSub(safeAdd(amount, feeRebateXfer), feeMakeXfer)); + tokens[tokenGet][feeAccount] = safeAdd(tokens[tokenGet][feeAccount], safeSub(safeAdd(feeMakeXfer, feeTakeXfer), feeRebateXfer)); + tokens[tokenGive][user] = safeSub(tokens[tokenGive][user], safeMul(amountGive, amount) / amountGet); + tokens[tokenGive][msg.sender] = safeAdd(tokens[tokenGive][msg.sender], safeMul(amountGive, amount) / amountGet); + } + + function testTrade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount, address sender) constant returns(bool) { + if (!( + tokens[tokenGet][sender] >= amount && + availableVolume(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, user, v, r, s) >= amount + )) return false; + return true; + } + + function availableVolume(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) constant returns(uint) { + bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); + if (!( + (orders[user][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) && + block.number <= expires + )) return 0; + uint available1 = safeSub(amountGet, orderFills[user][hash]); + uint available2 = safeMul(tokens[tokenGive][user], amountGet) / amountGive; + if (available1<available2) return available1; + return available2; + } + + function amountFilled(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) constant returns(uint) { + bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); + return orderFills[user][hash]; + } + + function cancelOrder(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, uint8 v, bytes32 r, bytes32 s) { + bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce); + if (!(orders[msg.sender][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == msg.sender)) throw; + orderFills[msg.sender][hash] = amountGet; + Cancel(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender, v, r, s); + } +} 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/tutorials/arbitrage.ts b/packages/contracts/test/tutorials/arbitrage.ts new file mode 100644 index 000000000..2bafbff0b --- /dev/null +++ b/packages/contracts/test/tutorials/arbitrage.ts @@ -0,0 +1,226 @@ +import { ECSignature, SignedOrder, ZeroEx } from '0x.js'; +import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as chai from 'chai'; +import ethUtil = require('ethereumjs-util'); +import * as Web3 from 'web3'; + +import { ArbitrageContract } from '../../src/contract_wrappers/generated/arbitrage'; +import { EtherDeltaContract } from '../../src/contract_wrappers/generated/ether_delta'; +import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange'; +import { Balances } from '../../util/balances'; +import { constants } from '../../util/constants'; +import { crypto } from '../../util/crypto'; +import { ExchangeWrapper } from '../../util/exchange_wrapper'; +import { OrderFactory } from '../../util/order_factory'; +import { BalancesByOwner, ContractName, ExchangeContractErrs } from '../../util/types'; +import { chaiSetup } from '../utils/chai_setup'; +import { deployer } from '../utils/deployer'; + +chaiSetup.configure(); +const expect = chai.expect; +const web3 = web3Factory.create(); +const web3Wrapper = new Web3Wrapper(web3.currentProvider); +const blockchainLifecycle = new BlockchainLifecycle(); + +describe('Arbitrage', () => { + let coinbase: string; + let maker: string; + let edMaker: string; + let edFrontRunner: string; + let amountGet: BigNumber; + let amountGive: BigNumber; + let makerTokenAmount: BigNumber; + let takerTokenAmount: BigNumber; + const feeRecipient = ZeroEx.NULL_ADDRESS; + const INITIAL_BALANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18); + const INITIAL_ALLOWANCE = ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18); + + let weth: Web3.ContractInstance; + let zrx: Web3.ContractInstance; + let arbitrage: ArbitrageContract; + let etherDelta: EtherDeltaContract; + + let signedOrder: SignedOrder; + let exWrapper: ExchangeWrapper; + let orderFactory: OrderFactory; + + let zeroEx: ZeroEx; + + // From a bird's eye view - we create two orders. + // 0x order of 1 ZRX (maker) for 1 WETH (taker) + // ED order of 2 WETH (tokenGive) for 1 ZRX (tokenGet) + // And then we do an atomic arbitrage between them which gives us 1 WETH. + before(async () => { + const accounts = await web3Wrapper.getAvailableAddressesAsync(); + [coinbase, maker, edMaker, edFrontRunner] = accounts; + weth = await deployer.deployAsync(ContractName.DummyToken); + zrx = await deployer.deployAsync(ContractName.DummyToken); + const accountLevels = await deployer.deployAsync(ContractName.AccountLevels); + const edAdminAddress = accounts[0]; + const edMakerFee = 0; + const edTakerFee = 0; + const edFeeRebate = 0; + const etherDeltaInstance = await deployer.deployAsync(ContractName.EtherDelta, [ + edAdminAddress, + feeRecipient, + accountLevels.address, + edMakerFee, + edTakerFee, + edFeeRebate, + ]); + etherDelta = new EtherDeltaContract(web3Wrapper, etherDeltaInstance.abi, etherDeltaInstance.address); + const tokenTransferProxy = await deployer.deployAsync(ContractName.TokenTransferProxy); + const exchangeInstance = await deployer.deployAsync(ContractName.Exchange, [ + zrx.address, + tokenTransferProxy.address, + ]); + await tokenTransferProxy.addAuthorizedAddress(exchangeInstance.address, { from: accounts[0] }); + zeroEx = new ZeroEx(web3.currentProvider, { + exchangeContractAddress: exchangeInstance.address, + networkId: constants.TESTRPC_NETWORK_ID, + }); + const exchange = new ExchangeContract(web3Wrapper, exchangeInstance.abi, exchangeInstance.address); + exWrapper = new ExchangeWrapper(exchange, zeroEx); + + makerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), 18); + takerTokenAmount = makerTokenAmount; + const defaultOrderParams = { + exchangeContractAddress: exchange.address, + maker, + feeRecipient, + makerTokenAddress: zrx.address, + takerTokenAddress: weth.address, + makerTokenAmount, + takerTokenAmount, + makerFee: new BigNumber(0), + takerFee: new BigNumber(0), + }; + orderFactory = new OrderFactory(zeroEx, defaultOrderParams); + const arbitrageInstance = await deployer.deployAsync(ContractName.Arbitrage, [ + exchange.address, + etherDelta.address, + tokenTransferProxy.address, + ]); + arbitrage = new ArbitrageContract(web3Wrapper, arbitrageInstance.abi, arbitrageInstance.address); + // Enable arbitrage and withdrawals of tokens + await arbitrage.setAllowances.sendTransactionAsync(weth.address, { from: coinbase }); + await arbitrage.setAllowances.sendTransactionAsync(zrx.address, { from: coinbase }); + + // Give some tokens to arbitrage contract + await weth.setBalance(arbitrage.address, takerTokenAmount, { from: coinbase }); + + // Fund the maker on exchange side + await zrx.setBalance(maker, makerTokenAmount, { from: coinbase }); + // Set the allowance for the maker on Exchange side + await zrx.approve(tokenTransferProxy.address, INITIAL_ALLOWANCE, { from: maker }); + + amountGive = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18); + // Fund the maker on EtherDelta side + await weth.setBalance(edMaker, amountGive, { from: coinbase }); + // Set the allowance for the maker on EtherDelta side + await weth.approve(etherDelta.address, INITIAL_ALLOWANCE, { from: edMaker }); + // Deposit maker funds into EtherDelta + await etherDelta.depositToken.sendTransactionAsync(weth.address, amountGive, { from: edMaker }); + + amountGet = makerTokenAmount; + // Fund the front runner on EtherDelta side + await zrx.setBalance(edFrontRunner, amountGet, { from: coinbase }); + // Set the allowance for the front-runner on EtherDelta side + await zrx.approve(etherDelta.address, INITIAL_ALLOWANCE, { from: edFrontRunner }); + // Deposit front runner funds into EtherDelta + await etherDelta.depositToken.sendTransactionAsync(zrx.address, amountGet, { from: edFrontRunner }); + }); + beforeEach(async () => { + await blockchainLifecycle.startAsync(); + }); + afterEach(async () => { + await blockchainLifecycle.revertAsync(); + }); + describe('makeAtomicTrade', () => { + let addresses: string[]; + let values: BigNumber[]; + let v: number[]; + let r: string[]; + let s: string[]; + let tokenGet: string; + let tokenGive: string; + let expires: BigNumber; + let nonce: BigNumber; + let edSignature: ECSignature; + before(async () => { + signedOrder = await orderFactory.newSignedOrderAsync(); + tokenGet = zrx.address; + tokenGive = weth.address; + const blockNumber = await web3Wrapper.getBlockNumberAsync(); + const ED_ORDER_EXPIRATION_IN_BLOCKS = 10; + expires = new BigNumber(blockNumber + ED_ORDER_EXPIRATION_IN_BLOCKS); + nonce = new BigNumber(42); + const edOrderHash = `0x${crypto + .solSHA256([etherDelta.address, tokenGet, amountGet, tokenGive, amountGive, expires, nonce]) + .toString('hex')}`; + const shouldAddPersonalMessagePrefix = false; + edSignature = await zeroEx.signOrderHashAsync(edOrderHash, edMaker, shouldAddPersonalMessagePrefix); + addresses = [ + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, + edMaker, + ]; + const fillTakerTokenAmount = takerTokenAmount; + const edFillAmount = makerTokenAmount; + values = [ + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, + fillTakerTokenAmount, + amountGet, + amountGive, + expires, + nonce, + edFillAmount, + ]; + v = [signedOrder.ecSignature.v, edSignature.v]; + r = [signedOrder.ecSignature.r, edSignature.r]; + s = [signedOrder.ecSignature.s, edSignature.s]; + }); + it('should successfully execute the arbitrage if not front-runned', async () => { + const txHash = await arbitrage.makeAtomicTrade.sendTransactionAsync(addresses, values, v, r, s, { + from: coinbase, + }); + const res = await zeroEx.awaitTransactionMinedAsync(txHash); + const postBalance = await weth.balanceOf(arbitrage.address); + expect(postBalance).to.be.bignumber.equal(amountGive); + }); + it('should fail and revert if front-runned', async () => { + const preBalance = await weth.balanceOf(arbitrage.address); + // Front-running transaction + await etherDelta.trade.sendTransactionAsync( + tokenGet, + amountGet, + tokenGive, + amountGive, + expires, + nonce, + edMaker, + edSignature.v, + edSignature.r, + edSignature.s, + amountGet, + { from: edFrontRunner }, + ); + // tslint:disable-next-line:await-promise + await expect( + arbitrage.makeAtomicTrade.sendTransactionAsync(addresses, values, v, r, s, { from: coinbase }), + ).to.be.rejectedWith(constants.REVERT); + const postBalance = await weth.balanceOf(arbitrage.address); + expect(preBalance).to.be.bignumber.equal(postBalance); + }); + }); +}); 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/crypto.ts b/packages/contracts/util/crypto.ts index 9173df643..97b8f5643 100644 --- a/packages/contracts/util/crypto.ts +++ b/packages/contracts/util/crypto.ts @@ -13,6 +13,12 @@ export const crypto = { * valid Ethereum address -> address */ solSHA3(args: any[]): Buffer { + return crypto._solHash(args, ABI.soliditySHA3); + }, + solSHA256(args: any[]): Buffer { + return crypto._solHash(args, ABI.soliditySHA256); + }, + _solHash(args: any[], hashFunction: (types: string[], values: any[]) => Buffer) { const argTypes: string[] = []; _.each(args, (arg, i) => { const isNumber = _.isFinite(arg); @@ -31,7 +37,7 @@ export const crypto = { throw new Error(`Unable to guess arg type: ${arg}`); } }); - const hash = ABI.soliditySHA3(argTypes, args); + const hash = hashFunction(argTypes, args); return hash; }, }; 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..61a19acb4 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; @@ -96,6 +96,9 @@ export enum ContractName { EtherToken = 'WETH9', MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', MaliciousToken = 'MaliciousToken', + AccountLevels = 'AccountLevels', + EtherDelta = 'EtherDelta', + Arbitrage = 'Arbitrage', } export interface Artifact { diff --git a/packages/deployer/CHANGELOG.md b/packages/deployer/CHANGELOG.md index 1d28cbd41..05383bed5 100644 --- a/packages/deployer/CHANGELOG.md +++ b/packages/deployer/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.2.0 - _March 4, 2018_ + + * Check dependencies when determining if contracts should be recompiled (#408). + ## v0.1.0 - _February 16, 2018_ * Add the ability to pass in specific contracts to compile in CLI (#400) diff --git a/packages/deployer/README.md b/packages/deployer/README.md index f4e688fd7..4c4d234dd 100644 --- a/packages/deployer/README.md +++ b/packages/deployer/README.md @@ -22,11 +22,11 @@ Commands: Options: --version Show version number [boolean] --contracts-dir path of contracts directory to compile - [string] [default: "/Users/leonidlogvinov/Dev/0x/0x.js/contracts"] + [string] [default: "/Users/leonidlogvinov/Dev/0x/contracts"] --network-id mainnet=1, kovan=42, testrpc=50 [number] [default: 50] --should-optimize enable optimizer [boolean] [default: false] --artifacts-dir path to write contracts artifacts to - [string] [default: "/Users/leonidlogvinov/Dev/0x/0x.js/build/artifacts/"] + [string] [default: "/Users/leonidlogvinov/Dev/0x/build/artifacts/"] --jsonrpc-port port connected to JSON RPC [number] [default: 8545] --gas-price gasPrice to be used for transactions [string] [default: "2000000000"] diff --git a/packages/deployer/package.json b/packages/deployer/package.json index f969e4eda..32f67f071 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/deployer", - "version": "0.1.0", + "version": "0.2.0", "description": "Smart contract deployer of 0x protocol", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", @@ -19,30 +19,31 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "author": "Amir Bandeali", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/deployer/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/deployer/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "chai": "^4.0.1", "copyfiles": "^1.2.0", + "ethers-typescript-typings": "^0.0.2", "mocha": "^4.0.1", "shx": "^0.2.2", "tslint": "5.8.0", "types-bn": "^0.0.1", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11" + "web3-typescript-typings": "^0.10.0" }, "dependencies": { - "@0xproject/json-schemas": "^0.7.12", - "@0xproject/types": "^0.2.3", - "@0xproject/utils": "^0.3.4", - "@0xproject/web3-wrapper": "^0.1.14", + "@0xproject/json-schemas": "^0.7.13", + "@0xproject/types": "^0.3.0", + "@0xproject/utils": "^0.4.0", + "@0xproject/web3-wrapper": "^0.2.0", "ethereumjs-util": "^5.1.1", "lodash": "^4.17.4", "solc": "^0.4.18", diff --git a/packages/deployer/src/cli.ts b/packages/deployer/src/cli.ts index 3c6d042c0..c976e8f97 100644 --- a/packages/deployer/src/cli.ts +++ b/packages/deployer/src/cli.ts @@ -6,11 +6,12 @@ import * as Web3 from 'web3'; import * as yargs from 'yargs'; import { commands } from './commands'; +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(); @@ -99,9 +100,13 @@ 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 => { - specifiedContracts.add(contractName); + const fileName = `${contractName}${constants.SOLIDITY_FILE_EXTENSION}`; + specifiedContracts.add(fileName); }); return specifiedContracts; } diff --git a/packages/deployer/src/compiler.ts b/packages/deployer/src/compiler.ts index 2b0b81c44..149ca5d6d 100644 --- a/packages/deployer/src/compiler.ts +++ b/packages/deployer/src/compiler.ts @@ -5,32 +5,39 @@ import solc = require('solc'); import * as Web3 from 'web3'; import { binPaths } from './solc/bin_paths'; +import { constants } from './utils/constants'; import { fsWrapper } from './utils/fs_wrapper'; import { CompilerOptions, ContractArtifact, - ContractData, + ContractNetworkData, ContractNetworks, + ContractSourceData, ContractSources, + ContractSpecificSourceData, ImportContents, } from './utils/types'; import { utils } from './utils/utils'; -const SOLIDITY_FILE_EXTENSION = '.sol'; const ALL_CONTRACTS_IDENTIFIER = '*'; +const SOLIDITY_VERSION_REGEX = /(?:solidity\s\^?)(\d+\.\d+\.\d+)/; +const SOLIDITY_FILE_EXTENSION_REGEX = /(.*\.sol)/; +const IMPORT_REGEX = /(import\s)/; +const DEPENDENCY_PATH_REGEX = /"([^"]+)"/; // Source: https://github.com/BlockChainCompany/soljitsu/blob/master/lib/shared.js export class Compiler { private _contractsDir: string; private _networkId: number; private _optimizerEnabled: number; private _artifactsDir: string; - private _contractSourcesIfExists?: ContractSources; - private _solcErrors: Set<string>; - private _specifiedContracts: Set<string>; + private _contractSources?: ContractSources; + private _solcErrors: Set<string> = new Set(); + private _specifiedContracts: Set<string> = new Set(); + private _contractSourceData: ContractSourceData = {}; /** * Recursively retrieves Solidity source code from directory. * @param dirPath Directory to search. - * @return Mapping of contract name to contract source. + * @return Mapping of contract fileName to contract source. */ private static async _getContractSourcesAsync(dirPath: string): Promise<ContractSources> { let dirContents: string[] = []; @@ -40,15 +47,16 @@ export class Compiler { throw new Error(`No directory found at ${dirPath}`); } let sources: ContractSources = {}; - for (const name of dirContents) { - const contentPath = `${dirPath}/${name}`; - if (path.extname(name) === SOLIDITY_FILE_EXTENSION) { + for (const fileName of dirContents) { + const contentPath = `${dirPath}/${fileName}`; + if (path.extname(fileName) === constants.SOLIDITY_FILE_EXTENSION) { try { const opts = { encoding: 'utf8', }; - sources[name] = await fsWrapper.readFileAsync(contentPath, opts); - utils.consoleLog(`Reading ${name} source...`); + const source = await fsWrapper.readFileAsync(contentPath, opts); + sources[fileName] = source; + utils.consoleLog(`Reading ${fileName} source...`); } catch (err) { utils.consoleLog(`Could not find file at ${contentPath}`); } @@ -60,19 +68,46 @@ export class Compiler { ...nestedSources, }; } catch (err) { - utils.consoleLog(`${contentPath} is not a directory or ${SOLIDITY_FILE_EXTENSION} file`); + utils.consoleLog(`${contentPath} is not a directory or ${constants.SOLIDITY_FILE_EXTENSION} file`); } } } return sources; } /** + * Gets contract dependendencies and keccak256 hash from source. + * @param source Source code of contract. + * @return Object with contract dependencies and keccak256 hash of source. + */ + private static _getContractSpecificSourceData(source: string): ContractSpecificSourceData { + const dependencies: string[] = []; + const sourceHash = ethUtil.sha3(source); + const solcVersion = Compiler._parseSolidityVersion(source); + const contractSpecificSourceData: ContractSpecificSourceData = { + dependencies, + solcVersion, + sourceHash, + }; + const lines = source.split('\n'); + _.forEach(lines, line => { + if (!_.isNull(line.match(IMPORT_REGEX))) { + const dependencyMatch = line.match(DEPENDENCY_PATH_REGEX); + if (!_.isNull(dependencyMatch)) { + const dependencyPath = dependencyMatch[1]; + const fileName = path.basename(dependencyPath); + contractSpecificSourceData.dependencies.push(fileName); + } + } + }); + return contractSpecificSourceData; + } + /** * Searches Solidity source code for compiler version. * @param source Source code of contract. * @return Solc compiler version. */ private static _parseSolidityVersion(source: string): string { - const solcVersionMatch = source.match(/(?:solidity\s\^?)([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{1,2})/); + const solcVersionMatch = source.match(SOLIDITY_VERSION_REGEX); if (_.isNull(solcVersionMatch)) { throw new Error('Could not find Solidity version in source'); } @@ -88,7 +123,7 @@ export class Compiler { * @return The error message with directories truncated from the contract path. */ private static _getNormalizedErrMsg(errMsg: string): string { - const errPathMatch = errMsg.match(/(.*\.sol)/); + const errPathMatch = errMsg.match(SOLIDITY_FILE_EXTENSION_REGEX); if (_.isNull(errPathMatch)) { throw new Error('Could not find a path in error message'); } @@ -107,7 +142,6 @@ export class Compiler { this._networkId = opts.networkId; this._optimizerEnabled = opts.optimizerEnabled; this._artifactsDir = opts.artifactsDir; - this._solcErrors = new Set(); this._specifiedContracts = opts.specifiedContracts; } /** @@ -115,68 +149,52 @@ export class Compiler { */ public async compileAllAsync(): Promise<void> { await this._createArtifactsDirIfDoesNotExistAsync(); - this._contractSourcesIfExists = await Compiler._getContractSourcesAsync(this._contractsDir); - const contractBaseNames = _.keys(this._contractSourcesIfExists); - const compiledContractPromises = _.map(contractBaseNames, async (contractBaseName: string): Promise<void> => { - return this._compileContractAsync(contractBaseName); + this._contractSources = await Compiler._getContractSourcesAsync(this._contractsDir); + _.forIn(this._contractSources, (source, fileName) => { + this._contractSourceData[fileName] = Compiler._getContractSpecificSourceData(source); }); - await Promise.all(compiledContractPromises); - + const fileNames = this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER) + ? _.keys(this._contractSources) + : Array.from(this._specifiedContracts.values()); + _.forEach(fileNames, fileName => { + this._setSourceTreeHash(fileName); + }); + await Promise.all(_.map(fileNames, async fileName => this._compileContractAsync(fileName))); this._solcErrors.forEach(errMsg => { utils.consoleLog(errMsg); }); } /** * Compiles contract and saves artifact to artifactsDir. - * @param contractBaseName Name of contract with '.sol' extension. + * @param fileName Name of contract with '.sol' extension. */ - private async _compileContractAsync(contractBaseName: string): Promise<void> { - if (_.isUndefined(this._contractSourcesIfExists)) { + private async _compileContractAsync(fileName: string): Promise<void> { + if (_.isUndefined(this._contractSources)) { throw new Error('Contract sources not yet initialized'); } + const contractSpecificSourceData = this._contractSourceData[fileName]; + const currentArtifactIfExists = (await this._getContractArtifactIfExistsAsync(fileName)) as ContractArtifact; + const sourceHash = `0x${contractSpecificSourceData.sourceHash.toString('hex')}`; + const sourceTreeHash = `0x${contractSpecificSourceData.sourceTreeHashIfExists.toString('hex')}`; - const source = this._contractSourcesIfExists[contractBaseName]; - const contractName = path.basename(contractBaseName, SOLIDITY_FILE_EXTENSION); - const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`; - const sourceHash = `0x${ethUtil.sha3(source).toString('hex')}`; - const isContractSpecified = - this._specifiedContracts.has(ALL_CONTRACTS_IDENTIFIER) || this._specifiedContracts.has(contractName); - - let currentArtifactString: string; - let currentArtifact: ContractArtifact; - let oldNetworks: ContractNetworks; - let shouldCompile: boolean; - try { - const opts = { - encoding: 'utf8', - }; - currentArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts); - currentArtifact = JSON.parse(currentArtifactString); - oldNetworks = currentArtifact.networks; - const oldNetwork: ContractData = oldNetworks[this._networkId]; - shouldCompile = - (_.isUndefined(oldNetwork) || - oldNetwork.keccak256 !== sourceHash || - oldNetwork.optimizer_enabled !== this._optimizerEnabled) && - isContractSpecified; - } catch (err) { - shouldCompile = isContractSpecified; - } - + const shouldCompile = + _.isUndefined(currentArtifactIfExists) || + currentArtifactIfExists.networks[this._networkId].optimizer_enabled !== this._optimizerEnabled || + currentArtifactIfExists.networks[this._networkId].source_tree_hash !== sourceTreeHash; if (!shouldCompile) { return; } - const input = { - [contractBaseName]: source, - }; - const solcVersion = Compiler._parseSolidityVersion(source); - const fullSolcVersion = binPaths[solcVersion]; + const fullSolcVersion = binPaths[contractSpecificSourceData.solcVersion]; const solcBinPath = `./solc/solc_bin/${fullSolcVersion}`; const solcBin = require(solcBinPath); const solcInstance = solc.setupMethods(solcBin); - utils.consoleLog(`Compiling ${contractBaseName}...`); + utils.consoleLog(`Compiling ${fileName}...`); + const source = this._contractSources[fileName]; + const input = { + [fileName]: source, + }; const sourcesToCompile = { sources: input, }; @@ -187,19 +205,21 @@ export class Compiler { ); if (!_.isUndefined(compiled.errors)) { - _.each(compiled.errors, errMsg => { + _.forEach(compiled.errors, errMsg => { const normalizedErrMsg = Compiler._getNormalizedErrMsg(errMsg); this._solcErrors.add(normalizedErrMsg); }); } - const contractIdentifier = `${contractBaseName}:${contractName}`; + const contractName = path.basename(fileName, constants.SOLIDITY_FILE_EXTENSION); + const contractIdentifier = `${fileName}:${contractName}`; const abi: Web3.ContractAbi = JSON.parse(compiled.contracts[contractIdentifier].interface); const unlinked_binary = `0x${compiled.contracts[contractIdentifier].bytecode}`; const updated_at = Date.now(); - const contractData: ContractData = { - solc_version: solcVersion, + const contractNetworkData: ContractNetworkData = { + solc_version: contractSpecificSourceData.solcVersion, keccak256: sourceHash, + source_tree_hash: sourceTreeHash, optimizer_enabled: this._optimizerEnabled, abi, unlinked_binary, @@ -207,26 +227,56 @@ export class Compiler { }; let newArtifact: ContractArtifact; - if (!_.isUndefined(currentArtifactString)) { + if (!_.isUndefined(currentArtifactIfExists)) { newArtifact = { - ...currentArtifact, + ...currentArtifactIfExists, networks: { - ...oldNetworks, - [this._networkId]: contractData, + ...currentArtifactIfExists.networks, + [this._networkId]: contractNetworkData, }, }; } else { newArtifact = { contract_name: contractName, networks: { - [this._networkId]: contractData, + [this._networkId]: contractNetworkData, }, }; } const artifactString = utils.stringifyWithFormatting(newArtifact); + const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`; await fsWrapper.writeFileAsync(currentArtifactPath, artifactString); - utils.consoleLog(`${contractBaseName} artifact saved!`); + utils.consoleLog(`${fileName} artifact saved!`); + } + /** + * Sets the source tree hash for a file and its dependencies. + * @param fileName Name of contract file. + */ + private _setSourceTreeHash(fileName: string): void { + const contractSpecificSourceData = this._contractSourceData[fileName]; + if (_.isUndefined(contractSpecificSourceData)) { + throw new Error(`Contract data for ${fileName} not yet set`); + } + if (_.isUndefined(contractSpecificSourceData.sourceTreeHashIfExists)) { + const dependencies = contractSpecificSourceData.dependencies; + if (dependencies.length === 0) { + contractSpecificSourceData.sourceTreeHashIfExists = contractSpecificSourceData.sourceHash; + } else { + _.forEach(dependencies, dependency => { + this._setSourceTreeHash(dependency); + }); + const dependencySourceTreeHashes = _.map( + dependencies, + dependency => this._contractSourceData[dependency].sourceTreeHashIfExists, + ); + const sourceTreeHashesBuffer = Buffer.concat([ + contractSpecificSourceData.sourceHash, + ...dependencySourceTreeHashes, + ]); + contractSpecificSourceData.sourceTreeHashIfExists = ethUtil.sha3(sourceTreeHashesBuffer); + } + } } /** * Callback to resolve dependencies with `solc.compile`. @@ -235,11 +285,11 @@ export class Compiler { * @return Import contents object containing source code of dependency. */ private _findImportsIfSourcesExist(importPath: string): ImportContents { - if (_.isUndefined(this._contractSourcesIfExists)) { - throw new Error('Contract sources not yet initialized'); + const fileName = path.basename(importPath); + const source = this._contractSources[fileName]; + if (_.isUndefined(source)) { + throw new Error(`Contract source not found for ${fileName}`); } - const contractBaseName = path.basename(importPath); - const source = this._contractSourcesIfExists[contractBaseName]; const importContents: ImportContents = { contents: source, }; @@ -254,4 +304,25 @@ export class Compiler { await fsWrapper.mkdirAsync(this._artifactsDir); } } + /** + * Gets contract data on network or returns if an artifact does not exist. + * @param fileName Name of contract file. + * @return Contract data on network or undefined. + */ + private async _getContractArtifactIfExistsAsync(fileName: string): Promise<ContractArtifact | void> { + let contractArtifact; + const contractName = path.basename(fileName, constants.SOLIDITY_FILE_EXTENSION); + const currentArtifactPath = `${this._artifactsDir}/${contractName}.json`; + try { + const opts = { + encoding: 'utf8', + }; + const contractArtifactString = await fsWrapper.readFileAsync(currentArtifactPath, opts); + contractArtifact = JSON.parse(contractArtifactString); + return contractArtifact; + } catch (err) { + utils.consoleLog(`Artifact for ${fileName} does not exist`); + return undefined; + } + } } diff --git a/packages/deployer/src/deployer.ts b/packages/deployer/src/deployer.ts index 6f03581e8..6710bcc85 100644 --- a/packages/deployer/src/deployer.ts +++ b/packages/deployer/src/deployer.ts @@ -6,7 +6,7 @@ import * as Web3 from 'web3'; import { Contract } from './utils/contract'; import { encoder } from './utils/encoder'; import { fsWrapper } from './utils/fs_wrapper'; -import { ContractArtifact, ContractData, DeployerOptions } from './utils/types'; +import { ContractArtifact, ContractNetworkData, DeployerOptions } from './utils/types'; import { utils } from './utils/utils'; // Gas added to gas estimate to make sure there is sufficient gas for deployment. @@ -35,9 +35,11 @@ export class Deployer { * @return Deployed contract instance. */ public async deployAsync(contractName: string, args: any[] = []): Promise<Web3.ContractInstance> { - const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName); - const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact); - const data = contractData.unlinked_binary; + const contractArtifactIfExists: ContractArtifact = this._loadContractArtifactIfExists(contractName); + const contractNetworkDataIfExists: ContractNetworkData = this._getContractNetworkDataFromArtifactIfExists( + contractArtifactIfExists, + ); + const data = contractNetworkDataIfExists.unlinked_binary; const from = await this._getFromAddressAsync(); const gas = await this._getAllowableGasEstimateAsync(data); const txData = { @@ -46,7 +48,7 @@ export class Deployer { data, gas, }; - const abi = contractData.abi; + const abi = contractNetworkDataIfExists.abi; const web3ContractInstance = await this._deployFromAbiAsync(abi, args, txData); utils.consoleLog(`${contractName}.sol successfully deployed at ${web3ContractInstance.address}`); const contractInstance = new Contract(web3ContractInstance, this._defaults); @@ -100,19 +102,21 @@ export class Deployer { contractAddress: string, args: any[], ): Promise<void> { - const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName); - const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact); - const abi = contractData.abi; + const contractArtifactIfExists: ContractArtifact = this._loadContractArtifactIfExists(contractName); + const contractNetworkDataIfExists: ContractNetworkData = this._getContractNetworkDataFromArtifactIfExists( + contractArtifactIfExists, + ); + const abi = contractNetworkDataIfExists.abi; const encodedConstructorArgs = encoder.encodeConstructorArgsFromAbi(args, abi); const newContractData = { - ...contractData, + ...contractNetworkDataIfExists, address: contractAddress, constructor_args: encodedConstructorArgs, }; const newArtifact = { - ...contractArtifact, + ...contractArtifactIfExists, networks: { - ...contractArtifact.networks, + ...contractArtifactIfExists.networks, [this._networkId]: newContractData, }, }; @@ -139,12 +143,12 @@ export class Deployer { * @param contractArtifact The contract artifact. * @return Network specific contract data. */ - private _getContractDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractData { - const contractData = contractArtifact.networks[this._networkId]; - if (_.isUndefined(contractData)) { + private _getContractNetworkDataFromArtifactIfExists(contractArtifact: ContractArtifact): ContractNetworkData { + const contractNetworkDataIfExists = contractArtifact.networks[this._networkId]; + if (_.isUndefined(contractNetworkDataIfExists)) { throw new Error(`Data not found in artifact for contract: ${contractArtifact.contract_name}`); } - return contractData; + return contractNetworkDataIfExists; } /** * Gets the address to use for sending a transaction. @@ -170,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/src/utils/constants.ts b/packages/deployer/src/utils/constants.ts index 8871a470d..57f30dec8 100644 --- a/packages/deployer/src/utils/constants.ts +++ b/packages/deployer/src/utils/constants.ts @@ -1,3 +1,4 @@ export const constants = { NULL_BYTES: '0x', + SOLIDITY_FILE_EXTENSION: '.sol', }; diff --git a/packages/deployer/src/utils/encoder.ts b/packages/deployer/src/utils/encoder.ts index d5f807774..e3acde252 100644 --- a/packages/deployer/src/utils/encoder.ts +++ b/packages/deployer/src/utils/encoder.ts @@ -9,7 +9,7 @@ export const encoder = { const constructorTypes: string[] = []; _.each(abi, (element: Web3.AbiDefinition) => { if (element.type === AbiType.Constructor) { - _.each(element.inputs, (input: Web3.FunctionParameter) => { + _.each(element.inputs, (input: Web3.DataItem) => { constructorTypes.push(input.type); }); } diff --git a/packages/deployer/src/utils/types.ts b/packages/deployer/src/utils/types.ts index 46481828e..a3f722976 100644 --- a/packages/deployer/src/utils/types.ts +++ b/packages/deployer/src/utils/types.ts @@ -15,13 +15,14 @@ export interface ContractArtifact { } export interface ContractNetworks { - [key: number]: ContractData; + [key: number]: ContractNetworkData; } -export interface ContractData { +export interface ContractNetworkData { solc_version: string; optimizer_enabled: number; keccak256: string; + source_tree_hash: string; abi: Web3.ContractAbi; unlinked_binary: string; address?: string; @@ -64,6 +65,17 @@ export interface ContractSources { [key: string]: string; } +export interface ContractSourceData { + [key: string]: ContractSpecificSourceData; +} + +export interface ContractSpecificSourceData { + dependencies: string[]; + solcVersion: string; + sourceHash: Buffer; + sourceTreeHashIfExists?: Buffer; +} + export interface ImportContents { contents: string; } diff --git a/packages/deployer/test/deploy_test.ts b/packages/deployer/test/deploy_test.ts index 6a8397982..422d3763e 100644 --- a/packages/deployer/test/deploy_test.ts +++ b/packages/deployer/test/deploy_test.ts @@ -4,7 +4,7 @@ import 'mocha'; import { Compiler } from '../src/compiler'; import { Deployer } from '../src/deployer'; import { fsWrapper } from '../src/utils/fs_wrapper'; -import { CompilerOptions, ContractArtifact, ContractData, DoneCallback } from '../src/utils/types'; +import { CompilerOptions, ContractArtifact, ContractNetworkData, DoneCallback } from '../src/utils/types'; import { constructor_args, exchange_binary } from './fixtures/exchange_bin'; import { constants } from './util/constants'; @@ -51,7 +51,7 @@ describe('#Compiler', () => { }; const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); - const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; + const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId]; // The last 43 bytes of the binaries are metadata which may not be equivalent const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86); const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86); @@ -68,7 +68,7 @@ describe('#Deployer', () => { }; const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); - const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; + const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId]; const exchangeAddress = exchangeContractInstance.address; expect(exchangeAddress).to.not.equal(undefined); expect(exchangeContractData.address).to.equal(undefined); @@ -84,7 +84,7 @@ describe('#Deployer', () => { }; const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); - const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; + const exchangeContractData: ContractNetworkData = exchangeArtifact.networks[constants.networkId]; const exchangeAddress = exchangeContractInstance.address; expect(exchangeAddress).to.be.equal(exchangeContractData.address); expect(constructor_args).to.be.equal(exchangeContractData.constructor_args); 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/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 41f59d3af..ecc5546ae 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## v0.1.0 - _February 16, 2018_ +## v0.2.0 - _February 16, 2018_ * Remove subproviders (#392) diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 515edc353..4ad613dbe 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/dev-utils", - "version": "0.1.0", + "version": "0.2.0", "description": "0x dev TS utils", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", @@ -16,20 +16,19 @@ "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/dev-utils/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", - "@0xproject/web3-wrapper": "^0.1.14", + "@0xproject/tslint-config": "^0.4.10", + "@0xproject/web3-wrapper": "^0.2.0", "@types/lodash": "^4.14.86", "@types/mocha": "^2.2.42", "chai": "^4.0.1", - "chai-typescript-typings": "^0.0.3", + "chai-typescript-typings": "^0.0.4", "mocha": "^4.0.1", "npm-run-all": "^4.1.2", "shx": "^0.2.2", @@ -39,8 +38,9 @@ "typescript": "2.7.1" }, "dependencies": { - "@0xproject/subproviders": "^0.5.0", - "@0xproject/utils": "^0.3.4", + "@0xproject/subproviders": "^0.6.0", + "@0xproject/types": "^0.3.0", + "@0xproject/utils": "^0.4.0", "ethereumjs-util": "^5.1.2", "lodash": "^4.17.4", "request-promise-native": "^1.0.5", 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..00bf165a4 --- /dev/null +++ b/packages/ethers-typescript-typings/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## v0.0.2 - _March 4, 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..588ff52b5 --- /dev/null +++ b/packages/ethers-typescript-typings/package.json @@ -0,0 +1,28 @@ +{ + "name": "ethers-typescript-typings", + "version": "0.0.2", + "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-monorepo.git" + }, + "author": "Fabio Berger", + "contributors": [ + "Leonid Logvinov <logvinov.leon@gmail.com>" + ], + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/0xProject/0x-monorepo/issues" + }, + "homepage": "https://github.com/0xProject/0x-monorepo/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..ab98227af 100644 --- a/packages/json-schemas/CHANGELOG.md +++ b/packages/json-schemas/CHANGELOG.md @@ -1,8 +1,8 @@ # CHANGELOG -## v0.7.10 - _February 9, 2018_ +## v0.7.13 - _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/json-schemas/package.json b/packages/json-schemas/package.json index 6952c9bdd..230732cec 100644 --- a/packages/json-schemas/package.json +++ b/packages/json-schemas/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/json-schemas", - "version": "0.7.12", + "version": "0.7.13", "description": "0x-related json schemas", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", @@ -15,26 +15,26 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "author": "", "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/json-schemas/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/json-schemas/README.md", "dependencies": { "jsonschema": "^1.2.0", "lodash.values": "^4.3.0" }, "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", - "@0xproject/utils": "^0.3.4", + "@0xproject/tslint-config": "^0.4.10", + "@0xproject/utils": "^0.4.0", "@types/lodash.foreach": "^4.5.3", "@types/lodash.values": "^4.3.3", "@types/mocha": "^2.2.42", "chai": "^4.0.1", - "chai-typescript-typings": "^0.0.3", + "chai-typescript-typings": "^0.0.4", "dirty-chai": "^2.0.1", "lodash.foreach": "^4.5.0", "mocha": "^4.0.1", diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index 8edfef605..c9bbe0c6a 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/monorepo-scripts", - "version": "0.1.11", + "version": "0.1.12", "private": true, "description": "Helper scripts for the monorepo", "scripts": { @@ -12,15 +12,15 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/monorepo-scripts/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/monorepo-scripts/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "@types/glob": "^5.0.33", "@types/node": "^8.0.53", "shx": "^0.2.2", diff --git a/packages/subproviders/CHANGELOG.md b/packages/subproviders/CHANGELOG.md index c2d590a35..7e1e006e3 100644 --- a/packages/subproviders/CHANGELOG.md +++ b/packages/subproviders/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## v0.6.0 - _March 4, 2018_ + + * Move web3 types from being a devDep to a dep since one cannot use this package without it (#429) + * Add `numberOfAccounts` param to `LedgerSubprovider` method `getAccountsAsync` (#432) + ## v0.5.0 - _February 16, 2018_ * Add EmptyWalletSubprovider and FakeGasEstimateSubprovider (#392) 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/subproviders/package.json b/packages/subproviders/package.json index 0c791b80f..ec0642bce 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/subproviders", - "version": "0.5.0", + "version": "0.6.0", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "license": "Apache-2.0", @@ -18,8 +18,9 @@ "test:integration": "run-s clean build run_mocha_integration" }, "dependencies": { - "@0xproject/assert": "^0.0.20", - "@0xproject/utils": "^0.3.4", + "@0xproject/assert": "^0.1.0", + "@0xproject/types": "^0.3.0", + "@0xproject/utils": "^0.4.0", "bn.js": "^4.11.8", "es6-promisify": "^5.0.0", "ethereumjs-tx": "^1.3.3", @@ -29,20 +30,20 @@ "lodash": "^4.17.4", "semaphore-async-await": "^1.5.1", "web3": "^0.20.0", - "web3-provider-engine": "^13.0.1" + "web3-provider-engine": "^13.0.1", + "web3-typescript-typings": "^0.10.0" }, "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", - "@0xproject/utils": "^0.3.4", + "@0xproject/tslint-config": "^0.4.10", + "@0xproject/utils": "^0.4.0", "@types/lodash": "^4.14.86", "@types/mocha": "^2.2.42", "@types/node": "^8.0.53", "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", - "chai-as-promised-typescript-typings": "^0.0.9", - "chai-typescript-typings": "^0.0.3", + "chai-as-promised-typescript-typings": "^0.0.10", + "chai-typescript-typings": "^0.0.4", "dirty-chai": "^2.0.1", "mocha": "^4.0.1", "npm-run-all": "^4.1.2", @@ -51,7 +52,6 @@ "types-bn": "^0.0.1", "types-ethereumjs-util": "0xProject/types-ethereumjs-util", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11", "webpack": "^3.1.0" } } diff --git a/packages/subproviders/src/subproviders/ledger.ts b/packages/subproviders/src/subproviders/ledger.ts index 5966a88bb..85cdf0efc 100644 --- a/packages/subproviders/src/subproviders/ledger.ts +++ b/packages/subproviders/src/subproviders/ledger.ts @@ -19,7 +19,7 @@ import { import { Subprovider } from './subprovider'; const DEFAULT_DERIVATION_PATH = `44'/60'/0'`; -const NUM_ADDRESSES_TO_FETCH = 10; +const DEFAULT_NUM_ADDRESSES_TO_FETCH = 10; const ASK_FOR_ON_DEVICE_CONFIRMATION = false; const SHOULD_GET_CHAIN_CODE = true; @@ -129,7 +129,7 @@ export class LedgerSubprovider extends Subprovider { return; } } - public async getAccountsAsync(): Promise<string[]> { + public async getAccountsAsync(numberOfAccounts: number = DEFAULT_NUM_ADDRESSES_TO_FETCH): Promise<string[]> { this._ledgerClientIfExists = await this._createLedgerClientAsync(); let ledgerResponse; @@ -148,7 +148,7 @@ export class LedgerSubprovider extends Subprovider { hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex'); const accounts = []; - for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) { + for (let i = 0; i < numberOfAccounts; i++) { const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`); const derivedPublicKey = derivedHDNode.publicKey; const shouldSanitizePublicKey = true; diff --git a/packages/subproviders/test/integration/ledger_subprovider_test.ts b/packages/subproviders/test/integration/ledger_subprovider_test.ts index 628b532d7..b052a76d2 100644 --- a/packages/subproviders/test/integration/ledger_subprovider_test.ts +++ b/packages/subproviders/test/integration/ledger_subprovider_test.ts @@ -26,11 +26,17 @@ describe('LedgerSubprovider', () => { }); }); describe('direct method calls', () => { - it('returns a list of accounts', async () => { + it('returns default number of accounts', async () => { const accounts = await ledgerSubprovider.getAccountsAsync(); expect(accounts[0]).to.not.be.an('undefined'); expect(accounts.length).to.be.equal(10); }); + it('returns requested number of accounts', async () => { + const numberOfAccounts = 20; + const accounts = await ledgerSubprovider.getAccountsAsync(numberOfAccounts); + expect(accounts[0]).to.not.be.an('undefined'); + expect(accounts.length).to.be.equal(numberOfAccounts); + }); it('signs a personal message', async () => { const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world')); const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data); @@ -172,7 +178,7 @@ describe('LedgerSubprovider', () => { }; const callback = reportCallbackErrors(done)((err: Error, response: Web3.JSONRPCResponsePayload) => { expect(err).to.be.a('null'); - const result = response.result.result; + const result = response.result; expect(result.length).to.be.equal(66); expect(result.substr(0, 2)).to.be.equal('0x'); done(); diff --git a/packages/subproviders/test/unit/ledger_subprovider_test.ts b/packages/subproviders/test/unit/ledger_subprovider_test.ts index 1c70dd3a6..0d301bce9 100644 --- a/packages/subproviders/test/unit/ledger_subprovider_test.ts +++ b/packages/subproviders/test/unit/ledger_subprovider_test.ts @@ -62,11 +62,17 @@ describe('LedgerSubprovider', () => { }); describe('direct method calls', () => { describe('success cases', () => { - it('returns a list of accounts', async () => { + it('returns default number of accounts', async () => { const accounts = await ledgerSubprovider.getAccountsAsync(); expect(accounts[0]).to.be.equal(FAKE_ADDRESS); expect(accounts.length).to.be.equal(10); }); + it('returns requested number of accounts', async () => { + const numberOfAccounts = 20; + const accounts = await ledgerSubprovider.getAccountsAsync(numberOfAccounts); + expect(accounts[0]).to.be.equal(FAKE_ADDRESS); + expect(accounts.length).to.be.equal(numberOfAccounts); + }); it('signs a personal message', async () => { const data = ethUtils.bufferToHex(ethUtils.toBuffer('hello world')); const ecSignatureHex = await ledgerSubprovider.signPersonalMessageAsync(data); diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 64f4427e1..ccb303909 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/testnet-faucets", - "version": "1.0.14", + "version": "1.0.15", "description": "A faucet micro-service that dispenses test ERC20 tokens or Ether", "main": "server.js", "scripts": { @@ -15,9 +15,9 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^0.32.4", - "@0xproject/subproviders": "^0.5.0", - "@0xproject/utils": "^0.3.4", + "0x.js": "^0.33.0", + "@0xproject/subproviders": "^0.6.0", + "@0xproject/utils": "^0.4.0", "body-parser": "^1.17.1", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.1.1", @@ -28,7 +28,7 @@ "web3-provider-engine": "^13.0.1" }, "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "@types/body-parser": "^1.16.1", "@types/express": "^4.0.35", "@types/lodash": "^4.14.86", @@ -41,7 +41,7 @@ "types-bn": "^0.0.1", "types-ethereumjs-util": "0xProject/types-ethereumjs-util", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11", + "web3-typescript-typings": "^0.10.0", "webpack": "^3.1.0", "webpack-node-externals": "^1.6.0" } diff --git a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts index 9aa47463c..56b0a9e45 100644 --- a/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts +++ b/packages/testnet-faucets/src/ts/dispense_asset_tasks.ts @@ -9,11 +9,21 @@ import { utils } from './utils'; const DISPENSE_AMOUNT_ETHER = 0.1; const DISPENSE_AMOUNT_TOKEN = 0.1; +const DISPENSE_MAX_AMOUNT_TOKEN = 2; +const DISPENSE_MAX_AMOUNT_ETHER = 2; export const dispenseAssetTasks = { dispenseEtherTask(recipientAddress: string, web3: Web3) { return async () => { utils.consoleLog(`Processing ETH ${recipientAddress}`); + const userBalance = await promisify<BigNumber>(web3.eth.getBalance)(recipientAddress); + const maxAmountInWei = new BigNumber(web3.toWei(DISPENSE_MAX_AMOUNT_ETHER, 'ether')); + if (userBalance.greaterThanOrEqualTo(maxAmountInWei)) { + utils.consoleLog( + `User exceeded ETH balance maximum (${maxAmountInWei}) ${recipientAddress} ${userBalance} `, + ); + return; + } const sendTransactionAsync = promisify(web3.eth.sendTransaction); const txHash = await sendTransactionAsync({ from: configs.DISPENSER_ADDRESS, @@ -32,6 +42,17 @@ export const dispenseAssetTasks = { throw new Error(`Unsupported asset type: ${tokenSymbol}`); } const baseUnitAmount = ZeroEx.toBaseUnitAmount(amountToDispense, token.decimals); + const userBalanceBaseUnits = await zeroEx.token.getBalanceAsync(token.address, recipientAddress); + const maxAmountBaseUnits = ZeroEx.toBaseUnitAmount( + new BigNumber(DISPENSE_MAX_AMOUNT_TOKEN), + token.decimals, + ); + if (userBalanceBaseUnits.greaterThanOrEqualTo(maxAmountBaseUnits)) { + utils.consoleLog( + `User exceeded token balance maximum (${maxAmountBaseUnits}) ${recipientAddress} ${userBalanceBaseUnits} `, + ); + return; + } const txHash = await zeroEx.token.transferAsync( token.address, configs.DISPENSER_ADDRESS, diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json index 3f431f1b4..4830a448e 100644 --- a/packages/tslint-config/package.json +++ b/packages/tslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/tslint-config", - "version": "0.4.9", + "version": "0.4.10", "description": "Lint rules related to 0xProject for TSLint", "main": "tslint.json", "scripts": { @@ -11,7 +11,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/0xProject/0x.js.git" + "url": "git://github.com/0xProject/0x-monorepo.git" }, "keywords": [ "tslint", @@ -26,9 +26,9 @@ }, "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/tslint-config/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/tslint-config/README.md", "devDependencies": { "@types/lodash": "^4.14.86", "shx": "^0.2.2", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index b1cb721d2..e1117b170 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## v0.3.0 - _March 4, 2018_ + + * Add `data` to `TxData` (#413) + * Add `number` as an option to `ContractEventArg` (#413) + * Move web3 types from devDep to dep since required when using this package (#429) + ## v0.2.1 - _February 9, 2018_ * Fix publishing issue where .npmignore was not properly excluding undesired content (#389) diff --git a/packages/types/package.json b/packages/types/package.json index afaa1aa48..31e853113 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/types", - "version": "0.2.3", + "version": "0.3.0", "description": "0x types", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -13,21 +13,21 @@ "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/types/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/types/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", + "@0xproject/tslint-config": "^0.4.10", "shx": "^0.2.2", "tslint": "5.8.0", - "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11" + "typescript": "2.7.1" }, "dependencies": { "bignumber.js": "~4.1.0", - "web3": "^0.20.0" + "web3": "^0.20.0", + "web3-typescript-typings": "^0.10.0" } } 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..bf9cf53b4 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## v0.4.0 - _March 4, 2018_ + + * Use `ethers-contracts` as a backend to decode event args (#413) + * Move web3 types from devDep to dep since required when using this package (#429) + ## 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 750ecaa2f..424a73dd2 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/utils", - "version": "0.3.4", + "version": "0.4.0", "description": "0x TS utils", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -13,26 +13,28 @@ "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/utils/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/utils/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", + "@0xproject/tslint-config": "^0.4.10", "@types/lodash": "^4.14.86", "npm-run-all": "^4.1.2", "shx": "^0.2.2", "tslint": "5.8.0", - "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11" + "typescript": "2.7.1" }, "dependencies": { + "@0xproject/types": "^0.3.0", "bignumber.js": "~4.1.0", + "ethers-contracts": "^2.2.1", + "ethers-typescript-typings": "^0.0.2", "js-sha3": "^0.7.0", "lodash": "^4.17.4", - "web3": "^0.20.0" + "web3": "^0.20.0", + "web3-typescript-typings": "^0.10.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-typescript-typings/CHANGELOG.md b/packages/web3-typescript-typings/CHANGELOG.md index 5f74ceef0..1bf6d7459 100644 --- a/packages/web3-typescript-typings/CHANGELOG.md +++ b/packages/web3-typescript-typings/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.10.0 - _March 4, 2018_ + + * Support ABIv2 (#401) + ## v0.9.11 - _February 16, 2018_ * Fix `web3.net.peerCount` to be of type number instead of boolean (#397) diff --git a/packages/web3-typescript-typings/index.d.ts b/packages/web3-typescript-typings/index.d.ts index 915c73b90..6155d10f0 100644 --- a/packages/web3-typescript-typings/index.d.ts +++ b/packages/web3-typescript-typings/index.d.ts @@ -62,8 +62,8 @@ declare module 'web3' { interface MethodAbi { type: AbiType.Function; name: string; - inputs: FunctionParameter[]; - outputs: FunctionParameter[]; + inputs: DataItem[]; + outputs: DataItem[]; constant: boolean; stateMutability: StateMutability; payable: boolean; @@ -71,7 +71,7 @@ declare module 'web3' { interface ConstructorAbi { type: AbiType.Constructor; - inputs: FunctionParameter[]; + inputs: DataItem[]; payable: boolean; stateMutability: ConstructorStateMutability; } @@ -81,9 +81,7 @@ declare module 'web3' { payable: boolean; } - interface EventParameter { - name: string; - type: string; + interface EventParameter extends DataItem { indexed: boolean; } @@ -94,9 +92,10 @@ declare module 'web3' { anonymous: boolean; } - interface FunctionParameter { + interface DataItem { name: string; type: string; + components: DataItem[]; } interface ContractInstance { diff --git a/packages/web3-typescript-typings/package.json b/packages/web3-typescript-typings/package.json index 2b9430323..7db818759 100644 --- a/packages/web3-typescript-typings/package.json +++ b/packages/web3-typescript-typings/package.json @@ -1,6 +1,6 @@ { "name": "web3-typescript-typings", - "version": "0.9.11", + "version": "0.10.0", "description": "Typescript type definitions for web3", "main": "index.d.ts", "types": "index.d.ts", @@ -9,7 +9,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/0xProject/0x.js.git" + "url": "git+https://github.com/0xProject/0x-monorepo.git" }, "author": "Fabio Berger", "contributors": [ @@ -17,9 +17,9 @@ ], "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/web3-typescript-typings#readme", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/web3-typescript-typings#readme", "devDependencies": { "@types/bignumber.js": "^4.0.2", "tslint": "5.8.0", diff --git a/packages/web3-wrapper/CHANGELOG.md b/packages/web3-wrapper/CHANGELOG.md index eb31f7e3c..ac0f5ff0b 100644 --- a/packages/web3-wrapper/CHANGELOG.md +++ b/packages/web3-wrapper/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## v0.2.0 _March 4, 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 8e861b1d5..b754e791c 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/web3-wrapper", - "version": "0.1.14", + "version": "0.2.0", "description": "Wraps around web3 and gives a nicer interface", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -13,25 +13,27 @@ "license": "Apache-2.0", "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/web3-wrapper/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/web3-wrapper/README.md", "devDependencies": { - "@0xproject/tslint-config": "^0.4.9", - "@0xproject/types": "^0.2.3", + "@0xproject/tslint-config": "^0.4.10", "@types/lodash": "^4.14.86", "npm-run-all": "^4.1.2", "shx": "^0.2.2", "tslint": "5.8.0", - "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11" + "typescript": "2.7.1" }, "dependencies": { - "@0xproject/utils": "^0.3.4", + "@0xproject/types": "^0.3.0", + "@0xproject/utils": "^0.4.0", + "ethers-contracts": "^2.2.1", + "ethers-typescript-typings": "^0.0.2", "lodash": "^4.17.4", - "web3": "^0.20.0" + "web3": "^0.20.0", + "web3-typescript-typings": "^0.10.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/0xjs/installation.md b/packages/website/md/docs/0xjs/installation.md index 5f5c9137e..ac0a47699 100644 --- a/packages/website/md/docs/0xjs/installation.md +++ b/packages/website/md/docs/0xjs/installation.md @@ -18,7 +18,7 @@ import { ZeroEx } from '0x.js'; **Install** -Download the UMD module from our [releases page](https://github.com/0xProject/0x.js/releases) and add it to your project. +Download the UMD module from our [releases page](https://github.com/0xProject/0x-monorepo/releases) and add it to your project. **Import** diff --git a/packages/website/md/docs/0xjs/introduction.md b/packages/website/md/docs/0xjs/introduction.md index 7bad3eaa9..008376d33 100644 --- a/packages/website/md/docs/0xjs/introduction.md +++ b/packages/website/md/docs/0xjs/introduction.md @@ -1 +1 @@ -Welcome to the [0x.js](https://github.com/0xProject/0x.js) documentation! 0x.js is a Javascript library for interacting with the 0x protocol. With it, you can easily make calls to the 0x smart contracts as well as any ERC20 token. Functionality includes generating, signing, filling and cancelling orders, verifying an orders signature, setting or checking a users ERC20 token balance/allowance and much more. +Welcome to the [0x.js](https://github.com/0xProject/0x-monorepo) documentation! 0x.js is a Javascript library for interacting with the 0x protocol. With it, you can easily make calls to the 0x smart contracts as well as any ERC20 token. Functionality includes generating, signing, filling and cancelling orders, verifying an orders signature, setting or checking a users ERC20 token balance/allowance and much more. diff --git a/packages/website/md/docs/connect/installation.md b/packages/website/md/docs/connect/installation.md index 184fa6e0d..950bf92ca 100644 --- a/packages/website/md/docs/connect/installation.md +++ b/packages/website/md/docs/connect/installation.md @@ -12,4 +12,4 @@ import { HttpClient } from '@0xproject/connect'; ### Wiki -Check out our [0x Connect introduction tutorial](https://0xproject.com/wiki#Intro-Tutorial:-Connect) for information on how to integrate relayers into your application. +Check out our [0x Connect introduction tutorial](https://0xproject.com/wiki#Intro-Tutorial) for information on how to integrate relayers into your application. diff --git a/packages/website/md/docs/connect/introduction.md b/packages/website/md/docs/connect/introduction.md index 533e1481a..4e3039442 100644 --- a/packages/website/md/docs/connect/introduction.md +++ b/packages/website/md/docs/connect/introduction.md @@ -1 +1 @@ -Welcome to the [0x Connect](https://github.com/0xProject/0x.js/tree/development/packages/connect) documentation! 0x Connect is a Javascript library that makes it easy to interact with relayers that conform to the [Standard Relayer API](https://github.com/0xProject/standard-relayer-api). Functionality includes getting supported token pairs from a relayer, getting orders filtered by different attributes, getting individual orders specified by order hash, getting orderbooks for specific token pairs, getting fee information, and submitting orders. +Welcome to the [0x Connect](https://github.com/0xProject/0x-monorepo/tree/development/packages/connect) documentation! 0x Connect is a Javascript library that makes it easy to interact with relayers that conform to the [Standard Relayer API](https://github.com/0xProject/standard-relayer-api). Functionality includes getting supported token pairs from a relayer, getting orders filtered by different attributes, getting individual orders specified by order hash, getting orderbooks for specific token pairs, getting fee information, and submitting orders. 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 1643cf0bd..ca1b596f3 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/website", - "version": "0.0.16", + "version": "0.0.17", "private": true, "description": "Website and 0x portal dapp", "scripts": { @@ -18,9 +18,9 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^0.32.4", - "@0xproject/subproviders": "^0.5.0", - "@0xproject/utils": "^0.3.4", + "0x.js": "^0.33.0", + "@0xproject/subproviders": "^0.6.0", + "@0xproject/utils": "^0.4.0", "accounting": "^0.4.1", "basscss": "^8.0.3", "blockies": "^0.0.2", @@ -43,10 +43,10 @@ "react-document-title": "^2.0.3", "react-dom": "15.6.1", "react-ga": "^2.4.1", - "react-highlight": "^0.10.0", + "react-highlight": "0xproject/react-highlight", "react-html5video": "^2.1.0", "react-inlinesvg": "^0.5.5", - "react-markdown": "^2.5.0", + "react-markdown": "^3.2.2", "react-recaptcha": "^2.3.2", "react-redux": "^5.0.3", "react-router-dom": "^4.1.1", @@ -60,7 +60,6 @@ "semver-sort": "0.0.4", "thenby": "^1.2.3", "truffle-contract": "2.0.1", - "tslint-config-0xproject": "^0.0.2", "web3": "^0.20.0", "web3-provider-engine": "^13.0.1", "whatwg-fetch": "^2.0.3", @@ -88,6 +87,7 @@ "copy-webpack-plugin": "^4.0.1", "copyfiles": "^1.2.0", "css-loader": "0.23.x", + "ethers-typescript-typings": "^0.0.2", "exports-loader": "0.6.x", "imports-loader": "0.6.x", "json-loader": "^0.5.4", @@ -97,8 +97,9 @@ "source-map-loader": "^0.1.6", "style-loader": "0.13.x", "tslint": "5.8.0", + "tslint-config-0xproject": "^0.0.2", "typescript": "2.7.1", - "web3-typescript-typings": "^0.9.11", + "web3-typescript-typings": "^0.10.0", "webpack": "^3.1.0", "webpack-dev-middleware": "^1.10.0", "webpack-dev-server": "^2.5.0" diff --git a/packages/website/public/css/basscss_responsive_custom.css b/packages/website/public/css/basscss_responsive_custom.css index c2e802125..5f8bd9117 100644 --- a/packages/website/public/css/basscss_responsive_custom.css +++ b/packages/website/public/css/basscss_responsive_custom.css @@ -4,12 +4,21 @@ .sm-center { text-align: center; } + .sm-align-middle { + vertical-align: middle; + } + .sm-align-top { + vertical-align: top; + } .sm-left-align { text-align: left; } .sm-right-align { text-align: right; } + .sm-table-cell { + display: table-cell; + } .sm-mx-auto { margin-left: auto; margin-right: auto; @@ -23,12 +32,21 @@ .md-center { text-align: center; } + .md-align-middle { + vertical-align: middle; + } + .md-align-top { + vertical-align: top; + } .md-left-align { text-align: left; } .md-right-align { text-align: right; } + .md-table-cell { + display: table-cell; + } .md-mx-auto { margin-left: auto; margin-right: auto; @@ -42,12 +60,21 @@ .lg-center { text-align: center; } + .lg-align-middle { + vertical-align: middle; + } + .lg-align-top { + vertical-align: top; + } .lg-left-align { text-align: left; } .lg-right-align { text-align: right; } + .lg-table-cell { + display: table-cell; + } .lg-mx-auto { margin-left: auto; margin-right: auto; diff --git a/packages/website/public/images/doc_icons/connect.png b/packages/website/public/images/doc_icons/connect.png Binary files differindex ba9bb8a3a..244f504b3 100644 --- a/packages/website/public/images/doc_icons/connect.png +++ b/packages/website/public/images/doc_icons/connect.png diff --git a/packages/website/public/images/doc_icons/contracts.png b/packages/website/public/images/doc_icons/contracts.png Binary files differindex f5c6545ca..03956f162 100644 --- a/packages/website/public/images/doc_icons/contracts.png +++ b/packages/website/public/images/doc_icons/contracts.png diff --git a/packages/website/public/images/doc_icons/zeroExJs.png b/packages/website/public/images/doc_icons/zeroExJs.png Binary files differindex 029777ffe..fe0c49a0f 100644 --- a/packages/website/public/images/doc_icons/zeroExJs.png +++ b/packages/website/public/images/doc_icons/zeroExJs.png diff --git a/packages/website/public/index.html b/packages/website/public/index.html index 3072ff03d..c28e4abf4 100644 --- a/packages/website/public/index.html +++ b/packages/website/public/index.html @@ -23,6 +23,18 @@ </head> <body style="margin: 0px; min-width: 355px;"> + <!-- Global site tag (gtag.js) - Google Analytics --> + <script async src="https://www.googletagmanager.com/gtag/js?id=UA-98720122-1"></script> + <script> + window.dataLayer = window.dataLayer || []; +function gtag() { + dataLayer.push(arguments); +} +gtag('js', new Date()); + +gtag('config', 'UA-98720122-1'); +</script> + <!-- End Google Analytics --> <!-- Facebook SDK --> <div id="fb-root"></div> <script> @@ -58,63 +70,6 @@ })(document, 'script', 'twitter-wjs'); </script> <!-- End Twitter SDK --> - <!-- Segment.io --> - <script> - !(function() { - var analytics = (window.analytics = window.analytics || []); - if (!analytics.initialize) - if (analytics.invoked) window.console && console.error && console.error('Segment snippet included twice.'); - else { - analytics.invoked = !0; - analytics.methods = [ - 'trackSubmit', - 'trackClick', - 'trackLink', - 'trackForm', - 'pageview', - 'identify', - 'reset', - 'group', - 'track', - 'ready', - 'alias', - 'debug', - 'page', - 'once', - 'off', - 'on', - ]; - analytics.factory = function(t) { - return function() { - var e = Array.prototype.slice.call(arguments); - e.unshift(t); - analytics.push(e); - return analytics; - }; - }; - for (var t = 0; t < analytics.methods.length; t++) { - var e = analytics.methods[t]; - analytics[e] = analytics.factory(e); - } - analytics.load = function(t) { - var e = document.createElement('script'); - e.type = 'text/javascript'; - e.async = !0; - e.src = - ('https:' === document.location.protocol ? 'https://' : 'http://') + - 'cdn.segment.com/analytics.js/v1/' + - t + - '/analytics.min.js'; - var n = document.getElementsByTagName('script')[0]; - n.parentNode.insertBefore(e, n); - }; - analytics.SNIPPET_VERSION = '4.0.0'; - analytics.load('T6jtT2F2iMrw9FDJ8exE9Uu1mLN5qd8n'); - analytics.page(); - } -})(); -</script> - <!-- End Segment.io --> <!-- Main --> <script type="text/javascript" crossorigin="anonymous" src="/bundle.js" charset="utf-8"></script> diff --git a/packages/website/translations/chinese.json b/packages/website/translations/chinese.json new file mode 100644 index 000000000..f5f906d6c --- /dev/null +++ b/packages/website/translations/chinese.json @@ -0,0 +1,72 @@ +{ + "TOP_HEADER": "去中心化交易的驱动者", + "TOP_TAGLINE": "0x 是一个无需许可的开源协议,用于促进以太坊区块链中 ERC20 代币的交易。", + "BUILD_CALL_TO_ACTION": "基于 0x 构建", + "COMMUNITY_CALL_TO_ACTION": "加入社区", + "PROJECTS_HEADER": "基于 0X 协议构建的项目", + "FULL_LIST_PROMPT": "查看", + "FULL_LIST_LINK": "完整列表", + "TOKENIZED_SECTION_HEADER": "世界正走向代币化时代", + "TOKENIZED_SECTION_DESCRIPTION": + "以太坊区块链是一种开源的金融服务系统,全网无边界,统一使用加密代币充当各类资产。在未来,大多数数字资产和商品都将实现代币化。", + "CURRENCY": "货币", + "TRADITIONAL_ASSETS": "传统资产", + "DIGITAL_GOODS": "数字商品", + "OFFCHAIN_ORDER_RELAY": "链下订单中继", + "OONCHAIN_SETTLEMENT": "链上最终结算", + "OFFCHAIN_ONCHAIN_DESCRIPTION": + "在 0x 协议中,所有订单都通过链下传输,大幅削减了损耗成本,能够有效避免区块链膨胀。任何人都可以构建中继方,由中继方广播订单,每促成一笔交易,就可以收取一笔交易费。", + "RELAYERS_HEADER": "基于 0X 协议构建的中继方", + "BENEFITS_HEADER": "0x 的好處", + "BENEFIT_ONE_TITLE": "去信任化的交易机制", + "BENEFIT_ONE_DESCRIPTION": + "基于以太坊的分布式网络构建,去除中心体系单点故障,保证无间断运营,每笔交易都自动操作进行结算,完全解除交易对手风险。", + "BENEFIT_TWO_TITLE": "共享流动性", + "BENEFIT_TWO_DESCRIPTION": + "通过共享标准 API,让中继方轻松聚集流动池,随着越来越多的中继方纷纷上线,将形成充裕的流动性,创造网络效应。", + "BENEFIT_THREE_TITLE": "开源优势", + "BENEFIT_THREE_DESCRIPTION": + "0x 是一种开源协议,全网无边界,可供免费使用。用户可以直接联系已知的交易对象进行免费交易,还可以支付一定数额的 ZRX 代币,以访问中继方的流动池。", + "BUILDING_BLOCK_SECTION_HEADER": "去中心化应用的构建块", + "BUILDING_BLOCK_SECTION_DESCRIPTION": + "0x 协议是需要交易功能的去中心化应用的可插构建块。如今许多开发人员都在使用 0x 协议构建 Web 应用程序和智能合约,赶快加入这一行列吧!", + "DEV_TOOLS_PROMPT": "了解具体的构建方法,请参见", + "SMART_CONTRACT": "智能合约 的文档", + "DOCS": "", + "AND": "和", + "DECENTRALIZED_GOVERNANCE": "去中心化的治理", + "DECENTRALIZED_GOVERNANCE_DESCRIPTION": + "去中心化组织使用代币代表所有权,指引其治理逻辑。去中心化组织利用 0x 协议,可以无缝安全地进行启动资金所有权的交易。", + "PREDICTION_MARKETS": "预测市场", + "PREDICTION_MARKETS_DESCRIPTION": + "去中心化预测市场平台会根据现实世界中发生的事件,按照其中包含的金融风险生成代币集合。使用 0x 协议,允许这些代币即刻交易。", + "STABLE_TOKENS": "稳定代币", + "STABLE_TOKENS_DESCRIPTION": + "StableCoins 等新型经济结构的成功建设有赖于高效的流动性市场的支持。0x 协议能有效促进底层经济机制,利于代币保持稳定。", + "DECENTRALIZED_LOANS": "去中心化的借贷模式", + "DECENTRALIZED_LOANS_DESCRIPTION": + "高效借贷需要流动性市场的支持,为投资者提供方便购买、转卖借贷商品的平台。使用 0x 协议能够为借款方搭建一个自组织的生态系统,高效地针对所有未偿贷款确定市场价格。", + "FUND_MANAGEMENT": "基金管理", + "FUND_MANAGEMENT_DESCRIPTION": + "去中心化基金管理通过划分需事先商定的资产类别,有效限制基金经理的投资行为。向基金管理智能合约中嵌入 0x 协议,可确保其遵守安全约束。", + "FINAL_CALL_TO_ACTION": "开始构建去中心化的未来", + "DOCUMENTATION": "文档", + "COMMUNITY": "社区", + "ORGANIZATION": "组织介绍", + "ABOUT": "关于我们", + "CAREERS": "人才招聘", + "CONTACT": "联系方式", + "BLOG": "博客", + "FORUM": "论坛", + "CONNECT": "0x 连接", + "WHITEPAPER": "白皮书", + "WIKI": "维基", + "FAQ": "FAQ", + "SMART_CONTRACTS": "0x 智能合约", + "STANDARD_RELAYER_API": "中继方标准API", + "PORTAL_DAPP": "去中心化应用门户", + "WEBSITE": "网站", + "DEVELOPERS": "首页", + "HOME": "Rocket.chat", + "ROCKETCHAT": "开发人员" +} diff --git a/packages/website/translations/english.json b/packages/website/translations/english.json new file mode 100644 index 000000000..9a1c9b2c8 --- /dev/null +++ b/packages/website/translations/english.json @@ -0,0 +1,73 @@ +{ + "TOP_HEADER": "powering decentralized exchange", + "TOP_TAGLINE": + "0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the Ethereum blockchain.", + "BUILD_CALL_TO_ACTION": "build on 0x", + "COMMUNITY_CALL_TO_ACTION": "join the community", + "PROJECTS_HEADER": "projects building on 0x", + "FULL_LIST_PROMPT": "view the", + "FULL_LIST_LINK": "full list", + "TOKENIZED_SECTION_HEADER": "the world's value is becoming tokenized", + "TOKENIZED_SECTION_DESCRIPTION": + "the Ethereum blockchain is an open, borderless financial system that represents a wide variety of assets as cryptographic tokens. In the future, most digital assets and goods will be tokenized.", + "CURRENCY": "currency", + "TRADITIONAL_ASSETS": "traditional assets", + "DIGITAL_GOODS": "digital goods", + "OFFCHAIN_ORDER_RELAY": "off-chain order relay", + "OONCHAIN_SETTLEMENT": "on-chain settlement", + "OFFCHAIN_ONCHAIN_DESCRIPTION": + "in 0x protocol, orders are transported off-chain, massively reducing gas costs and eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time they facilitate a trade. Anyone can build a relayer.", + "RELAYERS_HEADER": "relayers building on 0x", + "BENEFITS_HEADER": "benefits of 0x", + "BENEFIT_ONE_TITLE": "trustless exchange", + "BENEFIT_ONE_DESCRIPTION": + "built on Ethereum's distributed network with no centralized point of failure and no down time, each trade is settled atomically and without counterparty risk.", + "BENEFIT_TWO_TITLE": "shared liquidity", + "BENEFIT_TWO_DESCRIPTION": + "by sharing a standard API, relayers can easily aggregate liquidity pools, creating network effects around liquidity that compound as more relayers come online.", + "BENEFIT_THREE_TITLE": "open source", + "BENEFIT_THREE_DESCRIPTION": + "0x is open source, permissionless and free to use. Trade directly with a known counterparty for free or pay a relayer some ZRX tokens to access their liquidity pool.", + "BUILDING_BLOCK_SECTION_HEADER": "a building block for dApps", + "BUILDING_BLOCK_SECTION_DESCRIPTION": + "0x protocol is a pluggable building block for dApps that require exchange functionality. Join the many developers that are already using 0x in their web applications and smart contracts.", + "DEV_TOOLS_PROMPT": "learn how in our", + "SMART_CONTRACT": "smart contract", + "DOCS": "docs", + "AND": "and", + "DECENTRALIZED_GOVERNANCE": "decentralized governance", + "DECENTRALIZED_GOVERNANCE_DESCRIPTION": + "Decentralized organizations use tokens to represent ownership and guide their governance logic. 0x allows decentralized organizations to seamlessly and safely trade ownership for startup capital.", + "PREDICTION_MARKETS": "prediction markets", + "PREDICTION_MARKETS_DESCRIPTION": + "decentralized prediction market platforms generate sets of tokens that represent a financial stake in the outcomes of real-world events. 0x allows these tokens to be instantly tradable.", + "STABLE_TOKENS": "stable tokens", + "STABLE_TOKENS_DESCRIPTION": + "Novel economic constructs such as stable coins require efficient, liquid markets to succeed. 0x will facilitate the underlying economic mechanisms that allow these tokens to remain stable.", + "DECENTRALIZED_LOANS": "decentralized loans", + "DECENTRALIZED_LOANS_DESCRIPTION": + "Efficient lending requires liquid markets where investors can buy and re-sell loans. 0x enables an ecosystem of lenders to self-organize and efficiently determine market prices for all outstanding loans.", + "FUND_MANAGEMENT": "fund management", + "FUND_MANAGEMENT_DESCRIPTION": + "Decentralized fund management limits fund managers to investing in pre-agreed upon asset classes. Embedding 0x into fund management smart contracts enables them to enforce these security constraints.", + "FINAL_CALL_TO_ACTION": "get started on building the decentralized future", + "DOCUMENTATION": "documentation", + "COMMUNITY": "community", + "ORGANIZATION": "organization", + "ABOUT": "about", + "CAREERS": "careers", + "CONTACT": "contact", + "BLOG": "blog", + "FORUM": "forum", + "CONNECT": "0x Connect", + "WHITEPAPER": "whitepaper", + "WIKI": "wiki", + "FAQ": "FAQ", + "SMART_CONTRACTS": "0x smart contracts", + "STANDARD_RELAYER_API": "standard relayer API", + "PORTAL_DAPP": "portal dApp", + "WEBSITE": "website", + "DEVELOPERS": "developers", + "HOME": "home", + "ROCKETCHAT": "rocket.chat" +} diff --git a/packages/website/translations/korean.json b/packages/website/translations/korean.json new file mode 100644 index 000000000..b9be664e2 --- /dev/null +++ b/packages/website/translations/korean.json @@ -0,0 +1,72 @@ +{ + "TOP_HEADER": "탈중앙화된 거래소를 가능하게 하는 원동력", + "TOP_TAGLINE": "0x는 이더리움 블록체인에서 ERC20 토큰을 거래할 수 있게 해 주는 무허가형 개방 프로토콜입니다.", + "BUILD_CALL_TO_ACTION": "0x 기반", + "COMMUNITY_CALL_TO_ACTION": "커뮤니티 참여", + "PROJECTS_HEADER": "0x 기반 프로젝트", + "FULL_LIST_PROMPT": "보기", + "FULL_LIST_LINK": "전체 목록", + "TOKENIZED_SECTION_HEADER": "전 세계의 가치가 토큰으로 변환되고 있음", + "TOKENIZED_SECTION_DESCRIPTION": + "이더리움 블록체인은 국경이 없는 개방형 결제 시스템으로, 다양한 자산을 암호화 토큰으로 나타내 줍니다. 앞으로는 디지털 자산과 상품 대부분이 토큰으로 바뀔 것입니다.", + "CURRENCY": "통화", + "TRADITIONAL_ASSETS": "전통적 자산", + "DIGITAL_GOODS": "디지털 상품", + "OFFCHAIN_ORDER_RELAY": "오프체인 주문 릴레이", + "OONCHAIN_SETTLEMENT": "온체인 정산", + "OFFCHAIN_ONCHAIN_DESCRIPTION": + "0x 프로토콜에서 주문은 오프체인으로 전달되므로, 가스 비용이 대폭 줄고 블록체인이 불필요하게 커지지 않습니다. Relayer는 주문을 브로드캐스팅할 수 있게 해 주고, 주문에서 거래가 진행될 때마다 수수료를 받을 수 있습니다. 누구든지 Relayer를 생성할 수 있습니다.", + "RELAYERS_HEADER": "0x 기반 Relayer", + "BENEFITS_HEADER": "모두 보기", + "BENEFIT_ONE_TITLE": "신뢰할 수 없는 거래소", + "BENEFIT_ONE_DESCRIPTION": + "중앙화된 오류 지점과 중단 시간이 없는 이더리움의 분산 네트워크를 바탕으로 구축되므로, 각 거래가 개별 단위로 정산되며 거래 상대방으로 인한 위험도 없습니다.", + "BENEFIT_TWO_TITLE": "공유 유동 자금", + "BENEFIT_TWO_DESCRIPTION": + "표준 API를 공유하므로 Relayer는 유동 자금 풀을 쉽게 취합할 수 있습니다. 따라서 더 많은 Relayer가 온라인 상태가 되면 유동 자금을 바탕으로 한 복합적인 네트워크 효과를 만들 수 있습니다.", + "BENEFIT_THREE_TITLE": "오픈 소스", + "BENEFIT_THREE_DESCRIPTION": + "0x는 무허가형 오프 소스이며, 무료로 사용할 수 있습니다. 이미 알고 있는 상대방과 직접 무료로 거래하거나, Relayer에 약간의 ZRX 토큰을 지불하여 해당 유동 자금 풀에 액세스할 수 있습니다.", + "BUILDING_BLOCK_SECTION_HEADER": "dApp을 위한 기본 구성 요소", + "BUILDING_BLOCK_SECTION_DESCRIPTION": + "0x 프로토콜은 거래소 기능이 필요한 dApp을 위한 연결 가능한 기본 구성 요소입니다. 웹 애플리케이션과 스마트 계약에서 이미 0x를 사용하고 있는 여러 개발자 대열에 동참해 보세요.", + "DEV_TOOLS_PROMPT": "수행하는 방법 알아보기", + "SMART_CONTRACT": "스마트 계약 문서에 ", + "DOCS": "", + "AND": "및", + "DECENTRALIZED_GOVERNANCE": "탈중앙화된 거버넌스", + "DECENTRALIZED_GOVERNANCE_DESCRIPTION": + "탈중앙화된 조직은 토큰을 사용하여 소유권을 나타내며 거버넌스 로직의 방향을 정합니다. 0x를 사용하면 탈중앙화된 조직이 안전하고 원활하게 스타트업 자금의 소유권을 주고받을 수 있습니다.", + "PREDICTION_MARKETS": "예측 시장", + "PREDICTION_MARKETS_DESCRIPTION": + "탈중앙화된 예측 시장 플랫폼은 실제 이벤트 결과에서의 금전적인 지분을 나타내는 토큰 세트를 생성합니다. 0x를 사용하면 이러한 토큰을 즉시 거래할 수 있습니다.", + "STABLE_TOKENS": "안정적인 토큰", + "STABLE_TOKENS_DESCRIPTION": + "안정적인 코인과 같은 새롭게 등장한 경제 개념은 효율성이 높은 유동 시장에 적용해야 성공할 수 있습니다. 0x는 이러한 토큰이 안정적인 상태를 유지할 수 있게 하는 기반 경제 메커니즘을 가능하게 합니다.", + "DECENTRALIZED_LOANS": "탈중앙화된 대출", + "DECENTRALIZED_LOANS_DESCRIPTION": + "대출이 효율적으로 이루어지려면 투자자가 대출 상품을 사고 다시 파는 유동 시장이 있어야 합니다. 0x를 통해 전체 미상환 대출이 자체 구성되고 이러한 대출의 시장 가격을 효율적으로 결정할 수 있는 대출 기관 생태계가 가능해집니다.", + "FUND_MANAGEMENT": "자금 관리", + "FUND_MANAGEMENT_DESCRIPTION": + "탈중앙화된 자금 관리로 자금 운용 관리자가 사전 합의된 자산 등급에 투자하는 것이 제한됩니다. 자금 관리 스마트 계약에 0x를 포함시키면 자금 운용 담당자가 보안 관련 제한 사항을 강화할 수 있습니다.", + "FINAL_CALL_TO_ACTION": "탈중앙화된 미래 구축하기", + "DOCUMENTATION": "문서", + "COMMUNITY": "커뮤니티", + "ORGANIZATION": "조직", + "ABOUT": "기업 정보", + "CAREERS": "채용", + "CONTACT": "문의", + "BLOG": "블로그", + "FORUM": "포럼", + "CONNECT": "0x Connect", + "WHITEPAPER": "백서", + "WIKI": "위키", + "FAQ": "FAQ", + "SMART_CONTRACTS": "0x 스마트 계약", + "STANDARD_RELAYER_API": "Standard Relayer API", + "PORTAL_DAPP": "포털 dApp", + "WEBSITE": "Website", + "HOME": "홈", + "ROCKETCHAT": "Rocket.chat", + "DEVELOPERS": "개발자" +} diff --git a/packages/website/translations/russian.json b/packages/website/translations/russian.json new file mode 100644 index 000000000..c103960c0 --- /dev/null +++ b/packages/website/translations/russian.json @@ -0,0 +1,72 @@ +{ + "TOP_HEADER": "Стимулирование децентрализованного обмена", + "TOP_TAGLINE": "0x — это протокол с открытым кодом, позволяющий торговать токенами ERC20, на блокчейне Ethereum.", + "BUILD_CALL_TO_ACTION": "Разрабатывайте на 0x", + "COMMUNITY_CALL_TO_ACTION": "Сообщество", + "PROJECTS_HEADER": "Проекты разработанные на 0х", + "FULL_LIST_PROMPT": "Просмотреть", + "FULL_LIST_LINK": "полный список", + "TOKENIZED_SECTION_HEADER": "Сегодняшний мир движется к токенизации ценности", + "TOKENIZED_SECTION_DESCRIPTION": + "Блокчейн Ethereum — это открытая, безграничная финансовая система, большое количество активов которой представлено в виде криптографических токенов. В будущем большая часть цифровых активов и товаров будет токенизирована.", + "CURRENCY": "Валюта", + "TRADITIONAL_ASSETS": "Традиционные активы", + "DIGITAL_GOODS": "Цифровые товары", + "OFFCHAIN_ORDER_RELAY": "Офчейн-ордер", + "OONCHAIN_SETTLEMENT": "Ончейн-транзакция", + "OFFCHAIN_ONCHAIN_DESCRIPTION": + "При использовании протокола 0x ордера проводятся вне блокчейна, что сокращает расходы на газ (топливо) и предотвращает раздувание блокчейна. Релейеры помогают провести ордера и берут комиссию каждый раз, когда способствуют торгам. Любой может создать релейера.", + "RELAYERS_HEADER": "РЕЛЕЙЕРЫ, РАЗРАБОТАННЫЕ НА 0X", + "BENEFITS_HEADER": "Просмотреть все", + "BENEFIT_ONE_TITLE": "Обмен, не требующий доверия", + "BENEFIT_ONE_DESCRIPTION": + "Каждая сделка, основанная на распределенной сети Ethereum без единой точки отказа и с нулевым временем простоя, является атомарной операцией и проводится без риска для контрагента.", + "BENEFIT_TWO_TITLE": "Общая ликвидность", + "BENEFIT_TWO_DESCRIPTION": + "При обмене стандартным API релейеры могут легко объединять пулы ликвидности, создавая сетевые эффекты вокруг ликвидности, которые усложняются с появлением новых релейеров в сети.", + "BENEFIT_THREE_TITLE": "Открытый исходный код", + "BENEFIT_THREE_DESCRIPTION": + "0x — это бесплатный и доступный протокол с открытым кодом. Торгуйте напрямую с известными контрагентами бесплатно или заплатите релейеру несколько ZRX-токенов, чтобы получить доступ к его пулу ликвидности.", + "BUILDING_BLOCK_SECTION_HEADER": "Строительный блок для dApp", + "BUILDING_BLOCK_SECTION_DESCRIPTION": + "Протокол 0x — это подключаемый строительный блок для dApp, нуждающихся в функционале обмена. Присоединяйтесь к разработчикам, которые уже используют 0x в своих веб-приложениях и смарт-контрактах.", + "DEV_TOOLS_PROMPT": "Узнайте как это сделать в документации к", + "SMART_CONTRACT": "смарт-контрактам", + "DOCS": "", + "AND": "и", + "DECENTRALIZED_GOVERNANCE": "Децентрализированное управление", + "DECENTRALIZED_GOVERNANCE_DESCRIPTION": + "Децентрализованные организации используют токены для представления собственности и внедрения своей логики управления. Протокол 0x позволяет децентрализованным организациям беспрепятственно и безопасно торговать собственностью для стартового капитала.", + "PREDICTION_MARKETS": "Рынки предсказаний", + "PREDICTION_MARKETS_DESCRIPTION": + "Платформы для децентрализованных рынков предсказаний генерируют множество токенов, которые представляют собой финансовую долю в результате реальных событий. Протокол 0x позволяет мгновенно торговать эти токены.", + "STABLE_TOKENS": "Стабильные токены", + "STABLE_TOKENS_DESCRIPTION": + "Новые экономические конструкции, например стабильные токены, требуют наличия успешных и эффективных ликвидных рынков. Протокол 0x призван облегчить основные экономические механизмы, которые позволят этим токенам оставаться стабильными.", + "DECENTRALIZED_LOANS": "Децентрализированные займы", + "DECENTRALIZED_LOANS_DESCRIPTION": + "Эффективное кредитование требует наличия ликвидных рынков, где инвесторы могут купить и перепродать займы. Протокол 0x позволяет экосистеме кредиторов самоорганизовываться и эффективно определять рыночные цены для всех невыплаченных займов.", + "FUND_MANAGEMENT": "Управление средствами", + "FUND_MANAGEMENT_DESCRIPTION": + "Децентрализованное управление средствами ограничивает управляющих средствами путем определения предварительно согласованных классов активов для инвестиций. Встраивание протокола 0x в смарт-контракты для управления средствами позволяет им обеспечить исполнение этих ограничений безопасности.", + "FINAL_CALL_TO_ACTION": "Начните создавать децентрализованное будущее", + "DOCUMENTATION": "Документация", + "COMMUNITY": "Сообщество", + "ORGANIZATION": "Организация", + "ABOUT": "Kоманда", + "CAREERS": "Карьера", + "CONTACT": "Связаться с нами", + "BLOG": "Блог", + "FORUM": "Форум", + "CONNECT": "0x Connect", + "WHITEPAPER": "Whitepaper", + "WIKI": "Вики", + "FAQ": "Документация", + "SMART_CONTRACTS": "0x Смарт-контракты ", + "STANDARD_RELAYER_API": "standard relayer API", + "PORTAL_DAPP": "DApp-портал", + "WEBSITE": "Веб-сайт", + "DEVELOPERS": "Домашняя страница", + "HOME": "Rocket.chat", + "ROCKETCHAT": "Для разработчиков" +} diff --git a/packages/website/translations/spanish.json b/packages/website/translations/spanish.json new file mode 100644 index 000000000..c2aaf384c --- /dev/null +++ b/packages/website/translations/spanish.json @@ -0,0 +1,73 @@ +{ + "TOP_HEADER": "potenciar el intercambio descentralizado", + "TOP_TAGLINE": + "0x es un protocolo abierto y sin restricciones que permite el intercambio de tokens ERC20 en la cadena de bloques Ethereum.", + "BUILD_CALL_TO_ACTION": "crear en 0x", + "COMMUNITY_CALL_TO_ACTION": "unirse a la comunidad", + "PROJECTS_HEADER": "proyectos creados en 0x", + "FULL_LIST_PROMPT": "ver la", + "FULL_LIST_LINK": "lista completa", + "TOKENIZED_SECTION_HEADER": "el valor del mundo se está tokenizando", + "TOKENIZED_SECTION_DESCRIPTION": + "la cadena de bloques Ethereum es un sistema financiero abierto y sin fronteras que representa una amplia variedad de activos como tokens criptográficos. En el futuro, la mayoría de los activos y bienes digitales estarán tokenizados.", + "CURRENCY": "moneda", + "TRADITIONAL_ASSETS": "activos tradicionales", + "DIGITAL_GOODS": "bienes digitales", + "OFFCHAIN_ORDER_RELAY": "orden retransmisión fuera de cadena", + "OONCHAIN_SETTLEMENT": "liquidación en cadena", + "OFFCHAIN_ONCHAIN_DESCRIPTION": + "en el protocolo 0x, las órdenes se transportan fuera de la cadena, lo que reduce enormemente los costos de combustible y elimina el sobredimensionamiento de la cadena de bloques. Los transmisores ayudan a emitir órdenes y a cobrar un cargo cada vez que facilitan un intercambio. Cualquier persona puede crear un transmisor.", + "RELAYERS_HEADER": "transmisores creados en 0x", + "BENEFITS_HEADER": "beneficios de 0x", + "BENEFIT_ONE_TITLE": "intercambio confiable", + "BENEFIT_ONE_DESCRIPTION": + "creado en la red distribuida de Ethereum sin ningún punto de error centralizado y sin tiempo de inactividad; cada intercambio se concreta atómicamente y sin riesgos para la contraparte.", + "BENEFIT_TWO_TITLE": "liquidez compartida", + "BENEFIT_TWO_DESCRIPTION": + "al compartir un API estándar, los transmisores pueden acumular fácilmente fondos de liquidez, lo que crea efectos de red en torno a la liquidez que se forma a medida que más transmisores se conectan.", + "BENEFIT_THREE_TITLE": "código abierto", + "BENEFIT_THREE_DESCRIPTION": + "0x es código abierto, su uso es gratuito. Negocie directamente con una contraparte conocida sin costo o páguele a un transmisor con algunos para acceder a su fondo de liquidez.", + "BUILDING_BLOCK_SECTION_HEADER": "un bloque de creación para dApps", + "BUILDING_BLOCK_SECTION_DESCRIPTION": + "el protocolo 0x es un bloque de creación acoplable para dApps que requiere una funcionalidad de intercambio. Únase a los numerosos desarrolladores que ya utilizan 0x en sus aplicaciones web y contratos inteligentes.", + "DEV_TOOLS_PROMPT": "aprenda cómo hacerlo en nuestros documentos de", + "SMART_CONTRACT": "contratos inteligentes", + "DOCS": "", + "AND": "y", + "DECENTRALIZED_GOVERNANCE": "gobierno descentralizado", + "DECENTRALIZED_GOVERNANCE_DESCRIPTION": + "las organizaciones descentralizadas utilizan tokens para representar la titularidad y guiar su lógica de gobierno. 0x les permite a las organizaciones descentralizadas intercambiar titularidad por capital inicial sin problemas y de forma segura.", + "PREDICTION_MARKETS": "mercados de predicción", + "PREDICTION_MARKETS_DESCRIPTION": + "las plataformas del mercado de predicción descentralizado generan conjuntos de tokens que representan un interés financiero en los resultados de los sucesos del mundo real. 0x permite que estos tokens se negocien de manera instantánea.", + "STABLE_TOKENS": "tokens estables", + "STABLE_TOKENS_DESCRIPTION": + "las construcciones económicas novedosas, como las monedas estables, requieren mercados eficientes y con liquidez para tener éxito. 0x facilitará los mecanismos económicos subyacentes que permiten que estos tokens continúen siendo estables.", + "DECENTRALIZED_LOANS": "préstamos descentralizados", + "DECENTRALIZED_LOANS_DESCRIPTION": + "los préstamos eficientes requieren mercados con liquidez donde los inversores pueden comprar y revender préstamos. 0x facilita un ecosistema de prestamistas que se organizan ellos mismos y determinan, de forma eficaz, los precios del mercado para todos los préstamos pendientes.", + "FUND_MANAGEMENT": "administración de fondos", + "FUND_MANAGEMENT_DESCRIPTION": + "la administración descentralizada de fondos limita a los administradores de fondos a invertir en clases de activos preacordadas. Integrar 0x a los contratos inteligentes de la administración de fondos les permite imponer esas restricciones de seguridad.", + "FINAL_CALL_TO_ACTION": "comience a crear el futuro descentralizado", + "DOCUMENTATION": "documentación", + "COMMUNITY": "comunidad", + "ORGANIZATION": "organización", + "ABOUT": "equipo", + "CAREERS": "empleo", + "CONTACT": "contacto", + "BLOG": "blog", + "FORUM": "foro", + "CONNECT": "0x Connect", + "WHITEPAPER": "documento técnico", + "WIKI": "wiki", + "FAQ": "preguntas frecuentes", + "SMART_CONTRACTS": "0x contratos inteligentes", + "STANDARD_RELAYER_API": "API de transmisión estándar", + "PORTAL_DAPP": "portal dApp", + "WEBSITE": "website", + "DEVELOPERS": "inicio", + "HOME": "rocket.chat", + "ROCKETCHAT": "desarrolladores" +} diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index db3872a32..156dc44e8 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -69,14 +69,6 @@ export class Blockchain { private _cachedProviderNetworkId: number; private _ledgerSubprovider: LedgerWalletSubprovider; private _defaultGasPrice: BigNumber; - private static async _onPageLoadAsync(): Promise<void> { - if (document.readyState === 'complete') { - return; // Already loaded - } - return new Promise<void>((resolve, reject) => { - window.onload = () => resolve(); - }); - } private static _getNameGivenProvider(provider: Web3.Provider): string { if (!_.isUndefined((provider as any).isMetaMask)) { return constants.PROVIDER_NAME_METAMASK; @@ -672,7 +664,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.'); @@ -710,7 +702,7 @@ export class Blockchain { return tokenByAddress; } private async _onPageLoadInitFireAndForgetAsync() { - await Blockchain._onPageLoadAsync(); // wait for page to load + await utils.onPageLoadAsync(); // wait for page to load // Hack: We need to know the networkId the injectedWeb3 is connected to (if it is defined) in // order to properly instantiate the web3Wrapper. Since we must use the async call, we cannot diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx index a0f1a0c96..810460cac 100644 --- a/packages/website/ts/components/footer.tsx +++ b/packages/website/ts/components/footer.tsx @@ -1,9 +1,13 @@ import * as _ from 'lodash'; +import DropDownMenu from 'material-ui/DropDownMenu'; +import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; import { Link } from 'react-router-dom'; -import { WebsitePaths } from 'ts/types'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { Deco, Key, Language, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; interface MenuItemsBySection { [sectionName: string]: FooterMenuItem[]; @@ -15,105 +19,114 @@ interface FooterMenuItem { isExternal?: boolean; } -enum Sections { - Documentation = 'Documentation', - Community = 'Community', - Organization = 'Organization', -} - const ICON_DIMENSION = 16; -const menuItemsBySection: MenuItemsBySection = { - Documentation: [ - { - title: '0x.js', - path: WebsitePaths.ZeroExJs, - }, - { - title: '0x Smart Contracts', - path: WebsitePaths.SmartContracts, - }, - { - title: '0x Connect', - path: WebsitePaths.Connect, - }, - { - title: 'Whitepaper', - path: WebsitePaths.Whitepaper, - isExternal: true, - }, - { - title: 'Wiki', - path: WebsitePaths.Wiki, - }, - { - title: 'FAQ', - path: WebsitePaths.FAQ, - }, - ], - Community: [ - { - title: 'Rocket.chat', - isExternal: true, - path: constants.URL_ZEROEX_CHAT, - }, - { - title: 'Blog', - isExternal: true, - path: constants.URL_BLOG, - }, - { - title: 'Twitter', - isExternal: true, - path: constants.URL_TWITTER, - }, - { - title: 'Reddit', - isExternal: true, - path: constants.URL_REDDIT, - }, - { - title: 'Forum', - isExternal: true, - path: constants.URL_DISCOURSE_FORUM, - }, - ], - Organization: [ - { - title: 'About', - isExternal: false, - path: WebsitePaths.About, - }, - { - title: 'Careers', - isExternal: true, - path: constants.URL_ANGELLIST, - }, - { - title: 'Contact', - isExternal: true, - path: 'mailto:team@0xproject.com', - }, - ], -}; + const linkStyle = { color: colors.white, cursor: 'pointer', }; -const titleToIcon: { [title: string]: string } = { - 'Rocket.chat': 'rocketchat.png', - Blog: 'medium.png', - Twitter: 'twitter.png', - Reddit: 'reddit.png', - Forum: 'discourse.png', +const languageToMenuTitle = { + [Language.English]: 'English', + [Language.Russian]: 'Русский', + [Language.Spanish]: 'Español', + [Language.Korean]: '한국어', + [Language.Chinese]: '中文', }; -export interface FooterProps {} +export interface FooterProps { + translate: Translate; + dispatcher: Dispatcher; +} -interface FooterState {} +interface FooterState { + selectedLanguage: Language; +} export class Footer extends React.Component<FooterProps, FooterState> { + constructor(props: FooterProps) { + super(); + this.state = { + selectedLanguage: props.translate.getLanguage(), + }; + } public render() { + const menuItemsBySection: MenuItemsBySection = { + [Key.Documentation]: [ + { + title: '0x.js', + path: WebsitePaths.ZeroExJs, + }, + { + title: this.props.translate.get(Key.SmartContracts, Deco.Cap), + path: WebsitePaths.SmartContracts, + }, + { + title: this.props.translate.get(Key.Connect, Deco.Cap), + path: WebsitePaths.Connect, + }, + { + title: this.props.translate.get(Key.Whitepaper, Deco.Cap), + path: WebsitePaths.Whitepaper, + isExternal: true, + }, + { + title: this.props.translate.get(Key.Wiki, Deco.Cap), + path: WebsitePaths.Wiki, + }, + { + title: this.props.translate.get(Key.Faq, Deco.Cap), + path: WebsitePaths.FAQ, + }, + ], + [Key.Community]: [ + { + title: this.props.translate.get(Key.RocketChat, Deco.Cap), + isExternal: true, + path: constants.URL_ZEROEX_CHAT, + }, + { + title: this.props.translate.get(Key.Blog, Deco.Cap), + isExternal: true, + path: constants.URL_BLOG, + }, + { + title: 'Twitter', + isExternal: true, + path: constants.URL_TWITTER, + }, + { + title: 'Reddit', + isExternal: true, + path: constants.URL_REDDIT, + }, + { + title: this.props.translate.get(Key.Forum, Deco.Cap), + isExternal: true, + path: constants.URL_DISCOURSE_FORUM, + }, + ], + [Key.Organization]: [ + { + title: this.props.translate.get(Key.About, Deco.Cap), + isExternal: false, + path: WebsitePaths.About, + }, + { + title: this.props.translate.get(Key.Careers, Deco.Cap), + isExternal: true, + path: constants.URL_ANGELLIST, + }, + { + title: this.props.translate.get(Key.Contact, Deco.Cap), + isExternal: true, + path: 'mailto:team@0xproject.com', + }, + ], + }; + const languageMenuItems = _.map(languageToMenuTitle, (menuTitle: string, language: Language) => { + return <MenuItem key={menuTitle} value={language} primaryText={menuTitle} />; + }); return ( <div className="relative pb4 pt2" style={{ backgroundColor: colors.darkerGrey }}> <div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}> @@ -132,25 +145,34 @@ export class Footer extends React.Component<FooterProps, FooterState> { > © ZeroEx, Intl. </div> + <div className="pt4 center"> + <DropDownMenu + labelStyle={{ color: colors.white }} + value={this.state.selectedLanguage} + onChange={this._updateLanguage.bind(this)} + > + {languageMenuItems} + </DropDownMenu> + </div> </div> </div> <div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4"> <div className="col lg-col-4 md-col-4 col-12"> <div className="lg-right md-right sm-center"> - {this._renderHeader(Sections.Documentation)} - {_.map(menuItemsBySection[Sections.Documentation], this._renderMenuItem.bind(this))} + {this._renderHeader(Key.Documentation)} + {_.map(menuItemsBySection[Key.Documentation], this._renderMenuItem.bind(this))} </div> </div> <div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2"> <div className="lg-right md-right sm-center"> - {this._renderHeader(Sections.Community)} - {_.map(menuItemsBySection[Sections.Community], this._renderMenuItem.bind(this))} + {this._renderHeader(Key.Community)} + {_.map(menuItemsBySection[Key.Community], this._renderMenuItem.bind(this))} </div> </div> <div className="col lg-col-4 md-col-4 col-12"> <div className="lg-right md-right sm-center"> - {this._renderHeader(Sections.Organization)} - {_.map(menuItemsBySection[Sections.Organization], this._renderMenuItem.bind(this))} + {this._renderHeader(Key.Organization)} + {_.map(menuItemsBySection[Key.Organization], this._renderMenuItem.bind(this))} </div> </div> </div> @@ -166,17 +188,22 @@ export class Footer extends React.Component<FooterProps, FooterState> { ); } private _renderMenuItem(item: FooterMenuItem) { + const titleToIcon: { [title: string]: string } = { + [this.props.translate.get(Key.RocketChat, Deco.Cap)]: 'rocketchat.png', + [this.props.translate.get(Key.Blog, Deco.Cap)]: 'medium.png', + Twitter: 'twitter.png', + Reddit: 'reddit.png', + [this.props.translate.get(Key.Forum, Deco.Cap)]: 'discourse.png', + }; const iconIfExists = titleToIcon[item.title]; return ( <div key={item.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}> {item.isExternal ? ( <a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}> {!_.isUndefined(iconIfExists) ? ( - <div className="sm-mx-auto" style={{ width: 65 }}> - <div className="flex"> - <div className="pr1">{this._renderIcon(iconIfExists)}</div> - <div>{item.title}</div> - </div> + <div className="inline-block"> + <div className="pr1 table-cell">{this._renderIcon(iconIfExists)}</div> + <div className="table-cell">{item.title}</div> </div> ) : ( item.title @@ -195,9 +222,8 @@ export class Footer extends React.Component<FooterProps, FooterState> { </div> ); } - private _renderHeader(title: string) { + private _renderHeader(key: Key) { const headerStyle = { - textTransform: 'uppercase', color: colors.grey400, letterSpacing: 2, fontFamily: 'Roboto Mono', @@ -205,8 +231,14 @@ export class Footer extends React.Component<FooterProps, FooterState> { }; return ( <div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}> - {title} + {this.props.translate.get(key, Deco.Upper)} </div> ); } + private _updateLanguage(e: any, index: number, value: Language) { + this.setState({ + selectedLanguage: value, + }); + this.props.dispatcher.updateSelectedLanguage(value); + } } diff --git a/packages/website/ts/components/portal.tsx b/packages/website/ts/components/portal.tsx index 0409f28c0..4871997ac 100644 --- a/packages/website/ts/components/portal.tsx +++ b/packages/website/ts/components/portal.tsx @@ -27,6 +27,7 @@ import { BlockchainErrs, HashData, Order, ProviderType, ScreenWidths, TokenByAdd import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; const THROTTLE_TIMEOUT = 100; @@ -52,6 +53,7 @@ export interface PortalAllProps { location: Location; flashMessage?: string | React.ReactNode; lastForceTokenStateRefetch: number; + translate: Translate; } interface PortalAllState { @@ -166,6 +168,7 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> { blockchainIsLoaded={this.props.blockchainIsLoaded} location={this.props.location} blockchain={this._blockchain} + translate={this.props.translate} /> <div id="portal" className="mx-auto max-width-4" style={{ width: '100%' }}> <Paper className="mb3 mt2"> @@ -259,7 +262,7 @@ export class Portal extends React.Component<PortalAllProps, PortalAllState> { /> )} </div> - <Footer />; + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> </div> ); } diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index a412007f2..b2b2d2ebd 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -14,9 +14,10 @@ import { Identicon } from 'ts/components/ui/identicon'; import { DocsInfo } from 'ts/pages/documentation/docs_info'; import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { DocsMenu, MenuSubsectionsBySection, ProviderType, Styles, WebsitePaths } from 'ts/types'; +import { Deco, DocsMenu, Key, MenuSubsectionsBySection, ProviderType, Styles, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; interface TopBarProps { userAddress?: string; @@ -28,6 +29,7 @@ interface TopBarProps { dispatcher?: Dispatcher; blockchainIsLoaded: boolean; location: Location; + translate: Translate; docsVersion?: string; availableDocVersions?: string[]; menu?: DocsMenu; @@ -95,10 +97,16 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" /> </Link>, <Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none"> - <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Smart Contracts" /> + <MenuItem + style={{ fontSize: styles.menuItem.fontSize }} + primaryText={this.props.translate.get(Key.SmartContract, Deco.CapWords)} + /> </Link>, <Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none"> - <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x Connect" /> + <MenuItem + style={{ fontSize: styles.menuItem.fontSize }} + primaryText={this.props.translate.get(Key.Connect, Deco.CapWords)} + /> </Link>, <a key="subMenuItem-standard-relayer-api" @@ -106,7 +114,10 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { className="text-decoration-none" href={constants.URL_STANDARD_RELAYER_API_GITHUB} > - <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Standard Relayer API" /> + <MenuItem + style={{ fontSize: styles.menuItem.fontSize }} + primaryText={this.props.translate.get(Key.StandardRelayerApi, Deco.CapWords)} + /> </a>, <a key="subMenuItem-github" @@ -122,7 +133,10 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { className="text-decoration-none" href={`${WebsitePaths.Whitepaper}`} > - <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Whitepaper" /> + <MenuItem + style={{ fontSize: styles.menuItem.fontSize }} + primaryText={this.props.translate.get(Key.Whitepaper, Deco.CapWords)} + /> </a>, ]; const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {}; @@ -137,7 +151,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { }; const hoverActiveNode = ( <div className="flex relative" style={{ color: menuIconStyle.color }}> - <div style={{ paddingRight: 10 }}>Developers</div> + <div style={{ paddingRight: 10 }}>{this.props.translate.get(Key.Developers, Deco.Cap)}</div> <div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}> <i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} /> </div> @@ -165,28 +179,28 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { style={styles.menuItem} /> <TopBarMenuItem - title="Wiki" + title={this.props.translate.get(Key.Wiki, Deco.Cap)} path={`${WebsitePaths.Wiki}`} style={styles.menuItem} isNightVersion={isNightVersion} isExternal={false} /> <TopBarMenuItem - title="Blog" + title={this.props.translate.get(Key.Blog, Deco.Cap)} path={constants.URL_BLOG} style={styles.menuItem} isNightVersion={isNightVersion} isExternal={true} /> <TopBarMenuItem - title="About" + title={this.props.translate.get(Key.About, Deco.Cap)} path={`${WebsitePaths.About}`} style={styles.menuItem} isNightVersion={isNightVersion} isExternal={false} /> <TopBarMenuItem - title="Portal DApp" + title={this.props.translate.get(Key.PortalDApp, Deco.CapWords)} path={`${WebsitePaths.Portal}`} isPrimary={true} style={styles.menuItem} @@ -233,46 +247,54 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { {this._renderDocsMenu()} {this._renderWiki()} <div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}> - Website + {this.props.translate.get(Key.Website, Deco.Cap)} </div> <Link to={WebsitePaths.Home} className="text-decoration-none"> - <MenuItem className="py2">Home</MenuItem> + <MenuItem className="py2">{this.props.translate.get(Key.Home, Deco.Cap)}</MenuItem> </Link> <Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none"> - <MenuItem className="py2">Wiki</MenuItem> + <MenuItem className="py2">{this.props.translate.get(Key.Wiki, Deco.Cap)}</MenuItem> </Link> {!this._isViewing0xjsDocs() && ( <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <MenuItem className="py2">0x.js Docs</MenuItem> + <MenuItem className="py2">0x.js {this.props.translate.get(Key.Docs, Deco.Cap)}</MenuItem> </Link> )} {!this._isViewingConnectDocs() && ( <Link to={WebsitePaths.Connect} className="text-decoration-none"> - <MenuItem className="py2">0x Connect Docs</MenuItem> + <MenuItem className="py2"> + {this.props.translate.get(Key.Connect, Deco.Cap)}{' '} + {this.props.translate.get(Key.Docs, Deco.Cap)} + </MenuItem> </Link> )} {!this._isViewingSmartContractsDocs() && ( <Link to={WebsitePaths.SmartContracts} className="text-decoration-none"> - <MenuItem className="py2">Smart Contract Docs</MenuItem> + <MenuItem className="py2"> + {this.props.translate.get(Key.SmartContract, Deco.Cap)}{' '} + {this.props.translate.get(Key.Docs, Deco.Cap)} + </MenuItem> </Link> )} {!this._isViewingPortal() && ( <Link to={`${WebsitePaths.Portal}`} className="text-decoration-none"> - <MenuItem className="py2">Portal DApp</MenuItem> + <MenuItem className="py2"> + {this.props.translate.get(Key.PortalDApp, Deco.CapWords)} + </MenuItem> </Link> )} <a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}> - <MenuItem className="py2">Whitepaper</MenuItem> + <MenuItem className="py2">{this.props.translate.get(Key.Whitepaper, Deco.Cap)}</MenuItem> </a> <Link to={`${WebsitePaths.About}`} className="text-decoration-none"> - <MenuItem className="py2">About</MenuItem> + <MenuItem className="py2">{this.props.translate.get(Key.About, Deco.Cap)}</MenuItem> </Link> <a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}> - <MenuItem className="py2">Blog</MenuItem> + <MenuItem className="py2">{this.props.translate.get(Key.Blog, Deco.Cap)}</MenuItem> </a> <Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none"> <MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}> - FAQ + {this.props.translate.get(Key.Faq, Deco.Cap)} </MenuItem> </Link> </div> @@ -297,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> @@ -313,7 +334,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <NestedSidebarMenu topLevelMenu={this.props.menuSubsectionsBySection} menuSubsectionsBySection={this.props.menuSubsectionsBySection} - title="Wiki" + title={this.props.translate.get(Key.Wiki, Deco.Cap)} shouldDisplaySectionHeaders={false} onMenuItemClick={this._onMenuButtonClick.bind(this)} /> @@ -328,7 +349,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { return ( <div className="lg-hide md-hide"> <div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}> - Portal DApp + {this.props.translate.get(Key.PortalDApp, Deco.CapWords)} </div> <PortalMenu menuItemStyle={{ color: 'black' }} onClick={this._onMenuButtonClick.bind(this)} /> </div> diff --git a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx index 983050abc..e70381456 100644 --- a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx +++ b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx @@ -34,7 +34,7 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM marginTop: 15, paddingLeft: 9, paddingRight: 9, - width: 77, + minWidth: 77, } : {}; const menuItemColor = this.props.isNightVersion ? 'white' : this.props.style.color; diff --git a/packages/website/ts/containers/about.ts b/packages/website/ts/containers/about.ts new file mode 100644 index 000000000..ce8fd3afb --- /dev/null +++ b/packages/website/ts/containers/about.ts @@ -0,0 +1,26 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { About as AboutComponent, AboutProps } from 'ts/pages/about/about'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { Translate } from 'ts/utils/translate'; + +interface ConnectedState { + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +const mapStateToProps = (state: State, ownProps: AboutProps): ConnectedState => ({ + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const About: React.ComponentClass<AboutProps> = connect(mapStateToProps, mapDispatchToProps)(AboutComponent); diff --git a/packages/website/ts/containers/connect_documentation.tsx b/packages/website/ts/containers/connect_documentation.ts index 79eafa431..6a5ba1f99 100644 --- a/packages/website/ts/containers/connect_documentation.tsx +++ b/packages/website/ts/containers/connect_documentation.ts @@ -2,14 +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 { typeDocUtils } from 'ts/utils/typedoc_utils'; +import { Translate } from 'ts/utils/translate'; /* tslint:disable:no-var-requires */ const IntroMarkdown = require('md/docs/connect/introduction'); @@ -24,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, + packageUrl: 'https://github.com/0xProject/0x-monorepo', menu: { introduction: [connectDocSections.introduction], install: [connectDocSections.installation], @@ -76,7 +71,6 @@ const docsInfoConfig: DocsInfoConfig = { menuSubsectionToVersionWhenIntroduced: {}, sections: connectDocSections, visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel], - convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils), }; const docsInfo = new DocsInfo(docsInfoConfig); @@ -84,15 +78,17 @@ interface ConnectedState { docsVersion: string; availableDocVersions: string[]; docsInfo: DocsInfo; + translate: Translate; } 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, docsInfo, }); @@ -100,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/faq.ts b/packages/website/ts/containers/faq.ts new file mode 100644 index 000000000..b539e33c9 --- /dev/null +++ b/packages/website/ts/containers/faq.ts @@ -0,0 +1,26 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { FAQ as FAQComponent, FAQProps } from 'ts/pages/faq/faq'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { Translate } from 'ts/utils/translate'; + +interface ConnectedState { + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +const mapStateToProps = (state: State, ownProps: FAQProps): ConnectedState => ({ + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const FAQ: React.ComponentClass<FAQProps> = connect(mapStateToProps, mapDispatchToProps)(FAQComponent); diff --git a/packages/website/ts/containers/generate_order_form.tsx b/packages/website/ts/containers/generate_order_form.ts index 8c5deb690..8c5deb690 100644 --- a/packages/website/ts/containers/generate_order_form.tsx +++ b/packages/website/ts/containers/generate_order_form.ts diff --git a/packages/website/ts/containers/landing.ts b/packages/website/ts/containers/landing.ts new file mode 100644 index 000000000..a620bb12e --- /dev/null +++ b/packages/website/ts/containers/landing.ts @@ -0,0 +1,28 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { Landing as LandingComponent, LandingProps } from 'ts/pages/landing/landing'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { Translate } from 'ts/utils/translate'; + +interface ConnectedState { + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +const mapStateToProps = (state: State, ownProps: LandingProps): ConnectedState => ({ + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const Landing: React.ComponentClass<LandingProps> = connect(mapStateToProps, mapDispatchToProps)( + LandingComponent, +); diff --git a/packages/website/ts/containers/not_found.ts b/packages/website/ts/containers/not_found.ts new file mode 100644 index 000000000..dd151e2c8 --- /dev/null +++ b/packages/website/ts/containers/not_found.ts @@ -0,0 +1,28 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { NotFound as NotFoundComponent, NotFoundProps } from 'ts/pages/not_found'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { Translate } from 'ts/utils/translate'; + +interface ConnectedState { + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +const mapStateToProps = (state: State, ownProps: NotFoundProps): ConnectedState => ({ + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const NotFound: React.ComponentClass<NotFoundProps> = connect(mapStateToProps, mapDispatchToProps)( + NotFoundComponent, +); diff --git a/packages/website/ts/containers/portal.tsx b/packages/website/ts/containers/portal.ts index bcca0d70f..befa16bdb 100644 --- a/packages/website/ts/containers/portal.tsx +++ b/packages/website/ts/containers/portal.ts @@ -8,6 +8,7 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; import { BlockchainErrs, HashData, Order, ProviderType, ScreenWidths, Side, TokenByAddress } from 'ts/types'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; interface ConnectedState { blockchainErr: BlockchainErrs; @@ -26,6 +27,7 @@ interface ConnectedState { userAddress: string; userSuppliedOrderCache: Order; flashMessage?: string | React.ReactNode; + translate: Translate; } interface ConnectedDispatch { @@ -73,6 +75,7 @@ const mapStateToProps = (state: State, ownProps: PortalComponentAllProps): Conne userEtherBalance: state.userEtherBalance, userSuppliedOrderCache: state.userSuppliedOrderCache, flashMessage: state.flashMessage, + translate: state.translate, }; }; diff --git a/packages/website/ts/containers/smart_contracts_documentation.ts b/packages/website/ts/containers/smart_contracts_documentation.ts new file mode 100644 index 000000000..a839529aa --- /dev/null +++ b/packages/website/ts/containers/smart_contracts_documentation.ts @@ -0,0 +1,98 @@ +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 { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { + DocPackages, + DocsInfoConfig, + Networks, + SmartContractDocSections as Sections, + SupportedDocJson, + WebsitePaths, +} from 'ts/types'; +import { Translate } from 'ts/utils/translate'; + +/* tslint:disable:no-var-requires */ +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', + menu: { + introduction: [Sections.Introduction], + contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy], + }, + sectionNameToMarkdown: { + [Sections.Introduction]: IntroMarkdown, + }, + sections: { + Introduction: Sections.Introduction, + Exchange: Sections.Exchange, + TokenTransferProxy: Sections.TokenTransferProxy, + TokenRegistry: Sections.TokenRegistry, + ZRXToken: Sections.ZRXToken, + }, + visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy], + 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); + +interface ConnectedState { + docsVersion: string; + availableDocVersions: string[]; + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; + docsInfo: DocsInfo; +} + +const mapStateToProps = (state: State, ownProps: DocPageProps): ConnectedState => ({ + docsVersion: state.docsVersion, + availableDocVersions: state.availableDocVersions, + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), + docsInfo, +}); + +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 deleted file mode 100644 index 8be33b546..000000000 --- a/packages/website/ts/containers/smart_contracts_documentation.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; -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'; - -/* tslint:disable:no-var-requires */ -const IntroMarkdown = require('md/docs/smart_contracts/introduction'); -/* tslint:enable:no-var-requires */ - -const docsInfoConfig: DocsInfoConfig = { - 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], - }, - sectionNameToMarkdown: { - [Sections.Introduction]: IntroMarkdown, - }, - sections: { - Introduction: Sections.Introduction, - Exchange: Sections.Exchange, - TokenTransferProxy: Sections.TokenTransferProxy, - TokenRegistry: Sections.TokenRegistry, - ZRXToken: Sections.ZRXToken, - }, - visibleConstructors: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy], - convertToDocAgnosticFormatFn: doxityUtils.convertToDocAgnosticFormat.bind(doxityUtils), -}; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; - docsInfo: DocsInfo; -} - -const mapStateToProps = (state: State, ownProps: DocumentationAllProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), - docsInfo, -}); - -export const Documentation: React.ComponentClass<DocumentationAllProps> = connect(mapStateToProps, mapDispatchToProps)( - DocumentationComponent, -); diff --git a/packages/website/ts/containers/wiki.ts b/packages/website/ts/containers/wiki.ts new file mode 100644 index 000000000..2cb87d0a1 --- /dev/null +++ b/packages/website/ts/containers/wiki.ts @@ -0,0 +1,26 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { Wiki as WikiComponent, WikiProps } from 'ts/pages/wiki/wiki'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { Translate } from 'ts/utils/translate'; + +interface ConnectedState { + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +const mapStateToProps = (state: State, ownProps: WikiProps): ConnectedState => ({ + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const Wiki: React.ComponentClass<WikiProps> = connect(mapStateToProps, mapDispatchToProps)(WikiComponent); diff --git a/packages/website/ts/containers/zero_ex_js_documentation.tsx b/packages/website/ts/containers/zero_ex_js_documentation.ts index eee2c7cc8..d0d697e70 100644 --- a/packages/website/ts/containers/zero_ex_js_documentation.tsx +++ b/packages/website/ts/containers/zero_ex_js_documentation.ts @@ -2,14 +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 { typeDocUtils } from 'ts/utils/typedoc_utils'; +import { Translate } from 'ts/utils/translate'; /* tslint:disable:no-var-requires */ const IntroMarkdown = require('md/docs/0xjs/introduction'); @@ -36,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, + packageUrl: 'https://github.com/0xProject/0x-monorepo', menu: { introduction: [zeroExJsDocSections.introduction], install: [zeroExJsDocSections.installation], @@ -68,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', @@ -105,6 +102,7 @@ const docsInfoConfig: DocsInfoConfig = { 'ApprovalContractEventArgs', 'TokenContractEventArgs', 'ZeroExConfig', + 'TransactionReceipt', 'TransactionReceiptWithDecodedLogs', 'LogWithDecodedArgs', 'EtherTokenEvents', @@ -127,17 +125,33 @@ const docsInfoConfig: DocsInfoConfig = { 'FilterObject', ], sectionNameToModulePath: { - [zeroExJsDocSections.zeroEx]: ['"src/0x"'], - [zeroExJsDocSections.exchange]: ['"src/contract_wrappers/exchange_wrapper"'], - [zeroExJsDocSections.tokenRegistry]: ['"src/contract_wrappers/token_registry_wrapper"'], - [zeroExJsDocSections.token]: ['"src/contract_wrappers/token_wrapper"'], - [zeroExJsDocSections.etherToken]: ['"src/contract_wrappers/ether_token_wrapper"'], + [zeroExJsDocSections.zeroEx]: ['"0x.js/src/0x"', '"src/0x"'], + [zeroExJsDocSections.exchange]: [ + '"0x.js/src/contract_wrappers/exchange_wrapper"', + '"src/contract_wrappers/exchange_wrapper"', + ], + [zeroExJsDocSections.tokenRegistry]: [ + '"0x.js/src/contract_wrappers/token_registry_wrapper"', + '"src/contract_wrappers/token_registry_wrapper"', + ], + [zeroExJsDocSections.token]: [ + '"0x.js/src/contract_wrappers/token_wrapper"', + '"src/contract_wrappers/token_wrapper"', + ], + [zeroExJsDocSections.etherToken]: [ + '"0x.js/src/contract_wrappers/ether_token_wrapper"', + '"src/contract_wrappers/ether_token_wrapper"', + ], [zeroExJsDocSections.proxy]: [ - '"src/contract_wrappers/proxy_wrapper"', + '"0x.js/src/contract_wrappers/proxy_wrapper"', + '"0x.js/src/contract_wrappers/token_transfer_proxy_wrapper"', '"src/contract_wrappers/token_transfer_proxy_wrapper"', ], - [zeroExJsDocSections.orderWatcher]: ['"src/order_watcher/order_state_watcher"'], - [zeroExJsDocSections.types]: ['"src/types"'], + [zeroExJsDocSections.orderWatcher]: [ + '"0x.js/src/order_watcher/order_state_watcher"', + '"src/order_watcher/order_state_watcher"', + ], + [zeroExJsDocSections.types]: ['"0x.js/src/types"', '"src/types"', '"types/src/index"'], }, menuSubsectionToVersionWhenIntroduced: { [zeroExJsDocSections.etherToken]: '0.7.1', @@ -146,7 +160,6 @@ const docsInfoConfig: DocsInfoConfig = { }, sections: zeroExJsDocSections, visibleConstructors: [zeroExJsDocSections.zeroEx], - convertToDocAgnosticFormatFn: typeDocUtils.convertToDocAgnosticFormat.bind(typeDocUtils), }; const docsInfo = new DocsInfo(docsInfoConfig); @@ -154,22 +167,24 @@ interface ConnectedState { docsVersion: string; availableDocVersions: string[]; docsInfo: DocsInfo; + translate: Translate; } 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, + translate: state.translate, }); 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/index.tsx b/packages/website/ts/index.tsx index bc4e0b472..c0539c6d0 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -7,14 +7,14 @@ import { Provider } from 'react-redux'; import { BrowserRouter as Router, Redirect, Route, Switch } from 'react-router-dom'; import * as injectTapEventPlugin from 'react-tap-event-plugin'; import { createStore, Store as ReduxStore } from 'redux'; +import { About } from 'ts/containers/about'; +import { FAQ } from 'ts/containers/faq'; +import { Landing } from 'ts/containers/landing'; +import { NotFound } from 'ts/containers/not_found'; +import { Wiki } from 'ts/containers/wiki'; import { createLazyComponent } from 'ts/lazy_component'; import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage'; import { tradeHistoryStorage } from 'ts/local_storage/trade_history_storage'; -import { About } from 'ts/pages/about/about'; -import { FAQ } from 'ts/pages/faq/faq'; -import { Landing } from 'ts/pages/landing/landing'; -import { NotFound } from 'ts/pages/not_found'; -import { Wiki } from 'ts/pages/wiki/wiki'; import { reducer, State } from 'ts/redux/reducer'; import { WebsitePaths } from 'ts/types'; import { muiTheme } from 'ts/utils/mui_theme'; diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx index 0889e79f3..b99dc34ab 100644 --- a/packages/website/ts/pages/about/about.tsx +++ b/packages/website/ts/pages/about/about.tsx @@ -4,9 +4,11 @@ import * as DocumentTitle from 'react-document-title'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Profile } from 'ts/pages/about/profile'; +import { Dispatcher } from 'ts/redux/dispatcher'; import { ProfileInfo, Styles } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; const teamRow1: ProfileInfo[] = [ @@ -143,6 +145,8 @@ const advisors: ProfileInfo[] = [ export interface AboutProps { source: string; location: Location; + translate: Translate; + dispatcher: Dispatcher; } interface AboutState {} @@ -174,6 +178,7 @@ export class About extends React.Component<AboutProps, AboutState> { blockchainIsLoaded={false} location={this.props.location} style={{ backgroundColor: colors.lightestGrey }} + translate={this.props.translate} /> <div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}> <div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}> @@ -230,7 +235,7 @@ export class About extends React.Component<AboutProps, AboutState> { </div> </div> </div> - <Footer /> + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> </div> ); } diff --git a/packages/website/ts/pages/documentation/comment.tsx b/packages/website/ts/pages/documentation/comment.tsx index 23cfd96bd..5f177e97e 100644 --- a/packages/website/ts/pages/documentation/comment.tsx +++ b/packages/website/ts/pages/documentation/comment.tsx @@ -15,7 +15,7 @@ const defaultProps = { export const Comment: React.SFC<CommentProps> = (props: CommentProps) => { return ( <div className={`${props.className} comment`}> - <ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} /> + <ReactMarkdown source={props.comment} renderers={{ code: MarkdownCodeBlock }} /> </div> ); }; 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 da3728a60..699bef7a8 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,28 +13,27 @@ 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 { utils } from 'ts/utils/utils'; const TOP_BAR_HEIGHT = 60; -const SCROLL_TOP_ID = 'docsScrollTop'; const networkNameToColor: { [network: string]: string } = { [Networks.Kovan]: colors.purple, @@ -47,19 +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; -} - -interface DocumentationState { docAgnosticFormat?: DocAgnosticFormat; + menuSubsectionsBySection: MenuSubsectionsBySection; + sourceUrl: string; } +interface DocumentationState {} + const styles: Styles = { mainContainers: { position: 'absolute', @@ -79,56 +73,18 @@ 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)) { + const hash = this.props.location.hash.slice(1); + utils.scrollToHash(hash, configs.SCROLL_CONTAINER_ID); + } } 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} - /> - {_.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 @@ -152,8 +108,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> @@ -161,8 +116,12 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume className="relative col lg-col-9 md-col-9 sm-col-12 col-12" style={{ backgroundColor: colors.white }} > - <div id="documentation" style={styles.mainContainers} className="absolute px1"> - <div id={SCROLL_TOP_ID} /> + <div + id={configs.SCROLL_CONTAINER_ID} + style={styles.mainContainers} + className="absolute px1" + > + <div id={configs.SCROLL_TOP_ID} /> {this._renderDocumentation()} </div> </div> @@ -172,11 +131,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; @@ -193,7 +169,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; } @@ -275,7 +251,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) => { @@ -323,8 +305,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" />} @@ -345,54 +326,8 @@ export class Documentation extends React.Component<DocumentationAllProps, Docume typeDefinitionByName={typeDefinitionByName} libraryVersion={this.props.docsVersion} docsInfo={this.props.docsInfo} + sourceUrl={this.props.sourceUrl} /> ); } - private _scrollToHash(): void { - const hashWithPrefix = this.props.location.hash; - let hash = hashWithPrefix.slice(1); - if (_.isEmpty(hash)) { - hash = SCROLL_TOP_ID; // scroll to the top - } - - scroller.scrollTo(hash, { - duration: 0, - offset: 0, - 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/event_definition.tsx b/packages/website/ts/pages/documentation/event_definition.tsx index 0e53e38e7..e62c9ecbd 100644 --- a/packages/website/ts/pages/documentation/event_definition.tsx +++ b/packages/website/ts/pages/documentation/event_definition.tsx @@ -25,9 +25,10 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event } public render() { const event = this.props.event; + const id = `${this.props.sectionName}-${event.name}`; return ( <div - id={`${this.props.sectionName}-${event.name}`} + id={id} className="pb2" style={{ overflow: 'hidden', width: '100%' }} onMouseOver={this._setAnchorVisibility.bind(this, true)} @@ -36,7 +37,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event <AnchorTitle headerSize={HeaderSizes.H3} title={`Event ${event.name}`} - id={event.name} + id={id} shouldShowAnchor={this.state.shouldShowAnchor} /> <div style={{ fontSize: 16 }}> 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/documentation/type_definition.tsx b/packages/website/ts/pages/documentation/type_definition.tsx index d46eec76c..02bf63258 100644 --- a/packages/website/ts/pages/documentation/type_definition.tsx +++ b/packages/website/ts/pages/documentation/type_definition.tsx @@ -113,7 +113,9 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef <code className="hljs">{codeSnippet}</code> </pre> </div> - {customType.comment && <Comment comment={customType.comment} className="py2" />} + <div style={{ maxWidth: 620 }}> + {customType.comment && <Comment comment={customType.comment} className="py2" />} + </div> </div> ); } diff --git a/packages/website/ts/pages/faq/faq.tsx b/packages/website/ts/pages/faq/faq.tsx index 0a7eecc2d..34175abdc 100644 --- a/packages/website/ts/pages/faq/faq.tsx +++ b/packages/website/ts/pages/faq/faq.tsx @@ -4,14 +4,18 @@ import * as DocumentTitle from 'react-document-title'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Question } from 'ts/pages/faq/question'; +import { Dispatcher } from 'ts/redux/dispatcher'; import { FAQQuestion, FAQSection, Styles, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; export interface FAQProps { source: string; location: Location; + translate: Translate; + dispatcher: Dispatcher; } interface FAQState {} @@ -407,14 +411,14 @@ export class FAQ extends React.Component<FAQProps, FAQState> { return ( <div> <DocumentTitle title="0x FAQ" /> - <TopBar blockchainIsLoaded={false} location={this.props.location} /> + <TopBar blockchainIsLoaded={false} location={this.props.location} translate={this.props.translate} /> <div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}> <h1 className="center" style={{ ...styles.thin }}> 0x FAQ </h1> <div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div> </div> - <Footer /> + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> </div> ); } diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx index d4c934459..044f0b41f 100644 --- a/packages/website/ts/pages/landing/landing.tsx +++ b/packages/website/ts/pages/landing/landing.tsx @@ -5,9 +5,11 @@ import DocumentTitle = require('react-document-title'); import { Link } from 'react-router-dom'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; -import { ScreenWidths, WebsitePaths } from 'ts/types'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; interface BoxContent { @@ -36,35 +38,6 @@ interface Project { const THROTTLE_TIMEOUT = 100; -const boxContents: BoxContent[] = [ - { - title: 'Trustless exchange', - description: - "Built on Ethereum's distributed network with no centralized \ - point of failure and no down time, each trade is settled atomically \ - and without counterparty risk.", - imageUrl: '/images/landing/distributed_network.png', - classNames: '', - }, - { - title: 'Shared liquidity', - description: - 'By sharing a standard API, relayers can easily aggregate liquidity pools, \ - creating network effects around liquidity that compound as more relayers come online.', - imageUrl: '/images/landing/liquidity.png', - classNames: 'mx-auto', - }, - { - title: 'Open source', - description: - '0x is open source, permissionless and free to use. Trade directly with a known \ - counterparty for free or pay a relayer some ZRX tokens to access their liquidity \ - pool.', - imageUrl: '/images/landing/open_source.png', - classNames: 'right', - }, -]; - const relayersAndDappProjects: Project[] = [ { logoFileName: 'ethfinex.png', @@ -185,6 +158,8 @@ const relayerProjects: Project[] = [ export interface LandingProps { location: Location; + translate: Translate; + dispatcher: Dispatcher; } interface LandingState { @@ -216,17 +191,28 @@ export class Landing extends React.Component<LandingProps, LandingState> { location={this.props.location} isNightVersion={true} style={{ backgroundColor: colors.heroGrey, position: 'relative' }} + translate={this.props.translate} /> {this._renderHero()} - {this._renderProjects(relayersAndDappProjects, 'Projects building on 0x', colors.projectsGrey, false)} + {this._renderProjects( + relayersAndDappProjects, + this.props.translate.get(Key.ProjectsHeader, Deco.Upper), + colors.projectsGrey, + false, + )} {this._renderTokenizationSection()} {this._renderProtocolSection()} - {this._renderProjects(relayerProjects, 'Relayers building on 0x', colors.heroGrey, true)} + {this._renderProjects( + relayerProjects, + this.props.translate.get(Key.RelayersHeader, Deco.Upper), + colors.heroGrey, + true, + )} {this._renderInfoBoxes()} {this._renderBuildingBlocksSection()} {this._renderUseCases()} {this._renderCallToAction()} - <Footer /> + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> </div> ); } @@ -243,7 +229,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { lineHeight: '33px', height: 38, }; - const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; + const left = 'col lg-col-7 md-col-7 col-12 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; return ( <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}> <div className="mx-auto max-width-4 clearfix"> @@ -251,8 +237,14 @@ export class Landing extends React.Component<LandingProps, LandingState> { <div className="col lg-col-5 md-col-5 col-12 sm-center"> <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} /> </div> - <div className={left} style={{ color: colors.white }}> - <div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}> + <div className={left} style={{ color: colors.white, height: 390, lineHeight: '390px' }}> + <div + className="inline-block lg-align-middle md-align-middle sm-align-top" + style={{ + paddingLeft: isSmallScreen ? 0 : 12, + lineHeight: '36px', + }} + > <div className="sm-pb2" style={{ @@ -260,7 +252,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { fontSize: isSmallScreen ? 26 : 34, }} > - Powering decentralized exchange + {this.props.translate.get(Key.TopHeader, Deco.Cap)} </div> <div className="pt2 h5 sm-mx-auto" @@ -271,17 +263,16 @@ export class Landing extends React.Component<LandingProps, LandingState> { fontWeight: 300, }} > - 0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the - Ethereum blockchain. + {this.props.translate.get(Key.TopTagline)} </div> - <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}> + <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 389 }}> <div className="lg-pr2 md-pr2 col col-6 sm-center"> <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> <RaisedButton style={{ borderRadius: 6, minWidth: 157.36 }} buttonStyle={{ borderRadius: 6 }} labelStyle={buttonLabelStyle} - label="Build on 0x" + label={this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} onClick={_.noop} /> </Link> @@ -298,7 +289,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { labelColor="white" backgroundColor={colors.heroGrey} labelStyle={buttonLabelStyle} - label="Join the community" + label={this.props.translate.get(Key.CommunityCallToAction, Deco.Cap)} onClick={_.noop} /> </a> @@ -313,7 +304,6 @@ export class Landing extends React.Component<LandingProps, LandingState> { } private _renderProjects(projects: Project[], title: string, backgroundColor: string, isTitleCenter: boolean) { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; - const isMediumScreen = this.state.screenWidth === ScreenWidths.Md; const projectList = _.map(projects, (project: Project, i: number) => { const isRelayersOnly = projects.length === 12; let colWidth: number; @@ -346,7 +336,6 @@ export class Landing extends React.Component<LandingProps, LandingState> { const titleStyle: React.CSSProperties = { fontFamily: 'Roboto Mono', color: colors.grey, - textTransform: 'uppercase', fontWeight: 300, letterSpacing: 3, }; @@ -366,13 +355,13 @@ export class Landing extends React.Component<LandingProps, LandingState> { fontSize: 14, }} > - view the{' '} + {this.props.translate.get(Key.FullListPrompt)}{' '} <Link to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`} className="text-decoration-none underline" style={{ color: colors.landingLinkGrey }} > - full list + {this.props.translate.get(Key.FullListLink)} </Link> </div> </div> @@ -385,33 +374,22 @@ export class Landing extends React.Component<LandingProps, LandingState> { <div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}> <div className="mx-auto max-width-4 py4 clearfix"> {isSmallScreen && this._renderTokenCloud()} - <div className="col lg-col-6 md-col-6 col-12" style={{ color: colors.darkestGrey }}> - <div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}> + <div + className="col lg-col-6 md-col-6 col-12 center" + style={{ color: colors.darkestGrey, height: 364, lineHeight: '364px' }} + > + <div + className="mx-auto inline-block lg-align-middle md-align-middle sm-align-top" + style={{ maxWidth: 385, lineHeight: '44px', textAlign: 'left' }} + > <div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}> - The world's value is becoming tokenized + {this.props.translate.get(Key.TokenizedSectionHeader, Deco.Cap)} </div> <div className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center" - style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }} + style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7, maxWidth: 370 }} > - {isSmallScreen ? ( - <span> - The Ethereum blockchain is an open, borderless financial system that represents - a wide variety of assets as cryptographic tokens. In the future, most digital - assets and goods will be tokenized. - </span> - ) : ( - <div> - <div> - The Ethereum blockchain is an open, borderless financial system that - represents - </div> - <div> - a wide variety of assets as cryptographic tokens. In the future, most - digital assets and goods will be tokenized. - </div> - </div> - )} + {this.props.translate.get(Key.TokenizedSectionDescription, Deco.Cap)} </div> <div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div> </div> @@ -430,28 +408,36 @@ export class Landing extends React.Component<LandingProps, LandingState> { <img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} /> </div> <div - className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto lg-pt4 md-pt4 lg-mt3 md-mt3" + className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto" style={{ color: colors.beigeWhite, maxWidth: isSmallScreen ? 'none' : 445, + height: 430, + lineHeight: '430px', }} > - <div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}> - <div>Off-chain order relay</div> - <div>On-chain settlement</div> - </div> <div - className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto" - style={{ - fontFamily: 'Roboto Mono', - lineHeight: 1.7, - fontWeight: 300, - maxWidth: 445, - }} + className="inline-block lg-align-middle md-align-middle sm-align-top" + style={{ lineHeight: '43px' }} > - In 0x protocol, orders are transported off-chain, massively reducing gas costs and - eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time - they facilitate a trade. Anyone can build a relayer. + <div + className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" + style={{ fontFamily: 'Roboto Mono' }} + > + <div>{this.props.translate.get(Key.OffChainOrderRelay, Deco.Cap)}</div> + <div> {this.props.translate.get(Key.OonChainSettlement, Deco.Cap)}</div> + </div> + <div + className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto" + style={{ + fontFamily: 'Roboto Mono', + lineHeight: 1.7, + fontWeight: 300, + maxWidth: 445, + }} + > + {this.props.translate.get(Key.OffChainOnChainDescription, Deco.Cap)} + </div> </div> </div> </div> @@ -485,15 +471,13 @@ export class Landing extends React.Component<LandingProps, LandingState> { className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center" style={{ fontFamily: 'Roboto Mono' }} > - A building block for dApps + {this.props.translate.get(Key.BuildingBlockSectionHeader, Deco.Cap)} </div> <div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}> - 0x protocol is a pluggable building block for dApps that require exchange functionality. - Join the many developers that are already using 0x in their web applications and smart - contracts. + {this.props.translate.get(Key.BuildingBlockSectionDescription, Deco.Cap)} </div> <div className="sm-mx-auto sm-center" style={callToActionStyle}> - Learn how in our{' '} + {this.props.translate.get(Key.DevToolsPrompt, Deco.Cap)}{' '} <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none underline" @@ -501,15 +485,15 @@ export class Landing extends React.Component<LandingProps, LandingState> { > 0x.js </Link>{' '} - and{' '} + {this.props.translate.get(Key.And)}{' '} <Link to={WebsitePaths.SmartContracts} className="text-decoration-none underline" style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }} > - smart contract + {this.props.translate.get(Key.SmartContract)} </Link>{' '} - docs + {this.props.translate.get(Key.Docs)} </div> </div> {!isSmallScreen && this._renderBlockChipImage()} @@ -537,11 +521,11 @@ export class Landing extends React.Component<LandingProps, LandingState> { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const assetTypes: AssetType[] = [ { - title: 'Currency', + title: this.props.translate.get(Key.Currency, Deco.Cap), imageUrl: '/images/landing/currency.png', }, { - title: 'Traditional assets', + title: this.props.translate.get(Key.TraditionalAssets, Deco.Cap), imageUrl: '/images/landing/stocks.png', style: { paddingLeft: isSmallScreen ? 41 : 56, @@ -549,7 +533,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { }, }, { - title: 'Digital goods', + title: this.props.translate.get(Key.DigitalGoods, Deco.Cap), imageUrl: '/images/landing/digital_goods.png', }, ]; @@ -566,6 +550,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { fontSize: 13.5, fontWeight: 400, color: colors.darkestGrey, + lineHeight: 1.4, }} > {assetType.title} @@ -578,12 +563,32 @@ export class Landing extends React.Component<LandingProps, LandingState> { private _renderInfoBoxes() { const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const boxStyle: React.CSSProperties = { - maxWidth: 252, - height: 386, + maxWidth: 253, + height: 402, backgroundColor: colors.grey50, borderRadius: 5, padding: '10px 24px 24px', }; + const boxContents: BoxContent[] = [ + { + title: this.props.translate.get(Key.BenefitOneTitle, Deco.Cap), + description: this.props.translate.get(Key.BenefitOneDescription, Deco.Cap), + imageUrl: '/images/landing/distributed_network.png', + classNames: '', + }, + { + title: this.props.translate.get(Key.BenefitTwoTitle, Deco.Cap), + description: this.props.translate.get(Key.BenefitTwoDescription, Deco.Cap), + imageUrl: '/images/landing/liquidity.png', + classNames: 'mx-auto', + }, + { + title: this.props.translate.get(Key.BenefitThreeTitle, Deco.Cap), + description: this.props.translate.get(Key.BenefitThreeDescription, Deco.Cap), + imageUrl: '/images/landing/open_source.png', + classNames: 'right', + }, + ]; const boxes = _.map(boxContents, (boxContent: BoxContent) => { return ( <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4"> @@ -604,14 +609,13 @@ export class Landing extends React.Component<LandingProps, LandingState> { const titleStyle: React.CSSProperties = { fontFamily: 'Roboto Mono', color: colors.grey, - textTransform: 'uppercase', fontWeight: 300, letterSpacing: 3, }; return ( <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}> <div className="center pb3 pt4" style={titleStyle}> - Benefits of 0x + {this.props.translate.get(Key.BenefitsHeader, Deco.Upper)} </div> <div className="mx-auto pb4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}> {boxes} @@ -625,41 +629,29 @@ export class Landing extends React.Component<LandingProps, LandingState> { const useCases: UseCase[] = [ { imageUrl: '/images/landing/governance_icon.png', - type: 'Decentralized governance', - description: - 'Decentralized organizations use tokens to represent ownership and \ - guide their governance logic. 0x allows decentralized organizations \ - to seamlessly and safely trade ownership for startup capital.', + type: this.props.translate.get(Key.DecentralizedGovernance, Deco.Upper), + description: this.props.translate.get(Key.DecentralizedGovernanceDescription, Deco.Cap), projectIconUrls: ['/images/landing/aragon.png'], classNames: 'lg-px2 md-px2', }, { imageUrl: '/images/landing/prediction_market_icon.png', - type: 'Prediction markets', - description: - 'Decentralized prediction market platforms generate sets of tokens that \ - represent a financial stake in the outcomes of real-world events. 0x allows \ - these tokens to be instantly tradable.', + type: this.props.translate.get(Key.PredictionMarkets, Deco.Upper), + description: this.props.translate.get(Key.PredictionMarketsDescription, Deco.Cap), projectIconUrls: ['/images/landing/augur.png'], classNames: 'lg-px2 md-px2', }, { imageUrl: '/images/landing/stable_tokens_icon.png', - type: 'Stable tokens', - description: - 'Novel economic constructs such as stable coins require efficient, liquid \ - markets to succeed. 0x will facilitate the underlying economic mechanisms \ - that allow these tokens to remain stable.', + type: this.props.translate.get(Key.StableTokens, Deco.Upper), + description: this.props.translate.get(Key.StableTokensDescription, Deco.Cap), projectIconUrls: ['/images/landing/maker.png'], classNames: 'lg-px2 md-px2', }, { imageUrl: '/images/landing/loans_icon.png', - type: 'Decentralized loans', - description: - 'Efficient lending requires liquid markets where investors can buy and re-sell loans. \ - 0x enables an ecosystem of lenders to self-organize and efficiently determine \ - market prices for all outstanding loans.', + type: this.props.translate.get(Key.DecentralizedLoans, Deco.Upper), + description: this.props.translate.get(Key.DecentralizedLoansDescription, Deco.Cap), projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'], classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6', style: { @@ -670,11 +662,8 @@ export class Landing extends React.Component<LandingProps, LandingState> { }, { imageUrl: '/images/landing/fund_management_icon.png', - type: 'Fund management', - description: - 'Decentralized fund management limits fund managers to investing in pre-agreed \ - upon asset classes. Embedding 0x into fund management smart contracts enables \ - them to enforce these security constraints.', + type: this.props.translate.get(Key.FundManagement, Deco.Upper), + description: this.props.translate.get(Key.FundManagementDescription, Deco.Cap), projectIconUrls: ['/images/landing/melonport.png'], classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6', style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 }, @@ -685,7 +674,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style; const useCaseBoxStyle = { color: colors.grey, - border: '1px solid #565656', + border: `1px solid ${colors.grey750}`, borderRadius: 4, maxWidth: isSmallScreen ? 375 : 'none', ...style, @@ -741,38 +730,39 @@ export class Landing extends React.Component<LandingProps, LandingState> { }; const lightButtonStyle: React.CSSProperties = { borderRadius: 6, - border: '1px solid #a0a0a0', + border: `1px solid ${colors.grey500}`, lineHeight: '33px', height: 49, }; const callToActionClassNames = - 'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \ - lg-right-align md-right-align sm-center sm-px3 h4'; + 'lg-pr3 md-pr3 lg-right-align md-right-align sm-center sm-px3 h4 lg-table-cell md-table-cell'; return ( <div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}> - <div className="mx-auto max-width-4 pb4 mb3 clearfix"> - <div - className={callToActionClassNames} - style={{ - fontFamily: 'Roboto Mono', - color: colors.white, - lineHeight: isSmallScreen ? 1.7 : 3, - }} - > - Get started on building the decentralized future - </div> - <div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2"> - <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <RaisedButton - style={{ borderRadius: 6, minWidth: 150 }} - buttonStyle={lightButtonStyle} - labelColor={colors.white} - backgroundColor={colors.heroGrey} - labelStyle={buttonLabelStyle} - label="Build on 0x" - onClick={_.noop} - /> - </Link> + <div className="mx-auto max-width-4 pb4 mb3 clearfix center"> + <div className="center inline-block" style={{ textAlign: 'left' }}> + <div + className={callToActionClassNames} + style={{ + fontFamily: 'Roboto Mono', + color: colors.white, + lineHeight: isSmallScreen ? 1.7 : 3, + }} + > + {this.props.translate.get(Key.FinalCallToAction, Deco.Cap)} + </div> + <div className="sm-center sm-pt2 lg-table-cell md-table-cell"> + <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> + <RaisedButton + style={{ borderRadius: 6, minWidth: 150 }} + buttonStyle={lightButtonStyle} + labelColor={colors.white} + backgroundColor={colors.heroGrey} + labelStyle={buttonLabelStyle} + label={this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} + onClick={_.noop} + /> + </Link> + </div> </div> </div> </div> @@ -786,4 +776,7 @@ export class Landing extends React.Component<LandingProps, LandingState> { }); } } + private _onLanguageSelected(language: Language) { + this.props.dispatcher.updateSelectedLanguage(language); + } } // tslint:disable:max-file-line-count diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx index 0a6ec071c..ad37f6242 100644 --- a/packages/website/ts/pages/not_found.tsx +++ b/packages/website/ts/pages/not_found.tsx @@ -2,10 +2,14 @@ import * as _ from 'lodash'; import * as React from 'react'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; +import { Dispatcher } from 'ts/redux/dispatcher'; import { Styles } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; export interface NotFoundProps { location: Location; + translate: Translate; + dispatcher: Dispatcher; } interface NotFoundState {} @@ -20,7 +24,7 @@ export class NotFound extends React.Component<NotFoundProps, NotFoundState> { public render() { return ( <div> - <TopBar blockchainIsLoaded={false} location={this.props.location} /> + <TopBar blockchainIsLoaded={false} location={this.props.location} translate={this.props.translate} /> <div className="mx-auto max-width-4 py4"> <div className="center py4"> <div className="py4"> @@ -35,7 +39,7 @@ export class NotFound extends React.Component<NotFoundProps, NotFoundState> { </div> </div> </div> - <Footer /> + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> </div> ); } diff --git a/packages/website/ts/pages/shared/markdown_code_block.tsx b/packages/website/ts/pages/shared/markdown_code_block.tsx index 98ca3aee6..6dfb74554 100644 --- a/packages/website/ts/pages/shared/markdown_code_block.tsx +++ b/packages/website/ts/pages/shared/markdown_code_block.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import * as HighLight from 'react-highlight'; interface MarkdownCodeBlockProps { - literal: string; + value: string; language: string; } @@ -13,12 +13,12 @@ export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, M // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed. public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) { - return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language; + return nextProps.value !== this.props.value || nextProps.language !== this.props.language; } public render() { return ( <span style={{ fontSize: 14 }}> - <HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight> + <HighLight className={this.props.language || 'javascript'}>{this.props.value}</HighLight> </span> ); } diff --git a/packages/website/ts/pages/shared/markdown_link_block.tsx b/packages/website/ts/pages/shared/markdown_link_block.tsx new file mode 100644 index 000000000..e4553c87f --- /dev/null +++ b/packages/website/ts/pages/shared/markdown_link_block.tsx @@ -0,0 +1,46 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import { configs } from 'ts/utils/configs'; +import { utils } from 'ts/utils/utils'; + +interface MarkdownLinkBlockProps { + href: string; +} + +interface MarkdownLinkBlockState {} + +export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> { + // Re-rendering a linkBlock causes it to remain unclickable. + // We therefore noop re-renders on this component if it's props haven't changed. + public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState) { + return nextProps.href !== this.props.href; + } + public render() { + const href = this.props.href; + const isLinkToSection = _.startsWith(href, '#'); + // If protocol is http or https, we can open in a new tab, otherwise don't for security reasons + if (_.startsWith(href, 'http') || _.startsWith(href, 'https')) { + return ( + <a href={href} target="_blank" rel="nofollow noreferrer noopener"> + {this.props.children} + </a> + ); + } else if (isLinkToSection) { + return ( + <a + style={{ cursor: 'pointer', textDecoration: 'underline' }} + onClick={this._onHashUrlClick.bind(this, href)} + > + {this.props.children} + </a> + ); + } else { + return <a href={href}>{this.props.children}</a>; + } + } + private _onHashUrlClick(href: string) { + const hash = href.split('#')[1]; + utils.scrollToHash(hash, configs.SCROLL_CONTAINER_ID); + utils.setUrlHash(hash); + } +} diff --git a/packages/website/ts/pages/shared/markdown_section.tsx b/packages/website/ts/pages/shared/markdown_section.tsx index 4d7d8b4ca..7253072d9 100644 --- a/packages/website/ts/pages/shared/markdown_section.tsx +++ b/packages/website/ts/pages/shared/markdown_section.tsx @@ -5,6 +5,7 @@ import * as ReactMarkdown from 'react-markdown'; import { Element as ScrollElement } from 'react-scroll'; import { AnchorTitle } from 'ts/pages/shared/anchor_title'; import { MarkdownCodeBlock } from 'ts/pages/shared/markdown_code_block'; +import { MarkdownLinkBlock } from 'ts/pages/shared/markdown_link_block'; import { HeaderSizes } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; @@ -64,7 +65,14 @@ export class MarkdownSection extends React.Component<MarkdownSectionProps, Markd </div> </div> <hr style={{ border: `1px solid ${colors.lightestGrey}` }} /> - <ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} /> + <ReactMarkdown + source={this.props.markdownContent} + escapeHtml={false} + renderers={{ + code: MarkdownCodeBlock, + link: MarkdownLinkBlock, + }} + /> </ScrollElement> </div> ); diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx index ba794ee9f..82a40eb7e 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> @@ -92,14 +86,14 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N docs </div> </div> - <div className="pl1" style={{ color: colors.grey350, paddingBottom: 9, paddingLeft: 14, height: 17 }}> + <div className="pl1" style={{ color: colors.grey350, paddingBottom: 9, paddingLeft: 10, height: 17 }}> | </div> <div className="flex"> <div> - <img src={`/images/doc_icons/${titleToIcon[this.props.title]}`} width="24" /> + <img src={`/images/doc_icons/${titleToIcon[this.props.title]}`} width="22" /> </div> - <div className="pl1" style={{ fontWeight: 600, fontSize: 20, lineHeight: 1 }}> + <div className="pl1" style={{ fontWeight: 600, fontSize: 20, lineHeight: 1.2 }}> {this.props.title} </div> </div> diff --git a/packages/website/ts/pages/shared/section_header.tsx b/packages/website/ts/pages/shared/section_header.tsx index a5f5f52cf..52a1f30d9 100644 --- a/packages/website/ts/pages/shared/section_header.tsx +++ b/packages/website/ts/pages/shared/section_header.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { Element as ScrollElement } from 'react-scroll'; import { AnchorTitle } from 'ts/pages/shared/anchor_title'; import { HeaderSizes } from 'ts/types'; +import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; interface SectionHeaderProps { @@ -34,7 +35,19 @@ export class SectionHeader extends React.Component<SectionHeaderProps, SectionHe <ScrollElement name={id}> <AnchorTitle headerSize={this.props.headerSize} - title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>} + title={ + <span + style={{ + textTransform: 'uppercase', + color: colors.grey, + fontFamily: 'Roboto Mono', + fontWeight: 300, + fontSize: 27, + }} + > + {sectionName} + </span> + } id={id} shouldShowAnchor={this.state.shouldShowAnchor} /> diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx index b922e1048..1b4dbb375 100644 --- a/packages/website/ts/pages/shared/version_drop_down.tsx +++ b/packages/website/ts/pages/shared/version_drop_down.tsx @@ -2,11 +2,11 @@ import * as _ from 'lodash'; import DropDownMenu from 'material-ui/DropDownMenu'; import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; +import { utils } from 'ts/utils/utils'; interface VersionDropDownProps { selectedVersion: string; versions: string[]; - docPath: string; } interface VersionDropDownState {} @@ -31,7 +31,15 @@ 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) { + 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 = utils.getCurrentBaseUrl(); + window.location.href = `${baseUrl}${path}/${semver}${window.location.hash}`; } } diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx index bbbda6eee..4bb6052a2 100644 --- a/packages/website/ts/pages/wiki/wiki.tsx +++ b/packages/website/ts/pages/wiki/wiki.tsx @@ -8,10 +8,12 @@ import { TopBar } from 'ts/components/top_bar/top_bar'; 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 { Article, ArticlesBySection, HeaderSizes, Styles, WebsitePaths } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; const TOP_BAR_HEIGHT = 60; @@ -20,6 +22,8 @@ const WIKI_NOT_READY_BACKOUT_TIMEOUT_MS = 5000; export interface WikiProps { source: string; location: Location; + dispatcher: Dispatcher; + translate: Translate; } interface WikiState { @@ -79,6 +83,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> { blockchainIsLoaded={false} location={this.props.location} menuSubsectionsBySection={menuSubsectionsBySection} + translate={this.props.translate} /> {_.isUndefined(this.state.articlesBySection) ? ( <div className="col col-12" style={mainContainersStyle}> @@ -130,11 +135,11 @@ export class Wiki extends React.Component<WikiProps, WikiState> { }} > <div - id="documentation" + id={configs.SCROLL_CONTAINER_ID} style={{ ...mainContainersStyle, overflow: 'auto' }} className="absolute" > - <div id="0xProtocolWiki" /> + <div id={configs.SCROLL_TOP_ID} /> <div id="wiki" style={{ paddingRight: 2 }}> {this._renderWikiArticles()} </div> @@ -183,19 +188,6 @@ export class Wiki extends React.Component<WikiProps, WikiState> { </div> ); } - private _scrollToHash(): void { - const hashWithPrefix = this.props.location.hash; - let hash = hashWithPrefix.slice(1); - if (_.isEmpty(hash)) { - hash = '0xProtocolWiki'; // scroll to the top - } - - scroller.scrollTo(hash, { - duration: 0, - offset: 0, - containerId: 'documentation', - }); - } private async _fetchArticlesBySectionAsync(): Promise<void> { const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`; const response = await fetch(endpoint); @@ -219,8 +211,10 @@ export class Wiki extends React.Component<WikiProps, WikiState> { { articlesBySection, }, - () => { - this._scrollToHash(); + async () => { + await utils.onPageLoadAsync(); + const hash = this.props.location.hash.slice(1); + utils.scrollToHash(hash, configs.SCROLL_CONTAINER_ID); }, ); } diff --git a/packages/website/ts/redux/dispatcher.ts b/packages/website/ts/redux/dispatcher.ts index 925f2aa29..5c40ded2c 100644 --- a/packages/website/ts/redux/dispatcher.ts +++ b/packages/website/ts/redux/dispatcher.ts @@ -6,6 +6,7 @@ import { ActionTypes, AssetToken, BlockchainErrs, + Language, Order, ProviderType, ScreenWidths, @@ -211,4 +212,10 @@ export class Dispatcher { data: injectedProviderName, }); } + public updateSelectedLanguage(language: Language) { + this._dispatch({ + type: ActionTypes.UpdateSelectedLanguage, + data: language, + }); + } } diff --git a/packages/website/ts/redux/reducer.ts b/packages/website/ts/redux/reducer.ts index c2a21dc07..1f489db85 100644 --- a/packages/website/ts/redux/reducer.ts +++ b/packages/website/ts/redux/reducer.ts @@ -13,6 +13,7 @@ import { SideToAssetToken, TokenByAddress, } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; // Instead of defaulting the docs version to an empty string, we pre-populate it with @@ -49,6 +50,7 @@ export interface State { flashMessage: string | React.ReactNode; providerType: ProviderType; injectedProviderName: string; + translate: Translate; } const INITIAL_STATE: State = { @@ -86,13 +88,17 @@ const INITIAL_STATE: State = { flashMessage: undefined, providerType: ProviderType.Injected, injectedProviderName: '', + translate: new Translate(), }; export function reducer(state: State = INITIAL_STATE, action: Action) { switch (action.type) { // Portal case ActionTypes.ResetState: - return INITIAL_STATE; + return { + ...INITIAL_STATE, + translate: state.translate, + }; case ActionTypes.UpdateOrderSalt: { return { @@ -101,6 +107,13 @@ export function reducer(state: State = INITIAL_STATE, action: Action) { }; } + case ActionTypes.UpdateSelectedLanguage: { + return { + ...state, + translate: new Translate(action.data), + }; + } + case ActionTypes.UpdateNodeVersion: { return { ...state, diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 645c9cc11..28663270e 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -140,6 +140,7 @@ export enum ActionTypes { HideFlashMessage = 'HIDE_FLASH_MESSAGE', UpdateProviderType = 'UPDATE_PROVIDER_TYPE', UpdateInjectedProviderName = 'UPDATE_INJECTED_PROVIDER_NAME', + UpdateSelectedLanguage = 'UPDATE_SELECTED_LANGUAGE', } export interface Action { @@ -307,7 +308,7 @@ export interface TypeDocNode { returns?: string; declaration: TypeDocNode; flags?: TypeDocFlags; - indexSignature?: TypeDocNode[]; + indexSignature?: TypeDocNode | TypeDocNode[]; // TypeDocNode in TypeDoc <V0.9.0, TypeDocNode[] in >V0.9.0 signatures?: TypeDocNode[]; parameters?: TypeDocNode[]; typeParameter?: TypeDocNode[]; @@ -626,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 { @@ -667,4 +687,79 @@ export interface MaterialUIPosition { horizontal: 'left' | 'middle' | 'right'; } +export enum Language { + English = 'EN', + Spanish = 'ES', + Chinese = 'ZH', + Korean = 'KO', + Russian = 'RU', +} + +export enum Key { + TopHeader = 'TOP_HEADER', + TopTagline = 'TOP_TAGLINE', + BuildCallToAction = 'BUILD_CALL_TO_ACTION', + CommunityCallToAction = 'COMMUNITY_CALL_TO_ACTION', + ProjectsHeader = 'PROJECTS_HEADER', + FullListPrompt = 'FULL_LIST_PROMPT', + FullListLink = 'FULL_LIST_LINK', + TokenizedSectionHeader = 'TOKENIZED_SECTION_HEADER', + TokenizedSectionDescription = 'TOKENIZED_SECTION_DESCRIPTION', + Currency = 'CURRENCY', + TraditionalAssets = 'TRADITIONAL_ASSETS', + DigitalGoods = 'DIGITAL_GOODS', + OffChainOrderRelay = 'OFFCHAIN_ORDER_RELAY', + OonChainSettlement = 'OONCHAIN_SETTLEMENT', + OffChainOnChainDescription = 'OFFCHAIN_ONCHAIN_DESCRIPTION', + RelayersHeader = 'RELAYERS_HEADER', + BenefitsHeader = 'BENEFITS_HEADER', + BenefitOneTitle = 'BENEFIT_ONE_TITLE', + BenefitOneDescription = 'BENEFIT_ONE_DESCRIPTION', + BenefitTwoTitle = 'BENEFIT_TWO_TITLE', + BenefitTwoDescription = 'BENEFIT_TWO_DESCRIPTION', + BenefitThreeTitle = 'BENEFIT_THREE_TITLE', + BenefitThreeDescription = 'BENEFIT_THREE_DESCRIPTION', + BuildingBlockSectionHeader = 'BUILDING_BLOCK_SECTION_HEADER', + BuildingBlockSectionDescription = 'BUILDING_BLOCK_SECTION_DESCRIPTION', + DevToolsPrompt = 'DEV_TOOLS_PROMPT', + SmartContract = 'SMART_CONTRACT', + Docs = 'DOCS', + DecentralizedGovernance = 'DECENTRALIZED_GOVERNANCE', + DecentralizedGovernanceDescription = 'DECENTRALIZED_GOVERNANCE_DESCRIPTION', + PredictionMarkets = 'PREDICTION_MARKETS', + PredictionMarketsDescription = 'PREDICTION_MARKETS_DESCRIPTION', + StableTokens = 'STABLE_TOKENS', + StableTokensDescription = 'STABLE_TOKENS_DESCRIPTION', + DecentralizedLoans = 'DECENTRALIZED_LOANS', + DecentralizedLoansDescription = 'DECENTRALIZED_LOANS_DESCRIPTION', + FundManagement = 'FUND_MANAGEMENT', + FundManagementDescription = 'FUND_MANAGEMENT_DESCRIPTION', + FinalCallToAction = 'FINAL_CALL_TO_ACTION', + Documentation = 'DOCUMENTATION', + Community = 'COMMUNITY', + Organization = 'ORGANIZATION', + About = 'ABOUT', + Careers = 'CAREERS', + Contact = 'CONTACT', + Blog = 'BLOG', + Forum = 'FORUM', + Connect = 'CONNECT', + Whitepaper = 'WHITEPAPER', + Wiki = 'WIKI', + And = 'AND', + Faq = 'FAQ', + SmartContracts = 'SMART_CONTRACTS', + StandardRelayerApi = 'STANDARD_RELAYER_API', + PortalDApp = 'PORTAL_DAPP', + Website = 'WEBSITE', + Developers = 'DEVELOPERS', + Home = 'HOME', + RocketChat = 'ROCKETCHAT', +} + +export enum Deco { + Cap, + CapWords, + Upper, +} // tslint:disable:max-file-line-count diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts index 8e359f8bd..388fc8530 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'], @@ -129,6 +94,8 @@ export const configs = { [3]: [`https://ropsten.infura.io/${INFURA_API_KEY}`], [4]: [`https://rinkeby.infura.io/${INFURA_API_KEY}`], } as PublicNodeUrlsByNetworkId, + SCROLL_CONTAINER_ID: 'documentation', + SCROLL_TOP_ID: 'pageScrollTop', SHOULD_DEPRECATE_OLD_WETH_TOKEN: true, SYMBOLS_OF_MINTABLE_KOVAN_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'], SYMBOLS_OF_MINTABLE_RINKEBY_ROPSTEN_TOKENS: [ 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/translate.ts b/packages/website/ts/utils/translate.ts new file mode 100644 index 000000000..5148e48ad --- /dev/null +++ b/packages/website/ts/utils/translate.ts @@ -0,0 +1,83 @@ +import * as _ from 'lodash'; +import { Deco, Key, Language } from 'ts/types'; + +import * as chinese from '../../translations/chinese.json'; +import * as english from '../../translations/english.json'; +import * as korean from '../../translations/korean.json'; +import * as russian from '../../translations/russian.json'; +import * as spanish from '../../translations/spanish.json'; + +const languageToTranslations = { + [Language.English]: english, + [Language.Spanish]: spanish, + [Language.Chinese]: chinese, + [Language.Korean]: korean, + [Language.Russian]: russian, +}; + +const languagesWithoutCaps = [Language.Chinese, Language.Korean]; + +interface Translation { + [key: string]: string; +} + +export class Translate { + private _selectedLanguage: Language; + private _translation: Translation; + constructor(desiredLanguage?: Language) { + if (!_.isUndefined(desiredLanguage)) { + this.setLanguage(desiredLanguage); + return; + } + const browserLanguage = (window.navigator as any).userLanguage || window.navigator.language || 'en-US'; + let language = Language.English; + if (_.includes(browserLanguage, 'es-')) { + language = Language.Spanish; + } else if (_.includes(browserLanguage, 'zh-')) { + language = Language.Chinese; + } else if (_.includes(browserLanguage, 'ko-')) { + language = Language.Korean; + } else if (_.includes(browserLanguage, 'ru-')) { + language = Language.Russian; + } + this.setLanguage(language); + } + public getLanguage() { + return this._selectedLanguage; + } + public setLanguage(language: Language) { + const isLanguageSupported = !_.isUndefined(languageToTranslations[language]); + if (!isLanguageSupported) { + throw new Error(`${language} not supported`); + } + this._selectedLanguage = language; + this._translation = languageToTranslations[language]; + } + public get(key: Key, decoration?: Deco) { + let text = this._translation[key]; + if (!_.isUndefined(decoration) && !_.includes(languagesWithoutCaps, this._selectedLanguage)) { + switch (decoration) { + case Deco.Cap: + text = this._capitalize(text); + break; + + case Deco.Upper: + text = text.toUpperCase(); + break; + + case Deco.CapWords: + const words = text.split(' '); + const capitalizedWords = _.map(words, w => this._capitalize(w)); + text = capitalizedWords.join(' '); + break; + + default: + throw new Error(`Unrecognized decoration: ${decoration}`); + } + } + return text; + } + private _capitalize(text: string) { + return `${text.charAt(0).toUpperCase()}${text.slice(1)}`; + } +} diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts index 11ec8da58..ce7df4dbb 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, @@ -40,18 +41,17 @@ export const typeDocUtils = { isPrivateOrProtectedProperty(propertyName: string): boolean { return _.startsWith(propertyName, '_'); }, - getModuleDefinitionBySectionNameIfExists( - versionDocObj: TypeDocNode, - modulePaths: string[], - ): TypeDocNode | undefined { - const modules = versionDocObj.children; - for (const mod of modules) { - if (_.includes(modulePaths, mod.name)) { - const moduleWithName = mod; - return moduleWithName; - } - } - return undefined; + getModuleDefinitionsBySectionName(versionDocObj: TypeDocNode, configModulePaths: string[]): TypeDocNode[] { + const moduleDefinitions: TypeDocNode[] = []; + const jsonModules = versionDocObj.children; + _.each(jsonModules, jsonMod => { + _.each(configModulePaths, configModulePath => { + if (_.includes(configModulePath, jsonMod.name)) { + moduleDefinitions.push(jsonMod); + } + }); + }); + return moduleDefinitions; }, convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat { const subMenus = _.values(docsInfo.getMenu()); @@ -62,12 +62,23 @@ export const typeDocUtils = { if (_.isUndefined(modulePathsIfExists)) { return; // no-op } - const packageDefinitionIfExists = typeDocUtils.getModuleDefinitionBySectionNameIfExists( - typeDocJson, - modulePathsIfExists, - ); - if (_.isUndefined(packageDefinitionIfExists)) { + const packageDefinitions = typeDocUtils.getModuleDefinitionsBySectionName(typeDocJson, modulePathsIfExists); + let packageDefinitionWithMergedChildren; + if (_.isEmpty(packageDefinitions)) { return; // no-op + } else if (packageDefinitions.length === 1) { + packageDefinitionWithMergedChildren = packageDefinitions[0]; + } else { + // HACK: For now, if there are two modules to display in a single section, + // we simply concat the children. This works for our limited use-case where + // we want to display types stored in two files under a single section + packageDefinitionWithMergedChildren = packageDefinitions[0]; + for (let i = 1; i < packageDefinitions.length; i++) { + packageDefinitionWithMergedChildren.children = [ + ...packageDefinitionWithMergedChildren.children, + ...packageDefinitions[i].children, + ]; + } } // Since the `types.ts` file is the only file that does not export a module/class but @@ -76,10 +87,10 @@ export const typeDocUtils = { let entities; let packageComment = ''; if (sectionName === docsInfo.sections.types) { - entities = packageDefinitionIfExists.children; + entities = packageDefinitionWithMergedChildren.children; } else { - entities = packageDefinitionIfExists.children[0].children; - const commentObj = packageDefinitionIfExists.children[0].comment; + entities = packageDefinitionWithMergedChildren.children[0].children; + const commentObj = packageDefinitionWithMergedChildren.children[0].comment; packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment; } @@ -108,7 +119,7 @@ export const typeDocUtils = { isConstructor, docsInfo.sections, sectionName, - docsInfo.subPackageName, + docsInfo.id, ); docSection.constructors.push(constructor); break; @@ -121,7 +132,7 @@ export const typeDocUtils = { isConstructor, docsInfo.sections, sectionName, - docsInfo.subPackageName, + docsInfo.id, ); docSection.methods.push(method); } @@ -133,7 +144,7 @@ export const typeDocUtils = { entity, docsInfo.sections, sectionName, - docsInfo.subPackageName, + docsInfo.id, ); docSection.properties.push(property); } @@ -149,7 +160,7 @@ export const typeDocUtils = { entity, docsInfo.sections, sectionName, - docsInfo.subPackageName, + docsInfo.id, ); docSection.types.push(customType); } @@ -161,21 +172,24 @@ 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) + const doesIndexSignatureExist = !_.isUndefined(entity.indexSignature); + const isIndexSignatureArray = _.isArray(entity.indexSignature); + // HACK: TypeDoc Versions <0.9.0 indexSignature is of type TypeDocNode[] + // Versions >0.9.0 have it as type TypeDocNode + const indexSignature = + doesIndexSignatureExist && isIndexSignatureArray + ? (entity.indexSignature as TypeDocNode[])[0] + : (entity.indexSignature as TypeDocNode); + const indexSignatureIfExists = doesIndexSignatureExist + ? typeDocUtils._convertIndexSignature(indexSignature, sections, sectionName, docId) : undefined; const commentIfExists = !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText) @@ -185,7 +199,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 +226,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 +255,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 +267,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 +278,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 +306,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 +325,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 +335,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/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index c38f84c92..a1e045af7 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -4,6 +4,7 @@ import deepEqual = require('deep-equal'); import isMobile = require('is-mobile'); import * as _ from 'lodash'; import * as moment from 'moment'; +import { scroller } from 'react-scroll'; import { EtherscanLinkSuffixes, Networks, @@ -290,4 +291,30 @@ export const utils = { ); return isTestNetwork; }, + getCurrentBaseUrl() { + const port = window.location.port; + const hasPort = !_.isUndefined(port); + const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`; + return baseUrl; + }, + scrollToHash(hash: string, containerId: string): void { + let finalHash = hash; + if (_.isEmpty(hash)) { + finalHash = configs.SCROLL_TOP_ID; // scroll to the top + } + + scroller.scrollTo(finalHash, { + duration: 0, + offset: 0, + containerId, + }); + }, + async onPageLoadAsync(): Promise<void> { + if (document.readyState === 'complete') { + return; // Already loaded + } + return new Promise<void>((resolve, reject) => { + window.onload = () => resolve(); + }); + }, }; 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/scripts/postpublish_utils.js b/scripts/postpublish_utils.js index 7ce01189c..0a8c6f94d 100644 --- a/scripts/postpublish_utils.js +++ b/scripts/postpublish_utils.js @@ -1,3 +1,4 @@ +const _ = require('lodash'); const execAsync = require('async-child-process').execAsync; const semverSort = require('semver-sort'); const publishRelease = require('publish-release'); @@ -11,23 +12,22 @@ module.exports = { getLatestTagAndVersionAsync: function(subPackageName) { const subPackagePrefix = subPackageName + '@'; const gitTagsCommand = 'git tag -l "' + subPackagePrefix + '*"'; - return execAsync(gitTagsCommand) - .then(function(result) { - if (result.stderr !== '') { - throw new Error(result.stderr); - } - const tags = result.stdout.trim().split('\n'); - const versions = tags.map(function(tag) { - return tag.slice(subPackagePrefix.length); - }); - const sortedVersions = semverSort.desc(versions); - const latestVersion = sortedVersions[0]; - const latestTag = subPackagePrefix + latestVersion; - return { - tag: latestTag, - version: latestVersion - }; + return execAsync(gitTagsCommand).then(function(result) { + if (result.stderr !== '') { + throw new Error(result.stderr); + } + const tags = result.stdout.trim().split('\n'); + const versions = tags.map(function(tag) { + return tag.slice(subPackagePrefix.length); }); + const sortedVersions = semverSort.desc(versions); + const latestVersion = sortedVersions[0]; + const latestTag = subPackagePrefix + latestVersion; + return { + tag: latestTag, + version: latestVersion, + }; + }); }, publishReleaseNotesAsync: function(tag, releaseName, assets) { console.log('POSTPUBLISH: Releasing ', releaseName, '...'); @@ -43,7 +43,7 @@ module.exports = { reuseRelease: true, reuseDraftOnly: false, assets: assets, - }); + }); }, getReleaseName(subPackageName, version) { const releaseName = subPackageName + ' v' + version; @@ -51,14 +51,36 @@ module.exports = { }, standardPostPublishAsync: function(subPackageName) { return this.getLatestTagAndVersionAsync(subPackageName) - .then(function(result) { - const releaseName = this.getReleaseName(subPackageName, result.version); - const assets = []; - return this.publishReleaseNotesAsync(result.tag, releaseName, assets); - }.bind(this)) + .then( + function(result) { + const releaseName = this.getReleaseName(subPackageName, result.version); + const assets = []; + return this.publishReleaseNotesAsync(result.tag, releaseName, assets); + }.bind(this) + ) .catch(function(err) { throw err; }); }, + adjustFileIncludePaths: function(fileIncludes, cwd) { + const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => { + let path; + if (_.startsWith(fileInclude, '../')) { + path = cwd + '/../' + fileInclude; + } else if (_.startsWith(fileInclude, './')) { + path = cwd + '/../' + fileInclude.substr(2); + } else { + path = cwd + '/' + fileInclude; + } + + // HACK: tsconfig.json needs wildcard directory endings as `/**/*` + // but TypeDoc needs it as `/**` in order to pick up files at the root + if (_.endsWith(path, '/**/*')) { + path = path.slice(0, -2); + } + return path; + }); + return fileIncludesAdjusted; + }, generatedDocsDirectoryName, }; @@ -61,6 +61,12 @@ dependencies: "@types/node" "*" +"@types/fs-extra@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.0.tgz#d3e225b35eb5c6d3a5a782c28219df365c781413" + dependencies: + "@types/node" "*" + "@types/fs-extra@^4.0.0": version "4.0.7" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.7.tgz#02533262386b5a6b9a49797dc82feffdf269140a" @@ -75,11 +81,11 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/handlebars@^4.0.31", "@types/handlebars@^4.0.36": +"@types/handlebars@4.0.36", "@types/handlebars@^4.0.31", "@types/handlebars@^4.0.36": version "4.0.36" resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.36.tgz#ff57c77fa1ab6713bb446534ddc4d979707a3a79" -"@types/highlight.js@^9.1.8": +"@types/highlight.js@9.12.2", "@types/highlight.js@^9.1.8": version "9.12.2" resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.2.tgz#6ee7cd395effe5ec80b515d3ff1699068cd0cd1d" @@ -109,10 +115,18 @@ version "4.14.92" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.92.tgz#6e3cb0b71a1e12180a47a42a744e856c3ae99a57" +"@types/lodash@4.14.99": + version "4.14.99" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.99.tgz#e6e10c0a4cc16c7409b3181f1e66880d2fb7d4dc" + "@types/marked@0.0.28": version "0.0.28" resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.0.28.tgz#44ba754e9fa51432583e8eb30a7c4dd249b52faa" +"@types/marked@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.3.0.tgz#583c223dd33385a1dda01aaf77b0cd0411c4b524" + "@types/material-ui@0.18.0": version "0.18.0" resolved "https://registry.yarnpkg.com/@types/material-ui/-/material-ui-0.18.0.tgz#f3abc5431df8faa4592233c6c5377f2843eb807f" @@ -124,7 +138,7 @@ version "2.0.0" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b" -"@types/minimatch@*": +"@types/minimatch@*", "@types/minimatch@3.0.3": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -244,7 +258,7 @@ "@types/express-serve-static-core" "*" "@types/mime" "*" -"@types/shelljs@^0.7.0": +"@types/shelljs@0.7.7", "@types/shelljs@^0.7.0": version "0.7.7" resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.7.tgz#1f7bfa28947661afea06365db9b1135bbc903ec4" dependencies: @@ -1177,6 +1191,10 @@ babylon@^6.18.0, babylon@^6.7.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" +bail@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.2.tgz#f7d6c1731630a9f9f0d4d35ed1f962e2074a1764" + balanced-match@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" @@ -1727,6 +1745,18 @@ change-emitter@^0.1.2: version "0.1.6" resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" +character-entities-legacy@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz#f40779df1a101872bb510a3d295e1fccf147202f" + +character-entities@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.1.tgz#f76871be5ef66ddb7f8f8e3478ecc374c27d6dca" + +character-reference-invalid@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz#942835f750e4ec61a308e60c2ef8cc1011202efc" + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -1893,6 +1923,10 @@ coinstring@^2.0.0: bs58 "^2.0.1" create-hash "^1.1.1" +collapse-white-space@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.3.tgz#4b906f670e5a963a87b76b0e1689643341b6023c" + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1969,23 +2003,6 @@ commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -commonmark-react-renderer@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/commonmark-react-renderer/-/commonmark-react-renderer-4.3.4.tgz#29f345357951ab36eb386d45ea6bc08006f3ff9b" - dependencies: - lodash.assign "^4.2.0" - lodash.isplainobject "^4.0.6" - pascalcase "^0.1.1" - xss-filters "^1.2.6" - -commonmark@^0.24.0: - version "0.24.0" - resolved "https://registry.yarnpkg.com/commonmark/-/commonmark-0.24.0.tgz#b80de0182c546355643aa15db12bfb282368278f" - dependencies: - entities "~ 1.1.1" - mdurl "~ 1.0.1" - string.prototype.repeat "^0.2.0" - compare-func@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" @@ -2932,10 +2949,6 @@ enhanced-resolve@^3.4.0: object-assign "^4.0.1" tapable "^0.2.7" -"entities@~ 1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" - errno@^0.1.1, errno@^0.1.3, errno@~0.1.1: version "0.1.6" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.6.tgz#c386ce8a6283f14fc09563b71560908c9bf53026" @@ -3227,6 +3240,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" @@ -3743,6 +3771,14 @@ fs-extra@^4.0.0, fs-extra@^4.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -4276,6 +4312,10 @@ highlight.js@^9.0.0, highlight.js@^9.11.0: version "9.12.0" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" +highlightjs-solidity@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-1.0.5.tgz#fabb925e9d7ddbb362471b9db5499583bfb2b4f3" + history@^4.7.2: version "4.7.2" resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" @@ -4601,6 +4641,17 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-alphabetical@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.1.tgz#c77079cc91d4efac775be1034bf2d243f95e6f08" + +is-alphanumerical@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz#dfb4aa4d1085e33bdb61c2dee9c80e9c6c19f53b" + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4611,7 +4662,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-buffer@^1.1.5: +is-buffer@^1.1.4, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -4647,6 +4698,10 @@ is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" +is-decimal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.1.tgz#f5fb6a94996ad9e8e3761fbfbd091f1fca8c4e82" + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -4737,6 +4792,10 @@ is-hex-prefixed@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" +is-hexadecimal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69" + is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" @@ -4790,7 +4849,7 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.0.0: +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -4874,10 +4933,18 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is-whitespace-character@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz#9ae0176f3282b65457a1992cdb084f8a5f833e3b" + is-windows@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9" +is-word-character@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.1.tgz#5a03fa1ea91ace8a6eb0c7cd770eb86d65c8befb" + is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" @@ -4970,6 +5037,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" @@ -5416,7 +5487,7 @@ lodash._root@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" -lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0: +lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" @@ -5454,7 +5525,7 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" -lodash.isplainobject@^4.0.6, lodash.isplainobject@~4.0.4: +lodash.isplainobject@~4.0.4: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -5636,6 +5707,14 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +markdown-escapes@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.1.tgz#1994df2d3af4811de59a6714934c2b2292734518" + +marked@^0.3.12: + version "0.3.17" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.17.tgz#607f06668b3c6b1246b28f13da76116ac1aa2d2b" + marked@^0.3.5: version "0.3.12" resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.12.tgz#7cf25ff2252632f3fe2406bde258e94eee927519" @@ -5678,10 +5757,6 @@ md5.js@^1.3.4: hash-base "^3.0.0" inherits "^2.0.1" -"mdurl@~ 1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6483,6 +6558,17 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +parse-entities@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890" + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + parse-filepath@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" @@ -6948,9 +7034,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" @@ -7011,7 +7097,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.0.0, prop-types@^15.5.1, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0: +prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0: version "15.6.0" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" dependencies: @@ -7279,11 +7365,12 @@ react-ga@^2.4.1: prop-types "^15.6.0" react "^15.6.2 || ^16.0" -react-highlight@^0.10.0: +react-highlight@0xproject/react-highlight: version "0.10.0" - resolved "https://registry.yarnpkg.com/react-highlight/-/react-highlight-0.10.0.tgz#d386f9dceab867dc0dcc2364153fb1cc7645d046" + resolved "https://codeload.github.com/0xproject/react-highlight/tar.gz/83bbb4a09801abd341e2b9041cd884885a4a2098" dependencies: highlight.js "^9.11.0" + highlightjs-solidity "^1.0.5" react "^15.5.4" react-dom "^15.5.4" @@ -7299,13 +7386,15 @@ react-inlinesvg@^0.5.5: httpplease "^0.16" once "^1.4" -react-markdown@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-2.5.1.tgz#f7a6c26a3a5faf5d4c2098155d9775e826fd56ee" +react-markdown@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.2.2.tgz#439774c14f25eb25d1b96c126f28ca1486fb0a24" dependencies: - commonmark "^0.24.0" - commonmark-react-renderer "^4.3.4" - prop-types "^15.5.1" + prop-types "^15.6.0" + remark-parse "^4.0.0" + unified "^6.1.5" + unist-util-visit "^1.1.3" + xtend "^4.0.1" react-recaptcha@^2.3.2: version "2.3.5" @@ -7658,6 +7747,26 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" +remark-parse@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-4.0.0.tgz#99f1f049afac80382366e2e0d0bd55429dd45d8b" + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.0.2" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -7666,7 +7775,7 @@ repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" -repeat-string@^1.5.2, repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" @@ -7680,6 +7789,10 @@ replace-ext@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" +replace-ext@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + request-ip@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-1.2.3.tgz#66988f0e22406ec4af630d19b573fe4b447c3b49" @@ -8147,6 +8260,14 @@ shelljs@^0.7.0, shelljs@^0.7.3: interpret "^1.0.0" rechoir "^0.6.2" +shelljs@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.1.tgz#729e038c413a2254c4078b95ed46e0397154a9f1" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + shx@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/shx/-/shx-0.2.2.tgz#0a304d020b0edf1306ad81570e80f0346df58a39" @@ -8450,6 +8571,10 @@ ssri@^5.0.0: dependencies: safe-buffer "^5.1.0" +state-toggle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.0.tgz#d20f9a616bb4f0c3b98b91922d25b640aa2bc425" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -8540,10 +8665,6 @@ string.prototype.padend@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" -string.prototype.repeat@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf" - string.prototype.trim@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" @@ -8962,10 +9083,18 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +trim-trailing-lines@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz#7aefbb7808df9d669f6da2e438cac8c46ada7684" + trim@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" +trough@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.1.tgz#a9fd8b0394b0ae8fff82e0633a0a36ccad5b5f86" + truffle-blockchain-utils@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.1.tgz#07a58e55bb0555a64208c9119c0b04ffe1464aa4" @@ -9085,6 +9214,28 @@ typedoc-default-themes@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" +typedoc@0xProject/typedoc: + version "0.10.0" + resolved "https://codeload.github.com/0xProject/typedoc/tar.gz/a9970a52f0924fec2df608abe30ff81153b3def2" + dependencies: + "@types/fs-extra" "5.0.0" + "@types/handlebars" "4.0.36" + "@types/highlight.js" "9.12.2" + "@types/lodash" "4.14.99" + "@types/marked" "0.3.0" + "@types/minimatch" "3.0.3" + "@types/shelljs" "0.7.7" + fs-extra "^5.0.0" + handlebars "^4.0.6" + highlight.js "^9.0.0" + lodash "^4.13.1" + marked "^0.3.12" + minimatch "^3.0.0" + progress "^2.0.0" + shelljs "^0.8.1" + typedoc-default-themes "^0.5.0" + typescript "2.7.1" + typedoc@~0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.8.0.tgz#d7172bc6a29964f451b7609c005beadadefe2361" @@ -9183,6 +9334,25 @@ underscore@1.8.3: version "1.8.3" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" +unherit@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d" + dependencies: + inherits "^2.0.1" + xtend "^4.0.1" + +unified@^6.1.5: + version "6.1.6" + resolved "https://registry.yarnpkg.com/unified/-/unified-6.1.6.tgz#5ea7f807a0898f1f8acdeefe5f25faa010cc42b1" + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^1.1.0" + trough "^1.0.0" + vfile "^2.0.0" + x-is-function "^1.0.4" + x-is-string "^0.1.0" + union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" @@ -9228,6 +9398,26 @@ unique-string@^1.0.0: dependencies: crypto-random-string "^1.0.0" +unist-util-is@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b" + +unist-util-remove-position@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz#5a85c1555fc1ba0c101b86707d15e50fa4c871bb" + dependencies: + unist-util-visit "^1.1.0" + +unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c" + +unist-util-visit@^1.1.0, unist-util-visit@^1.1.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444" + dependencies: + unist-util-is "^2.1.1" + universalify@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" @@ -9399,6 +9589,25 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vfile-location@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.2.tgz#d3675c59c877498e492b4756ff65e4af1a752255" + +vfile-message@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-1.0.0.tgz#a6adb0474ea400fa25d929f1d673abea6a17e359" + dependencies: + unist-util-stringify-position "^1.1.1" + +vfile@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-2.3.0.tgz#e62d8e72b20e83c324bc6c67278ee272488bf84a" + dependencies: + is-buffer "^1.1.4" + replace-ext "1.0.0" + unist-util-stringify-position "^1.0.0" + vfile-message "^1.0.0" + vinyl-fs@^0.3.0: version "0.3.14" resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" @@ -9770,6 +9979,14 @@ ws@^3.0.0: safe-buffer "~5.1.0" ultron "~1.1.0" +x-is-function@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/x-is-function/-/x-is-function-1.0.4.tgz#5d294dc3d268cbdd062580e0c5df77a391d1fa1e" + +x-is-string@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -9811,14 +10028,10 @@ 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" -xss-filters@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/xss-filters/-/xss-filters-1.2.7.tgz#59fa1de201f36f2f3470dcac5f58ccc2830b0a9a" - "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" |