Compare commits
381 Commits
0x.js@0.32
...
@0xproject
Author | SHA1 | Date | |
---|---|---|---|
|
8e5a876b37 | ||
|
c71b710d7e | ||
|
7440b87596 | ||
|
583a17d627 | ||
|
caf1a22084 | ||
|
29abc5e921 | ||
|
098dae9a7e | ||
|
aaa7affa46 | ||
|
40ca846cdc | ||
|
2a24f6e2ea | ||
|
98e8105ec5 | ||
|
4a94a2b4e8 | ||
|
2011349eb1 | ||
|
8057f4a678 | ||
|
f9ec8a0828 | ||
|
a0030c7bdb | ||
|
0e4448fd3f | ||
|
21d2d59b50 | ||
|
295f177271 | ||
|
f3154313a8 | ||
|
e37f3b4fa3 | ||
|
7e5c35d06e | ||
|
60756aa02b | ||
|
3779ab90de | ||
|
5b5037a844 | ||
|
03902b0b26 | ||
|
883feabb8b | ||
|
5fb79e3253 | ||
|
c44811fbc2 | ||
|
c3eaa694dd | ||
|
bd8b8abfea | ||
|
1a6c2e2bac | ||
|
e2e6ae937d | ||
|
5b9c5d2790 | ||
|
896a57d4ed | ||
|
c3de8d3a67 | ||
|
d1a92a0a2e | ||
|
5f626495fd | ||
|
238f3c89a7 | ||
|
6e724eb8a5 | ||
|
9aec1feae3 | ||
|
8517de128b | ||
|
a3e15c910c | ||
|
a6303de4d1 | ||
|
5356b0e118 | ||
|
e31309f213 | ||
|
6f8a70834b | ||
|
327cc307b3 | ||
|
f191ba6e69 | ||
|
a2b89411b0 | ||
|
f66efed777 | ||
|
f61b59fa89 | ||
|
6288a72036 | ||
|
a941f0ffb6 | ||
|
d7373a5c04 | ||
|
2ff485d2e0 | ||
|
5a67068348 | ||
|
d39af6c9eb | ||
|
1789025da9 | ||
|
696f49497b | ||
|
e88eba1877 | ||
|
f8b8a10b8f | ||
|
01e505a5f4 | ||
|
5b2d9a4668 | ||
|
71008dc819 | ||
|
9301173f7d | ||
|
60d95475eb | ||
|
c8ace2edc0 | ||
|
0b1ba9f997 | ||
|
f3026e33fd | ||
|
f014a97e9a | ||
|
ddad09a936 | ||
|
5dd0654105 | ||
|
b4b664e97a | ||
|
551771235b | ||
|
eb201c4084 | ||
|
7bfc499ec8 | ||
|
71e7e9c9c3 | ||
|
8521775389 | ||
|
61ad8d4c10 | ||
|
38a4ccd9f2 | ||
|
cf342dd00e | ||
|
08ab81c54c | ||
|
d355382f70 | ||
|
d171ce4fba | ||
|
5a90fece80 | ||
|
994935b5da | ||
|
874e667849 | ||
|
1817f6eaf6 | ||
|
2e19930178 | ||
|
2b01461748 | ||
|
24b9df475c | ||
|
011bab3c80 | ||
|
699c0c3e05 | ||
|
5f4b28960e | ||
|
3837913855 | ||
|
65eb3997d9 | ||
|
47411b406d | ||
|
f710026a8f | ||
|
925e133f50 | ||
|
2bdd60ed72 | ||
|
9ac1cce26f | ||
|
0a597c94d6 | ||
|
02f82be094 | ||
|
86e26240a1 | ||
|
82c5be2564 | ||
|
42f4f07268 | ||
|
df4db8fa4c | ||
|
bd85fe0af3 | ||
|
aee15e5dff | ||
|
d7a803d9fd | ||
|
839e5895e4 | ||
|
49a4f0c74c | ||
|
5bea8e63de | ||
|
e64be284dd | ||
|
e11e26a352 | ||
|
bee90abbc4 | ||
|
8782559c33 | ||
|
223ddc0f68 | ||
|
4445d1d5a0 | ||
|
b7d001da88 | ||
|
3592ebef08 | ||
|
a783d21409 | ||
|
a716e3de74 | ||
|
c797c720be | ||
|
1b5742fbf0 | ||
|
5794349d97 | ||
|
456f094913 | ||
|
abb9eb0df4 | ||
|
9e7b45ea4c | ||
|
6c6bd60a48 | ||
|
cef82e72dc | ||
|
45b9647ba0 | ||
|
160f74d53e | ||
|
3ab6139522 | ||
|
9aa54257e7 | ||
|
8eafa62bbe | ||
|
968c24f0bc | ||
|
e5c755b1fc | ||
|
6d56f01c40 | ||
|
eefce48e68 | ||
|
c7d97c733a | ||
|
3db42deb42 | ||
|
02603e8926 | ||
|
c5003554f4 | ||
|
eb223805ca | ||
|
244c148a80 | ||
|
4dbb2ed167 | ||
|
212d680a47 | ||
|
a853e35dec | ||
|
fdaf9f0bfc | ||
|
0afe45b3a8 | ||
|
f9a37168b0 | ||
|
52232e98c7 | ||
|
0fbb443e4b | ||
|
8021694b81 | ||
|
a2b262c9df | ||
|
5906f4c995 | ||
|
da8edd2226 | ||
|
406aedfdc2 | ||
|
67c834841e | ||
|
edaa0b0e34 | ||
|
31f03fcf3a | ||
|
4a57f2a762 | ||
|
92b9dbd706 | ||
|
6edd7682a9 | ||
|
447891b396 | ||
|
89bfcafb80 | ||
|
a74a04c5d5 | ||
|
0c16f0ea22 | ||
|
003d43b03a | ||
|
6323496945 | ||
|
fd5e231a93 | ||
|
ae209677de | ||
|
d5ca00de95 | ||
|
7be84c6ad3 | ||
|
425039e4d3 | ||
|
6c5333180d | ||
|
cb47a51b70 | ||
|
e36fb654b0 | ||
|
6325fac020 | ||
|
c6358d5f22 | ||
|
413e8b6062 | ||
|
e113a8e7af | ||
|
e42891ae5b | ||
|
c90770472e | ||
|
45df9de5b5 | ||
|
2d0940589e | ||
|
5908f189a7 | ||
|
17328bce53 | ||
|
451a0dacbe | ||
|
a46199e37d | ||
|
e25cc301fd | ||
|
5bbb0d1f60 | ||
|
a5b8875356 | ||
|
3e86df311d | ||
|
002f9ebde7 | ||
|
72e6e1ce8b | ||
|
a3c7af95e1 | ||
|
0987c9a7cf | ||
|
bbd87daf6d | ||
|
30e4613d0a | ||
|
79593f52b0 | ||
|
bab8c1eeff | ||
|
8b6cc95c1b | ||
|
90236b87de | ||
|
b6a133cc64 | ||
|
7aa070f9ea | ||
|
c2ec2291e8 | ||
|
97fcfb7f6c | ||
|
ce677fd55a | ||
|
e48a3edacb | ||
|
ce0b92d681 | ||
|
29c5ba5639 | ||
|
cdea618457 | ||
|
425a519f97 | ||
|
c07d64c6ff | ||
|
c07e3a76bb | ||
|
8fe844bcc9 | ||
|
a0390956a9 | ||
|
4f1e6296ca | ||
|
0ef372e531 | ||
|
06e2894750 | ||
|
10e2d4b99c | ||
|
ef40cb9687 | ||
|
758604fc1a | ||
|
34c1134b55 | ||
|
a5ef1db0c5 | ||
|
748ed40321 | ||
|
42063f785e | ||
|
1657451f37 | ||
|
0bb0bff0b3 | ||
|
747732118c | ||
|
2aec1501d0 | ||
|
39c6bc1106 | ||
|
4e451479f8 | ||
|
93b2736d65 | ||
|
34274a1042 | ||
|
fa822caa62 | ||
|
ddc30cc2c0 | ||
|
9d9cab1711 | ||
|
fe8f2d8d89 | ||
|
2d561bc8a0 | ||
|
f5275d3ad7 | ||
|
5fbdf9cfb9 | ||
|
0409c9c1e5 | ||
|
42a5da1df4 | ||
|
0b326a8bbe | ||
|
9c8501a84e | ||
|
2da7f82171 | ||
|
593474031d | ||
|
fce10548d2 | ||
|
addca63938 | ||
|
6961169f89 | ||
|
3d66feb89f | ||
|
bb157eefc6 | ||
|
7f8f4df0a0 | ||
|
4b325676f7 | ||
|
ecba95250d | ||
|
dd116b3cd6 | ||
|
eabe96fd19 | ||
|
7dd9ce2e32 | ||
|
fffaafe4c9 | ||
|
0b9646136a | ||
|
55f38b9c35 | ||
|
709fa9e02e | ||
|
f42bdb8bab | ||
|
10aed46062 | ||
|
6e43e89b2d | ||
|
10c0c0b6d2 | ||
|
e13924cd2d | ||
|
7afe00f06a | ||
|
87b9caa7dc | ||
|
f689d335c0 | ||
|
31f9a848f9 | ||
|
3d2c5d67af | ||
|
63f8f469b0 | ||
|
9929f1acf0 | ||
|
42ecc087cb | ||
|
93adee36b0 | ||
|
0e95fd0b9b | ||
|
611ddfeeb8 | ||
|
dfe2579eeb | ||
|
66b36f6d8f | ||
|
1b3a9102f1 | ||
|
9993a50903 | ||
|
c226509be0 | ||
|
ef6f52e722 | ||
|
7d8cad8e3a | ||
|
15507d3827 | ||
|
e2d17d122e | ||
|
0d7bf50581 | ||
|
a50618fcb0 | ||
|
fc2a9a756a | ||
|
07721eb99f | ||
|
13fed15e0c | ||
|
38a308ce5b | ||
|
be19316dfb | ||
|
c4f65681a1 | ||
|
f600226aa9 | ||
|
67f2864501 | ||
|
c1bbcaba73 | ||
|
6685cb3fba | ||
|
d770e46208 | ||
|
665636e642 | ||
|
0028e71ab2 | ||
|
7fb66bf71a | ||
|
3120d854f8 | ||
|
c85c14210f | ||
|
0fb81a11a8 | ||
|
7b67afae06 | ||
|
fe9e319a61 | ||
|
097fc477a2 | ||
|
f60b00d116 | ||
|
3a36e0621f | ||
|
b482473e23 | ||
|
9a5fd3f784 | ||
|
b703ccde9b | ||
|
80eca30725 | ||
|
7dbc14dc43 | ||
|
b3f9010eb5 | ||
|
f62d72e548 | ||
|
d12352972e | ||
|
03d3d84db3 | ||
|
6d818c25c7 | ||
|
6a8f624e75 | ||
|
0801b1ddf9 | ||
|
4fd64ca492 | ||
|
c4bcf24640 | ||
|
0114fc9608 | ||
|
8db098eaec | ||
|
05c3a66543 | ||
|
9349752baa | ||
|
974fab7284 | ||
|
8a52ffe7b7 | ||
|
c6ecdbd86e | ||
|
03797545f9 | ||
|
2778f96483 | ||
|
6cd4e7a17e | ||
|
5c91b4bfc6 | ||
|
e2b51c5dc4 | ||
|
b610b7c192 | ||
|
b75fdd6b66 | ||
|
060b02eaed | ||
|
003e5da00d | ||
|
02951d4813 | ||
|
db52ed9941 | ||
|
af333b1838 | ||
|
f62762bd0e | ||
|
4b67352278 | ||
|
76afb6b116 | ||
|
db52e87740 | ||
|
e22788abe8 | ||
|
bbfbfcda85 | ||
|
0dfb36e675 | ||
|
95a9d77301 | ||
|
ab1f070901 | ||
|
8201d5d1f8 | ||
|
8704c34a0f | ||
|
599adaf1bf | ||
|
778e399438 | ||
|
485ae4d997 | ||
|
8cd2ba3ad6 | ||
|
dbad7d1869 | ||
|
4d482438f5 | ||
|
b53a1b51d6 | ||
|
49375c73d4 | ||
|
98b78c56c5 | ||
|
f3e6ef0fa9 | ||
|
18e1c2dea5 | ||
|
91ae01e484 | ||
|
2897b72967 | ||
|
3510985cf4 | ||
|
5927e65045 | ||
|
13e2041d50 | ||
|
4bf530ed9e | ||
|
4c797405ad | ||
|
713c922e35 | ||
|
7f1e789264 | ||
|
07d00cc515 | ||
|
ba57c34adb |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -68,6 +68,10 @@ generated_docs/
|
|||||||
TODO.md
|
TODO.md
|
||||||
|
|
||||||
packages/website/public/bundle*
|
packages/website/public/bundle*
|
||||||
|
packages/react-docs/example/public/bundle*
|
||||||
|
|
||||||
# generated binaries
|
# generated binaries
|
||||||
bin/
|
bin/
|
||||||
|
|
||||||
|
# generated contract artifacts
|
||||||
|
packages/contracts/src/artifacts
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
lib
|
lib
|
||||||
generated
|
|
||||||
.nyc_output
|
.nyc_output
|
||||||
/packages/contracts/build/contracts
|
/packages/contracts/src/artifacts
|
||||||
package.json
|
package.json
|
||||||
|
scripts/postpublish_utils.js
|
||||||
|
@@ -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:
|
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 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
|
* 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/)
|
* Write [good commit messages](https://chris.beams.io/posts/git-commit/)
|
||||||
|
|
||||||
### Code quality
|
### Code quality
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ If the sub-package you are modifying has a `CHANGELOG.md` file, make sure to add
|
|||||||
|
|
||||||
### Styleguide
|
### 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`
|
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:
|
If using the Atom text editor, we recommend you install the following packages:
|
||||||
|
|
||||||
* [atom-typescript](https://atom.io/packages/atom-typescript)
|
* [atom-typescript](https://atom.io/packages/atom-typescript)
|
||||||
* [linter-tslint](https://atom.io/packages/linter-tslint)
|
* [linter-tslint](https://atom.io/packages/linter-tslint)
|
||||||
* [prettier-atom](https://atom.io/packages/prettier-atom)
|
* [prettier-atom](https://atom.io/packages/prettier-atom)
|
||||||
* [language-ethereum](https://atom.io/packages/language-ethereum)
|
* [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.
|
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.
|
||||||
|
|
||||||
|
@@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
<!--- 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)
|
* [ ] Bug fix (non-breaking change which fixes an issue)
|
||||||
* [ ] New feature (non-breaking change which adds functionality)
|
* [ ] New feature (non-breaking change which adds functionality)
|
||||||
* [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
* [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
||||||
|
|
||||||
## Checklist:
|
## Checklist:
|
||||||
|
|
||||||
@@ -34,9 +34,9 @@
|
|||||||
|
|
||||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
<!--- 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.
|
* [ ] Change requires a change to the documentation.
|
||||||
* [ ] Added tests to cover my changes.
|
* [ ] Added tests to cover my changes.
|
||||||
* [ ] Added new entries to the relevant CHANGELOGs.
|
* [ ] Added new entries to the relevant CHANGELOGs.
|
||||||
* [ ] Updated the new versions of the changed packages in 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 'WIP' label if it is a work in progress.
|
||||||
* [ ] Labeled this PR with the labels corresponding to the changed package.
|
* [ ] Labeled this PR with the labels corresponding to the changed package.
|
||||||
|
51
README.md
51
README.md
@@ -4,36 +4,39 @@
|
|||||||
|
|
||||||
[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].
|
[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/
|
[website-url]: https://0xproject.com/
|
||||||
[whitepaper-url]: https://0xproject.com/pdfs/0x_white_paper.pdf
|
[whitepaper-url]: https://0xproject.com/pdfs/0x_white_paper.pdf
|
||||||
|
|
||||||
[](https://circleci.com/gh/0xProject/0x.js)
|
[](https://circleci.com/gh/0xProject/0x-monorepo)
|
||||||
[](https://coveralls.io/github/0xProject/0x.js?branch=master)
|
[](https://coveralls.io/github/0xProject/0x-monorepo?branch=master)
|
||||||
[](https://chat.0xproject.com)
|
[](https://chat.0xproject.com)
|
||||||
[](https://gitter.im/0xProject/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](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://opensource.org/licenses/Apache-2.0)
|
||||||
[](https://greenkeeper.io/)
|
[](https://greenkeeper.io/)
|
||||||
|
|
||||||
### Published Packages
|
### Published Packages
|
||||||
|
|
||||||
| Package | Version | Description |
|
| Package | Version | Description |
|
||||||
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||||
| [`0x.js`](/packages/0x.js) | [](https://www.npmjs.com/package/0x.js) | A Javascript library for interacting with the 0x protocol |
|
| [`0x.js`](/packages/0x.js) | [](https://www.npmjs.com/package/0x.js) | A Javascript library for interacting with the 0x protocol |
|
||||||
| [`chai-as-promised-typescript-typings`](/packages/chai-as-promised-typescript-typings) | [](https://www.npmjs.com/package/chai-as-promised-typescript-typings) | Chai as promised typescript typings |
|
| [`@0xproject/abi-gen`](/packages/abi-gen) | [](https://www.npmjs.com/package/@0xproject/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
|
||||||
| [`chai-typescript-typings`](/packages/chai-typescript-typings) | [](https://www.npmjs.com/package/chai-typescript-typings) | Chai typescript typings |
|
| [`@0xproject/assert`](/packages/assert) | [](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages |
|
||||||
| [`web3-typescript-typings`](/packages/web3-typescript-typings) | [](https://www.npmjs.com/package/web3-typescript-typings) | Web3 typescript typings |
|
| [`@0xproject/base-contract`](/packages/base-contract) | [](https://www.npmjs.com/package/@0xproject/base-contract) | BaseContract to derive all auto-generated wrappers from |
|
||||||
| [`@0xproject/abi-gen`](/packages/abi-gen) | [](https://www.npmjs.com/package/@0xproject/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
|
| [`chai-as-promised-typescript-typings`](/packages/chai-as-promised-typescript-typings) | [](https://www.npmjs.com/package/chai-as-promised-typescript-typings) | Chai as promised typescript typings |
|
||||||
| [`@0xproject/assert`](/packages/assert) | [](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages |
|
| [`chai-typescript-typings`](/packages/chai-typescript-typings) | [](https://www.npmjs.com/package/chai-typescript-typings) | Chai typescript typings |
|
||||||
| [`@0xproject/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the standard relayer api |
|
| [`@0xproject/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the standard relayer api |
|
||||||
| [`@0xproject/dev-utils`](/packages/dev-utils) | [](https://www.npmjs.com/package/@0xproject/dev-utils) | Dev utils to be shared across 0x projects and packages |
|
| [`@0xproject/deployer`](/packages/deployer) | [](https://www.npmjs.com/package/@0xproject/deployer) | Smart contract deployer |
|
||||||
| [`@0xproject/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas |
|
| [`@0xproject/dev-utils`](/packages/dev-utils) | [](https://www.npmjs.com/package/@0xproject/dev-utils) | Dev utils to be shared across 0x projects and packages |
|
||||||
| [`@0xproject/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
|
| [`ethers-typescript-typings`](/packages/ethers-typescript-typings) | [](https://www.npmjs.com/package/ethers-typescript-typings) | [Ethers.js](https://github.com/ethers-io/ethers.js/) typescript typings |
|
||||||
| [`@0xproject/tslint-config`](/packages/tslint-config) | [](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules |
|
| [`@0xproject/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas |
|
||||||
| [`@0xproject/types`](/packages/types) | [](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations |
|
| [`@0xproject/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
|
||||||
| [`@0xproject/utils`](/packages/utils) | [](https://www.npmjs.com/package/@0xproject/utils) | Shared utilities |
|
| [`@0xproject/tslint-config`](/packages/tslint-config) | [](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules |
|
||||||
| [`@0xproject/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0xproject/web3-wrapper) | Web3 wrapper |
|
| [`@0xproject/types`](/packages/types) | [](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations |
|
||||||
|
| [`@0xproject/utils`](/packages/utils) | [](https://www.npmjs.com/package/@0xproject/utils) | Shared utilities |
|
||||||
|
| [`web3-typescript-typings`](/packages/web3-typescript-typings) | [](https://www.npmjs.com/package/web3-typescript-typings) | Web3 typescript typings |
|
||||||
|
| [`@0xproject/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0xproject/web3-wrapper) | Web3 wrapper |
|
||||||
|
|
||||||
### Private Packages
|
### Private Packages
|
||||||
|
|
||||||
@@ -48,10 +51,10 @@ This repository contains all the 0x developer tools written in TypeScript. Our h
|
|||||||
|
|
||||||
Dedicated documentation pages:
|
Dedicated documentation pages:
|
||||||
|
|
||||||
* [0x.js Library](https://0xproject.com/docs/0xjs)
|
* [0x.js Library](https://0xproject.com/docs/0xjs)
|
||||||
* [0x Connect](https://0xproject.com/docs/connect)
|
* [0x Connect](https://0xproject.com/docs/connect)
|
||||||
* [Smart contracts](https://0xproject.com/docs/contracts)
|
* [Smart contracts](https://0xproject.com/docs/contracts)
|
||||||
* [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
|
* [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@@ -1,6 +1,11 @@
|
|||||||
{
|
{
|
||||||
"lerna": "2.5.1",
|
"lerna": "2.5.1",
|
||||||
"packages": ["packages/*"],
|
"packages": ["packages/*"],
|
||||||
|
"commands": {
|
||||||
|
"publish": {
|
||||||
|
"allowBranch": "development"
|
||||||
|
}
|
||||||
|
},
|
||||||
"version": "independent",
|
"version": "independent",
|
||||||
"commands": {
|
"commands": {
|
||||||
"publish": {
|
"publish": {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "0x.js",
|
"name": "0x-monorepo",
|
||||||
"workspaces": ["packages/*"],
|
"workspaces": ["packages/*"],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "lerna run --parallel build:watch",
|
"dev": "lerna run --parallel build:watch",
|
||||||
@@ -16,11 +16,11 @@
|
|||||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/utils": "^0.3.2",
|
"@0xproject/utils": "^0.4.0",
|
||||||
"async-child-process": "^1.1.1",
|
"async-child-process": "^1.1.1",
|
||||||
"ethereumjs-testrpc": "^6.0.3",
|
"ethereumjs-testrpc": "^6.0.3",
|
||||||
"lerna": "^2.5.1",
|
"lerna": "^2.5.1",
|
||||||
"prettier": "1.9.2",
|
"prettier": "^1.11.1",
|
||||||
"publish-release": "0xproject/publish-release",
|
"publish-release": "0xproject/publish-release",
|
||||||
"semver-sort": "^0.0.4"
|
"semver-sort": "^0.0.4"
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,17 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.33.1 - _March 8, 2018_
|
||||||
|
|
||||||
|
* Add missing EthersJs typescript typings as dependency
|
||||||
|
|
||||||
|
## 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_
|
## v0.32.2 - _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)
|
||||||
|
@@ -18,11 +18,20 @@ npm install 0x.js --save
|
|||||||
import { ZeroEx } from '0x.js';
|
import { ZeroEx } from '0x.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
|
||||||
|
|
||||||
|
```
|
||||||
|
"include": [
|
||||||
|
"./node_modules/web3-typescript-typings/index.d.ts",
|
||||||
|
"./node_modules/ethers-typescript-typings/index.d.ts"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
#### UMD:
|
#### UMD:
|
||||||
|
|
||||||
**Install**
|
**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**
|
**Import**
|
||||||
|
|
||||||
|
@@ -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;
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,6 +0,0 @@
|
|||||||
{{#singleReturnValue}}
|
|
||||||
{{#returnType outputs.0.type}}{{/returnType}}
|
|
||||||
{{/singleReturnValue}}
|
|
||||||
{{^singleReturnValue}}
|
|
||||||
[{{#each outputs}}{{#returnType type}}{{/returnType}}{{#unless @last}}, {{/unless}}{{/each}}]
|
|
||||||
{{/singleReturnValue}}
|
|
@@ -1,3 +0,0 @@
|
|||||||
{{#each inputs}}
|
|
||||||
{{name}}: {{#parameterType type}}{{/parameterType}},
|
|
||||||
{{/each}}
|
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "0x.js",
|
"name": "0x.js",
|
||||||
"version": "0.32.2",
|
"version": "0.33.1",
|
||||||
"description": "A javascript library for interacting with the 0x protocol",
|
"description": "A javascript library for interacting with the 0x protocol",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"0x.js",
|
"0x.js",
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
"build:watch": "tsc -w",
|
"build:watch": "tsc -w",
|
||||||
"prebuild": "run-s clean generate_contract_wrappers",
|
"prebuild": "run-s clean generate_contract_wrappers",
|
||||||
"build": "run-p build:umd:prod build:commonjs; exit 0;",
|
"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",
|
"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'",
|
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
||||||
"test:circleci": "run-s test:coverage report_test_coverage",
|
"test:circleci": "run-s test:coverage report_test_coverage",
|
||||||
"test": "run-s clean test:commonjs",
|
"test": "run-s clean test:commonjs",
|
||||||
@@ -35,16 +35,16 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js"
|
"url": "https://github.com/0xProject/0x-monorepo"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/abi-gen": "^0.2.1",
|
"@0xproject/abi-gen": "^0.2.5",
|
||||||
"@0xproject/dev-utils": "^0.0.12",
|
"@0xproject/dev-utils": "^0.2.1",
|
||||||
"@0xproject/tslint-config": "^0.4.8",
|
"@0xproject/tslint-config": "^0.4.10",
|
||||||
"@types/bintrees": "^1.0.2",
|
"@types/bintrees": "^1.0.2",
|
||||||
"@types/jsonschema": "^1.1.1",
|
"@types/jsonschema": "^1.1.1",
|
||||||
"@types/lodash": "^4.14.86",
|
"@types/lodash": "^4.14.86",
|
||||||
@@ -55,9 +55,9 @@
|
|||||||
"awesome-typescript-loader": "^3.1.3",
|
"awesome-typescript-loader": "^3.1.3",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
"chai-as-promised": "^7.1.0",
|
"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-bignumber": "^2.0.1",
|
||||||
"chai-typescript-typings": "^0.0.3",
|
"chai-typescript-typings": "^0.0.4",
|
||||||
"copyfiles": "^1.2.0",
|
"copyfiles": "^1.2.0",
|
||||||
"coveralls": "^3.0.0",
|
"coveralls": "^3.0.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
@@ -73,27 +73,30 @@
|
|||||||
"source-map-support": "^0.5.0",
|
"source-map-support": "^0.5.0",
|
||||||
"truffle-hdwallet-provider": "^0.0.3",
|
"truffle-hdwallet-provider": "^0.0.3",
|
||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"typedoc": "~0.8.0",
|
"typedoc": "0xProject/typedoc",
|
||||||
"types-bn": "^0.0.1",
|
"types-bn": "^0.0.1",
|
||||||
"typescript": "2.7.1",
|
"typescript": "2.7.1",
|
||||||
"web3-provider-engine": "^13.0.1",
|
"web3-provider-engine": "^13.0.1",
|
||||||
"web3-typescript-typings": "^0.9.10",
|
|
||||||
"webpack": "^3.1.0"
|
"webpack": "^3.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0xproject/assert": "^0.0.18",
|
"@0xproject/assert": "^0.2.0",
|
||||||
"@0xproject/json-schemas": "^0.7.10",
|
"@0xproject/base-contract": "^0.0.3",
|
||||||
"@0xproject/types": "^0.2.1",
|
"@0xproject/json-schemas": "^0.7.14",
|
||||||
"@0xproject/utils": "^0.3.2",
|
"@0xproject/types": "^0.3.1",
|
||||||
"@0xproject/web3-wrapper": "^0.1.12",
|
"@0xproject/utils": "^0.4.1",
|
||||||
|
"@0xproject/web3-wrapper": "^0.2.1",
|
||||||
"bintrees": "^1.0.2",
|
"bintrees": "^1.0.2",
|
||||||
"bn.js": "^4.11.8",
|
"bn.js": "^4.11.8",
|
||||||
"ethereumjs-abi": "^0.6.4",
|
"ethereumjs-abi": "^0.6.4",
|
||||||
"ethereumjs-blockstream": "^2.0.6",
|
"ethereumjs-blockstream": "^2.0.6",
|
||||||
"ethereumjs-util": "^5.1.1",
|
"ethereumjs-util": "^5.1.1",
|
||||||
|
"ethers-contracts": "^2.2.1",
|
||||||
|
"ethers-typescript-typings": "^0.0.2",
|
||||||
"js-sha3": "^0.7.0",
|
"js-sha3": "^0.7.0",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"uuid": "^3.1.0",
|
"uuid": "^3.1.0",
|
||||||
"web3": "^0.20.0"
|
"web3": "^0.20.0",
|
||||||
|
"web3-typescript-typings": "^0.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,16 @@
|
|||||||
const execAsync = require('async-child-process').execAsync;
|
const execAsync = require('async-child-process').execAsync;
|
||||||
const postpublish_utils = require('../../../scripts/postpublish_utils');
|
const postpublish_utils = require('../../../scripts/postpublish_utils');
|
||||||
const packageJSON = require('../package.json');
|
const packageJSON = require('../package.json');
|
||||||
|
const tsConfig = require('../tsconfig.json');
|
||||||
|
|
||||||
const cwd = __dirname + '/..';
|
const cwd = __dirname + '/..';
|
||||||
const subPackageName = packageJSON.name;
|
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/';
|
const S3BucketPath = 's3://0xjs-docs-jsons/';
|
||||||
|
|
||||||
let tag;
|
let tag;
|
||||||
@@ -20,7 +27,7 @@ postpublish_utils
|
|||||||
.then(function(release) {
|
.then(function(release) {
|
||||||
console.log('POSTPUBLISH: Release successful, generating docs...');
|
console.log('POSTPUBLISH: Release successful, generating docs...');
|
||||||
const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
|
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,
|
cwd,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
31
packages/0x.js/scripts/stagedocs.js
Normal file
31
packages/0x.js/scripts/stagedocs.js
Normal file
@@ -0,0 +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_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,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
@@ -13,6 +13,8 @@ import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_pr
|
|||||||
import { TokenWrapper } from './contract_wrappers/token_wrapper';
|
import { TokenWrapper } from './contract_wrappers/token_wrapper';
|
||||||
import { OrderStateWatcher } from './order_watcher/order_state_watcher';
|
import { OrderStateWatcher } from './order_watcher/order_state_watcher';
|
||||||
import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
|
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 { ECSignature, Order, SignedOrder, Web3Provider, ZeroExConfig, ZeroExError } from './types';
|
||||||
import { assert } from './utils/assert';
|
import { assert } from './utils/assert';
|
||||||
import { constants } from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
@@ -74,8 +76,9 @@ export class ZeroEx {
|
|||||||
assert.isHexString('data', data);
|
assert.isHexString('data', data);
|
||||||
assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
|
assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
|
||||||
assert.isETHAddressHex('signerAddress', signerAddress);
|
assert.isETHAddressHex('signerAddress', signerAddress);
|
||||||
|
const normalizedSignerAddress = signerAddress.toLowerCase();
|
||||||
|
|
||||||
const isValidSignature = signatureUtils.isValidSignature(data, signature, signerAddress);
|
const isValidSignature = signatureUtils.isValidSignature(data, signature, normalizedSignerAddress);
|
||||||
return isValidSignature;
|
return isValidSignature;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -163,7 +166,10 @@ export class ZeroEx {
|
|||||||
*/
|
*/
|
||||||
constructor(provider: Web3Provider, config: ZeroExConfig) {
|
constructor(provider: Web3Provider, config: ZeroExConfig) {
|
||||||
assert.isWeb3Provider('provider', provider);
|
assert.isWeb3Provider('provider', provider);
|
||||||
assert.doesConformToSchema('config', config, zeroExConfigSchema);
|
assert.doesConformToSchema('config', config, zeroExConfigSchema, [
|
||||||
|
zeroExPrivateNetworkConfigSchema,
|
||||||
|
zeroExPublicNetworkConfigSchema,
|
||||||
|
]);
|
||||||
const artifactJSONs = _.values(artifacts);
|
const artifactJSONs = _.values(artifacts);
|
||||||
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
|
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
|
||||||
this._abiDecoder = new AbiDecoder(abiArrays);
|
this._abiDecoder = new AbiDecoder(abiArrays);
|
||||||
@@ -245,6 +251,7 @@ export class ZeroEx {
|
|||||||
): Promise<ECSignature> {
|
): Promise<ECSignature> {
|
||||||
assert.isHexString('orderHash', orderHash);
|
assert.isHexString('orderHash', orderHash);
|
||||||
await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper);
|
||||||
|
const normalizedSignerAddress = signerAddress.toLowerCase();
|
||||||
|
|
||||||
let msgHashHex = orderHash;
|
let msgHashHex = orderHash;
|
||||||
if (shouldAddPersonalMessagePrefix) {
|
if (shouldAddPersonalMessagePrefix) {
|
||||||
@@ -253,7 +260,7 @@ export class ZeroEx {
|
|||||||
msgHashHex = ethUtil.bufferToHex(msgHashBuff);
|
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
|
// 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)
|
// 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 validVParamValues = [27, 28];
|
||||||
const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature);
|
const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature);
|
||||||
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
|
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
|
||||||
const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, signerAddress);
|
const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
|
||||||
if (isValidVRSSignature) {
|
if (isValidVRSSignature) {
|
||||||
return ecSignatureVRS;
|
return ecSignatureVRS;
|
||||||
}
|
}
|
||||||
@@ -270,7 +277,7 @@ export class ZeroEx {
|
|||||||
|
|
||||||
const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature);
|
const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature);
|
||||||
if (_.includes(validVParamValues, ecSignatureRSV.v)) {
|
if (_.includes(validVParamValues, ecSignatureRSV.v)) {
|
||||||
const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, signerAddress);
|
const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
|
||||||
if (isValidRSVSignature) {
|
if (isValidRSVSignature) {
|
||||||
return ecSignatureRSV;
|
return ecSignatureRSV;
|
||||||
}
|
}
|
||||||
|
@@ -108,10 +108,10 @@ export class ContractWrapper {
|
|||||||
const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log);
|
const logWithDecodedArgs = this._abiDecoder.tryToDecodeLogOrNoop(log);
|
||||||
return logWithDecodedArgs;
|
return logWithDecodedArgs;
|
||||||
}
|
}
|
||||||
protected async _instantiateContractIfExistsAsync(
|
protected async _getContractAbiAndAddressFromArtifactsAsync(
|
||||||
artifact: Artifact,
|
artifact: Artifact,
|
||||||
addressIfExists?: string,
|
addressIfExists?: string,
|
||||||
): Promise<Web3.ContractInstance> {
|
): Promise<[Web3.ContractAbi, string]> {
|
||||||
let contractAddress: string;
|
let contractAddress: string;
|
||||||
if (_.isUndefined(addressIfExists)) {
|
if (_.isUndefined(addressIfExists)) {
|
||||||
if (_.isUndefined(artifact.networks[this._networkId])) {
|
if (_.isUndefined(artifact.networks[this._networkId])) {
|
||||||
@@ -125,8 +125,8 @@ export class ContractWrapper {
|
|||||||
if (!doesContractExist) {
|
if (!doesContractExist) {
|
||||||
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
||||||
}
|
}
|
||||||
const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
|
const abiAndAddress: [Web3.ContractAbi, string] = [artifact.abi, contractAddress];
|
||||||
return contractInstance;
|
return abiAndAddress;
|
||||||
}
|
}
|
||||||
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
||||||
if (_.isUndefined(addressIfExists)) {
|
if (_.isUndefined(addressIfExists)) {
|
||||||
|
@@ -41,15 +41,18 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
depositor: string,
|
depositor: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
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);
|
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({
|
const txHash = await wethContract.deposit.sendTransactionAsync({
|
||||||
from: depositor,
|
from: normalizedDepositorAddress,
|
||||||
value: amountInWei,
|
value: amountInWei,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
@@ -72,14 +75,20 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
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);
|
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, {
|
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
|
||||||
from: withdrawer,
|
from: normalizedWithdrawerAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
@@ -101,11 +110,12 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
indexFilterValues: IndexedFilterValues,
|
indexFilterValues: IndexedFilterValues,
|
||||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
|
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
etherTokenAddress,
|
normalizedEtherTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
blockRange,
|
blockRange,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
@@ -129,11 +139,12 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
callback: EventCallback<ArgsType>,
|
callback: EventCallback<ArgsType>,
|
||||||
): string {
|
): string {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
|
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
etherTokenAddress,
|
normalizedEtherTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
artifacts.EtherTokenArtifact.abi,
|
artifacts.EtherTokenArtifact.abi,
|
||||||
@@ -151,7 +162,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
/**
|
/**
|
||||||
* Cancels all existing subscriptions
|
* Cancels all existing subscriptions
|
||||||
*/
|
*/
|
||||||
public _unsubscribeAll(): void {
|
public unsubscribeAll(): void {
|
||||||
super._unsubscribeAll();
|
super._unsubscribeAll();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -168,7 +179,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
return contractAddressIfExists;
|
return contractAddressIfExists;
|
||||||
}
|
}
|
||||||
private _invalidateContractInstance(): void {
|
private _invalidateContractInstance(): void {
|
||||||
this._unsubscribeAll();
|
this.unsubscribeAll();
|
||||||
this._etherTokenContractsByAddress = {};
|
this._etherTokenContractsByAddress = {};
|
||||||
}
|
}
|
||||||
private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
|
private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
|
||||||
@@ -176,11 +187,11 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
if (!_.isUndefined(etherTokenContract)) {
|
if (!_.isUndefined(etherTokenContract)) {
|
||||||
return etherTokenContract;
|
return etherTokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||||
artifacts.EtherTokenArtifact,
|
artifacts.EtherTokenArtifact,
|
||||||
etherTokenAddress,
|
etherTokenAddress,
|
||||||
);
|
);
|
||||||
const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new EtherTokenContract(this._web3Wrapper, abi, address);
|
||||||
etherTokenContract = contractInstance;
|
etherTokenContract = contractInstance;
|
||||||
this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract;
|
this._etherTokenContractsByAddress[etherTokenAddress] = etherTokenContract;
|
||||||
return etherTokenContract;
|
return etherTokenContract;
|
||||||
|
@@ -108,8 +108,10 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
|
|
||||||
const exchangeContract = await this._getExchangeContractAsync();
|
const exchangeContract = await this._getExchangeContractAsync();
|
||||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
||||||
|
const txData = {};
|
||||||
let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
||||||
orderHash,
|
orderHash,
|
||||||
|
txData,
|
||||||
defaultBlock,
|
defaultBlock,
|
||||||
);
|
);
|
||||||
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
// 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 exchangeContract = await this._getExchangeContractAsync();
|
||||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
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
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
fillAmountInBaseUnits = new BigNumber(fillAmountInBaseUnits);
|
fillAmountInBaseUnits = new BigNumber(fillAmountInBaseUnits);
|
||||||
return fillAmountInBaseUnits;
|
return fillAmountInBaseUnits;
|
||||||
@@ -144,7 +147,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
|
|
||||||
const exchangeContract = await this._getExchangeContractAsync();
|
const exchangeContract = await this._getExchangeContractAsync();
|
||||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
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
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
cancelledAmountInBaseUnits = new BigNumber(cancelledAmountInBaseUnits);
|
cancelledAmountInBaseUnits = new BigNumber(cancelledAmountInBaseUnits);
|
||||||
return cancelledAmountInBaseUnits;
|
return cancelledAmountInBaseUnits;
|
||||||
@@ -180,6 +184,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
@@ -192,7 +197,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -208,7 +213,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
signedOrder.ecSignature.r,
|
signedOrder.ecSignature.r,
|
||||||
signedOrder.ecSignature.s,
|
signedOrder.ecSignature.s,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -254,6 +259,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
? SHOULD_VALIDATE_BY_DEFAULT
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
@@ -267,7 +273,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount.minus(filledTakerTokenAmount),
|
fillTakerTokenAmount.minus(filledTakerTokenAmount),
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
|
filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
|
||||||
@@ -301,7 +307,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
rArray,
|
rArray,
|
||||||
sArray,
|
sArray,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -345,6 +351,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
);
|
);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
? SHOULD_VALIDATE_BY_DEFAULT
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
@@ -356,7 +363,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
orderFillRequest.signedOrder,
|
orderFillRequest.signedOrder,
|
||||||
orderFillRequest.takerTokenFillAmount,
|
orderFillRequest.takerTokenFillAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -389,7 +396,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
rArray,
|
rArray,
|
||||||
sArray,
|
sArray,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -417,6 +424,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
@@ -430,7 +438,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -444,7 +452,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
signedOrder.ecSignature.r,
|
signedOrder.ecSignature.r,
|
||||||
signedOrder.ecSignature.s,
|
signedOrder.ecSignature.s,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -476,6 +484,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
);
|
);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
if (_.isEmpty(orderFillRequests)) {
|
if (_.isEmpty(orderFillRequests)) {
|
||||||
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
}
|
}
|
||||||
@@ -492,7 +501,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
orderFillRequest.signedOrder,
|
orderFillRequest.signedOrder,
|
||||||
orderFillRequest.takerTokenFillAmount,
|
orderFillRequest.takerTokenFillAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -520,7 +529,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
rParams,
|
rParams,
|
||||||
sParams,
|
sParams,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -544,6 +553,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
||||||
|
const normalizedMakerAddress = order.maker.toLowerCase();
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
@@ -566,7 +576,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
orderValues,
|
orderValues,
|
||||||
cancelTakerTokenAmount,
|
cancelTakerTokenAmount,
|
||||||
{
|
{
|
||||||
from: order.maker,
|
from: normalizedMakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -603,6 +613,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
||||||
const maker = makers[0];
|
const maker = makers[0];
|
||||||
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
||||||
|
const normalizedMakerAddress = maker.toLowerCase();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
? SHOULD_VALIDATE_BY_DEFAULT
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
@@ -636,7 +648,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
orderValues,
|
orderValues,
|
||||||
cancelTakerTokenAmounts,
|
cancelTakerTokenAmounts,
|
||||||
{
|
{
|
||||||
from: maker,
|
from: normalizedMakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -679,7 +691,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
/**
|
/**
|
||||||
* Cancels all existing subscriptions
|
* Cancels all existing subscriptions
|
||||||
*/
|
*/
|
||||||
public _unsubscribeAll(): void {
|
public unsubscribeAll(): void {
|
||||||
super._unsubscribeAll();
|
super._unsubscribeAll();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -757,13 +769,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -803,13 +816,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
const normalizedTakerAddress = takerAddress.toLowerCase();
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -848,7 +862,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
});
|
});
|
||||||
if (!_.isUndefined(errLog)) {
|
if (!_.isUndefined(errLog)) {
|
||||||
const logArgs = (errLog as LogWithDecodedArgs<LogErrorContractEventArgs>).args;
|
const logArgs = (errLog as LogWithDecodedArgs<LogErrorContractEventArgs>).args;
|
||||||
const errCode = logArgs.errorId.toNumber();
|
const errCode = logArgs.errorId;
|
||||||
const errMessage = this._exchangeContractErrCodesToMsg[errCode];
|
const errMessage = this._exchangeContractErrCodesToMsg[errCode];
|
||||||
throw new Error(errMessage);
|
throw new Error(errMessage);
|
||||||
}
|
}
|
||||||
@@ -862,7 +876,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
private _invalidateContractInstances(): void {
|
private _invalidateContractInstances(): void {
|
||||||
this._unsubscribeAll();
|
this.unsubscribeAll();
|
||||||
delete this._exchangeContractIfExists;
|
delete this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
private async _isValidSignatureUsingContractCallAsync(
|
private async _isValidSignatureUsingContractCallAsync(
|
||||||
@@ -873,11 +887,12 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.isHexString('dataHex', dataHex);
|
assert.isHexString('dataHex', dataHex);
|
||||||
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
|
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
|
||||||
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
|
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
|
||||||
|
const normalizedSignerAddress = signerAddressHex.toLowerCase();
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
|
const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
|
||||||
signerAddressHex,
|
normalizedSignerAddress,
|
||||||
dataHex,
|
dataHex,
|
||||||
ecSignature.v,
|
ecSignature.v,
|
||||||
ecSignature.r,
|
ecSignature.r,
|
||||||
@@ -895,11 +910,11 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
if (!_.isUndefined(this._exchangeContractIfExists)) {
|
if (!_.isUndefined(this._exchangeContractIfExists)) {
|
||||||
return this._exchangeContractIfExists;
|
return this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||||
artifacts.ExchangeArtifact,
|
artifacts.ExchangeArtifact,
|
||||||
this._contractAddressIfExists,
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new ExchangeContract(this._web3Wrapper, abi, address);
|
||||||
this._exchangeContractIfExists = contractInstance;
|
this._exchangeContractIfExists = contractInstance;
|
||||||
return this._exchangeContractIfExists;
|
return this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1 @@
|
|||||||
dummy_token.ts
|
*
|
||||||
ether_token.ts
|
|
||||||
exchange.ts
|
|
||||||
token_registry.ts
|
|
||||||
token_transfer_proxy.ts
|
|
||||||
token.ts
|
|
||||||
|
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -23,7 +23,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
address: metadata[0],
|
address: metadata[0],
|
||||||
name: metadata[1],
|
name: metadata[1],
|
||||||
symbol: metadata[2],
|
symbol: metadata[2],
|
||||||
decimals: metadata[3].toNumber(),
|
decimals: metadata[3],
|
||||||
};
|
};
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,8 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
public async getTokenAddressesAsync(): Promise<string[]> {
|
public async getTokenAddressesAsync(): Promise<string[]> {
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const addresses = await tokenRegistryContract.getTokenAddresses.callAsync();
|
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
|
* 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> {
|
public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> {
|
||||||
assert.isETHAddressHex('address', address);
|
assert.isETHAddressHex('address', address);
|
||||||
|
const normalizedAddress = address.toLowerCase();
|
||||||
|
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
|
const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress);
|
||||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -115,14 +117,11 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
|
if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
|
||||||
return this._tokenRegistryContractIfExists;
|
return this._tokenRegistryContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||||
artifacts.TokenRegistryArtifact,
|
artifacts.TokenRegistryArtifact,
|
||||||
this._contractAddressIfExists,
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenRegistryContract(
|
const contractInstance = new TokenRegistryContract(this._web3Wrapper, abi, address);
|
||||||
web3ContractInstance,
|
|
||||||
this._web3Wrapper.getContractDefaults(),
|
|
||||||
);
|
|
||||||
this._tokenRegistryContractIfExists = contractInstance;
|
this._tokenRegistryContractIfExists = contractInstance;
|
||||||
return this._tokenRegistryContractIfExists;
|
return this._tokenRegistryContractIfExists;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts } from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
|
import { assert } from '../utils/assert';
|
||||||
|
|
||||||
import { ContractWrapper } from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
|
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
|
||||||
@@ -22,8 +23,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
* @return Whether the exchangeContractAddress is authorized.
|
* @return Whether the exchangeContractAddress is authorized.
|
||||||
*/
|
*/
|
||||||
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
||||||
|
assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress);
|
||||||
|
const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase();
|
||||||
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
|
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
|
||||||
const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(exchangeContractAddress);
|
const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(
|
||||||
|
normalizedExchangeContractAddress,
|
||||||
|
);
|
||||||
return isAuthorized;
|
return isAuthorized;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -54,14 +59,11 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
|
if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
|
||||||
return this._tokenTransferProxyContractIfExists;
|
return this._tokenTransferProxyContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||||
artifacts.TokenTransferProxyArtifact,
|
artifacts.TokenTransferProxyArtifact,
|
||||||
this._contractAddressIfExists,
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenTransferProxyContract(
|
const contractInstance = new TokenTransferProxyContract(this._web3Wrapper, abi, address);
|
||||||
web3ContractInstance,
|
|
||||||
this._web3Wrapper.getContractDefaults(),
|
|
||||||
);
|
|
||||||
this._tokenTransferProxyContractIfExists = contractInstance;
|
this._tokenTransferProxyContractIfExists = contractInstance;
|
||||||
return this._tokenTransferProxyContractIfExists;
|
return this._tokenTransferProxyContractIfExists;
|
||||||
}
|
}
|
||||||
|
@@ -46,10 +46,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
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;
|
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
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
balance = new BigNumber(balance);
|
balance = new BigNumber(balance);
|
||||||
return balance;
|
return balance;
|
||||||
@@ -72,14 +75,17 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
|
||||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
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);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const tokenContract = await this._getTokenContractAsync(tokenAddress);
|
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||||
const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
|
const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, {
|
||||||
from: ownerAddress,
|
from: normalizedOwnerAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
@@ -103,10 +109,16 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
spenderAddress: string,
|
spenderAddress: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): 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(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
ownerAddress,
|
normalizedOwnerAddress,
|
||||||
spenderAddress,
|
normalizedSpenderAddress,
|
||||||
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
txOpts,
|
txOpts,
|
||||||
);
|
);
|
||||||
@@ -128,10 +140,20 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
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;
|
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
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
|
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
|
||||||
return allowanceInBaseUnits;
|
return allowanceInBaseUnits;
|
||||||
@@ -149,9 +171,16 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
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;
|
return allowanceInBaseUnits;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -172,12 +201,14 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
ownerAddress,
|
normalizedOwnerAddress,
|
||||||
proxyAddress,
|
proxyAddress,
|
||||||
amountInBaseUnits,
|
amountInBaseUnits,
|
||||||
txOpts,
|
txOpts,
|
||||||
@@ -200,9 +231,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
ownerAddress: string,
|
ownerAddress: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
const txHash = await this.setProxyAllowanceAsync(
|
const txHash = await this.setProxyAllowanceAsync(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
ownerAddress,
|
normalizedOwnerAddress,
|
||||||
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
txOpts,
|
txOpts,
|
||||||
);
|
);
|
||||||
@@ -225,19 +260,22 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
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);
|
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)) {
|
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
|
||||||
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
|
const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, {
|
||||||
from: fromAddress,
|
from: normalizedFromAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
@@ -265,30 +303,38 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
|
||||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
|
assert.isETHAddressHex('fromAddress', fromAddress);
|
||||||
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
|
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);
|
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)) {
|
if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
|
||||||
throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
|
throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
|
const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress);
|
||||||
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
|
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
|
||||||
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
||||||
fromAddress,
|
normalizedFromAddress,
|
||||||
toAddress,
|
normalizedToAddress,
|
||||||
amountInBaseUnits,
|
amountInBaseUnits,
|
||||||
{
|
{
|
||||||
from: senderAddress,
|
from: normalizedSenderAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@@ -311,11 +357,12 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
callback: EventCallback<ArgsType>,
|
callback: EventCallback<ArgsType>,
|
||||||
): string {
|
): string {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
artifacts.TokenArtifact.abi,
|
artifacts.TokenArtifact.abi,
|
||||||
@@ -333,7 +380,7 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
/**
|
/**
|
||||||
* Cancels all existing subscriptions
|
* Cancels all existing subscriptions
|
||||||
*/
|
*/
|
||||||
public _unsubscribeAll(): void {
|
public unsubscribeAll(): void {
|
||||||
super._unsubscribeAll();
|
super._unsubscribeAll();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -352,11 +399,12 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
indexFilterValues: IndexedFilterValues,
|
indexFilterValues: IndexedFilterValues,
|
||||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
blockRange,
|
blockRange,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
@@ -365,21 +413,22 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
private _invalidateContractInstances(): void {
|
private _invalidateContractInstances(): void {
|
||||||
this._unsubscribeAll();
|
this.unsubscribeAll();
|
||||||
this._tokenContractsByAddress = {};
|
this._tokenContractsByAddress = {};
|
||||||
}
|
}
|
||||||
private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
|
private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
|
||||||
let tokenContract = this._tokenContractsByAddress[tokenAddress];
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress];
|
||||||
if (!_.isUndefined(tokenContract)) {
|
if (!_.isUndefined(tokenContract)) {
|
||||||
return tokenContract;
|
return tokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||||
artifacts.TokenArtifact,
|
artifacts.TokenArtifact,
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new TokenContract(this._web3Wrapper, abi, address);
|
||||||
tokenContract = contractInstance;
|
tokenContract = contractInstance;
|
||||||
this._tokenContractsByAddress[tokenAddress] = tokenContract;
|
this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract;
|
||||||
return tokenContract;
|
return tokenContract;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ export {
|
|||||||
BlockParam,
|
BlockParam,
|
||||||
ContractEventArg,
|
ContractEventArg,
|
||||||
LogWithDecodedArgs,
|
LogWithDecodedArgs,
|
||||||
|
TransactionReceipt,
|
||||||
TransactionReceiptWithDecodedLogs,
|
TransactionReceiptWithDecodedLogs,
|
||||||
} from '@0xproject/types';
|
} from '@0xproject/types';
|
||||||
|
|
||||||
@@ -58,5 +59,3 @@ export {
|
|||||||
ExchangeContractEventArgs,
|
ExchangeContractEventArgs,
|
||||||
ExchangeEvents,
|
ExchangeEvents,
|
||||||
} from './contract_wrappers/generated/exchange';
|
} from './contract_wrappers/generated/exchange';
|
||||||
|
|
||||||
export { TransactionReceipt } from '@0xproject/types';
|
|
||||||
|
@@ -1,27 +1,5 @@
|
|||||||
export const zeroExConfigSchema = {
|
export const zeroExConfigSchema = {
|
||||||
id: '/ZeroExConfig',
|
id: '/ZeroExConfig',
|
||||||
properties: {
|
oneOf: [{ $ref: '/ZeroExPrivateNetworkConfig' }, { $ref: '/ZeroExPublicNetworkConfig' }],
|
||||||
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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: 'object',
|
type: 'object',
|
||||||
required: ['networkId'],
|
|
||||||
};
|
};
|
||||||
|
@@ -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',
|
||||||
|
],
|
||||||
|
};
|
@@ -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'],
|
||||||
|
};
|
@@ -127,7 +127,7 @@ export interface SignedOrder extends Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [address, name, symbol, decimals, ipfsHash, swarmHash]
|
// [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 {
|
export interface Token {
|
||||||
name: string;
|
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
|
* gasPrice: Gas price to use with every transaction
|
||||||
* exchangeContractAddress: The address of an exchange contract to use
|
* exchangeContractAddress: The address of an exchange contract to use
|
||||||
* zrxContractAddress: The address of the ZRX contract to use
|
* zrxContractAddress: The address of the ZRX contract to use
|
||||||
|
@@ -75,11 +75,14 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const contractAddressIfExists = zeroEx.etherToken.getContractAddressIfExists();
|
const contractAddressIfExists = zeroEx.etherToken.getContractAddressIfExists();
|
||||||
expect(contractAddressIfExists).to.not.be.undefined();
|
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 UNKNOWN_NETWORK_NETWORK_ID = 10;
|
||||||
const unknownNetworkZeroEx = new ZeroEx(web3.currentProvider, { networkId: UNKNOWN_NETWORK_NETWORK_ID });
|
expect(
|
||||||
const contractAddressIfExists = unknownNetworkZeroEx.etherToken.getContractAddressIfExists();
|
() =>
|
||||||
expect(contractAddressIfExists).to.be.undefined();
|
new ZeroEx(web3.currentProvider, {
|
||||||
|
networkId: UNKNOWN_NETWORK_NETWORK_ID,
|
||||||
|
} as any),
|
||||||
|
).to.throw();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#depositAsync', () => {
|
describe('#depositAsync', () => {
|
||||||
@@ -155,7 +158,7 @@ describe('EtherTokenWrapper', () => {
|
|||||||
etherTokenAddress = etherToken.address;
|
etherTokenAddress = etherToken.address;
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
zeroEx.etherToken._unsubscribeAll();
|
zeroEx.etherToken.unsubscribeAll();
|
||||||
});
|
});
|
||||||
// Hack: Mocha does not allow a test to be both async and have a `done` callback
|
// 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,
|
// Since we need to await the receipt of the event in the `subscribe` callback,
|
||||||
|
@@ -922,7 +922,7 @@ describe('ExchangeWrapper', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
zeroEx.exchange._unsubscribeAll();
|
zeroEx.exchange.unsubscribeAll();
|
||||||
});
|
});
|
||||||
// Hack: Mocha does not allow a test to be both async and have a `done` callback
|
// 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,
|
// Since we need to await the receipt of the event in the `subscribe` callback,
|
||||||
|
@@ -9,10 +9,10 @@ import * as Web3 from 'web3';
|
|||||||
import { ZeroEx } from '../src/0x';
|
import { ZeroEx } from '../src/0x';
|
||||||
import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher';
|
import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher';
|
||||||
import { DoneCallback, Token } from '../src/types';
|
import { DoneCallback, Token } from '../src/types';
|
||||||
import { constants } from '../src/utils/constants';
|
|
||||||
import { utils } from '../src/utils/utils';
|
import { utils } from '../src/utils/utils';
|
||||||
|
|
||||||
import { chaiSetup } from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
|
import { constants } from './utils/constants';
|
||||||
import { FillScenarios } from './utils/fill_scenarios';
|
import { FillScenarios } from './utils/fill_scenarios';
|
||||||
import { reportNoErrorCallbackErrors } from './utils/report_callback_errors';
|
import { reportNoErrorCallbackErrors } from './utils/report_callback_errors';
|
||||||
import { TokenUtils } from './utils/token_utils';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
|
@@ -49,7 +49,7 @@ describe('SubscriptionTest', () => {
|
|||||||
tokenAddress = token.address;
|
tokenAddress = token.address;
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
zeroEx.token._unsubscribeAll();
|
zeroEx.token.unsubscribeAll();
|
||||||
_.each(stubs, s => s.restore());
|
_.each(stubs, s => s.restore());
|
||||||
stubs = [];
|
stubs = [];
|
||||||
});
|
});
|
||||||
@@ -76,7 +76,7 @@ describe('SubscriptionTest', () => {
|
|||||||
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
||||||
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
|
||||||
zeroEx.token._unsubscribeAll();
|
zeroEx.token.unsubscribeAll();
|
||||||
done();
|
done();
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
|
@@ -377,7 +377,7 @@ describe('TokenWrapper', () => {
|
|||||||
tokenAddress = token.address;
|
tokenAddress = token.address;
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
zeroEx.token._unsubscribeAll();
|
zeroEx.token.unsubscribeAll();
|
||||||
});
|
});
|
||||||
// Hack: Mocha does not allow a test to be both async and have a `done` callback
|
// 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,
|
// Since we need to await the receipt of the event in the `subscribe` callback,
|
||||||
|
@@ -35,12 +35,8 @@ export class FillScenarios {
|
|||||||
const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
|
const web3Wrapper = (this._zeroEx as any)._web3Wrapper as Web3Wrapper;
|
||||||
for (const token of this._tokens) {
|
for (const token of this._tokens) {
|
||||||
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
|
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
|
||||||
const contractInstance = web3Wrapper.getContractInstance(
|
|
||||||
artifacts.DummyTokenArtifact.abi,
|
|
||||||
token.address,
|
|
||||||
);
|
|
||||||
const defaults = {};
|
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 tokenSupply = ZeroEx.toBaseUnitAmount(INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS, token.decimals);
|
||||||
const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
|
const txHash = await dummyToken.setBalance.sendTransactionAsync(this._coinbase, tokenSupply, {
|
||||||
from: this._coinbase,
|
from: this._coinbase,
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
"./test/**/*",
|
"./test/**/*",
|
||||||
"../../node_modules/types-bn/index.d.ts",
|
"../../node_modules/types-bn/index.d.ts",
|
||||||
"../../node_modules/types-ethereumjs-util/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/web3-typescript-typings/index.d.ts",
|
||||||
"../../node_modules/chai-typescript-typings/index.d.ts",
|
"../../node_modules/chai-typescript-typings/index.d.ts",
|
||||||
"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
|
"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
# CHANGELOG
|
# 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_
|
## v0.2.1 - _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)
|
||||||
|
@@ -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.
|
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.
|
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.
|
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.js/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files.
|
[Here](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -36,14 +36,14 @@ The abi file should be either a [Truffle](http://truffleframework.com/) contract
|
|||||||
|
|
||||||
## How to write custom templates?
|
## 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.
|
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.
|
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?
|
## 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.
|
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
|
## Output files
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/abi-gen",
|
"name": "@0xproject/abi-gen",
|
||||||
"version": "0.2.1",
|
"version": "0.2.5",
|
||||||
"description": "Generate contract wrappers from ABI and handlebars templates",
|
"description": "Generate contract wrappers from ABI and handlebars templates",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
@@ -15,15 +15,15 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js.git"
|
"url": "https://github.com/0xProject/0x-monorepo.git"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bugs": {
|
"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": {
|
"dependencies": {
|
||||||
"@0xproject/utils": "^0.3.2",
|
"@0xproject/utils": "^0.4.1",
|
||||||
"chalk": "^2.3.0",
|
"chalk": "^2.3.0",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
"handlebars": "^4.0.11",
|
"handlebars": "^4.0.11",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"yargs": "^10.0.3"
|
"yargs": "^10.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.4.8",
|
"@0xproject/tslint-config": "^0.4.10",
|
||||||
"@types/glob": "^5.0.33",
|
"@types/glob": "^5.0.33",
|
||||||
"@types/handlebars": "^4.0.36",
|
"@types/handlebars": "^4.0.36",
|
||||||
"@types/mkdirp": "^0.5.1",
|
"@types/mkdirp": "^0.5.1",
|
||||||
@@ -44,6 +44,6 @@
|
|||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"typescript": "2.7.1",
|
"typescript": "2.7.1",
|
||||||
"web3-typescript-typings": "^0.9.10"
|
"web3-typescript-typings": "^0.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,13 +11,14 @@ import * as yargs from 'yargs';
|
|||||||
import toSnakeCase = require('to-snake-case');
|
import toSnakeCase = require('to-snake-case');
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import { ContextData, ParamKind } from './types';
|
import { ContextData, ContractsBackend, ParamKind } from './types';
|
||||||
import { utils } from './utils';
|
import { utils } from './utils';
|
||||||
|
|
||||||
const ABI_TYPE_CONSTRUCTOR = 'constructor';
|
const ABI_TYPE_CONSTRUCTOR = 'constructor';
|
||||||
const ABI_TYPE_METHOD = 'function';
|
const ABI_TYPE_METHOD = 'function';
|
||||||
const ABI_TYPE_EVENT = 'event';
|
const ABI_TYPE_EVENT = 'event';
|
||||||
const DEFAULT_NETWORK_ID = 50;
|
const DEFAULT_NETWORK_ID = 50;
|
||||||
|
const DEFAULT_BACKEND = 'web3';
|
||||||
|
|
||||||
const args = yargs
|
const args = yargs
|
||||||
.option('abis', {
|
.option('abis', {
|
||||||
@@ -43,6 +44,12 @@ const args = yargs
|
|||||||
demandOption: true,
|
demandOption: true,
|
||||||
normalize: 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', {
|
.option('network-id', {
|
||||||
describe: 'ID of the network where contract ABIs are nested in artifacts',
|
describe: 'ID of the network where contract ABIs are nested in artifacts',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
@@ -73,8 +80,8 @@ function writeOutputFile(name: string, renderedTsCode: string): void {
|
|||||||
utils.log(`Created: ${chalk.bold(filePath)}`);
|
utils.log(`Created: ${chalk.bold(filePath)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input));
|
Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend));
|
||||||
Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output));
|
Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend));
|
||||||
|
|
||||||
if (args.partials) {
|
if (args.partials) {
|
||||||
registerPartials(args.partials);
|
registerPartials(args.partials);
|
||||||
@@ -129,6 +136,7 @@ for (const abiFileName of abiFileNames) {
|
|||||||
const methodData = {
|
const methodData = {
|
||||||
...methodAbi,
|
...methodAbi,
|
||||||
singleReturnValue: methodAbi.outputs.length === 1,
|
singleReturnValue: methodAbi.outputs.length === 1,
|
||||||
|
hasReturnValue: methodAbi.outputs.length !== 0,
|
||||||
};
|
};
|
||||||
return methodData;
|
return methodData;
|
||||||
});
|
});
|
||||||
|
@@ -12,8 +12,14 @@ export enum AbiType {
|
|||||||
Fallback = 'fallback',
|
Fallback = 'fallback',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ContractsBackend {
|
||||||
|
Web3 = 'web3',
|
||||||
|
Ethers = 'ethers',
|
||||||
|
}
|
||||||
|
|
||||||
export interface Method extends Web3.MethodAbi {
|
export interface Method extends Web3.MethodAbi {
|
||||||
singleReturnValue: boolean;
|
singleReturnValue: boolean;
|
||||||
|
hasReturnValue: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContextData {
|
export interface ContextData {
|
||||||
|
@@ -3,17 +3,23 @@ import * as _ from 'lodash';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import { AbiType, ParamKind } from './types';
|
import { AbiType, ContractsBackend, ParamKind } from './types';
|
||||||
|
|
||||||
export const utils = {
|
export const utils = {
|
||||||
solTypeToTsType(paramKind: ParamKind, solType: string): string {
|
solTypeToTsType(
|
||||||
|
paramKind: ParamKind,
|
||||||
|
backend: ContractsBackend,
|
||||||
|
solType: string,
|
||||||
|
components?: Web3.DataItem[],
|
||||||
|
): string {
|
||||||
const trailingArrayRegex = /\[\d*\]$/;
|
const trailingArrayRegex = /\[\d*\]$/;
|
||||||
if (solType.match(trailingArrayRegex)) {
|
if (solType.match(trailingArrayRegex)) {
|
||||||
const arrayItemSolType = solType.replace(trailingArrayRegex, '');
|
const arrayItemSolType = solType.replace(trailingArrayRegex, '');
|
||||||
const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
|
const arrayItemTsType = utils.solTypeToTsType(paramKind, backend, arrayItemSolType, components);
|
||||||
const arrayTsType = utils.isUnionType(arrayItemTsType)
|
const arrayTsType =
|
||||||
? `Array<${arrayItemTsType}>`
|
utils.isUnionType(arrayItemTsType) || utils.isObjectType(arrayItemTsType)
|
||||||
: `${arrayItemTsType}[]`;
|
? `Array<${arrayItemTsType}>`
|
||||||
|
: `${arrayItemTsType}[]`;
|
||||||
return arrayTsType;
|
return arrayTsType;
|
||||||
} else {
|
} else {
|
||||||
const solTypeRegexToTsType = [
|
const solTypeRegexToTsType = [
|
||||||
@@ -24,25 +30,49 @@ export const utils = {
|
|||||||
{ regex: '^bytes\\d*$', tsType: 'string' },
|
{ regex: '^bytes\\d*$', tsType: 'string' },
|
||||||
];
|
];
|
||||||
if (paramKind === ParamKind.Input) {
|
if (paramKind === ParamKind.Input) {
|
||||||
// web3 allows to pass those an non-bignumbers and that's nice
|
// web3 and ethers allow to pass those as numbers instead of bignumbers
|
||||||
// but it always returns stuff as BigNumbers
|
|
||||||
solTypeRegexToTsType.unshift({
|
solTypeRegexToTsType.unshift({
|
||||||
regex: '^u?int(8|16|32)?$',
|
regex: '^u?int(8|16|32)?$',
|
||||||
tsType: 'number|BigNumber',
|
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) {
|
for (const regexAndTxType of solTypeRegexToTsType) {
|
||||||
const { regex, tsType } = regexAndTxType;
|
const { regex, tsType } = regexAndTxType;
|
||||||
if (solType.match(regex)) {
|
if (solType.match(regex)) {
|
||||||
return tsType;
|
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}`);
|
throw new Error(`Unknown Solidity type found: ${solType}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isUnionType(tsType: string): boolean {
|
isUnionType(tsType: string): boolean {
|
||||||
return tsType === 'number|BigNumber';
|
return tsType === 'number|BigNumber';
|
||||||
},
|
},
|
||||||
|
isObjectType(tsType: string): boolean {
|
||||||
|
return /^{.*}$/.test(tsType);
|
||||||
|
},
|
||||||
log(...args: any[]): void {
|
log(...args: any[]): void {
|
||||||
console.log(...args); // tslint:disable-line:no-console
|
console.log(...args); // tslint:disable-line:no-console
|
||||||
},
|
},
|
||||||
|
@@ -1,5 +1,14 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.2.0 - _March 8, 2018_
|
||||||
|
|
||||||
|
* Rename `isHttpUrl` to `isWebUri` (#412)
|
||||||
|
|
||||||
|
## 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_
|
## v0.0.18 - _February 9, 2017_
|
||||||
|
|
||||||
* Fix publishing issue where .npmignore was not properly excluding undesired content (#389)
|
* Fix publishing issue where .npmignore was not properly excluding undesired content (#389)
|
||||||
|
@@ -8,6 +8,14 @@ Standard type and schema assertions to be used across all 0x projects and packag
|
|||||||
yarn add @0xproject/assert
|
yarn add @0xproject/assert
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
|
||||||
|
|
||||||
|
```
|
||||||
|
"include": [
|
||||||
|
"./node_modules/web3-typescript-typings/index.d.ts",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/assert",
|
"name": "@0xproject/assert",
|
||||||
"version": "0.0.18",
|
"version": "0.2.0",
|
||||||
"description": "Provides a standard way of performing type and schema validation across 0x projects",
|
"description": "Provides a standard way of performing type and schema validation across 0x projects",
|
||||||
"main": "lib/src/index.js",
|
"main": "lib/src/index.js",
|
||||||
"types": "lib/src/index.d.ts",
|
"types": "lib/src/index.d.ts",
|
||||||
@@ -17,19 +17,19 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js.git"
|
"url": "https://github.com/0xProject/0x-monorepo.git"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"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": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.4.8",
|
"@0xproject/tslint-config": "^0.4.10",
|
||||||
"@types/lodash": "^4.14.86",
|
"@types/lodash": "^4.14.86",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
"@types/valid-url": "^1.0.2",
|
"@types/valid-url": "^1.0.2",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
"chai-typescript-typings": "^0.0.3",
|
"chai-typescript-typings": "^0.0.4",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"mocha": "^4.0.1",
|
"mocha": "^4.0.1",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
"typescript": "2.7.1"
|
"typescript": "2.7.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0xproject/json-schemas": "^0.7.10",
|
"@0xproject/json-schemas": "^0.7.14",
|
||||||
"@0xproject/utils": "^0.3.2",
|
"@0xproject/utils": "^0.4.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"valid-url": "^1.0.9"
|
"valid-url": "^1.0.9"
|
||||||
}
|
}
|
||||||
|
@@ -33,11 +33,8 @@ export const assert = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
isETHAddressHex(variableName: string, value: string): void {
|
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), 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(
|
doesBelongToStringEnum(
|
||||||
variableName: string,
|
variableName: string,
|
||||||
@@ -66,8 +63,11 @@ export const assert = {
|
|||||||
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
|
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
|
||||||
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
|
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();
|
const schemaValidator = new SchemaValidator();
|
||||||
|
if (!_.isUndefined(subSchemas)) {
|
||||||
|
_.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator));
|
||||||
|
}
|
||||||
const validationResult = schemaValidator.validate(value, schema);
|
const validationResult = schemaValidator.validate(value, schema);
|
||||||
const hasValidationErrors = validationResult.errors.length > 0;
|
const hasValidationErrors = validationResult.errors.length > 0;
|
||||||
const msg = `Expected ${variableName} to conform to schema ${schema.id}
|
const msg = `Expected ${variableName} to conform to schema ${schema.id}
|
||||||
@@ -75,9 +75,9 @@ Encountered: ${JSON.stringify(value, null, '\t')}
|
|||||||
Validation errors: ${validationResult.errors.join(', ')}`;
|
Validation errors: ${validationResult.errors.join(', ')}`;
|
||||||
this.assert(!hasValidationErrors, msg);
|
this.assert(!hasValidationErrors, msg);
|
||||||
},
|
},
|
||||||
isHttpUrl(variableName: string, value: any): void {
|
isWebUri(variableName: string, value: any): void {
|
||||||
const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
|
const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
|
||||||
this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
|
this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'web uri', value));
|
||||||
},
|
},
|
||||||
isUri(variableName: string, value: any): void {
|
isUri(variableName: string, value: any): void {
|
||||||
const isValidUri = !_.isUndefined(validUrl.isUri(value));
|
const isValidUri = !_.isUndefined(validUrl.isUri(value));
|
||||||
|
@@ -183,7 +183,7 @@ describe('Assertions', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isHttpUrl', () => {
|
describe('#isWebUri', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [
|
||||||
'http://www.google.com',
|
'http://www.google.com',
|
||||||
@@ -191,7 +191,7 @@ describe('Assertions', () => {
|
|||||||
'https://api.radarrelay.com/0x/v0/',
|
'https://api.radarrelay.com/0x/v0/',
|
||||||
'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
|
'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
|
||||||
];
|
];
|
||||||
validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isWebUri.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
@@ -205,7 +205,7 @@ describe('Assertions', () => {
|
|||||||
'user:password@api.example-relayer.net',
|
'user:password@api.example-relayer.net',
|
||||||
'//api.example-relayer.net',
|
'//api.example-relayer.net',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isWebUri.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isUri', () => {
|
describe('#isUri', () => {
|
||||||
|
5
packages/base-contract/.npmignore
Normal file
5
packages/base-contract/.npmignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.*
|
||||||
|
yarn-error.log
|
||||||
|
/scripts/
|
||||||
|
/src/
|
||||||
|
tsconfig.json
|
5
packages/base-contract/CHANGELOG.md
Normal file
5
packages/base-contract/CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.0.2 - _March 4, 2018_
|
||||||
|
|
||||||
|
* Initial release
|
62
packages/base-contract/README.md
Normal file
62
packages/base-contract/README.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
## @0xproject/base-contract
|
||||||
|
|
||||||
|
BaseContract to derive all auto-generated wrappers from
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn add @0xproject/base-contract
|
||||||
|
```
|
||||||
|
|
||||||
|
If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
|
||||||
|
|
||||||
|
```
|
||||||
|
"include": [
|
||||||
|
"./node_modules/web3-typescript-typings/index.d.ts",
|
||||||
|
"./node_modules/ethers-typescript-typings/index.d.ts"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
|
```
|
39
packages/base-contract/package.json
Normal file
39
packages/base-contract/package.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"name": "@0xproject/base-contract",
|
||||||
|
"version": "0.0.3",
|
||||||
|
"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.1",
|
||||||
|
"@0xproject/web3-wrapper": "^0.2.1",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
68
packages/base-contract/src/index.ts
Normal file
68
packages/base-contract/src/index.ts
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
11
packages/base-contract/tsconfig.json
Normal file
11
packages/base-contract/tsconfig.json
Normal file
@@ -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"
|
||||||
|
]
|
||||||
|
}
|
3
packages/base-contract/tslint.json
Normal file
3
packages/base-contract/tslint.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": ["@0xproject/tslint-config"]
|
||||||
|
}
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "chai-as-promised-typescript-typings",
|
"name": "chai-as-promised-typescript-typings",
|
||||||
"version": "0.0.9",
|
"version": "0.0.10",
|
||||||
"description": "Typescript type definitions for chai-as-promised",
|
"description": "Typescript type definitions for chai-as-promised",
|
||||||
"main": "index.d.ts",
|
"main": "index.d.ts",
|
||||||
"types": "index.d.ts",
|
"types": "index.d.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/0xProject/0x.js.git"
|
"url": "git+https://github.com/0xProject/0x-monorepo.git"
|
||||||
},
|
},
|
||||||
"author": "Fabio Berger",
|
"author": "Fabio Berger",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
],
|
],
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bugs": {
|
"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": {
|
"dependencies": {
|
||||||
"chai-typescript-typings": "^0.0.3"
|
"chai-typescript-typings": "^0.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "chai-typescript-typings",
|
"name": "chai-typescript-typings",
|
||||||
"version": "0.0.3",
|
"version": "0.0.4",
|
||||||
"description": "Typescript type definitions for chai",
|
"description": "Typescript type definitions for chai",
|
||||||
"main": "index.d.ts",
|
"main": "index.d.ts",
|
||||||
"types": "index.d.ts",
|
"types": "index.d.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/0xProject/0x.js.git"
|
"url": "git+https://github.com/0xProject/0x-monorepo.git"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bugs": {
|
"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"
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,14 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.6.2 - _February 16, 2018_
|
||||||
|
|
||||||
|
* Fix JSON parse empty response (#407)
|
||||||
|
|
||||||
|
## v0.6.0 - _February 16, 2018_
|
||||||
|
|
||||||
|
* Add pagination options to HttpClient methods (#393)
|
||||||
|
* Add heartbeat configuration to WebSocketOrderbookChannel constructor (#406)
|
||||||
|
|
||||||
## v0.5.7 - _February 9, 2018_
|
## v0.5.7 - _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)
|
||||||
|
@@ -8,10 +8,18 @@ This repository contains a Javascript library that makes it easy to interact wit
|
|||||||
yarn add @0xproject/connect
|
yarn add @0xproject/connect
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
|
||||||
|
|
||||||
|
```
|
||||||
|
"include": [
|
||||||
|
"./node_modules/web3-typescript-typings/index.d.ts",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
* [Docs](https://0xproject.com/docs/connect)
|
* [Docs](https://0xproject.com/docs/connect)
|
||||||
* [Tutorials](https://0xproject.com/wiki#connect)
|
* [Tutorials](https://0xproject.com/wiki#connect)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/connect",
|
"name": "@0xproject/connect",
|
||||||
"version": "0.5.7",
|
"version": "0.6.3",
|
||||||
"description": "A javascript library for interacting with the standard relayer api",
|
"description": "A javascript library for interacting with the standard relayer api",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"connect",
|
"connect",
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"build:watch": "tsc -w",
|
"build:watch": "tsc -w",
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"clean": "shx rm -rf _bundles lib test_temp",
|
"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",
|
"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",
|
"copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
|
||||||
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js.git"
|
"url": "https://github.com/0xProject/0x-monorepo.git"
|
||||||
},
|
},
|
||||||
"author": "Brandon Millman",
|
"author": "Brandon Millman",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -33,20 +33,20 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"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": {
|
"dependencies": {
|
||||||
"@0xproject/assert": "^0.0.18",
|
"@0xproject/assert": "^0.2.0",
|
||||||
"@0xproject/json-schemas": "^0.7.10",
|
"@0xproject/json-schemas": "^0.7.14",
|
||||||
"@0xproject/utils": "^0.3.2",
|
"@0xproject/utils": "^0.4.1",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"query-string": "^5.0.1",
|
"query-string": "^5.0.1",
|
||||||
"websocket": "^1.0.25"
|
"websocket": "^1.0.25"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.4.8",
|
"@0xproject/tslint-config": "^0.4.10",
|
||||||
"@types/fetch-mock": "^5.12.1",
|
"@types/fetch-mock": "^5.12.1",
|
||||||
"@types/lodash": "^4.14.86",
|
"@types/lodash": "^4.14.86",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
@@ -54,8 +54,8 @@
|
|||||||
"@types/websocket": "^0.0.34",
|
"@types/websocket": "^0.0.34",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
"chai-as-promised": "^7.1.0",
|
"chai-as-promised": "^7.1.0",
|
||||||
"chai-as-promised-typescript-typings": "^0.0.9",
|
"chai-as-promised-typescript-typings": "^0.0.10",
|
||||||
"chai-typescript-typings": "^0.0.3",
|
"chai-typescript-typings": "^0.0.4",
|
||||||
"copyfiles": "^1.2.0",
|
"copyfiles": "^1.2.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"fetch-mock": "^5.13.1",
|
"fetch-mock": "^5.13.1",
|
||||||
@@ -65,6 +65,6 @@
|
|||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"typedoc": "~0.8.0",
|
"typedoc": "~0.8.0",
|
||||||
"typescript": "2.7.1",
|
"typescript": "2.7.1",
|
||||||
"web3-typescript-typings": "^0.9.10"
|
"web3-typescript-typings": "^0.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,16 @@
|
|||||||
const execAsync = require('async-child-process').execAsync;
|
const execAsync = require('async-child-process').execAsync;
|
||||||
const postpublish_utils = require('../../../scripts/postpublish_utils');
|
const postpublish_utils = require('../../../scripts/postpublish_utils');
|
||||||
const packageJSON = require('../package.json');
|
const packageJSON = require('../package.json');
|
||||||
|
const tsConfig = require('../tsconfig.json');
|
||||||
|
|
||||||
const cwd = __dirname + '/..';
|
const cwd = __dirname + '/..';
|
||||||
const subPackageName = packageJSON.name;
|
const subPackageName = packageJSON.name;
|
||||||
const S3BucketPath = 's3://connect-docs-jsons/';
|
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 tag;
|
||||||
let version;
|
let version;
|
||||||
@@ -14,12 +20,12 @@ postpublish_utils
|
|||||||
tag = result.tag;
|
tag = result.tag;
|
||||||
version = result.version;
|
version = result.version;
|
||||||
const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
|
const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
|
||||||
return postpublish_utils.publishReleaseNotes(tag, releaseName);
|
return postpublish_utils.publishReleaseNotesAsync(tag, releaseName);
|
||||||
})
|
})
|
||||||
.then(function(release) {
|
.then(function(release) {
|
||||||
console.log('POSTPUBLISH: Release successful, generating docs...');
|
console.log('POSTPUBLISH: Release successful, generating docs...');
|
||||||
const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
|
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,
|
cwd,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
30
packages/connect/scripts/stagedocs.js
Normal file
30
packages/connect/scripts/stagedocs.js
Normal file
@@ -0,0 +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_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,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
@@ -13,59 +13,88 @@ import {
|
|||||||
HttpRequestType,
|
HttpRequestType,
|
||||||
OrderbookRequest,
|
OrderbookRequest,
|
||||||
OrderbookResponse,
|
OrderbookResponse,
|
||||||
OrdersRequest,
|
OrdersRequestOpts,
|
||||||
|
PagedRequestOpts,
|
||||||
SignedOrder,
|
SignedOrder,
|
||||||
TokenPairsItem,
|
TokenPairsItem,
|
||||||
TokenPairsRequest,
|
TokenPairsRequestOpts,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
|
import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
|
||||||
|
|
||||||
const TRAILING_SLASHES_REGEX = /\/+$/;
|
const TRAILING_SLASHES_REGEX = /\/+$/;
|
||||||
|
const DEFAULT_PAGED_REQUEST_OPTS: PagedRequestOpts = {
|
||||||
|
page: 1,
|
||||||
|
perPage: 100,
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* This mapping defines how an option property name gets converted into an HTTP request query field
|
||||||
|
*/
|
||||||
|
const OPTS_TO_QUERY_FIELD_MAP = {
|
||||||
|
perPage: 'per_page',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes all the functionality related to interacting with a set of HTTP endpoints
|
* This class includes all the functionality related to interacting with a set of HTTP endpoints
|
||||||
* that implement the standard relayer API v0
|
* that implement the standard relayer API v0
|
||||||
*/
|
*/
|
||||||
export class HttpClient implements Client {
|
export class HttpClient implements Client {
|
||||||
private _apiEndpointUrl: string;
|
private _apiEndpointUrl: string;
|
||||||
|
/**
|
||||||
|
* Format parameters to be appended to http requests into query string form
|
||||||
|
*/
|
||||||
|
private static _buildQueryStringFromHttpParams(params?: object): string {
|
||||||
|
// if params are undefined or empty, return an empty string
|
||||||
|
if (_.isUndefined(params) || _.isEmpty(params)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// format params into a form the api expects
|
||||||
|
const formattedParams = _.mapKeys(params, (value: any, key: string) => {
|
||||||
|
return _.get(OPTS_TO_QUERY_FIELD_MAP, key, key);
|
||||||
|
});
|
||||||
|
// stringify the formatted object
|
||||||
|
const stringifiedParams = queryString.stringify(formattedParams);
|
||||||
|
return `?${stringifiedParams}`;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Instantiates a new HttpClient instance
|
* Instantiates a new HttpClient instance
|
||||||
* @param url The relayer API base HTTP url you would like to interact with
|
* @param url The relayer API base HTTP url you would like to interact with
|
||||||
* @return An instance of HttpClient
|
* @return An instance of HttpClient
|
||||||
*/
|
*/
|
||||||
constructor(url: string) {
|
constructor(url: string) {
|
||||||
assert.isHttpUrl('url', url);
|
assert.isWebUri('url', url);
|
||||||
this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
|
this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieve token pair info from the API
|
* Retrieve token pair info from the API
|
||||||
* @param request A TokenPairsRequest instance describing specific token information
|
* @param requestOpts Options specifying token information to retrieve and page information, defaults to { page: 1, perPage: 100 }
|
||||||
* to retrieve
|
|
||||||
* @return The resulting TokenPairsItems that match the request
|
* @return The resulting TokenPairsItems that match the request
|
||||||
*/
|
*/
|
||||||
public async getTokenPairsAsync(request?: TokenPairsRequest): Promise<TokenPairsItem[]> {
|
public async getTokenPairsAsync(requestOpts?: TokenPairsRequestOpts & PagedRequestOpts): Promise<TokenPairsItem[]> {
|
||||||
if (!_.isUndefined(request)) {
|
if (!_.isUndefined(requestOpts)) {
|
||||||
assert.doesConformToSchema('request', request, clientSchemas.relayerTokenPairsRequestSchema);
|
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.tokenPairsRequestOptsSchema);
|
||||||
|
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||||
}
|
}
|
||||||
const requestOpts = {
|
const httpRequestOpts = {
|
||||||
params: request,
|
params: _.defaults({}, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
|
||||||
};
|
};
|
||||||
const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
|
const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, httpRequestOpts);
|
||||||
const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
|
const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
|
||||||
return tokenPairs;
|
return tokenPairs;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieve orders from the API
|
* Retrieve orders from the API
|
||||||
* @param request An OrdersRequest instance describing specific orders to retrieve
|
* @param requestOpts Options specifying orders to retrieve and page information, defaults to { page: 1, perPage: 100 }
|
||||||
* @return The resulting SignedOrders that match the request
|
* @return The resulting SignedOrders that match the request
|
||||||
*/
|
*/
|
||||||
public async getOrdersAsync(request?: OrdersRequest): Promise<SignedOrder[]> {
|
public async getOrdersAsync(requestOpts?: OrdersRequestOpts & PagedRequestOpts): Promise<SignedOrder[]> {
|
||||||
if (!_.isUndefined(request)) {
|
if (!_.isUndefined(requestOpts)) {
|
||||||
assert.doesConformToSchema('request', request, clientSchemas.relayerOrdersRequestSchema);
|
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.ordersRequestOptsSchema);
|
||||||
|
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||||
}
|
}
|
||||||
const requestOpts = {
|
const httpRequestOpts = {
|
||||||
params: request,
|
params: _.defaults({}, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
|
||||||
};
|
};
|
||||||
const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, requestOpts);
|
const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, httpRequestOpts);
|
||||||
const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
|
const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
|
||||||
return orders;
|
return orders;
|
||||||
}
|
}
|
||||||
@@ -82,15 +111,22 @@ export class HttpClient implements Client {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieve an orderbook from the API
|
* Retrieve an orderbook from the API
|
||||||
* @param request An OrderbookRequest instance describing the specific orderbook to retrieve
|
* @param request An OrderbookRequest instance describing the specific orderbook to retrieve
|
||||||
|
* @param requestOpts Options specifying page information, defaults to { page: 1, perPage: 100 }
|
||||||
* @return The resulting OrderbookResponse that matches the request
|
* @return The resulting OrderbookResponse that matches the request
|
||||||
*/
|
*/
|
||||||
public async getOrderbookAsync(request: OrderbookRequest): Promise<OrderbookResponse> {
|
public async getOrderbookAsync(
|
||||||
assert.doesConformToSchema('request', request, clientSchemas.relayerOrderBookRequestSchema);
|
request: OrderbookRequest,
|
||||||
const requestOpts = {
|
requestOpts?: PagedRequestOpts,
|
||||||
params: request,
|
): Promise<OrderbookResponse> {
|
||||||
|
assert.doesConformToSchema('request', request, clientSchemas.orderBookRequestSchema);
|
||||||
|
if (!_.isUndefined(requestOpts)) {
|
||||||
|
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||||
|
}
|
||||||
|
const httpRequestOpts = {
|
||||||
|
params: _.defaults({}, request, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
|
||||||
};
|
};
|
||||||
const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, requestOpts);
|
const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, httpRequestOpts);
|
||||||
const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
|
const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
|
||||||
return orderbook;
|
return orderbook;
|
||||||
}
|
}
|
||||||
@@ -100,11 +136,11 @@ export class HttpClient implements Client {
|
|||||||
* @return The resulting FeesResponse that matches the request
|
* @return The resulting FeesResponse that matches the request
|
||||||
*/
|
*/
|
||||||
public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
|
public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
|
||||||
assert.doesConformToSchema('request', request, schemas.relayerApiFeesPayloadSchema);
|
assert.doesConformToSchema('request', request, clientSchemas.feesRequestSchema);
|
||||||
const requestOpts = {
|
const httpRequestOpts = {
|
||||||
payload: request,
|
payload: request,
|
||||||
};
|
};
|
||||||
const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, requestOpts);
|
const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, httpRequestOpts);
|
||||||
const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
|
const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
|
||||||
return fees;
|
return fees;
|
||||||
}
|
}
|
||||||
@@ -126,11 +162,7 @@ export class HttpClient implements Client {
|
|||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const params = _.get(requestOptions, 'params');
|
const params = _.get(requestOptions, 'params');
|
||||||
const payload = _.get(requestOptions, 'payload');
|
const payload = _.get(requestOptions, 'payload');
|
||||||
let query = '';
|
const query = HttpClient._buildQueryStringFromHttpParams(params);
|
||||||
if (!_.isUndefined(params) && !_.isEmpty(params)) {
|
|
||||||
const stringifiedParams = queryString.stringify(params);
|
|
||||||
query = `?${stringifiedParams}`;
|
|
||||||
}
|
|
||||||
const url = `${this._apiEndpointUrl}${path}${query}`;
|
const url = `${this._apiEndpointUrl}${path}${query}`;
|
||||||
const headers = new Headers({
|
const headers = new Headers({
|
||||||
'content-type': 'application/json',
|
'content-type': 'application/json',
|
||||||
@@ -140,13 +172,12 @@ export class HttpClient implements Client {
|
|||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
headers,
|
headers,
|
||||||
});
|
});
|
||||||
const json = await response.json();
|
const text = await response.text();
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${JSON.stringify(
|
const errorString = `${response.status} - ${response.statusText}\n${requestType} ${url}\n${text}`;
|
||||||
json,
|
|
||||||
)}`;
|
|
||||||
throw Error(errorString);
|
throw Error(errorString);
|
||||||
}
|
}
|
||||||
return json;
|
const result = !_.isEmpty(text) ? JSON.parse(text) : undefined;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,9 +11,11 @@ export {
|
|||||||
OrderbookChannelSubscriptionOpts,
|
OrderbookChannelSubscriptionOpts,
|
||||||
OrderbookRequest,
|
OrderbookRequest,
|
||||||
OrderbookResponse,
|
OrderbookResponse,
|
||||||
OrdersRequest,
|
OrdersRequestOpts,
|
||||||
|
PagedRequestOpts,
|
||||||
SignedOrder,
|
SignedOrder,
|
||||||
TokenPairsItem,
|
TokenPairsItem,
|
||||||
TokenPairsRequest,
|
TokenPairsRequestOpts,
|
||||||
TokenTradeInfo,
|
TokenTradeInfo,
|
||||||
|
WebSocketOrderbookChannelConfig,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
26
packages/connect/src/schemas/fees_request_schema.ts
Normal file
26
packages/connect/src/schemas/fees_request_schema.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
export const feesRequestSchema = {
|
||||||
|
id: '/FeesRequest',
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
exchangeContractAddress: { $ref: '/Address' },
|
||||||
|
maker: { $ref: '/Address' },
|
||||||
|
taker: { $ref: '/Address' },
|
||||||
|
makerTokenAddress: { $ref: '/Address' },
|
||||||
|
takerTokenAddress: { $ref: '/Address' },
|
||||||
|
makerTokenAmount: { $ref: '/Number' },
|
||||||
|
takerTokenAmount: { $ref: '/Number' },
|
||||||
|
expirationUnixTimestampSec: { $ref: '/Number' },
|
||||||
|
salt: { $ref: '/Number' },
|
||||||
|
},
|
||||||
|
required: [
|
||||||
|
'exchangeContractAddress',
|
||||||
|
'maker',
|
||||||
|
'taker',
|
||||||
|
'makerTokenAddress',
|
||||||
|
'takerTokenAddress',
|
||||||
|
'makerTokenAmount',
|
||||||
|
'takerTokenAmount',
|
||||||
|
'expirationUnixTimestampSec',
|
||||||
|
'salt',
|
||||||
|
],
|
||||||
|
};
|
@@ -1,8 +1,9 @@
|
|||||||
export const relayerOrderBookRequestSchema = {
|
export const orderBookRequestSchema = {
|
||||||
id: '/RelayerOrderBookRequest',
|
id: '/OrderBookRequest',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
baseTokenAddress: { $ref: '/Address' },
|
baseTokenAddress: { $ref: '/Address' },
|
||||||
quoteTokenAddress: { $ref: '/Address' },
|
quoteTokenAddress: { $ref: '/Address' },
|
||||||
},
|
},
|
||||||
|
required: ['baseTokenAddress', 'quoteTokenAddress'],
|
||||||
};
|
};
|
@@ -1,5 +1,5 @@
|
|||||||
export const relayerOrdersRequestSchema = {
|
export const ordersRequestOptsSchema = {
|
||||||
id: '/RelayerOrdersRequest',
|
id: '/OrdersRequestOpts',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
exchangeContractAddress: { $ref: '/Address' },
|
exchangeContractAddress: { $ref: '/Address' },
|
@@ -0,0 +1,8 @@
|
|||||||
|
export const pagedRequestOptsSchema = {
|
||||||
|
id: '/PagedRequestOpts',
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
page: { type: 'number' },
|
||||||
|
perPage: { type: 'number' },
|
||||||
|
},
|
||||||
|
};
|
@@ -1,8 +0,0 @@
|
|||||||
export const relayerOrderBookRequestSchema = {
|
|
||||||
id: '/RelayerOrderBookRequest',
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
baseTokenAddress: { $ref: '/Address' },
|
|
||||||
quoteTokenAddress: { $ref: '/Address' },
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,9 +1,15 @@
|
|||||||
import { relayerOrderBookRequestSchema } from './relayer_orderbook_request_schema';
|
import { feesRequestSchema } from './fees_request_schema';
|
||||||
import { relayerOrdersRequestSchema } from './relayer_orders_request_schema';
|
import { orderBookRequestSchema } from './orderbook_request_schema';
|
||||||
import { relayerTokenPairsRequestSchema } from './relayer_token_pairs_request_schema';
|
import { ordersRequestOptsSchema } from './orders_request_opts_schema';
|
||||||
|
import { pagedRequestOptsSchema } from './paged_request_opts_schema';
|
||||||
|
import { tokenPairsRequestOptsSchema } from './token_pairs_request_opts_schema';
|
||||||
|
import { webSocketOrderbookChannelConfigSchema } from './websocket_orderbook_channel_config_schema';
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
relayerOrderBookRequestSchema,
|
feesRequestSchema,
|
||||||
relayerOrdersRequestSchema,
|
orderBookRequestSchema,
|
||||||
relayerTokenPairsRequestSchema,
|
ordersRequestOptsSchema,
|
||||||
|
pagedRequestOptsSchema,
|
||||||
|
tokenPairsRequestOptsSchema,
|
||||||
|
webSocketOrderbookChannelConfigSchema,
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
export const relayerTokenPairsRequestSchema = {
|
export const tokenPairsRequestOptsSchema = {
|
||||||
id: '/RelayerTokenPairsRequest',
|
id: '/TokenPairsRequestOpts',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
tokenA: { $ref: '/Address' },
|
tokenA: { $ref: '/Address' },
|
@@ -0,0 +1,10 @@
|
|||||||
|
export const webSocketOrderbookChannelConfigSchema = {
|
||||||
|
id: '/WebSocketOrderbookChannelConfig',
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
heartbeatIntervalMs: {
|
||||||
|
type: 'number',
|
||||||
|
minimum: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@@ -30,10 +30,10 @@ export interface ECSignature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Client {
|
export interface Client {
|
||||||
getTokenPairsAsync: (request?: TokenPairsRequest) => Promise<TokenPairsItem[]>;
|
getTokenPairsAsync: (requestOpts?: TokenPairsRequestOpts & PagedRequestOpts) => Promise<TokenPairsItem[]>;
|
||||||
getOrdersAsync: (request?: OrdersRequest) => Promise<SignedOrder[]>;
|
getOrdersAsync: (requestOpts?: OrdersRequestOpts & PagedRequestOpts) => Promise<SignedOrder[]>;
|
||||||
getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
|
getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
|
||||||
getOrderbookAsync: (request: OrderbookRequest) => Promise<OrderbookResponse>;
|
getOrderbookAsync: (request: OrderbookRequest, requestOpts?: PagedRequestOpts) => Promise<OrderbookResponse>;
|
||||||
getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
|
getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
|
||||||
submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
|
submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
|
||||||
}
|
}
|
||||||
@@ -43,6 +43,13 @@ export interface OrderbookChannel {
|
|||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* heartbeatInterval: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
|
||||||
|
*/
|
||||||
|
export interface WebSocketOrderbookChannelConfig {
|
||||||
|
heartbeatIntervalMs?: number;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price
|
* baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price
|
||||||
* quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price
|
* quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price
|
||||||
@@ -111,7 +118,7 @@ export enum WebsocketClientEventType {
|
|||||||
ConnectFailed = 'connectFailed',
|
ConnectFailed = 'connectFailed',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TokenPairsRequest {
|
export interface TokenPairsRequestOpts {
|
||||||
tokenA?: string;
|
tokenA?: string;
|
||||||
tokenB?: string;
|
tokenB?: string;
|
||||||
}
|
}
|
||||||
@@ -128,7 +135,7 @@ export interface TokenTradeInfo {
|
|||||||
precision: number;
|
precision: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OrdersRequest {
|
export interface OrdersRequestOpts {
|
||||||
exchangeContractAddress?: string;
|
exchangeContractAddress?: string;
|
||||||
tokenAddress?: string;
|
tokenAddress?: string;
|
||||||
makerTokenAddress?: string;
|
makerTokenAddress?: string;
|
||||||
@@ -167,6 +174,11 @@ export interface FeesResponse {
|
|||||||
takerFee: BigNumber;
|
takerFee: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PagedRequestOpts {
|
||||||
|
page?: number;
|
||||||
|
perPage?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface HttpRequestOptions {
|
export interface HttpRequestOptions {
|
||||||
params?: object;
|
params?: object;
|
||||||
payload?: object;
|
payload?: object;
|
||||||
|
@@ -3,6 +3,7 @@ import { schemas } from '@0xproject/json-schemas';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as WebSocket from 'websocket';
|
import * as WebSocket from 'websocket';
|
||||||
|
|
||||||
|
import { schemas as clientSchemas } from './schemas/schemas';
|
||||||
import {
|
import {
|
||||||
OrderbookChannel,
|
OrderbookChannel,
|
||||||
OrderbookChannelHandler,
|
OrderbookChannelHandler,
|
||||||
@@ -10,9 +11,13 @@ import {
|
|||||||
OrderbookChannelSubscriptionOpts,
|
OrderbookChannelSubscriptionOpts,
|
||||||
WebsocketClientEventType,
|
WebsocketClientEventType,
|
||||||
WebsocketConnectionEventType,
|
WebsocketConnectionEventType,
|
||||||
|
WebSocketOrderbookChannelConfig,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
|
import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
|
||||||
|
|
||||||
|
const DEFAULT_HEARTBEAT_INTERVAL_MS = 15000;
|
||||||
|
const MINIMUM_HEARTBEAT_INTERVAL_MS = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes all the functionality related to interacting with a websocket endpoint
|
* This class includes all the functionality related to interacting with a websocket endpoint
|
||||||
* that implements the standard relayer API v0
|
* that implements the standard relayer API v0
|
||||||
@@ -21,15 +26,25 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
|
|||||||
private _apiEndpointUrl: string;
|
private _apiEndpointUrl: string;
|
||||||
private _client: WebSocket.client;
|
private _client: WebSocket.client;
|
||||||
private _connectionIfExists?: WebSocket.connection;
|
private _connectionIfExists?: WebSocket.connection;
|
||||||
|
private _heartbeatTimerIfExists?: NodeJS.Timer;
|
||||||
private _subscriptionCounter = 0;
|
private _subscriptionCounter = 0;
|
||||||
|
private _heartbeatIntervalMs: number;
|
||||||
/**
|
/**
|
||||||
* Instantiates a new WebSocketOrderbookChannel instance
|
* Instantiates a new WebSocketOrderbookChannel instance
|
||||||
* @param url The relayer API base WS url you would like to interact with
|
* @param url The relayer API base WS url you would like to interact with
|
||||||
|
* @param config The configuration object. Look up the type for the description.
|
||||||
* @return An instance of WebSocketOrderbookChannel
|
* @return An instance of WebSocketOrderbookChannel
|
||||||
*/
|
*/
|
||||||
constructor(url: string) {
|
constructor(url: string, config?: WebSocketOrderbookChannelConfig) {
|
||||||
assert.isUri('url', url);
|
assert.isUri('url', url);
|
||||||
|
if (!_.isUndefined(config)) {
|
||||||
|
assert.doesConformToSchema('config', config, clientSchemas.webSocketOrderbookChannelConfigSchema);
|
||||||
|
}
|
||||||
this._apiEndpointUrl = url;
|
this._apiEndpointUrl = url;
|
||||||
|
this._heartbeatIntervalMs =
|
||||||
|
_.isUndefined(config) || _.isUndefined(config.heartbeatIntervalMs)
|
||||||
|
? DEFAULT_HEARTBEAT_INTERVAL_MS
|
||||||
|
: config.heartbeatIntervalMs;
|
||||||
this._client = new WebSocket.client();
|
this._client = new WebSocket.client();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -63,7 +78,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
|
|||||||
connection.on(WebsocketConnectionEventType.Error, wsError => {
|
connection.on(WebsocketConnectionEventType.Error, wsError => {
|
||||||
handler.onError(this, subscriptionOpts, wsError);
|
handler.onError(this, subscriptionOpts, wsError);
|
||||||
});
|
});
|
||||||
connection.on(WebsocketConnectionEventType.Close, () => {
|
connection.on(WebsocketConnectionEventType.Close, (code: number, desc: string) => {
|
||||||
handler.onClose(this, subscriptionOpts);
|
handler.onClose(this, subscriptionOpts);
|
||||||
});
|
});
|
||||||
connection.on(WebsocketConnectionEventType.Message, message => {
|
connection.on(WebsocketConnectionEventType.Message, message => {
|
||||||
@@ -80,6 +95,9 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
|
|||||||
if (!_.isUndefined(this._connectionIfExists)) {
|
if (!_.isUndefined(this._connectionIfExists)) {
|
||||||
this._connectionIfExists.close();
|
this._connectionIfExists.close();
|
||||||
}
|
}
|
||||||
|
if (!_.isUndefined(this._heartbeatTimerIfExists)) {
|
||||||
|
clearInterval(this._heartbeatTimerIfExists);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
|
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
|
||||||
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
|
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
|
||||||
@@ -87,6 +105,20 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
|
|||||||
} else {
|
} else {
|
||||||
this._client.on(WebsocketClientEventType.Connect, connection => {
|
this._client.on(WebsocketClientEventType.Connect, connection => {
|
||||||
this._connectionIfExists = connection;
|
this._connectionIfExists = connection;
|
||||||
|
if (this._heartbeatIntervalMs >= MINIMUM_HEARTBEAT_INTERVAL_MS) {
|
||||||
|
this._heartbeatTimerIfExists = setInterval(() => {
|
||||||
|
connection.ping('');
|
||||||
|
}, this._heartbeatIntervalMs);
|
||||||
|
} else {
|
||||||
|
callback(
|
||||||
|
new Error(
|
||||||
|
`Heartbeat interval is ${
|
||||||
|
this._heartbeatIntervalMs
|
||||||
|
}ms which is less than the required minimum of ${MINIMUM_HEARTBEAT_INTERVAL_MS}ms`,
|
||||||
|
),
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
}
|
||||||
callback(undefined, this._connectionIfExists);
|
callback(undefined, this._connectionIfExists);
|
||||||
});
|
});
|
||||||
this._client.on(WebsocketClientEventType.ConnectFailed, error => {
|
this._client.on(WebsocketClientEventType.ConnectFailed, error => {
|
||||||
|
@@ -40,19 +40,22 @@ describe('HttpClient', () => {
|
|||||||
});
|
});
|
||||||
describe('#getTokenPairsAsync', () => {
|
describe('#getTokenPairsAsync', () => {
|
||||||
const url = `${relayUrl}/token_pairs`;
|
const url = `${relayUrl}/token_pairs`;
|
||||||
it('gets token pairs', async () => {
|
it('gets token pairs with default options when none are provided', async () => {
|
||||||
fetchMock.get(url, tokenPairsResponseJSON);
|
const urlWithQuery = `${url}?page=1&per_page=100`;
|
||||||
|
fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
|
||||||
const tokenPairs = await relayerClient.getTokenPairsAsync();
|
const tokenPairs = await relayerClient.getTokenPairsAsync();
|
||||||
expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
|
expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
|
||||||
});
|
});
|
||||||
it('gets specific token pairs for request', async () => {
|
it('gets token pairs with specified request options', async () => {
|
||||||
const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
|
const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
|
||||||
const tokenPairsRequest = {
|
const tokenPairsRequestOpts = {
|
||||||
tokenA: tokenAddress,
|
tokenA: tokenAddress,
|
||||||
|
page: 3,
|
||||||
|
perPage: 50,
|
||||||
};
|
};
|
||||||
const urlWithQuery = `${url}?tokenA=${tokenAddress}`;
|
const urlWithQuery = `${url}?page=3&per_page=50&tokenA=${tokenAddress}`;
|
||||||
fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
|
fetchMock.get(urlWithQuery, tokenPairsResponseJSON);
|
||||||
const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequest);
|
const tokenPairs = await relayerClient.getTokenPairsAsync(tokenPairsRequestOpts);
|
||||||
expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
|
expect(tokenPairs).to.be.deep.equal(tokenPairsResponse);
|
||||||
});
|
});
|
||||||
it('throws an error for invalid JSON response', async () => {
|
it('throws an error for invalid JSON response', async () => {
|
||||||
@@ -62,17 +65,20 @@ describe('HttpClient', () => {
|
|||||||
});
|
});
|
||||||
describe('#getOrdersAsync', () => {
|
describe('#getOrdersAsync', () => {
|
||||||
const url = `${relayUrl}/orders`;
|
const url = `${relayUrl}/orders`;
|
||||||
it('gets orders', async () => {
|
it('gets orders with default options when none are provided', async () => {
|
||||||
fetchMock.get(url, ordersResponseJSON);
|
const urlWithQuery = `${url}?page=1&per_page=100`;
|
||||||
|
fetchMock.get(urlWithQuery, ordersResponseJSON);
|
||||||
const orders = await relayerClient.getOrdersAsync();
|
const orders = await relayerClient.getOrdersAsync();
|
||||||
expect(orders).to.be.deep.equal(ordersResponse);
|
expect(orders).to.be.deep.equal(ordersResponse);
|
||||||
});
|
});
|
||||||
it('gets specific orders for request', async () => {
|
it('gets orders with specified request options', async () => {
|
||||||
const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
|
const tokenAddress = '0x323b5d4c32345ced77393b3530b1eed0f346429d';
|
||||||
const ordersRequest = {
|
const ordersRequest = {
|
||||||
tokenAddress,
|
tokenAddress,
|
||||||
|
page: 3,
|
||||||
|
perPage: 50,
|
||||||
};
|
};
|
||||||
const urlWithQuery = `${url}?tokenAddress=${tokenAddress}`;
|
const urlWithQuery = `${url}?page=3&per_page=50&tokenAddress=${tokenAddress}`;
|
||||||
fetchMock.get(urlWithQuery, ordersResponseJSON);
|
fetchMock.get(urlWithQuery, ordersResponseJSON);
|
||||||
const orders = await relayerClient.getOrdersAsync(ordersRequest);
|
const orders = await relayerClient.getOrdersAsync(ordersRequest);
|
||||||
expect(orders).to.be.deep.equal(ordersResponse);
|
expect(orders).to.be.deep.equal(ordersResponse);
|
||||||
@@ -100,14 +106,27 @@ describe('HttpClient', () => {
|
|||||||
baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
|
baseTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
|
||||||
quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
|
quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
|
||||||
};
|
};
|
||||||
const url = `${relayUrl}/orderbook?baseTokenAddress=${request.baseTokenAddress}"eTokenAddress=${
|
const url = `${relayUrl}/orderbook`;
|
||||||
request.quoteTokenAddress
|
it('gets orderbook with default page options when none are provided', async () => {
|
||||||
}`;
|
const urlWithQuery = `${url}?baseTokenAddress=${
|
||||||
it('gets order book', async () => {
|
request.baseTokenAddress
|
||||||
fetchMock.get(url, orderbookJSON);
|
}&page=1&per_page=100"eTokenAddress=${request.quoteTokenAddress}`;
|
||||||
|
fetchMock.get(urlWithQuery, orderbookJSON);
|
||||||
const orderbook = await relayerClient.getOrderbookAsync(request);
|
const orderbook = await relayerClient.getOrderbookAsync(request);
|
||||||
expect(orderbook).to.be.deep.equal(orderbookResponse);
|
expect(orderbook).to.be.deep.equal(orderbookResponse);
|
||||||
});
|
});
|
||||||
|
it('gets orderbook with specified page options', async () => {
|
||||||
|
const urlWithQuery = `${url}?baseTokenAddress=${
|
||||||
|
request.baseTokenAddress
|
||||||
|
}&page=3&per_page=50"eTokenAddress=${request.quoteTokenAddress}`;
|
||||||
|
fetchMock.get(urlWithQuery, orderbookJSON);
|
||||||
|
const pagedRequestOptions = {
|
||||||
|
page: 3,
|
||||||
|
perPage: 50,
|
||||||
|
};
|
||||||
|
const orderbook = await relayerClient.getOrderbookAsync(request, pagedRequestOptions);
|
||||||
|
expect(orderbook).to.be.deep.equal(orderbookResponse);
|
||||||
|
});
|
||||||
it('throws an error for invalid JSON response', async () => {
|
it('throws an error for invalid JSON response', async () => {
|
||||||
fetchMock.get(url, { test: 'dummy' });
|
fetchMock.get(url, { test: 'dummy' });
|
||||||
expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
|
expect(relayerClient.getOrderbookAsync(request)).to.be.rejected();
|
||||||
|
@@ -1,15 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
* This file is auto-generated using abi-gen. Don't edit directly.
|
* 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:no-consecutive-blank-lines
|
||||||
// tslint:disable-next-line:no-unused-variable
|
// tslint:disable-next-line:no-unused-variable
|
||||||
|
import { BaseContract } from '@0xproject/base-contract';
|
||||||
import { TxData, TxDataPayable } from '@0xproject/types';
|
import { TxData, TxDataPayable } from '@0xproject/types';
|
||||||
import { BigNumber, classUtils, promisify } from '@0xproject/utils';
|
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 * as Web3 from 'web3';
|
||||||
|
|
||||||
import {BaseContract} from './base_contract';
|
|
||||||
|
|
||||||
{{#if events}}
|
{{#if events}}
|
||||||
export type {{contractName}}ContractEventArgs =
|
export type {{contractName}}ContractEventArgs =
|
||||||
{{#each events}}
|
{{#each events}}
|
||||||
@@ -28,6 +30,7 @@ export enum {{contractName}}Events {
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
// tslint:disable:no-parameter-reassignment
|
||||||
export class {{contractName}}Contract extends BaseContract {
|
export class {{contractName}}Contract extends BaseContract {
|
||||||
{{#each methods}}
|
{{#each methods}}
|
||||||
{{#this.constant}}
|
{{#this.constant}}
|
||||||
@@ -37,8 +40,8 @@ export class {{contractName}}Contract extends BaseContract {
|
|||||||
{{> tx contractName=../contractName}}
|
{{> tx contractName=../contractName}}
|
||||||
{{/this.constant}}
|
{{/this.constant}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial<TxData>) {
|
constructor(web3Wrapper: Web3Wrapper, abi: Web3.ContractAbi, address: string) {
|
||||||
super(web3ContractInstance, defaults);
|
super(web3Wrapper, abi, address);
|
||||||
classUtils.bindAll(this, ['_web3ContractInstance', '_defaults']);
|
classUtils.bindAll(this, ['_ethersInterface', 'address', 'abi', '_web3Wrapper']);
|
||||||
}
|
}
|
||||||
} // tslint:disable:max-file-line-count
|
} // tslint:disable:max-file-line-count
|
3
packages/contract_templates/partials/call.handlebars
Normal file
3
packages/contract_templates/partials/call.handlebars
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
public {{this.name}} = {
|
||||||
|
{{> callAsync}}
|
||||||
|
};
|
30
packages/contract_templates/partials/callAsync.handlebars
Normal file
30
packages/contract_templates/partials/callAsync.handlebars
Normal file
@@ -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}}
|
@@ -1,5 +1,5 @@
|
|||||||
export interface {{name}}ContractEventArgs {
|
export interface {{name}}ContractEventArgs {
|
||||||
{{#each inputs}}
|
{{#each inputs}}
|
||||||
{{name}}: {{#returnType type}}{{/returnType}};
|
{{name}}: {{#returnType type components}}{{/returnType}};
|
||||||
{{/each}}
|
{{/each}}
|
||||||
}
|
}
|
10
packages/contract_templates/partials/return_type.handlebars
Normal file
10
packages/contract_templates/partials/return_type.handlebars
Normal file
@@ -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}}
|
@@ -9,19 +9,22 @@ public {{this.name}} = {
|
|||||||
{{/this.payable}}
|
{{/this.payable}}
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const self = this as {{contractName}}Contract;
|
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(
|
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
|
||||||
txData,
|
{
|
||||||
|
...txData,
|
||||||
|
data: encodedData,
|
||||||
|
},
|
||||||
self.{{this.name}}.estimateGasAsync.bind(
|
self.{{this.name}}.estimateGasAsync.bind(
|
||||||
self,
|
self,
|
||||||
{{> params inputs=inputs}}
|
{{> params inputs=inputs}}
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const txHash = await promisify<string>(
|
const txHash = await this._web3Wrapper.sendTransactionAsync(txDataWithDefaults);
|
||||||
self._web3ContractInstance.{{this.name}}, self._web3ContractInstance,
|
|
||||||
)(
|
|
||||||
{{> params inputs=inputs}}
|
|
||||||
txDataWithDefaults,
|
|
||||||
);
|
|
||||||
return txHash;
|
return txHash;
|
||||||
},
|
},
|
||||||
async estimateGasAsync(
|
async estimateGasAsync(
|
||||||
@@ -29,15 +32,16 @@ public {{this.name}} = {
|
|||||||
txData: TxData = {},
|
txData: TxData = {},
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
const self = this as {{contractName}}Contract;
|
const self = this as {{contractName}}Contract;
|
||||||
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
|
const encodedData = this._ethersInterface.functions.{{this.name}}(
|
||||||
txData,
|
|
||||||
);
|
|
||||||
const gas = await promisify<number>(
|
|
||||||
self._web3ContractInstance.{{this.name}}.estimateGas, self._web3ContractInstance,
|
|
||||||
)(
|
|
||||||
{{> params inputs=inputs}}
|
{{> params inputs=inputs}}
|
||||||
txDataWithDefaults,
|
).data
|
||||||
|
const txDataWithDefaults = await self._applyDefaultsToTxDataAsync(
|
||||||
|
{
|
||||||
|
...txData,
|
||||||
|
data: encodedData,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
const gas = await this._web3Wrapper.estimateGasAsync(txDataWithDefaults);
|
||||||
return gas;
|
return gas;
|
||||||
},
|
},
|
||||||
getABIEncodedTransactionData(
|
getABIEncodedTransactionData(
|
||||||
@@ -45,7 +49,10 @@ public {{this.name}} = {
|
|||||||
txData: TxData = {},
|
txData: TxData = {},
|
||||||
): string {
|
): string {
|
||||||
const self = this as {{contractName}}Contract;
|
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;
|
return abiEncodedTransactionData;
|
||||||
},
|
},
|
||||||
|
{{> callAsync}}
|
||||||
};
|
};
|
@@ -0,0 +1,3 @@
|
|||||||
|
{{#each inputs}}
|
||||||
|
{{name}}: {{#parameterType type components}}{{/parameterType}},
|
||||||
|
{{/each}}
|
@@ -4,11 +4,11 @@ Smart contracts that implement the 0x protocol.
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
* [Docs](https://0xproject.com/docs/contracts)
|
* [Docs](https://0xproject.com/docs/contracts)
|
||||||
* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
|
* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
|
||||||
* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
|
* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
|
||||||
* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
|
* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
|
||||||
* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
|
* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
|
||||||
|
|
||||||
## Contributing
|
## 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.
|
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
|
```bash
|
||||||
cd ../..
|
cd ../..
|
||||||
|
@@ -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
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -1,3 +0,0 @@
|
|||||||
{{#each inputs}}
|
|
||||||
{{name}},
|
|
||||||
{{/each}}
|
|
@@ -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}}
|
|
@@ -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;
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,3 +0,0 @@
|
|||||||
{{#each inputs}}
|
|
||||||
{{name}}: {{#parameterType type}}{{/parameterType}},
|
|
||||||
{{/each}}
|
|
1
packages/contracts/globals.d.ts
vendored
1
packages/contracts/globals.d.ts
vendored
@@ -30,5 +30,6 @@ declare module 'web3-eth-abi' {
|
|||||||
|
|
||||||
declare module 'ethereumjs-abi' {
|
declare module 'ethereumjs-abi' {
|
||||||
const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
|
const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
|
||||||
|
const soliditySHA256: (argTypes: string[], args: any[]) => Buffer;
|
||||||
const methodID: (name: string, types: string[]) => Buffer;
|
const methodID: (name: string, types: string[]) => Buffer;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "contracts",
|
"name": "contracts",
|
||||||
"version": "2.1.11",
|
"version": "2.1.15",
|
||||||
"description": "Smart contract components of 0x protocol",
|
"description": "Smart contract components of 0x protocol",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -9,33 +9,35 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:watch": "tsc -w",
|
"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",
|
"copy_artifacts": "copyfiles './src/artifacts/**/*' ./lib",
|
||||||
"build": "tsc",
|
"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",
|
"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: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-dir src/contracts --artifacts-dir src/artifacts",
|
"compile": "node ../deployer/lib/src/cli.js compile --contracts ${npm_package_config_contracts} --contracts-dir src/contracts --artifacts-dir src/artifacts",
|
||||||
"clean": "rm -rf ./lib",
|
"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",
|
"migrate": "node ../deployer/lib/src/cli.js migrate",
|
||||||
"lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
|
"lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'",
|
||||||
"test:circleci": "yarn test"
|
"test:circleci": "yarn test"
|
||||||
},
|
},
|
||||||
|
"config": {
|
||||||
|
"contracts": "Exchange,DummyToken,ZRXToken,Token,WETH9,TokenTransferProxy,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,MaliciousToken,TokenRegistry,Arbitrage,EtherDelta,AccountLevels"
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js.git"
|
"url": "https://github.com/0xProject/0x-monorepo.git"
|
||||||
},
|
},
|
||||||
"author": "Amir Bandeali",
|
"author": "Amir Bandeali",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bugs": {
|
"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": {
|
"devDependencies": {
|
||||||
"@0xproject/dev-utils": "^0.0.12",
|
"@0xproject/dev-utils": "^0.2.1",
|
||||||
"@0xproject/tslint-config": "^0.4.8",
|
"@0xproject/tslint-config": "^0.4.10",
|
||||||
"@0xproject/types": "^0.2.1",
|
|
||||||
"@types/bluebird": "^3.5.3",
|
"@types/bluebird": "^3.5.3",
|
||||||
"@types/lodash": "^4.14.86",
|
"@types/lodash": "^4.14.86",
|
||||||
"@types/node": "^8.0.53",
|
"@types/node": "^8.0.53",
|
||||||
@@ -43,31 +45,35 @@
|
|||||||
"@types/yargs": "^10.0.0",
|
"@types/yargs": "^10.0.0",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
"chai-as-promised": "^7.1.0",
|
"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-bignumber": "^2.0.1",
|
||||||
"chai-typescript-typings": "^0.0.3",
|
"chai-typescript-typings": "^0.0.4",
|
||||||
"copyfiles": "^1.2.0",
|
"copyfiles": "^1.2.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
|
"ethers-typescript-typings": "^0.0.2",
|
||||||
"mocha": "^4.0.1",
|
"mocha": "^4.0.1",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
|
"shx": "^0.2.2",
|
||||||
"solc": "^0.4.18",
|
"solc": "^0.4.18",
|
||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"types-bn": "^0.0.1",
|
"types-bn": "^0.0.1",
|
||||||
"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
|
"types-ethereumjs-util": "0xProject/types-ethereumjs-util",
|
||||||
"typescript": "2.7.1",
|
"typescript": "2.7.1",
|
||||||
"web3-typescript-typings": "^0.9.10",
|
"web3-typescript-typings": "^0.10.0",
|
||||||
"yargs": "^10.0.3"
|
"yargs": "^10.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"0x.js": "^0.32.2",
|
"0x.js": "^0.33.1",
|
||||||
"@0xproject/deployer": "^0.0.8",
|
"@0xproject/deployer": "^0.2.1",
|
||||||
"@0xproject/json-schemas": "^0.7.10",
|
"@0xproject/json-schemas": "^0.7.14",
|
||||||
"@0xproject/utils": "^0.3.2",
|
"@0xproject/types": "^0.3.1",
|
||||||
"@0xproject/web3-wrapper": "^0.1.12",
|
"@0xproject/utils": "^0.4.1",
|
||||||
|
"@0xproject/web3-wrapper": "^0.2.1",
|
||||||
"bluebird": "^3.5.0",
|
"bluebird": "^3.5.0",
|
||||||
"bn.js": "^4.11.8",
|
"bn.js": "^4.11.8",
|
||||||
"ethereumjs-abi": "^0.6.4",
|
"ethereumjs-abi": "^0.6.4",
|
||||||
"ethereumjs-util": "^5.1.1",
|
"ethereumjs-util": "^5.1.1",
|
||||||
|
"ethers-contracts": "^2.2.1",
|
||||||
"isomorphic-fetch": "^2.2.1",
|
"isomorphic-fetch": "^2.2.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"request": "^2.81.0",
|
"request": "^2.81.0",
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -1,188 +0,0 @@
|
|||||||
{
|
|
||||||
"contract_name": "ERC20Token",
|
|
||||||
"networks": {
|
|
||||||
"50": {
|
|
||||||
"solc_version": "0.4.18",
|
|
||||||
"keccak256": "0x31be5b5f8d7ae32e5ac282b8740cc7aa87cdc383cabafa02292ea6f38302efcc",
|
|
||||||
"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":
|
|
||||||
"0x6060604052341561000f57600080fd5b6109528061001e6000396000f300606060405260043610610078576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b31461007d57806318160ddd146100d757806323b872dd1461010057806370a0823114610179578063a9059cbb146101c6578063dd62ed3e14610220575b600080fd5b341561008857600080fd5b6100bd600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061028c565b604051808215151515815260200191505060405180910390f35b34156100e257600080fd5b6100ea61037e565b6040518082815260200191505060405180910390f35b341561010b57600080fd5b61015f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610384565b604051808215151515815260200191505060405180910390f35b341561018457600080fd5b6101b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610677565b6040518082815260200191505060405180910390f35b34156101d157600080fd5b610206600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106bf565b604051808215151515815260200191505060405180910390f35b341561022b57600080fd5b610276600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061089f565b6040518082815260200191505060405180910390f35b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60025481565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610450575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b80156104da57506000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b15156104e557600080fd5b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561078d57506000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b151561079857600080fd5b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a72305820d9af9b2b6ffe19f00d45d30a243f833e31053a2e48142e183c9f1e6b0ead7a9e0029",
|
|
||||||
"updated_at": 1517509619365
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,182 +0,0 @@
|
|||||||
{
|
|
||||||
"contract_name": "ERC20Token_v1",
|
|
||||||
"networks": {
|
|
||||||
"50": {
|
|
||||||
"solc_version": "0.4.11",
|
|
||||||
"keccak256": "0x3d710b436c430d6fe49f64b091555405360d76da6454b93faa8e213eea34a96d",
|
|
||||||
"optimizer_enabled": 0,
|
|
||||||
"abi": [
|
|
||||||
{
|
|
||||||
"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": "_owner",
|
|
||||||
"type": "address"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "balanceOf",
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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":
|
|
||||||
"0x6060604052341561000c57fe5b5b61095b8061001c6000396000f30060606040523615610076576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063095ea7b31461007857806318160ddd146100cf57806323b872dd146100f557806370a082311461016b578063a9059cbb146101b5578063dd62ed3e1461020c575bfe5b341561008057fe5b6100b5600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610275565b604051808215151515815260200191505060405180910390f35b34156100d757fe5b6100df610368565b6040518082815260200191505060405180910390f35b34156100fd57fe5b610151600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061036e565b604051808215151515815260200191505060405180910390f35b341561017357fe5b61019f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b6040518082815260200191505060405180910390f35b34156101bd57fe5b6101f2600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106b9565b604051808215151515815260200191505060405180910390f35b341561021457fe5b61025f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506108a7565b6040518082815260200191505060405180910390f35b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a3600190505b92915050565b60025481565b600081600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561043b575081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b80156104c75750600060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b1561065e5781600060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050610668565b60009050610668565b5b9392505050565b6000600060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b600081600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561078a5750600060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110155b156108975781600060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190506108a1565b600090506108a1565b5b92915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b929150505600a165627a7a72305820441601e8451e1c2d31e6cde19fc920b8f95e79f9d42dd662aeefad13fd8bcfaa0029",
|
|
||||||
"updated_at": 1517509621756
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user