Compare commits
537 Commits
monorepo@8
...
@0x/react-
Author | SHA1 | Date | |
---|---|---|---|
|
0ebbbdfca4 | ||
|
085d34834b | ||
|
b866ce787c | ||
|
4d5bc8b8ee | ||
|
7f013515e7 | ||
|
33dbdb0184 | ||
|
c41622c20a | ||
|
348556a544 | ||
|
6fa6579c31 | ||
|
6f61268514 | ||
|
8efc6c2112 | ||
|
b21c1bea46 | ||
|
fd7ba3ecea | ||
|
8aeb18bcc3 | ||
|
9e4a594eb1 | ||
|
3b421ef796 | ||
|
e0c4f58970 | ||
|
df8fd36c94 | ||
|
bc960fe8f8 | ||
|
517c620397 | ||
|
d3592d362e | ||
|
397b4e2890 | ||
|
38896c9358 | ||
|
26cbe7ae66 | ||
|
fd83ca2cb8 | ||
|
4072076965 | ||
|
93054ae52b | ||
|
5c1b1a1203 | ||
|
acb7e876b2 | ||
|
2c585bfbdc | ||
|
1f0ac47bd9 | ||
|
773cf3cd14 | ||
|
53d0f5b98e | ||
|
cc8debe53b | ||
|
36b8c9c5dd | ||
|
474db7c18d | ||
|
39657b633b | ||
|
2e8f74abce | ||
|
df91d34315 | ||
|
3980bf39a9 | ||
|
b4a11de097 | ||
|
a22d78e273 | ||
|
12bc6f5d58 | ||
|
b147cd8885 | ||
|
d703c13f8e | ||
|
3dacc6157b | ||
|
fd12bdbbd5 | ||
|
297a62fe80 | ||
|
1e39d56cf7 | ||
|
ca6f99da61 | ||
|
e45b6c7e98 | ||
|
3eac119399 | ||
|
8755737344 | ||
|
cd44470a29 | ||
|
dd4d3b10cf | ||
|
211163b372 | ||
|
f44c5b2292 | ||
|
5d74421e43 | ||
|
eb5f514d25 | ||
|
57318a6ef2 | ||
|
857a35d4f7 | ||
|
4f4d901eca | ||
|
6a84877f9a | ||
|
117e2f583f | ||
|
b074fe2de5 | ||
|
3dad385533 | ||
|
15a12cfa22 | ||
|
c448a409c1 | ||
|
dfef33bc41 | ||
|
27ea271842 | ||
|
316f3e2e76 | ||
|
624f5cee8d | ||
|
7acaae37a9 | ||
|
fd73c17db1 | ||
|
689f8f1fbc | ||
|
5ffd20214c | ||
|
3395b8d095 | ||
|
b388d54962 | ||
|
c27194a357 | ||
|
8493d619b4 | ||
|
adcfe51190 | ||
|
d71362af99 | ||
|
a5665a6875 | ||
|
7a99b2099d | ||
|
c84e163edb | ||
|
cde192df0d | ||
|
d0c009adff | ||
|
f6abc007ff | ||
|
88eb642aa5 | ||
|
8b09286173 | ||
|
bfe708533f | ||
|
d7742029c7 | ||
|
1151371e57 | ||
|
ecb92a44bc | ||
|
f7642c06f0 | ||
|
94d1e427c1 | ||
|
4181a040b5 | ||
|
c0d8ceca82 | ||
|
771f8a6a6c | ||
|
54b51830d0 | ||
|
c6e7ad5a53 | ||
|
6d5f65b77e | ||
|
370452238f | ||
|
28df5bfd94 | ||
|
eb8f7b0ef5 | ||
|
dfbf10c94b | ||
|
95b2898b9c | ||
|
094f710662 | ||
|
d1186e08b4 | ||
|
cab71fd4d1 | ||
|
4cf6fbc6a3 | ||
|
10da1e24e1 | ||
|
c30dca6961 | ||
|
42c441fafa | ||
|
6861cd7462 | ||
|
d59027f0bc | ||
|
d1444f228d | ||
|
9cc7090e28 | ||
|
a73522e7f1 | ||
|
d941901e32 | ||
|
eb3fda059a | ||
|
0823bd24d6 | ||
|
897c15fd28 | ||
|
006a13448f | ||
|
88c7d907fa | ||
|
e8814ecbe7 | ||
|
f90486c99c | ||
|
a2bc62b17a | ||
|
ce4081bb18 | ||
|
b7a111366b | ||
|
f6487122d1 | ||
|
7c9d47451b | ||
|
8b06b36274 | ||
|
188e317504 | ||
|
ecae3f9c48 | ||
|
543ff7739a | ||
|
18d24f8db1 | ||
|
58a65d0ed9 | ||
|
338594d3e5 | ||
|
e4f9ae6ad5 | ||
|
7e2acb6e7e | ||
|
04e70df330 | ||
|
eb46570a38 | ||
|
bb9c21fb14 | ||
|
245fa95424 | ||
|
16fa0fdda1 | ||
|
66261102de | ||
|
6748c36b03 | ||
|
d0f20a4fd5 | ||
|
f5c7a3c26a | ||
|
cfa748e206 | ||
|
8284f9c2ba | ||
|
18fef7ade4 | ||
|
5fc2483be7 | ||
|
d5521ea5e0 | ||
|
cc4ccda623 | ||
|
389665d3a1 | ||
|
d160792923 | ||
|
819ba14303 | ||
|
b0f2ab45e9 | ||
|
620f439816 | ||
|
6a57a7b5be | ||
|
1f3055c1bc | ||
|
ec83a1d9e7 | ||
|
b895b855cb | ||
|
a770ea56ea | ||
|
5e66cc8a40 | ||
|
4fda2a2d04 | ||
|
e7e9c2a2eb | ||
|
7619bc4f13 | ||
|
515b8712a1 | ||
|
e2ff7b7c84 | ||
|
209b2c9dcb | ||
|
cdaa1407da | ||
|
92706a4b43 | ||
|
ab245fe7de | ||
|
f5623632d8 | ||
|
7de33c5dd9 | ||
|
180f176716 | ||
|
a2e1bf0e62 | ||
|
ad96e953ce | ||
|
695d1453ac | ||
|
7c30fd4b2d | ||
|
5573b092a9 | ||
|
d16499da4e | ||
|
c50c4a4669 | ||
|
32de4862ba | ||
|
f341626e29 | ||
|
c2645b26b4 | ||
|
ce19ec207b | ||
|
7858dafce4 | ||
|
0955feb023 | ||
|
9fd931f799 | ||
|
57fba86154 | ||
|
0a3af4eb22 | ||
|
7fc1a88680 | ||
|
9f5f31d39f | ||
|
bda9d4c1b0 | ||
|
b55ba3a318 | ||
|
dc655fd903 | ||
|
82b6a81a22 | ||
|
f9d13cd43a | ||
|
771e01162d | ||
|
61a1a0be97 | ||
|
3430896eb7 | ||
|
cd79a2fad1 | ||
|
f82d16a5b0 | ||
|
9990f8720c | ||
|
544ddd44a0 | ||
|
66b485c7d4 | ||
|
9ef6f82a95 | ||
|
a148db5022 | ||
|
f9a38fcb32 | ||
|
3f918622bc | ||
|
6091ee732d | ||
|
906909e33f | ||
|
d192a7d466 | ||
|
096f9decee | ||
|
ae84dac463 | ||
|
8c33692560 | ||
|
44a34ee541 | ||
|
76f88a0a62 | ||
|
c1defba429 | ||
|
c1ad1d203d | ||
|
3061afdafb | ||
|
59ad2b75c1 | ||
|
935e5da78e | ||
|
28ded5d02d | ||
|
27258fe3d4 | ||
|
ad0129fa02 | ||
|
5911879639 | ||
|
cc2719492d | ||
|
d675547208 | ||
|
d938ba4606 | ||
|
9a5b52036b | ||
|
229f11f164 | ||
|
91f8487947 | ||
|
0e1e9b27f6 | ||
|
9787d1085d | ||
|
1c0569cfc6 | ||
|
9cc82308e5 | ||
|
5d6fde356a | ||
|
96fcbeaba6 | ||
|
d21487d0c0 | ||
|
dc90136529 | ||
|
abaa39a5e2 | ||
|
4456c3ee14 | ||
|
a49bf353f8 | ||
|
05f059492b | ||
|
13b41c976b | ||
|
bcb633e5cb | ||
|
05b74ba1c8 | ||
|
a918e7099d | ||
|
12dad41143 | ||
|
9a0595a607 | ||
|
37405038e8 | ||
|
25039a036c | ||
|
728f70f51b | ||
|
f9eba65aee | ||
|
d0a0af5130 | ||
|
4cba70f32e | ||
|
5901ee7e96 | ||
|
09ee7d84f7 | ||
|
2ad2644b6b | ||
|
30454fe467 | ||
|
475698ed92 | ||
|
274e4b3bcd | ||
|
a49fc27042 | ||
|
17f024056a | ||
|
10e6c3cd90 | ||
|
cd419edf69 | ||
|
ac72df4188 | ||
|
9610ada446 | ||
|
8ab8c27998 | ||
|
48ff13e3e2 | ||
|
25ca3d4c29 | ||
|
02a975dde4 | ||
|
aeec8f47ef | ||
|
fdf9e860de | ||
|
3f35239b27 | ||
|
aab9bedd7f | ||
|
4e4291eccd | ||
|
7ed44f7b2f | ||
|
8288e8cce9 | ||
|
1bb7a28690 | ||
|
8d1689073b | ||
|
3052c8d303 | ||
|
ff295daa5c | ||
|
bb307a55d3 | ||
|
ae6202ed3d | ||
|
0e55f76db8 | ||
|
667b1e03dd | ||
|
4f5ab1a72d | ||
|
6ad8ac6a48 | ||
|
86febc3cce | ||
|
e73fceaa20 | ||
|
cacfcc291a | ||
|
e1ae551560 | ||
|
476cbbb6cb | ||
|
1880c34ce0 | ||
|
cc7321cb5b | ||
|
ae64fc15e0 | ||
|
6f4dbc71f2 | ||
|
4bd4ff46cf | ||
|
edfb56de6c | ||
|
03007e420c | ||
|
7fa1f25e06 | ||
|
341d7b3407 | ||
|
9be4c47499 | ||
|
9512978de9 | ||
|
ffecba21f4 | ||
|
af91a56a55 | ||
|
51da5311b5 | ||
|
a414dc9b83 | ||
|
0f63071696 | ||
|
951a5271e1 | ||
|
4c5b26db18 | ||
|
e1306f55ed | ||
|
d2bf23de71 | ||
|
3206e1528b | ||
|
68182fb6c4 | ||
|
80711eafeb | ||
|
cbe595af54 | ||
|
dcae27c1a4 | ||
|
3e8d9510ec | ||
|
a3d4482c4a | ||
|
1c5745dbd9 | ||
|
22d0c76bf1 | ||
|
30809e646b | ||
|
27d9e516e1 | ||
|
948d62200a | ||
|
39f92e4c95 | ||
|
d5d99b9d2e | ||
|
4a96dbe085 | ||
|
ced4c893ba | ||
|
a2d09a68b0 | ||
|
98cf046b4c | ||
|
e3510f3bcf | ||
|
89e59cca28 | ||
|
0515a914e0 | ||
|
f04eba7773 | ||
|
cd06c0e913 | ||
|
23b1656692 | ||
|
d06b40bd8a | ||
|
de18fa0069 | ||
|
1a10715fcb | ||
|
062187f28d | ||
|
e55d8802e1 | ||
|
3adc6b6daa | ||
|
c5e8bb1763 | ||
|
acefeff5f0 | ||
|
2a1c2a55ed | ||
|
45d828e154 | ||
|
dc3b867b35 | ||
|
b7f4062ac8 | ||
|
73f5ea2906 | ||
|
11bc10a3ae | ||
|
e45ce4c167 | ||
|
85b7362073 | ||
|
46a8aad87a | ||
|
ab2759f431 | ||
|
379f7c7883 | ||
|
c7a063ca47 | ||
|
db3ad83ebc | ||
|
979527a5ee | ||
|
2d9c961d4f | ||
|
11f7f2d29f | ||
|
c5554fe30c | ||
|
6da6540c03 | ||
|
059868e994 | ||
|
f89b314a94 | ||
|
06ba26a6d3 | ||
|
e50decfa8a | ||
|
78fb43f59c | ||
|
09f0bf7f00 | ||
|
05ce8aa124 | ||
|
ce5bc3c1c9 | ||
|
33d8044f02 | ||
|
fefb64442a | ||
|
119c4e2dc6 | ||
|
c1f9f2e8d9 | ||
|
38f47a380b | ||
|
8635f8d732 | ||
|
47737d4d0f | ||
|
b737313d16 | ||
|
9c26334eff | ||
|
2c04ee3f5e | ||
|
4df8e60f42 | ||
|
df7a1bd8de | ||
|
657ae0cf57 | ||
|
d43f89fa0a | ||
|
2e184f081e | ||
|
3cd9f40e63 | ||
|
8e501e5ec7 | ||
|
4c4286ac66 | ||
|
4a72dc6c6f | ||
|
7ccfa8a8af | ||
|
751b87af96 | ||
|
2110ac32b7 | ||
|
c2e8390d21 | ||
|
075f3c9bfe | ||
|
6027e275b1 | ||
|
a5edb0b421 | ||
|
da54fc3296 | ||
|
053e147afc | ||
|
f0c79473bd | ||
|
864f89c535 | ||
|
4db33ba2b3 | ||
|
37f87ab267 | ||
|
104b2ed759 | ||
|
56953320b3 | ||
|
af2bf053bc | ||
|
117ee19370 | ||
|
dcd428a4a2 | ||
|
e086c7b8e6 | ||
|
1f0c7f8fbe | ||
|
b75fe10c79 | ||
|
b7a5e40c62 | ||
|
28f0deb3eb | ||
|
bdf623dab5 | ||
|
921492e818 | ||
|
194cbc3ba9 | ||
|
1ba207f1fe | ||
|
c5014af7fe | ||
|
579a49ba91 | ||
|
071f9a5a73 | ||
|
4bf1ca0d17 | ||
|
5e67756037 | ||
|
48e4452a04 | ||
|
be97eebe02 | ||
|
37c5165319 | ||
|
15ed3b35df | ||
|
19f9649e74 | ||
|
d52a04e725 | ||
|
daf447361f | ||
|
1a3b1607b1 | ||
|
2bb53d5b1d | ||
|
38eaacdd44 | ||
|
77a4d7e2b7 | ||
|
dbf75a43c3 | ||
|
39c7f3dc88 | ||
|
01f82ddf78 | ||
|
24b5b35a74 | ||
|
4dfbc6747e | ||
|
528ae4376e | ||
|
e0149618f3 | ||
|
632d7b6fc1 | ||
|
b9dccf9da3 | ||
|
7e24c04c0b | ||
|
a766d78706 | ||
|
bf0a4bd91b | ||
|
51779fec38 | ||
|
ac2d93ab22 | ||
|
092d010c2d | ||
|
30b0770993 | ||
|
a017f5e385 | ||
|
6510454337 | ||
|
d2766d7ced | ||
|
6c79a858df | ||
|
f06541ec94 | ||
|
d5105b5c9f | ||
|
17b282b1d7 | ||
|
43ad2fe23b | ||
|
2c308c0f4c | ||
|
d8001e696e | ||
|
aeb607d485 | ||
|
c070142dc0 | ||
|
6f80c7e6d9 | ||
|
48dd9569f7 | ||
|
c66e2f6704 | ||
|
b49e5c76e4 | ||
|
ce4da870d7 | ||
|
6588cf919e | ||
|
2f4e498a09 | ||
|
66465816ca | ||
|
bce9031868 | ||
|
100f446031 | ||
|
0de654bbd5 | ||
|
eb3a4d2fab | ||
|
48f1e6057c | ||
|
d129c922ed | ||
|
6f2217570f | ||
|
90ba8e0e8d | ||
|
669ea191a5 | ||
|
3f2b6482c3 | ||
|
16ba01cd2e | ||
|
7282e3ce03 | ||
|
977e20edc3 | ||
|
17643d98aa | ||
|
724f3b9cf7 | ||
|
a7a17c85dc | ||
|
7742df8614 | ||
|
26cd5ec149 | ||
|
da0c5dd9d3 | ||
|
a60cf44d45 | ||
|
62f219ea74 | ||
|
c26b3f5dfc | ||
|
0eb9769cd4 | ||
|
eca862f818 | ||
|
3f43f9bb4c | ||
|
ee6bb229e0 | ||
|
f3a6800306 | ||
|
7bc2df5602 | ||
|
1737411ab7 | ||
|
7a8adf9db5 | ||
|
ad6dc8e891 | ||
|
44635f34f0 | ||
|
b4fb6b5ff3 | ||
|
c87e68f833 | ||
|
ff1f0a9678 | ||
|
aa0e07b058 | ||
|
a42347a776 | ||
|
8ff5e19269 | ||
|
8a6e077664 | ||
|
f9d8610383 | ||
|
b4af27dd44 | ||
|
9aa6753823 | ||
|
94ace00e0c | ||
|
12b6877aeb | ||
|
65d85ca500 | ||
|
3f0059d4bb | ||
|
4b348e1e60 | ||
|
a764dfa789 | ||
|
c2038eae5b | ||
|
c4ae91c7c5 | ||
|
857eb95ac0 | ||
|
4fd3f12aeb | ||
|
a7336d3c65 | ||
|
f74080fe0d | ||
|
9f61735f94 | ||
|
91ca80b248 | ||
|
59743d32da | ||
|
e40a4addc9 | ||
|
ad0fe2f079 | ||
|
9b4f5dfdda | ||
|
71a61a4dc3 | ||
|
1053aed74d |
@@ -31,7 +31,7 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: cd packages/website && yarn build
|
||||
- run: cd packages/website && yarn build:prod
|
||||
test-contracts-ganache:
|
||||
docker:
|
||||
- image: circleci/node:9
|
||||
@@ -162,6 +162,9 @@ jobs:
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
- image: circleci/python
|
||||
- image: 0xorg/ganache-cli
|
||||
command: |
|
||||
ganache-cli --gasLimit 10000000 --noVMErrorsOnRPCResponse --db /snapshot --noVMErrorsOnRPCResponse -p 8545 --networkId 50 -m "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo chown -R circleci:circleci /usr/local/bin
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -99,6 +99,7 @@ packages/*/scripts/
|
||||
.mypy_cache
|
||||
.tox
|
||||
python-packages/*/build
|
||||
python-packages/*/dist
|
||||
__pycache__
|
||||
python-packages/*/src/*.egg-info
|
||||
python-packages/*/.coverage
|
||||
|
@@ -4,6 +4,7 @@ lib
|
||||
/packages/contracts/generated-artifacts
|
||||
/packages/abi-gen-wrappers/src/generated-wrappers
|
||||
/packages/contract-artifacts/artifacts
|
||||
/python-packages/order_utils/src/zero_ex/contract_artifacts/artifacts
|
||||
/packages/json-schemas/schemas
|
||||
/packages/metacoin/src/contract_wrappers
|
||||
/packages/metacoin/artifacts
|
||||
|
19
CODEOWNERS
19
CODEOWNERS
@@ -10,19 +10,26 @@ packages/instant/ @BMillman19 @fragosti @steveklebanoff
|
||||
packages/website/ @BMillman19 @fragosti @fabioberger @steveklebanoff
|
||||
|
||||
# Dev tools & setup
|
||||
.circleci/ @LogvinovLeon
|
||||
packages/abi-gen/ @LogvinovLeon
|
||||
packages/base-contract/ @LogvinovLeon
|
||||
packages/connect/ @fragosti
|
||||
packages/contract_templates/ @LogvinovLeon
|
||||
packages/contract-addresses/ @albrow
|
||||
packages/contract-artifacts/ @albrow
|
||||
packages/dev-utils/ @LogvinovLeon @fabioberger
|
||||
|
||||
packages/devnet/ @albrow
|
||||
packages/ethereum-types/ @LogvinovLeon
|
||||
packages/metacoin/ @LogvinovLeon
|
||||
packages/monorepo-scripts/ @fabioberger
|
||||
packages/order-utils/ @fabioberger @LogvinovLeon
|
||||
packages/sol-compiler/ @LogvinovLeon
|
||||
packages/sol-cov/ @LogvinovLeon
|
||||
packages/sol-resolver/ @LogvinovLeon
|
||||
packages/web3-wrapper/ @LogvinovLeon @fabioberger
|
||||
.circleci/ @LogvinovLeon
|
||||
packages/subproviders/ @fabioberger @dekz
|
||||
packages/connect/ @fragosti
|
||||
packages/monorepo-scripts/ @fabioberger
|
||||
packages/order-utils/ @fabioberger @LogvinovLeon
|
||||
packages/verdaccio/ @albrow
|
||||
packages/web3-wrapper/ @LogvinovLeon @fabioberger
|
||||
python-packages/ @feuGeneA
|
||||
|
||||
# Protocol/smart contracts
|
||||
packages/contracts/test/ @albrow
|
||||
|
58
README.md
58
README.md
@@ -20,29 +20,37 @@ If you're developing on 0x now or are interested in using 0x infrastructure in t
|
||||
|
||||
### Published Packages
|
||||
|
||||
| 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/abi-gen`](/packages/abi-gen) | [](https://www.npmjs.com/package/@0x/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
|
||||
| [`@0x/assert`](/packages/assert) | [](https://www.npmjs.com/package/@0x/assert) | Type and schema assertions used by our packages |
|
||||
| [`@0x/asset-buyer`](/packages/asset-buyer) | [](https://www.npmjs.com/package/@0x/asset-buyer) | Convenience package for discovering and buying assets with Ether. |
|
||||
| [`@0x/base-contract`](/packages/base-contract) | [](https://www.npmjs.com/package/@0x/base-contract) | BaseContract used by auto-generated `abi-gen` wrapper contracts |
|
||||
| [`@0x/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0x/connect) | A Javascript library for interacting with the Standard Relayer API |
|
||||
| [`@0x/dev-utils`](/packages/dev-utils) | [](https://www.npmjs.com/package/@0x/dev-utils) | Dev utils to be shared across 0x projects and packages |
|
||||
| [`@0x/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0x/json-schemas) | 0x-related json schemas |
|
||||
| [`@0x/monorepo-scripts`](/packages/monorepo-scripts) | [](https://www.npmjs.com/package/@0x/monorepo-scripts) | Monorepo scripts |
|
||||
| [`@0x/order-utils`](/packages/order-utils) | [](https://www.npmjs.com/package/@0x/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders. |
|
||||
| [`@0x/react-docs`](/packages/react-docs) | [](https://www.npmjs.com/package/@0x/react-docs) | React documentation component for rendering TypeDoc & Doxity generated JSON |
|
||||
| [`@0x/react-shared`](/packages/react-shared) | [](https://www.npmjs.com/package/@0x/react-shared) | 0x shared react components |
|
||||
| [`@0x/sol-compiler`](/packages/sol-compiler) | [](https://www.npmjs.com/package/@0x/sol-compiler) | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties. |
|
||||
| [`@0x/sol-cov`](/packages/sol-cov) | [](https://www.npmjs.com/package/@0x/sol-cov) | Solidity test coverage tool |
|
||||
| [`@0x/sra-spec`](/packages/sra-spec) | [](https://www.npmjs.com/package/@0x/sra-spec) | OpenAPI specification for the standard relayer API |
|
||||
| [`@0x/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0x/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
|
||||
| [`@0x/tslint-config`](/packages/tslint-config) | [](https://www.npmjs.com/package/@0x/tslint-config) | Custom 0x development TSLint rules |
|
||||
| [`@0x/types`](/packages/types) | [](https://www.npmjs.com/package/@0x/types) | Shared type declarations |
|
||||
| [`@0x/typescript-typings`](/packages/typescript-typings) | [](https://www.npmjs.com/package/@0x/typescript-typings) | Repository of types for external packages |
|
||||
| [`@0x/utils`](/packages/utils) | [](https://www.npmjs.com/package/@0x/utils) | Shared utilities |
|
||||
| [`@0x/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0x/web3-wrapper) | Web3 wrapper |
|
||||
| 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/abi-gen`](/packages/abi-gen) | [](https://www.npmjs.com/package/@0x/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
|
||||
| [`@0x/abi-gen-wrappers`](/packages/abi-gen-wrappers) | [](https://www.npmjs.com/package/@0x/abi-gen-wrappers) | Low-level 0x smart contract wrappers generated using @0x/abi-gen |
|
||||
| [`@0x/assert`](/packages/assert) | [](https://www.npmjs.com/package/@0x/assert) | Type and schema assertions used by our packages |
|
||||
| [`@0x/asset-buyer`](/packages/asset-buyer) | [](https://www.npmjs.com/package/@0x/asset-buyer) | Convenience package for discovering and buying assets with Ether |
|
||||
| [`@0x/base-contract`](/packages/base-contract) | [](https://www.npmjs.com/package/@0x/base-contract) | BaseContract used by auto-generated `abi-gen` wrapper contracts |
|
||||
| [`@0x/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0x/connect) | A Javascript library for interacting with the Standard Relayer API |
|
||||
| [`@0x/contract-addresses`](/packages/contract-addresses) | [](https://www.npmjs.com/package/@0x/contract-addresses) | Used to get known addresses of deployed 0x contracts |
|
||||
| [`@0x/contract-artifacts`](/packages/contract-artifacts) | [](https://www.npmjs.com/package/@0x/contract-artifacts) | 0x smart contract compilation artifacts |
|
||||
| [`@0x/contract-wrappers`](/packages/contract-wrappers) | [](https://www.npmjs.com/package/@0x/contract-wrappers) | Smart TS wrappers for 0x smart contracts |
|
||||
| [`@0x/dev-utils`](/packages/dev-utils) | [](https://www.npmjs.com/package/@0x/dev-utils) | Dev utils to be shared across 0x projects and packages |
|
||||
| [`@0x/fill-scenarios`](/packages/fill-scenarios) | [](https://www.npmjs.com/package/@0x/fill-scenarios) | 0x order fill scenario generation |
|
||||
| [`@0x/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0x/json-schemas) | 0x-related json schemas |
|
||||
| [`@0x/migrations`](/packages/migrations) | [](https://www.npmjs.com/package/@0x/migrations) | 0x smart contract migrations |
|
||||
| [`@0x/order-utils`](/packages/order-utils) | [](https://www.npmjs.com/package/@0x/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders |
|
||||
| [`@0x/order-watcher`](/packages/order-watcher) | [](https://www.npmjs.com/package/@0x/order-watcher) | An order watcher daemon that watches for order validity |
|
||||
| [`@0x/react-docs`](/packages/react-docs) | [](https://www.npmjs.com/package/@0x/react-docs) | React documentation component for rendering TypeDoc & Doxity generated JSON |
|
||||
| [`@0x/react-shared`](/packages/react-shared) | [](https://www.npmjs.com/package/@0x/react-shared) | 0x shared react components |
|
||||
| [`@0x/sol-compiler`](/packages/sol-compiler) | [](https://www.npmjs.com/package/@0x/sol-compiler) | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties |
|
||||
| [`@0x/sol-cov`](/packages/sol-cov) | [](https://www.npmjs.com/package/@0x/sol-cov) | Solidity test coverage tool |
|
||||
| [`@0x/sol-doc`](/packages/sol-doc) | [](https://www.npmjs.com/package/@0x/sol-doc) | Solidity documentation generator |
|
||||
| [`@0x/sol-resolver`](/packages/sol-resolver) | [](https://www.npmjs.com/package/@0x/sol-resolver) | Import resolver for smart contracts dependencies |
|
||||
| [`@0x/sra-spec`](/packages/sra-spec) | [](https://www.npmjs.com/package/@0x/sra-spec) | OpenAPI specification for the standard relayer API |
|
||||
| [`@0x/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0x/subproviders) | Useful web3 subproviders (e.g. LedgerSubprovider) |
|
||||
| [`@0x/tslint-config`](/packages/tslint-config) | [](https://www.npmjs.com/package/@0x/tslint-config) | Custom 0x development TSLint rules |
|
||||
| [`@0x/types`](/packages/types) | [](https://www.npmjs.com/package/@0x/types) | Shared type declarations |
|
||||
| [`@0x/typescript-typings`](/packages/typescript-typings) | [](https://www.npmjs.com/package/@0x/typescript-typings) | Repository of types for external packages |
|
||||
| [`@0x/utils`](/packages/utils) | [](https://www.npmjs.com/package/@0x/utils) | Shared utilities |
|
||||
| [`@0x/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0x/web3-wrapper) | Web3 wrapper |
|
||||
|
||||
### Private Packages
|
||||
|
||||
@@ -86,6 +94,10 @@ We strongly recommend that the community help us make improvements and determine
|
||||
|
||||
Make sure you are using Yarn v1.9.4. To install using brew:
|
||||
|
||||
```bash
|
||||
brew install yarn@1.9.4
|
||||
```
|
||||
|
||||
Then install dependencies
|
||||
|
||||
```bash
|
||||
|
@@ -50,7 +50,7 @@
|
||||
},
|
||||
{
|
||||
"path": "packages/instant/public/main.bundle.js",
|
||||
"maxSize": "500kB"
|
||||
"maxSize": "1000kB"
|
||||
}
|
||||
],
|
||||
"ci": {
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "2.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.0.2 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.1 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.0.0 - _October 18, 2018_
|
||||
|
||||
* Add support for `eth_signTypedData`. (#1102)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "0x.js",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -18,7 +18,7 @@
|
||||
"build": "yarn build:all",
|
||||
"build:ci": "yarn build:commonjs",
|
||||
"build:all": "run-p build:umd:prod build:commonjs",
|
||||
"lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"test:circleci": "run-s test:coverage",
|
||||
"rebuild_and_test": "run-s build test",
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
@@ -42,13 +42,12 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.14",
|
||||
"@0x/abi-gen-wrappers": "^1.0.1",
|
||||
"@0x/contract-addresses": "^1.0.1",
|
||||
"@0x/dev-utils": "^1.0.13",
|
||||
"@0x/migrations": "^2.0.0",
|
||||
"@0x/monorepo-scripts": "^1.0.12",
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/abi-gen": "^1.0.15",
|
||||
"@0x/abi-gen-wrappers": "^1.0.3",
|
||||
"@0x/contract-addresses": "^1.1.0",
|
||||
"@0x/dev-utils": "^1.0.15",
|
||||
"@0x/migrations": "^2.0.2",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "*",
|
||||
@@ -74,18 +73,18 @@
|
||||
"webpack": "^4.20.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.14",
|
||||
"@0x/base-contract": "^3.0.2",
|
||||
"@0x/contract-wrappers": "^3.0.0",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/order-watcher": "^2.2.0",
|
||||
"@0x/subproviders": "^2.1.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"@0x/assert": "^1.0.16",
|
||||
"@0x/base-contract": "^3.0.4",
|
||||
"@0x/contract-wrappers": "^4.0.0",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/order-watcher": "^2.2.2",
|
||||
"@0x/subproviders": "^2.1.2",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"@types/web3-provider-engine": "^14.0.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"ethers": "~4.0.4",
|
||||
"lodash": "^4.17.5",
|
||||
"web3-provider-engine": "14.0.6"
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "1.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"timestamp": 1539871071,
|
||||
"version": "1.0.1",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.3 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.2 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.1 - _October 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/abi-gen-wrappers",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -12,7 +12,7 @@
|
||||
"scripts": {
|
||||
"build": "yarn pre_build && tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"pre_build": "yarn generate_contract_wrappers",
|
||||
"clean": "shx rm -rf lib wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated-wrappers --backend ethers"
|
||||
@@ -30,17 +30,17 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen-wrappers/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.14",
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"@0x/abi-gen": "^1.0.15",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"ethers": "~4.0.4",
|
||||
"lodash": "^4.17.5",
|
||||
"shx": "^0.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.2"
|
||||
"@0x/base-contract": "^3.0.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "1.0.15",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"timestamp": 1539871071,
|
||||
"version": "1.0.14",
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.15 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.14 - _October 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/abi-gen",
|
||||
"version": "1.0.14",
|
||||
"version": "1.0.15",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -8,7 +8,7 @@
|
||||
"main": "lib/src/index.js",
|
||||
"types": "lib/src/index.d.ts",
|
||||
"scripts": {
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"clean": "shx rm -rf lib",
|
||||
"build": "tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
@@ -31,10 +31,10 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
|
||||
"dependencies": {
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"chalk": "^2.3.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"glob": "^7.1.2",
|
||||
"handlebars": "^4.0.11",
|
||||
"lodash": "^4.17.5",
|
||||
@@ -45,7 +45,7 @@
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/glob": "5.0.35",
|
||||
"@types/handlebars": "^4.0.36",
|
||||
"@types/mkdirp": "^0.5.1",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "1.0.16",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.0.15",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"timestamp": 1539871071,
|
||||
"version": "1.0.14",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.16 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.15 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.14 - _October 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/assert",
|
||||
"version": "1.0.14",
|
||||
"version": "1.0.16",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -11,7 +11,7 @@
|
||||
"build": "tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"clean": "shx rm -rf lib test_temp",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/valid-url": "^1.0.2",
|
||||
@@ -44,9 +44,9 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/json-schemas": "^2.0.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/json-schemas": "^2.1.0",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"lodash": "^4.17.5",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
|
@@ -1,4 +1,46 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "2.2.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "`getAssetBuyerForProvidedOrders` factory function now takes 3 args instead of 4",
|
||||
"pr": 1187
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"the `OrderProvider` now requires a new method `getAvailableMakerAssetDatasAsync` and the `StandardRelayerAPIOrderProvider` requires the network id at init.",
|
||||
"pr": 1203
|
||||
},
|
||||
{
|
||||
"note": "No longer require that provided orders all have the same maker and taker asset data",
|
||||
"pr": 1197
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Fix bug where `BuyQuoteInfo` objects could return `totalEthAmount` and `feeEthAmount` that were not whole numbers",
|
||||
"pr": 1207
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Fix bug where default values for `AssetBuyer` public facing methods could get overriden by `undefined` values",
|
||||
"pr": 1207
|
||||
},
|
||||
{
|
||||
"note": "Lower default expiry buffer from 5 minutes to 2 minutes",
|
||||
"pr": 1217
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"changes": [
|
||||
@@ -25,6 +67,10 @@
|
||||
{
|
||||
"note": "Add missing types to public interface",
|
||||
"pr": 1139
|
||||
},
|
||||
{
|
||||
"note": "Throw `SignatureRequestDenied` and `TransactionValueTooLow` errors when executing buy",
|
||||
"pr": 1147
|
||||
}
|
||||
],
|
||||
"timestamp": 1539871071
|
||||
|
@@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v2.2.1 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v2.2.0 - _November 9, 2018_
|
||||
|
||||
* `getAssetBuyerForProvidedOrders` factory function now takes 3 args instead of 4 (#1187)
|
||||
* the `OrderProvider` now requires a new method `getAvailableMakerAssetDatasAsync` and the `StandardRelayerAPIOrderProvider` requires the network id at init. (#1203)
|
||||
* No longer require that provided orders all have the same maker and taker asset data (#1197)
|
||||
* Fix bug where `BuyQuoteInfo` objects could return `totalEthAmount` and `feeEthAmount` that were not whole numbers (#1207)
|
||||
* Fix bug where default values for `AssetBuyer` public facing methods could get overriden by `undefined` values (#1207)
|
||||
* Lower default expiry buffer from 5 minutes to 2 minutes (#1217)
|
||||
|
||||
## v2.1.0 - _October 18, 2018_
|
||||
|
||||
* Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts`
|
||||
@@ -13,6 +26,7 @@ CHANGELOG
|
||||
* Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts` (#1116)
|
||||
* Add `docs:json` command to package.json (#1139)
|
||||
* Add missing types to public interface (#1139)
|
||||
* Throw `SignatureRequestDenied` and `TransactionValueTooLow` errors when executing buy (#1147)
|
||||
|
||||
## v2.0.0 - _October 4, 2018_
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/asset-buyer",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.1",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -10,7 +10,7 @@
|
||||
"scripts": {
|
||||
"build": "yarn tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
@@ -36,21 +36,21 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/asset-buyer/README.md",
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.14",
|
||||
"@0x/connect": "^3.0.2",
|
||||
"@0x/contract-wrappers": "^3.0.0",
|
||||
"@0x/json-schemas": "^2.0.0",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/subproviders": "^2.1.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"@0x/assert": "^1.0.16",
|
||||
"@0x/connect": "^3.0.4",
|
||||
"@0x/contract-wrappers": "^4.0.0",
|
||||
"@0x/json-schemas": "^2.1.0",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/subproviders": "^2.1.2",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"lodash": "^4.17.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "^4.14.116",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "*",
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ContractWrappers } from '@0x/contract-wrappers';
|
||||
import { ContractWrappers, ContractWrappersError, ForwarderWrapperError } from '@0x/contract-wrappers';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import { SignedOrder } from '@0x/order-utils';
|
||||
import { ObjectMap } from '@0x/types';
|
||||
@@ -52,16 +52,12 @@ export class AssetBuyer {
|
||||
public static getAssetBuyerForProvidedOrders(
|
||||
provider: Provider,
|
||||
orders: SignedOrder[],
|
||||
feeOrders: SignedOrder[] = [],
|
||||
options: Partial<AssetBuyerOpts> = {},
|
||||
): AssetBuyer {
|
||||
assert.isWeb3Provider('provider', provider);
|
||||
assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema);
|
||||
assert.doesConformToSchema('feeOrders', feeOrders, schemas.signedOrdersSchema);
|
||||
assert.areValidProvidedOrders('orders', orders);
|
||||
assert.areValidProvidedOrders('feeOrders', feeOrders);
|
||||
assert.assert(orders.length !== 0, `Expected orders to contain at least one order`);
|
||||
const orderProvider = new BasicOrderProvider(_.concat(orders, feeOrders));
|
||||
const orderProvider = new BasicOrderProvider(orders);
|
||||
const assetBuyer = new AssetBuyer(provider, orderProvider, options);
|
||||
return assetBuyer;
|
||||
}
|
||||
@@ -80,7 +76,8 @@ export class AssetBuyer {
|
||||
): AssetBuyer {
|
||||
assert.isWeb3Provider('provider', provider);
|
||||
assert.isWebUri('sraApiUrl', sraApiUrl);
|
||||
const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl);
|
||||
const networkId = options.networkId || constants.DEFAULT_ASSET_BUYER_OPTS.networkId;
|
||||
const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl, networkId);
|
||||
const assetBuyer = new AssetBuyer(provider, orderProvider, options);
|
||||
return assetBuyer;
|
||||
}
|
||||
@@ -93,10 +90,11 @@ export class AssetBuyer {
|
||||
* @return An instance of AssetBuyer
|
||||
*/
|
||||
constructor(provider: Provider, orderProvider: OrderProvider, options: Partial<AssetBuyerOpts> = {}) {
|
||||
const { networkId, orderRefreshIntervalMs, expiryBufferSeconds } = {
|
||||
...constants.DEFAULT_ASSET_BUYER_OPTS,
|
||||
...options,
|
||||
};
|
||||
const { networkId, orderRefreshIntervalMs, expiryBufferSeconds } = _.merge(
|
||||
{},
|
||||
constants.DEFAULT_ASSET_BUYER_OPTS,
|
||||
options,
|
||||
);
|
||||
assert.isWeb3Provider('provider', provider);
|
||||
assert.isValidOrderProvider('orderProvider', orderProvider);
|
||||
assert.isNumber('networkId', networkId);
|
||||
@@ -125,19 +123,25 @@ export class AssetBuyer {
|
||||
assetBuyAmount: BigNumber,
|
||||
options: Partial<BuyQuoteRequestOpts> = {},
|
||||
): Promise<BuyQuote> {
|
||||
const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = {
|
||||
...constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS,
|
||||
...options,
|
||||
};
|
||||
const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = _.merge(
|
||||
{},
|
||||
constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS,
|
||||
options,
|
||||
);
|
||||
assert.isString('assetData', assetData);
|
||||
assert.isBigNumber('assetBuyAmount', assetBuyAmount);
|
||||
assert.isValidPercentage('feePercentage', feePercentage);
|
||||
assert.isBoolean('shouldForceOrderRefresh', shouldForceOrderRefresh);
|
||||
assert.isNumber('slippagePercentage', slippagePercentage);
|
||||
const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow();
|
||||
const isMakerAssetZrxToken = assetData === zrxTokenAssetData;
|
||||
// get the relevant orders for the makerAsset and fees
|
||||
// if the requested assetData is ZRX, don't get the fee info
|
||||
const [ordersAndFillableAmounts, feeOrdersAndFillableAmounts] = await Promise.all([
|
||||
this._getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh),
|
||||
this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
|
||||
isMakerAssetZrxToken
|
||||
? Promise.resolve(constants.EMPTY_ORDERS_AND_FILLABLE_AMOUNTS)
|
||||
: this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
|
||||
shouldForceOrderRefresh,
|
||||
]);
|
||||
if (ordersAndFillableAmounts.orders.length === 0) {
|
||||
@@ -149,6 +153,7 @@ export class AssetBuyer {
|
||||
assetBuyAmount,
|
||||
feePercentage,
|
||||
slippagePercentage,
|
||||
isMakerAssetZrxToken,
|
||||
);
|
||||
return buyQuote;
|
||||
}
|
||||
@@ -183,10 +188,11 @@ export class AssetBuyer {
|
||||
buyQuote: BuyQuote,
|
||||
options: Partial<BuyQuoteExecutionOpts> = {},
|
||||
): Promise<string> {
|
||||
const { ethAmount, takerAddress, feeRecipient, gasLimit, gasPrice } = {
|
||||
...constants.DEFAULT_BUY_QUOTE_EXECUTION_OPTS,
|
||||
...options,
|
||||
};
|
||||
const { ethAmount, takerAddress, feeRecipient, gasLimit, gasPrice } = _.merge(
|
||||
{},
|
||||
constants.DEFAULT_BUY_QUOTE_EXECUTION_OPTS,
|
||||
options,
|
||||
);
|
||||
assert.isValidBuyQuote('buyQuote', buyQuote);
|
||||
if (!_.isUndefined(ethAmount)) {
|
||||
assert.isBigNumber('ethAmount', ethAmount);
|
||||
@@ -195,6 +201,12 @@ export class AssetBuyer {
|
||||
assert.isETHAddressHex('takerAddress', takerAddress);
|
||||
}
|
||||
assert.isETHAddressHex('feeRecipient', feeRecipient);
|
||||
if (!_.isUndefined(gasLimit)) {
|
||||
assert.isNumber('gasLimit', gasLimit);
|
||||
}
|
||||
if (!_.isUndefined(gasPrice)) {
|
||||
assert.isBigNumber('gasPrice', gasPrice);
|
||||
}
|
||||
const { orders, feeOrders, feePercentage, assetBuyAmount, worstCaseQuoteInfo } = buyQuote;
|
||||
// if no takerAddress is provided, try to get one from the provider
|
||||
let finalTakerAddress;
|
||||
@@ -210,21 +222,41 @@ export class AssetBuyer {
|
||||
throw new Error(AssetBuyerError.NoAddressAvailable);
|
||||
}
|
||||
}
|
||||
// if no ethAmount is provided, default to the worst ethAmount from buyQuote
|
||||
const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync(
|
||||
orders,
|
||||
assetBuyAmount,
|
||||
finalTakerAddress,
|
||||
ethAmount || worstCaseQuoteInfo.totalEthAmount,
|
||||
feeOrders,
|
||||
feePercentage,
|
||||
feeRecipient,
|
||||
{
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
},
|
||||
);
|
||||
return txHash;
|
||||
try {
|
||||
// if no ethAmount is provided, default to the worst ethAmount from buyQuote
|
||||
const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync(
|
||||
orders,
|
||||
assetBuyAmount,
|
||||
finalTakerAddress,
|
||||
ethAmount || worstCaseQuoteInfo.totalEthAmount,
|
||||
feeOrders,
|
||||
feePercentage,
|
||||
feeRecipient,
|
||||
{
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
shouldValidate: true,
|
||||
},
|
||||
);
|
||||
return txHash;
|
||||
} catch (err) {
|
||||
if (_.includes(err.message, ContractWrappersError.SignatureRequestDenied)) {
|
||||
throw new Error(AssetBuyerError.SignatureRequestDenied);
|
||||
} else if (_.includes(err.message, ForwarderWrapperError.CompleteFillFailed)) {
|
||||
throw new Error(AssetBuyerError.TransactionValueTooLow);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the asset data of all assets that are purchaseable with ether token (wETH) in the order provider passed in at init.
|
||||
*
|
||||
* @return An array of asset data strings that can be purchased using wETH.
|
||||
*/
|
||||
public async getAvailableAssetDatasAsync(): Promise<string[]> {
|
||||
const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow();
|
||||
return this.orderProvider.getAvailableMakerAssetDatasAsync(etherTokenAssetData);
|
||||
}
|
||||
/**
|
||||
* Grab orders from the map, if there is a miss or it is time to refresh, fetch and process the orders
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { AssetBuyerOpts, BuyQuoteExecutionOpts, BuyQuoteRequestOpts } from './types';
|
||||
import { AssetBuyerOpts, BuyQuoteExecutionOpts, BuyQuoteRequestOpts, OrdersAndFillableAmounts } from './types';
|
||||
|
||||
const NULL_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
const MAINNET_NETWORK_ID = 1;
|
||||
@@ -8,7 +9,7 @@ const MAINNET_NETWORK_ID = 1;
|
||||
const DEFAULT_ASSET_BUYER_OPTS: AssetBuyerOpts = {
|
||||
networkId: MAINNET_NETWORK_ID,
|
||||
orderRefreshIntervalMs: 10000, // 10 seconds
|
||||
expiryBufferSeconds: 300, // 5 minutes
|
||||
expiryBufferSeconds: 120, // 2 minutes
|
||||
};
|
||||
|
||||
const DEFAULT_BUY_QUOTE_REQUEST_OPTS: BuyQuoteRequestOpts = {
|
||||
@@ -22,6 +23,11 @@ const DEFAULT_BUY_QUOTE_EXECUTION_OPTS: BuyQuoteExecutionOpts = {
|
||||
feeRecipient: NULL_ADDRESS,
|
||||
};
|
||||
|
||||
const EMPTY_ORDERS_AND_FILLABLE_AMOUNTS: OrdersAndFillableAmounts = {
|
||||
orders: [] as SignedOrder[],
|
||||
remainingFillableMakerAssetAmounts: [] as BigNumber[],
|
||||
};
|
||||
|
||||
export const constants = {
|
||||
ZERO_AMOUNT: new BigNumber(0),
|
||||
NULL_ADDRESS,
|
||||
@@ -30,5 +36,5 @@ export const constants = {
|
||||
DEFAULT_ASSET_BUYER_OPTS,
|
||||
DEFAULT_BUY_QUOTE_EXECUTION_OPTS,
|
||||
DEFAULT_BUY_QUOTE_REQUEST_OPTS,
|
||||
MAX_PER_PAGE: 10000,
|
||||
EMPTY_ORDERS_AND_FILLABLE_AMOUNTS,
|
||||
};
|
||||
|
@@ -29,4 +29,13 @@ export class BasicOrderProvider implements OrderProvider {
|
||||
});
|
||||
return { orders };
|
||||
}
|
||||
/**
|
||||
* Given a taker asset data string, return all availabled paired maker asset data strings.
|
||||
* @param takerAssetData A string representing the taker asset data.
|
||||
* @return An array of asset data strings that can be purchased using takerAssetData.
|
||||
*/
|
||||
public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise<string[]> {
|
||||
const ordersWithTakerAssetData = _.filter(this.orders, { takerAssetData });
|
||||
return _.map(ordersWithTakerAssetData, order => order.makerAssetData);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { HttpClient } from '@0x/connect';
|
||||
import { APIOrder, OrderbookResponse } from '@0x/types';
|
||||
import { APIOrder, AssetPairsResponse, OrderbookResponse } from '@0x/types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
@@ -14,6 +14,7 @@ import { orderUtils } from '../utils/order_utils';
|
||||
|
||||
export class StandardRelayerAPIOrderProvider implements OrderProvider {
|
||||
public readonly apiUrl: string;
|
||||
public readonly networkId: number;
|
||||
private readonly _sraClient: HttpClient;
|
||||
/**
|
||||
* Given an array of APIOrder objects from a standard relayer api, return an array
|
||||
@@ -30,7 +31,7 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
|
||||
'remainingTakerAssetAmount',
|
||||
order.takerAssetAmount,
|
||||
);
|
||||
const remainingFillableMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount(
|
||||
const remainingFillableMakerAssetAmount = orderUtils.getRemainingMakerAmount(
|
||||
order,
|
||||
remainingFillableTakerAssetAmount,
|
||||
);
|
||||
@@ -44,12 +45,15 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
|
||||
}
|
||||
/**
|
||||
* Instantiates a new StandardRelayerAPIOrderProvider instance
|
||||
* @param apiUrl The standard relayer API base HTTP url you would like to source orders from.
|
||||
* @param apiUrl The standard relayer API base HTTP url you would like to source orders from.
|
||||
* @param networkId The ethereum network id.
|
||||
* @return An instance of StandardRelayerAPIOrderProvider
|
||||
*/
|
||||
constructor(apiUrl: string) {
|
||||
constructor(apiUrl: string, networkId: number) {
|
||||
assert.isWebUri('apiUrl', apiUrl);
|
||||
assert.isNumber('networkId', networkId);
|
||||
this.apiUrl = apiUrl;
|
||||
this.networkId = networkId;
|
||||
this._sraClient = new HttpClient(apiUrl);
|
||||
}
|
||||
/**
|
||||
@@ -59,9 +63,9 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
|
||||
*/
|
||||
public async getOrdersAsync(orderProviderRequest: OrderProviderRequest): Promise<OrderProviderResponse> {
|
||||
assert.isValidOrderProviderRequest('orderProviderRequest', orderProviderRequest);
|
||||
const { makerAssetData, takerAssetData, networkId } = orderProviderRequest;
|
||||
const { makerAssetData, takerAssetData } = orderProviderRequest;
|
||||
const orderbookRequest = { baseAssetData: makerAssetData, quoteAssetData: takerAssetData };
|
||||
const requestOpts = { networkId };
|
||||
const requestOpts = { networkId: this.networkId };
|
||||
let orderbook: OrderbookResponse;
|
||||
try {
|
||||
orderbook = await this._sraClient.getOrderbookAsync(orderbookRequest, requestOpts);
|
||||
@@ -76,4 +80,26 @@ export class StandardRelayerAPIOrderProvider implements OrderProvider {
|
||||
orders,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Given a taker asset data string, return all availabled paired maker asset data strings.
|
||||
* @param takerAssetData A string representing the taker asset data.
|
||||
* @return An array of asset data strings that can be purchased using takerAssetData.
|
||||
*/
|
||||
public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise<string[]> {
|
||||
// Return a maximum of 1000 asset datas
|
||||
const maxPerPage = 1000;
|
||||
const requestOpts = { networkId: this.networkId, perPage: maxPerPage };
|
||||
const assetPairsRequest = { assetDataA: takerAssetData };
|
||||
const fullRequest = {
|
||||
...requestOpts,
|
||||
...assetPairsRequest,
|
||||
};
|
||||
let response: AssetPairsResponse;
|
||||
try {
|
||||
response = await this._sraClient.getAssetPairsAsync(fullRequest);
|
||||
} catch (err) {
|
||||
throw new Error(AssetBuyerError.StandardRelayerApiError);
|
||||
}
|
||||
return _.map(response.records, item => item.assetDataB.assetData);
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@ import { BigNumber } from '@0x/utils';
|
||||
export interface OrderProviderRequest {
|
||||
makerAssetData: string;
|
||||
takerAssetData: string;
|
||||
networkId: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,10 +26,12 @@ export interface SignedOrderWithRemainingFillableMakerAssetAmount extends Signed
|
||||
remainingFillableMakerAssetAmount?: BigNumber;
|
||||
}
|
||||
/**
|
||||
* Given an OrderProviderRequest, get an OrderProviderResponse.
|
||||
* gerOrdersAsync: Given an OrderProviderRequest, get an OrderProviderResponse.
|
||||
* getAvailableMakerAssetDatasAsync: Given a taker asset data string, return all availabled paired maker asset data strings.
|
||||
*/
|
||||
export interface OrderProvider {
|
||||
getOrdersAsync: (orderProviderRequest: OrderProviderRequest) => Promise<OrderProviderResponse>;
|
||||
getAvailableMakerAssetDatasAsync: (takerAssetData: string) => Promise<string[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,6 +113,8 @@ export enum AssetBuyerError {
|
||||
NoAddressAvailable = 'NO_ADDRESS_AVAILABLE',
|
||||
InvalidOrderProviderResponse = 'INVALID_ORDER_PROVIDER_RESPONSE',
|
||||
AssetUnavailable = 'ASSET_UNAVAILABLE',
|
||||
SignatureRequestDenied = 'SIGNATURE_REQUEST_DENIED',
|
||||
TransactionValueTooLow = 'TRANSACTION_VALUE_TOO_LOW',
|
||||
}
|
||||
|
||||
export interface OrdersAndFillableAmounts {
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { assert as sharedAssert } from '@0x/assert';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { BuyQuote, BuyQuoteInfo, OrderProvider, OrderProviderRequest } from '../types';
|
||||
@@ -29,22 +28,6 @@ export const assert = {
|
||||
isValidOrderProviderRequest(variableName: string, orderFetcherRequest: OrderProviderRequest): void {
|
||||
sharedAssert.isHexString(`${variableName}.makerAssetData`, orderFetcherRequest.makerAssetData);
|
||||
sharedAssert.isHexString(`${variableName}.takerAssetData`, orderFetcherRequest.takerAssetData);
|
||||
sharedAssert.isNumber(`${variableName}.networkId`, orderFetcherRequest.networkId);
|
||||
},
|
||||
areValidProvidedOrders(variableName: string, orders: SignedOrder[]): void {
|
||||
if (orders.length === 0) {
|
||||
return;
|
||||
}
|
||||
const makerAssetData = orders[0].makerAssetData;
|
||||
const takerAssetData = orders[0].takerAssetData;
|
||||
const filteredOrders = _.filter(
|
||||
orders,
|
||||
order => order.makerAssetData === makerAssetData && order.takerAssetData === takerAssetData,
|
||||
);
|
||||
sharedAssert.assert(
|
||||
orders.length === filteredOrders.length,
|
||||
`Expected all orders in ${variableName} to have the same makerAssetData and takerAssetData.`,
|
||||
);
|
||||
},
|
||||
isValidPercentage(variableName: string, percentage: number): void {
|
||||
assert.isNumber(variableName, percentage);
|
||||
|
@@ -1,10 +1,12 @@
|
||||
import { marketUtils, rateUtils } from '@0x/order-utils';
|
||||
import { marketUtils, SignedOrder } from '@0x/order-utils';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { constants } from '../constants';
|
||||
import { AssetBuyerError, BuyQuote, BuyQuoteInfo, OrdersAndFillableAmounts } from '../types';
|
||||
|
||||
import { orderUtils } from './order_utils';
|
||||
|
||||
// Calculates a buy quote for orders that have WETH as the takerAsset
|
||||
export const buyQuoteCalculator = {
|
||||
calculate(
|
||||
@@ -13,6 +15,7 @@ export const buyQuoteCalculator = {
|
||||
assetBuyAmount: BigNumber,
|
||||
feePercentage: number,
|
||||
slippagePercentage: number,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): BuyQuote {
|
||||
const orders = ordersAndFillableAmounts.orders;
|
||||
const remainingFillableMakerAssetAmounts = ordersAndFillableAmounts.remainingFillableMakerAssetAmounts;
|
||||
@@ -32,22 +35,31 @@ export const buyQuoteCalculator = {
|
||||
if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) {
|
||||
throw new Error(AssetBuyerError.InsufficientAssetLiquidity);
|
||||
}
|
||||
// if we are not buying ZRX:
|
||||
// given the orders calculated above, find the fee-orders that cover the desired assetBuyAmount (with slippage)
|
||||
// TODO(bmillman): optimization
|
||||
// update this logic to find the minimum amount of feeOrders to cover the worst case as opposed to
|
||||
// finding order that cover all fees, this will help with estimating ETH and minimizing gas usage
|
||||
const {
|
||||
resultFeeOrders,
|
||||
remainingFeeAmount,
|
||||
feeOrdersRemainingFillableMakerAssetAmounts,
|
||||
} = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(resultOrders, feeOrders, {
|
||||
remainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts,
|
||||
remainingFillableFeeAmounts,
|
||||
});
|
||||
// if we do not have enough feeOrders to cover the fees, throw
|
||||
if (remainingFeeAmount.gt(constants.ZERO_AMOUNT)) {
|
||||
throw new Error(AssetBuyerError.InsufficientZrxLiquidity);
|
||||
let resultFeeOrders = [] as SignedOrder[];
|
||||
let feeOrdersRemainingFillableMakerAssetAmounts = [] as BigNumber[];
|
||||
if (!isMakerAssetZrxToken) {
|
||||
const feeOrdersAndRemainingFeeAmount = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(
|
||||
resultOrders,
|
||||
feeOrders,
|
||||
{
|
||||
remainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts,
|
||||
remainingFillableFeeAmounts,
|
||||
},
|
||||
);
|
||||
// if we do not have enough feeOrders to cover the fees, throw
|
||||
if (feeOrdersAndRemainingFeeAmount.remainingFeeAmount.gt(constants.ZERO_AMOUNT)) {
|
||||
throw new Error(AssetBuyerError.InsufficientZrxLiquidity);
|
||||
}
|
||||
resultFeeOrders = feeOrdersAndRemainingFeeAmount.resultFeeOrders;
|
||||
feeOrdersRemainingFillableMakerAssetAmounts =
|
||||
feeOrdersAndRemainingFeeAmount.feeOrdersRemainingFillableMakerAssetAmounts;
|
||||
}
|
||||
|
||||
// assetData information for the result
|
||||
const assetData = orders[0].makerAssetData;
|
||||
// compile the resulting trimmed set of orders for makerAsset and feeOrders that are needed for assetBuyAmount
|
||||
@@ -64,6 +76,7 @@ export const buyQuoteCalculator = {
|
||||
trimmedFeeOrdersAndFillableAmounts,
|
||||
assetBuyAmount,
|
||||
feePercentage,
|
||||
isMakerAssetZrxToken,
|
||||
);
|
||||
// in order to calculate the maxRate, reverse the ordersAndFillableAmounts such that they are sorted from worst rate to best rate
|
||||
const worstCaseQuoteInfo = calculateQuoteInfo(
|
||||
@@ -71,6 +84,7 @@ export const buyQuoteCalculator = {
|
||||
reverseOrdersAndFillableAmounts(trimmedFeeOrdersAndFillableAmounts),
|
||||
assetBuyAmount,
|
||||
feePercentage,
|
||||
isMakerAssetZrxToken,
|
||||
);
|
||||
return {
|
||||
assetData,
|
||||
@@ -89,22 +103,30 @@ function calculateQuoteInfo(
|
||||
feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
assetBuyAmount: BigNumber,
|
||||
feePercentage: number,
|
||||
isMakerAssetZrxToken: boolean,
|
||||
): BuyQuoteInfo {
|
||||
// find the total eth and zrx needed to buy assetAmount from the resultOrders from left to right
|
||||
const [ethAmountToBuyAsset, zrxAmountToBuyAsset] = findEthAndZrxAmountNeededToBuyAsset(
|
||||
ordersAndFillableAmounts,
|
||||
assetBuyAmount,
|
||||
);
|
||||
// find the total eth needed to buy fees
|
||||
const ethAmountToBuyFees = findEthAmountNeededToBuyFees(feeOrdersAndFillableAmounts, zrxAmountToBuyAsset);
|
||||
const affiliateFeeEthAmount = ethAmountToBuyAsset.mul(feePercentage);
|
||||
const totalEthAmountWithoutAffiliateFee = ethAmountToBuyAsset.plus(ethAmountToBuyFees);
|
||||
const totalEthAmount = totalEthAmountWithoutAffiliateFee.plus(affiliateFeeEthAmount);
|
||||
let ethAmountToBuyAsset = constants.ZERO_AMOUNT;
|
||||
let ethAmountToBuyZrx = constants.ZERO_AMOUNT;
|
||||
if (isMakerAssetZrxToken) {
|
||||
ethAmountToBuyAsset = findEthAmountNeededToBuyZrx(ordersAndFillableAmounts, assetBuyAmount);
|
||||
} else {
|
||||
// find eth and zrx amounts needed to buy
|
||||
const ethAndZrxAmountToBuyAsset = findEthAndZrxAmountNeededToBuyAsset(ordersAndFillableAmounts, assetBuyAmount);
|
||||
ethAmountToBuyAsset = ethAndZrxAmountToBuyAsset[0];
|
||||
const zrxAmountToBuyAsset = ethAndZrxAmountToBuyAsset[1];
|
||||
// find eth amount needed to buy zrx
|
||||
ethAmountToBuyZrx = findEthAmountNeededToBuyZrx(feeOrdersAndFillableAmounts, zrxAmountToBuyAsset);
|
||||
}
|
||||
/// find the eth amount needed to buy the affiliate fee
|
||||
const ethAmountToBuyAffiliateFee = ethAmountToBuyAsset.mul(feePercentage).ceil();
|
||||
const totalEthAmountWithoutAffiliateFee = ethAmountToBuyAsset.plus(ethAmountToBuyZrx);
|
||||
const ethAmountTotal = totalEthAmountWithoutAffiliateFee.plus(ethAmountToBuyAffiliateFee);
|
||||
// divide into the assetBuyAmount in order to find rate of makerAsset / WETH
|
||||
const ethPerAssetPrice = totalEthAmountWithoutAffiliateFee.div(assetBuyAmount);
|
||||
return {
|
||||
totalEthAmount,
|
||||
feeEthAmount: affiliateFeeEthAmount,
|
||||
totalEthAmount: ethAmountTotal,
|
||||
feeEthAmount: ethAmountToBuyAffiliateFee,
|
||||
ethPerAssetPrice,
|
||||
};
|
||||
}
|
||||
@@ -119,29 +141,38 @@ function reverseOrdersAndFillableAmounts(ordersAndFillableAmounts: OrdersAndFill
|
||||
};
|
||||
}
|
||||
|
||||
function findEthAmountNeededToBuyFees(
|
||||
function findEthAmountNeededToBuyZrx(
|
||||
feeOrdersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
feeAmount: BigNumber,
|
||||
zrxBuyAmount: BigNumber,
|
||||
): BigNumber {
|
||||
const { orders, remainingFillableMakerAssetAmounts } = feeOrdersAndFillableAmounts;
|
||||
const result = _.reduce(
|
||||
orders,
|
||||
(acc, order, index) => {
|
||||
const { totalEthAmount, remainingZrxBuyAmount } = acc;
|
||||
const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
|
||||
const amountToFill = BigNumber.min(acc.remainingFeeAmount, remainingFillableMakerAssetAmount);
|
||||
const feeAdjustedRate = rateUtils.getFeeAdjustedRateOfFeeOrder(order);
|
||||
const ethAmountForThisOrder = feeAdjustedRate.mul(amountToFill);
|
||||
const makerFillAmount = BigNumber.min(remainingZrxBuyAmount, remainingFillableMakerAssetAmount);
|
||||
const [takerFillAmount, adjustedMakerFillAmount] = orderUtils.getTakerFillAmountForFeeOrder(
|
||||
order,
|
||||
makerFillAmount,
|
||||
);
|
||||
const extraFeeAmount = remainingFillableMakerAssetAmount.greaterThanOrEqualTo(adjustedMakerFillAmount)
|
||||
? constants.ZERO_AMOUNT
|
||||
: adjustedMakerFillAmount.sub(makerFillAmount);
|
||||
return {
|
||||
ethAmount: acc.ethAmount.plus(ethAmountForThisOrder),
|
||||
remainingFeeAmount: BigNumber.max(constants.ZERO_AMOUNT, acc.remainingFeeAmount.minus(amountToFill)),
|
||||
totalEthAmount: totalEthAmount.plus(takerFillAmount),
|
||||
remainingZrxBuyAmount: BigNumber.max(
|
||||
constants.ZERO_AMOUNT,
|
||||
remainingZrxBuyAmount.minus(makerFillAmount).plus(extraFeeAmount),
|
||||
),
|
||||
};
|
||||
},
|
||||
{
|
||||
ethAmount: constants.ZERO_AMOUNT,
|
||||
remainingFeeAmount: feeAmount,
|
||||
totalEthAmount: constants.ZERO_AMOUNT,
|
||||
remainingZrxBuyAmount: zrxBuyAmount,
|
||||
},
|
||||
);
|
||||
return result.ethAmount;
|
||||
return result.totalEthAmount;
|
||||
}
|
||||
|
||||
function findEthAndZrxAmountNeededToBuyAsset(
|
||||
@@ -152,28 +183,25 @@ function findEthAndZrxAmountNeededToBuyAsset(
|
||||
const result = _.reduce(
|
||||
orders,
|
||||
(acc, order, index) => {
|
||||
const { totalEthAmount, totalZrxAmount, remainingAssetBuyAmount } = acc;
|
||||
const remainingFillableMakerAssetAmount = remainingFillableMakerAssetAmounts[index];
|
||||
const amountToFill = BigNumber.min(acc.remainingAssetBuyAmount, remainingFillableMakerAssetAmount);
|
||||
// find the amount of eth required to fill amountToFill (amountToFill / makerAssetAmount) * takerAssetAmount
|
||||
const ethAmountForThisOrder = amountToFill
|
||||
.mul(order.takerAssetAmount)
|
||||
.dividedToIntegerBy(order.makerAssetAmount);
|
||||
// find the amount of zrx required to fill fees for amountToFill (amountToFill / makerAssetAmount) * takerFee
|
||||
const zrxAmountForThisOrder = amountToFill.mul(order.takerFee).dividedToIntegerBy(order.makerAssetAmount);
|
||||
const makerFillAmount = BigNumber.min(acc.remainingAssetBuyAmount, remainingFillableMakerAssetAmount);
|
||||
const takerFillAmount = orderUtils.getTakerFillAmount(order, makerFillAmount);
|
||||
const takerFeeAmount = orderUtils.getTakerFeeAmount(order, takerFillAmount);
|
||||
return {
|
||||
ethAmount: acc.ethAmount.plus(ethAmountForThisOrder),
|
||||
zrxAmount: acc.zrxAmount.plus(zrxAmountForThisOrder),
|
||||
totalEthAmount: totalEthAmount.plus(takerFillAmount),
|
||||
totalZrxAmount: totalZrxAmount.plus(takerFeeAmount),
|
||||
remainingAssetBuyAmount: BigNumber.max(
|
||||
constants.ZERO_AMOUNT,
|
||||
acc.remainingAssetBuyAmount.minus(amountToFill),
|
||||
remainingAssetBuyAmount.minus(makerFillAmount),
|
||||
),
|
||||
};
|
||||
},
|
||||
{
|
||||
ethAmount: constants.ZERO_AMOUNT,
|
||||
zrxAmount: constants.ZERO_AMOUNT,
|
||||
totalEthAmount: constants.ZERO_AMOUNT,
|
||||
totalZrxAmount: constants.ZERO_AMOUNT,
|
||||
remainingAssetBuyAmount: assetBuyAmount,
|
||||
},
|
||||
);
|
||||
return [result.ethAmount, result.zrxAmount];
|
||||
return [result.totalEthAmount, result.totalZrxAmount];
|
||||
}
|
||||
|
@@ -110,10 +110,7 @@ function getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain(
|
||||
traderInfo.makerZrxBalance,
|
||||
]);
|
||||
const remainingTakerAssetAmount = order.takerAssetAmount.minus(orderInfo.orderTakerAssetFilledAmount);
|
||||
const remainingMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount(
|
||||
order,
|
||||
remainingTakerAssetAmount,
|
||||
);
|
||||
const remainingMakerAssetAmount = orderUtils.getRemainingMakerAmount(order, remainingTakerAssetAmount);
|
||||
const remainingFillableCalculator = new RemainingFillableCalculator(
|
||||
order.makerFee,
|
||||
order.makerAssetAmount,
|
||||
|
@@ -12,19 +12,63 @@ export const orderUtils = {
|
||||
const currentUnixTimestampSec = new BigNumber(Date.now() / millisecondsInSecond).round();
|
||||
return order.expirationTimeSeconds.lessThan(currentUnixTimestampSec.plus(secondsFromNow));
|
||||
},
|
||||
calculateRemainingMakerAssetAmount(order: SignedOrder, remainingTakerAssetAmount: BigNumber): BigNumber {
|
||||
if (remainingTakerAssetAmount.eq(0)) {
|
||||
return constants.ZERO_AMOUNT;
|
||||
}
|
||||
return remainingTakerAssetAmount.times(order.makerAssetAmount).dividedToIntegerBy(order.takerAssetAmount);
|
||||
},
|
||||
calculateRemainingTakerAssetAmount(order: SignedOrder, remainingMakerAssetAmount: BigNumber): BigNumber {
|
||||
if (remainingMakerAssetAmount.eq(0)) {
|
||||
return constants.ZERO_AMOUNT;
|
||||
}
|
||||
return remainingMakerAssetAmount.times(order.takerAssetAmount).dividedToIntegerBy(order.makerAssetAmount);
|
||||
},
|
||||
isOpenOrder(order: SignedOrder): boolean {
|
||||
return order.takerAddress === constants.NULL_ADDRESS;
|
||||
},
|
||||
// given a remaining amount of takerAsset, calculate how much makerAsset is available
|
||||
getRemainingMakerAmount(order: SignedOrder, remainingTakerAmount: BigNumber): BigNumber {
|
||||
const remainingMakerAmount = remainingTakerAmount
|
||||
.times(order.makerAssetAmount)
|
||||
.div(order.takerAssetAmount)
|
||||
.floor();
|
||||
return remainingMakerAmount;
|
||||
},
|
||||
// given a desired amount of makerAsset, calculate how much takerAsset is required to fill that amount
|
||||
getTakerFillAmount(order: SignedOrder, makerFillAmount: BigNumber): BigNumber {
|
||||
// Round up because exchange rate favors Maker
|
||||
const takerFillAmount = makerFillAmount
|
||||
.mul(order.takerAssetAmount)
|
||||
.div(order.makerAssetAmount)
|
||||
.ceil();
|
||||
return takerFillAmount;
|
||||
},
|
||||
// given a desired amount of takerAsset to fill, calculate how much fee is required by the taker to fill that amount
|
||||
getTakerFeeAmount(order: SignedOrder, takerFillAmount: BigNumber): BigNumber {
|
||||
// Round down because Taker fee rate favors Taker
|
||||
const takerFeeAmount = takerFillAmount
|
||||
.mul(order.takerFee)
|
||||
.div(order.takerAssetAmount)
|
||||
.floor();
|
||||
return takerFeeAmount;
|
||||
},
|
||||
// given a desired amount of takerAsset to fill, calculate how much makerAsset will be filled
|
||||
getMakerFillAmount(order: SignedOrder, takerFillAmount: BigNumber): BigNumber {
|
||||
// Round down because exchange rate favors Maker
|
||||
const makerFillAmount = takerFillAmount
|
||||
.mul(order.makerAssetAmount)
|
||||
.div(order.takerAssetAmount)
|
||||
.floor();
|
||||
return makerFillAmount;
|
||||
},
|
||||
// given a desired amount of makerAsset, calculate how much fee is required by the maker to fill that amount
|
||||
getMakerFeeAmount(order: SignedOrder, makerFillAmount: BigNumber): BigNumber {
|
||||
// Round down because Maker fee rate favors Maker
|
||||
const makerFeeAmount = makerFillAmount
|
||||
.mul(order.makerFee)
|
||||
.div(order.makerAssetAmount)
|
||||
.floor();
|
||||
return makerFeeAmount;
|
||||
},
|
||||
// given a desired amount of ZRX from a fee order, calculate how much takerAsset is required to fill that amount
|
||||
// also calculate how much ZRX needs to be bought in order fill the desired amount + takerFee
|
||||
getTakerFillAmountForFeeOrder(order: SignedOrder, makerFillAmount: BigNumber): [BigNumber, BigNumber] {
|
||||
// For each unit of TakerAsset we buy (MakerAsset - TakerFee)
|
||||
const adjustedTakerFillAmount = makerFillAmount
|
||||
.mul(order.takerAssetAmount)
|
||||
.div(order.makerAssetAmount.sub(order.takerFee))
|
||||
.ceil();
|
||||
// The amount that we buy will be greater than makerFillAmount, since we buy some amount for fees.
|
||||
const adjustedMakerFillAmount = orderUtils.getMakerFillAmount(order, adjustedTakerFillAmount);
|
||||
return [adjustedTakerFillAmount, adjustedMakerFillAmount];
|
||||
},
|
||||
};
|
||||
|
@@ -49,9 +49,9 @@ describe('buyQuoteCalculator', () => {
|
||||
remainingFillableMakerAssetAmounts: [smallFeeOrder.makerAssetAmount],
|
||||
};
|
||||
const largeFeeOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: new BigNumber(110),
|
||||
makerAssetAmount: new BigNumber(113),
|
||||
takerAssetAmount: new BigNumber(200),
|
||||
takerFee: new BigNumber(10),
|
||||
takerFee: new BigNumber(11),
|
||||
});
|
||||
allFeeOrdersAndFillableAmounts = {
|
||||
orders: [smallFeeOrder, largeFeeOrder],
|
||||
@@ -70,6 +70,7 @@ describe('buyQuoteCalculator', () => {
|
||||
new BigNumber(500),
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
).to.throw(AssetBuyerError.InsufficientAssetLiquidity);
|
||||
});
|
||||
@@ -82,6 +83,7 @@ describe('buyQuoteCalculator', () => {
|
||||
new BigNumber(300),
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
),
|
||||
).to.throw(AssetBuyerError.InsufficientZrxLiquidity);
|
||||
});
|
||||
@@ -97,6 +99,7 @@ describe('buyQuoteCalculator', () => {
|
||||
assetBuyAmount,
|
||||
feePercentage,
|
||||
slippagePercentage,
|
||||
false,
|
||||
);
|
||||
// test if orders are correct
|
||||
expect(buyQuote.orders).to.deep.equal([ordersAndFillableAmounts.orders[0]]);
|
||||
@@ -134,6 +137,7 @@ describe('buyQuoteCalculator', () => {
|
||||
assetBuyAmount,
|
||||
feePercentage,
|
||||
slippagePercentage,
|
||||
false,
|
||||
);
|
||||
// test if orders are correct
|
||||
expect(buyQuote.orders).to.deep.equal(ordersAndFillableAmounts.orders);
|
||||
@@ -149,9 +153,9 @@ describe('buyQuoteCalculator', () => {
|
||||
expect(buyQuote.bestCaseQuoteInfo.feeEthAmount).to.bignumber.equal(expectedFeeEthAmount);
|
||||
expect(buyQuote.bestCaseQuoteInfo.totalEthAmount).to.bignumber.equal(expectedTotalEthAmount);
|
||||
expect(buyQuote.bestCaseQuoteInfo.ethPerAssetPrice).to.bignumber.equal(expectedEthPerAssetPrice);
|
||||
// 100 eth to fill the first order + 200 eth for fees
|
||||
// 100 eth to fill the first order + 208 eth for fees
|
||||
const expectedWorstEthAmountForAsset = new BigNumber(100);
|
||||
const expectedWorstEthAmountForZrxFees = new BigNumber(200);
|
||||
const expectedWorstEthAmountForZrxFees = new BigNumber(208);
|
||||
const expectedWorstFillEthAmount = expectedWorstEthAmountForAsset.plus(expectedWorstEthAmountForZrxFees);
|
||||
const expectedWorstFeeEthAmount = expectedWorstEthAmountForAsset.mul(feePercentage);
|
||||
const expectedWorstTotalEthAmount = expectedWorstFillEthAmount.plus(expectedWorstFeeEthAmount);
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "3.0.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"timestamp": 1539871071,
|
||||
"version": "3.0.2",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.0.4 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.0.3 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.0.2 - _October 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/base-contract",
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.4",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -17,7 +17,7 @@
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --bail --exit",
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
|
||||
"lint": "tslint --project . --exclude **/src/contract_wrappers/**/*"
|
||||
"lint": "tslint --format stylish --project ."
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "4.14.104",
|
||||
"chai": "^4.0.1",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
@@ -40,10 +40,10 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"ethers": "~4.0.4",
|
||||
"lodash": "^4.17.5"
|
||||
},
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "3.0.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "3.0.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"timestamp": 1539871071,
|
||||
"version": "3.0.2",
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v3.0.4 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.0.3 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v3.0.2 - _October 18, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/connect",
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.4",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -19,7 +19,7 @@
|
||||
"build:ci": "yarn build",
|
||||
"clean": "shx rm -rf lib test_temp generated_docs",
|
||||
"copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
|
||||
"test": "run-s copy_test_fixtures run_mocha",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
@@ -44,12 +44,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.14",
|
||||
"@0x/json-schemas": "^2.0.0",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/assert": "^1.0.16",
|
||||
"@0x/json-schemas": "^2.1.0",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"lodash": "^4.17.5",
|
||||
"query-string": "^5.0.1",
|
||||
"sinon": "^4.0.0",
|
||||
@@ -57,7 +57,7 @@
|
||||
"websocket": "^1.0.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/fetch-mock": "^6.0.3",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
|
@@ -19,7 +19,6 @@ import { fetchAsync } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
import * as queryString from 'query-string';
|
||||
|
||||
import { schemas as clientSchemas } from './schemas/schemas';
|
||||
import { Client, HttpRequestOptions, HttpRequestType } from './types';
|
||||
import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
|
||||
|
||||
@@ -61,9 +60,9 @@ export class HttpClient implements Client {
|
||||
requestOpts?: RequestOpts & AssetPairsRequestOpts & PagedRequestOpts,
|
||||
): Promise<AssetPairsResponse> {
|
||||
if (!_.isUndefined(requestOpts)) {
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.assetPairsRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.assetPairsRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.requestOptsSchema);
|
||||
}
|
||||
const httpRequestOpts = {
|
||||
params: requestOpts,
|
||||
@@ -81,9 +80,9 @@ export class HttpClient implements Client {
|
||||
requestOpts?: RequestOpts & OrdersRequestOpts & PagedRequestOpts,
|
||||
): Promise<OrdersResponse> {
|
||||
if (!_.isUndefined(requestOpts)) {
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.ordersRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.ordersRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.requestOptsSchema);
|
||||
}
|
||||
const httpRequestOpts = {
|
||||
params: requestOpts,
|
||||
@@ -99,7 +98,7 @@ export class HttpClient implements Client {
|
||||
*/
|
||||
public async getOrderAsync(orderHash: string, requestOpts?: RequestOpts): Promise<APIOrder> {
|
||||
if (!_.isUndefined(requestOpts)) {
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.requestOptsSchema);
|
||||
}
|
||||
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
|
||||
const httpRequestOpts = {
|
||||
@@ -119,10 +118,10 @@ export class HttpClient implements Client {
|
||||
request: OrderbookRequest,
|
||||
requestOpts?: RequestOpts & PagedRequestOpts,
|
||||
): Promise<OrderbookResponse> {
|
||||
assert.doesConformToSchema('request', request, clientSchemas.orderBookRequestSchema);
|
||||
assert.doesConformToSchema('request', request, schemas.orderBookRequestSchema);
|
||||
if (!_.isUndefined(requestOpts)) {
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.requestOptsSchema);
|
||||
}
|
||||
const httpRequestOpts = {
|
||||
params: _.defaults({}, request, requestOpts),
|
||||
@@ -142,9 +141,9 @@ export class HttpClient implements Client {
|
||||
requestOpts?: RequestOpts,
|
||||
): Promise<OrderConfigResponse> {
|
||||
if (!_.isUndefined(requestOpts)) {
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.requestOptsSchema);
|
||||
}
|
||||
assert.doesConformToSchema('request', request, clientSchemas.orderConfigRequestSchema);
|
||||
assert.doesConformToSchema('request', request, schemas.orderConfigRequestSchema);
|
||||
const httpRequestOpts = {
|
||||
params: requestOpts,
|
||||
payload: request,
|
||||
@@ -160,8 +159,8 @@ export class HttpClient implements Client {
|
||||
*/
|
||||
public async getFeeRecipientsAsync(requestOpts?: RequestOpts & PagedRequestOpts): Promise<FeeRecipientsResponse> {
|
||||
if (!_.isUndefined(requestOpts)) {
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.pagedRequestOptsSchema);
|
||||
assert.doesConformToSchema('requestOpts', requestOpts, schemas.requestOptsSchema);
|
||||
}
|
||||
const httpRequestOpts = {
|
||||
params: requestOpts,
|
||||
|
@@ -1,8 +0,0 @@
|
||||
export const assetPairsRequestOptsSchema = {
|
||||
id: '/AssetPairsRequestOpts',
|
||||
type: 'object',
|
||||
properties: {
|
||||
assetDataA: { $ref: '/hexSchema' },
|
||||
assetDataB: { $ref: '/hexSchema' },
|
||||
},
|
||||
};
|
@@ -1,24 +0,0 @@
|
||||
export const orderConfigRequestSchema = {
|
||||
id: '/OrderConfigRequest',
|
||||
type: 'object',
|
||||
properties: {
|
||||
makerAddress: { $ref: '/addressSchema' },
|
||||
takerAddress: { $ref: '/addressSchema' },
|
||||
makerAssetAmount: { $ref: '/numberSchema' },
|
||||
takerAssetAmount: { $ref: '/numberSchema' },
|
||||
makerAssetData: { $ref: '/hexSchema' },
|
||||
takerAssetData: { $ref: '/hexSchema' },
|
||||
exchangeAddress: { $ref: '/addressSchema' },
|
||||
expirationTimeSeconds: { $ref: '/numberSchema' },
|
||||
},
|
||||
required: [
|
||||
'makerAddress',
|
||||
'takerAddress',
|
||||
'makerAssetAmount',
|
||||
'takerAssetAmount',
|
||||
'makerAssetData',
|
||||
'takerAssetData',
|
||||
'exchangeAddress',
|
||||
'expirationTimeSeconds',
|
||||
],
|
||||
};
|
@@ -1,9 +0,0 @@
|
||||
export const orderBookRequestSchema = {
|
||||
id: '/OrderBookRequest',
|
||||
type: 'object',
|
||||
properties: {
|
||||
baseAssetData: { $ref: '/hexSchema' },
|
||||
quoteAssetData: { $ref: '/hexSchema' },
|
||||
},
|
||||
required: ['baseAssetData', 'quoteAssetData'],
|
||||
};
|
@@ -1,19 +0,0 @@
|
||||
export const ordersRequestOptsSchema = {
|
||||
id: '/OrdersRequestOpts',
|
||||
type: 'object',
|
||||
properties: {
|
||||
makerAssetProxyId: { $ref: '/hexSchema' },
|
||||
takerAssetProxyId: { $ref: '/hexSchema' },
|
||||
makerAssetAddress: { $ref: '/addressSchema' },
|
||||
takerAssetAddress: { $ref: '/addressSchema' },
|
||||
exchangeAddress: { $ref: '/addressSchema' },
|
||||
senderAddress: { $ref: '/addressSchema' },
|
||||
makerAssetData: { $ref: '/hexSchema' },
|
||||
takerAssetData: { $ref: '/hexSchema' },
|
||||
traderAssetData: { $ref: '/hexSchema' },
|
||||
makerAddress: { $ref: '/addressSchema' },
|
||||
takerAddress: { $ref: '/addressSchema' },
|
||||
traderAddress: { $ref: '/addressSchema' },
|
||||
feeRecipientAddress: { $ref: '/addressSchema' },
|
||||
},
|
||||
};
|
@@ -1,8 +0,0 @@
|
||||
export const pagedRequestOptsSchema = {
|
||||
id: '/PagedRequestOpts',
|
||||
type: 'object',
|
||||
properties: {
|
||||
page: { type: 'number' },
|
||||
perPage: { type: 'number' },
|
||||
},
|
||||
};
|
@@ -1,7 +0,0 @@
|
||||
export const requestOptsSchema = {
|
||||
id: '/RequestOpts',
|
||||
type: 'object',
|
||||
properties: {
|
||||
networkId: { type: 'number' },
|
||||
},
|
||||
};
|
@@ -1,15 +0,0 @@
|
||||
import { assetPairsRequestOptsSchema } from './asset_pairs_request_opts_schema';
|
||||
import { orderConfigRequestSchema } from './order_config_request_schema';
|
||||
import { orderBookRequestSchema } from './orderbook_request_schema';
|
||||
import { ordersRequestOptsSchema } from './orders_request_opts_schema';
|
||||
import { pagedRequestOptsSchema } from './paged_request_opts_schema';
|
||||
import { requestOptsSchema } from './request_opts_schema';
|
||||
|
||||
export const schemas = {
|
||||
orderConfigRequestSchema,
|
||||
orderBookRequestSchema,
|
||||
ordersRequestOptsSchema,
|
||||
pagedRequestOptsSchema,
|
||||
requestOptsSchema,
|
||||
assetPairsRequestOptsSchema,
|
||||
};
|
@@ -1,4 +1,14 @@
|
||||
[
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"pr": 1192,
|
||||
"note": "Update Forwarder addresses"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.0 - _November 9, 2018_
|
||||
|
||||
* Update Forwarder addresses (#1192)
|
||||
|
||||
## v1.0.1 - _October 18, 2018_
|
||||
|
||||
* Initial release (#1105)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contract-addresses",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
|
@@ -25,7 +25,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
|
||||
etherToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
exchange: '0x4f833a24e1f95d70f028921e27040ca56e09ab0b',
|
||||
assetProxyOwner: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6',
|
||||
forwarder: '0x7afc2d5107af94c462a194d2c21b5bdd238709d6',
|
||||
forwarder: '0x5468a1dc173652ee28d249c271fa9933144746b1',
|
||||
orderValidator: '0x9463e518dea6810309563c81d5266c1b1d149138',
|
||||
},
|
||||
3: {
|
||||
@@ -35,7 +35,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
|
||||
etherToken: '0xc778417e063141139fce010982780140aa0cd5ab',
|
||||
exchange: '0x4530c0483a1633c7a1c97d2c53721caff2caaaaf',
|
||||
assetProxyOwner: '0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b',
|
||||
forwarder: '0x3983e204b12b3c02fb0638caf2cd406a62e0ead3',
|
||||
forwarder: '0x2240dab907db71e64d3e0dba4800c83b5c502d4e',
|
||||
orderValidator: '0x90431a90516ab49af23a0530e04e8c7836e7122f',
|
||||
},
|
||||
42: {
|
||||
@@ -45,7 +45,7 @@ const networkToAddresses: { [networkId: number]: ContractAddresses } = {
|
||||
etherToken: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
exchange: '0x35dd2932454449b14cee11a94d3674a936d5d7b2',
|
||||
assetProxyOwner: '0x2c824d2882baa668e0d5202b1e7f2922278703f8',
|
||||
forwarder: '0xd85e2fa7e7e252b27b01bf0d65c946959d2f45b8',
|
||||
forwarder: '0x17992e4ffb22730138e4b62aaa6367fa9d3699a6',
|
||||
orderValidator: '0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d',
|
||||
},
|
||||
};
|
||||
|
@@ -1,4 +1,14 @@
|
||||
[
|
||||
{
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"pr": 1192,
|
||||
"note": "Update Forwarder artifact"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.0 - _November 9, 2018_
|
||||
|
||||
* Update Forwarder artifact (#1192)
|
||||
|
||||
## v1.0.1 - _October 18, 2018_
|
||||
|
||||
* Initial release (#1105)
|
||||
|
887
packages/contract-artifacts/artifacts/Forwarder.json
generated
887
packages/contract-artifacts/artifacts/Forwarder.json
generated
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contract-artifacts",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
|
@@ -1,4 +1,35 @@
|
||||
[
|
||||
{
|
||||
"version": "4.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note":
|
||||
"Add signature validation, regular cancellation and `cancelledUpTo` checks to `validateOrderFillableOrThrowAsync`",
|
||||
"pr": 1235
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Improved the errors thrown by `validateOrderFillableOrThrowAsync` by making them more descriptive",
|
||||
"pr": 1235
|
||||
},
|
||||
{
|
||||
"note":
|
||||
"Throw previously swallowed network errors when calling `validateOrderFillableOrThrowAsync` (see issue: #1218)",
|
||||
"pr": 1235
|
||||
}
|
||||
],
|
||||
"timestamp": 1542028948
|
||||
},
|
||||
{
|
||||
"version": "3.0.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Fix bug in `ForwarderWrapper` where `feeRecipientAddress` was not correctly normalized.",
|
||||
"pr": 1178
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"changes": [
|
||||
@@ -37,6 +68,14 @@
|
||||
"note":
|
||||
"Removed ContractNotFound errors. Checking for this error was somewhat ineffecient. Relevant methods/functions now return the default error from web3-wrapper, which we feel provides enough information.",
|
||||
"pr": 1105
|
||||
},
|
||||
{
|
||||
"note": "Add `ForwarderWrapperError` to public interface",
|
||||
"pr": 1147
|
||||
},
|
||||
{
|
||||
"note": "Add `ContractWrapperError.SignatureRequestDenied` to public interface",
|
||||
"pr": 1147
|
||||
}
|
||||
],
|
||||
"timestamp": 1539871071
|
||||
|
@@ -5,6 +5,16 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.0.0 - _November 12, 2018_
|
||||
|
||||
* Add signature validation, regular cancellation and `cancelledUpTo` checks to `validateOrderFillableOrThrowAsync` (#1235)
|
||||
* Improved the errors thrown by `validateOrderFillableOrThrowAsync` by making them more descriptive (#1235)
|
||||
* Throw previously swallowed network errors when calling `validateOrderFillableOrThrowAsync` (see issue: #1218) (#1235)
|
||||
|
||||
## v3.0.1 - _November 9, 2018_
|
||||
|
||||
* Fix bug in `ForwarderWrapper` where `feeRecipientAddress` was not correctly normalized. (#1178)
|
||||
|
||||
## v3.0.0 - _October 18, 2018_
|
||||
|
||||
* Add optional validation to the forwarder wrapper methods
|
||||
@@ -15,6 +25,8 @@ CHANGELOG
|
||||
* Removed `setProvider` method in top-level `ContractWrapper` class and added new `unsubscribeAll` method. (#1105)
|
||||
* Some properties and methods have been renamed. For example, some methods that previously could throw no longer can, and so their names have been updated accordingly. (#1105)
|
||||
* Removed ContractNotFound errors. Checking for this error was somewhat ineffecient. Relevant methods/functions now return the default error from web3-wrapper, which we feel provides enough information. (#1105)
|
||||
* Add `ForwarderWrapperError` to public interface (#1147)
|
||||
* Add `ContractWrapperError.SignatureRequestDenied` to public interface (#1147)
|
||||
|
||||
## v2.0.2 - _October 4, 2018_
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/contract-wrappers",
|
||||
"version": "3.0.0",
|
||||
"version": "4.0.0",
|
||||
"description": "Smart TS wrappers for 0x smart contracts",
|
||||
"keywords": [
|
||||
"0xproject",
|
||||
@@ -13,7 +13,7 @@
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*",
|
||||
"lint": "tslint --format stylish --project . --exclude **/lib/**/*",
|
||||
"test:circleci": "run-s test:coverage",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s build test",
|
||||
@@ -37,10 +37,10 @@
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/dev-utils": "^1.0.13",
|
||||
"@0x/migrations": "^2.0.0",
|
||||
"@0x/subproviders": "^2.1.0",
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/dev-utils": "^1.0.15",
|
||||
"@0x/migrations": "^2.0.2",
|
||||
"@0x/subproviders": "^2.1.2",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "*",
|
||||
@@ -65,18 +65,18 @@
|
||||
"web3-provider-engine": "14.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/abi-gen-wrappers": "^1.0.1",
|
||||
"@0x/assert": "^1.0.14",
|
||||
"@0x/contract-addresses": "^1.0.1",
|
||||
"@0x/contract-artifacts": "^1.0.1",
|
||||
"@0x/fill-scenarios": "^1.0.8",
|
||||
"@0x/json-schemas": "^2.0.0",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"@0x/abi-gen-wrappers": "^1.0.3",
|
||||
"@0x/assert": "^1.0.16",
|
||||
"@0x/contract-addresses": "^1.1.0",
|
||||
"@0x/contract-artifacts": "^1.1.0",
|
||||
"@0x/fill-scenarios": "^1.0.10",
|
||||
"@0x/json-schemas": "^2.1.0",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"ethereumjs-blockstream": "6.0.0",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"ethers": "~4.0.4",
|
||||
|
@@ -28,10 +28,10 @@ export abstract class ContractWrapper {
|
||||
protected _networkId: number;
|
||||
protected _web3Wrapper: Web3Wrapper;
|
||||
private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined;
|
||||
private _blockPollingIntervalMs: number;
|
||||
private readonly _blockPollingIntervalMs: number;
|
||||
private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer;
|
||||
private _filters: { [filterToken: string]: FilterObject };
|
||||
private _filterCallbacks: {
|
||||
private readonly _filters: { [filterToken: string]: FilterObject };
|
||||
private readonly _filterCallbacks: {
|
||||
[filterToken: string]: EventCallback<ContractEventArgs>;
|
||||
};
|
||||
private _onLogAddedSubscriptionToken: string | undefined;
|
||||
|
@@ -34,6 +34,9 @@ export class ERC20ProxyWrapper extends ContractWrapper {
|
||||
*/
|
||||
public async getProxyIdAsync(): Promise<AssetProxyId> {
|
||||
const ERC20ProxyContractInstance = this._getERC20ProxyContract();
|
||||
// Note(albrow): Below is a TSLint false positive. Code won't compile if
|
||||
// you remove the type assertion.
|
||||
/* tslint:disable-next-line:no-unnecessary-type-assertion */
|
||||
const proxyId = (await ERC20ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId;
|
||||
return proxyId;
|
||||
}
|
||||
|
@@ -18,12 +18,11 @@ import {
|
||||
} from '../types';
|
||||
import { assert } from '../utils/assert';
|
||||
import { constants } from '../utils/constants';
|
||||
import { utils } from '../utils/utils';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { ERC20ProxyWrapper } from './erc20_proxy_wrapper';
|
||||
|
||||
const removeUndefinedProperties = _.pickBy;
|
||||
|
||||
/**
|
||||
* This class includes all the functionality related to interacting with ERC20 token contracts.
|
||||
* All ERC20 method calls are supported, along with some convenience methods for getting/setting allowances
|
||||
@@ -32,8 +31,8 @@ const removeUndefinedProperties = _.pickBy;
|
||||
export class ERC20TokenWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = ERC20Token.compilerOutput.abi;
|
||||
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
||||
private _tokenContractsByAddress: { [address: string]: ERC20TokenContract };
|
||||
private _erc20ProxyWrapper: ERC20ProxyWrapper;
|
||||
private readonly _tokenContractsByAddress: { [address: string]: ERC20TokenContract };
|
||||
private readonly _erc20ProxyWrapper: ERC20ProxyWrapper;
|
||||
/**
|
||||
* Instantiate ERC20TokenWrapper
|
||||
* @param web3Wrapper Web3Wrapper instance to use
|
||||
@@ -108,7 +107,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
|
||||
const txHash = await tokenContract.approve.sendTransactionAsync(
|
||||
normalizedSpenderAddress,
|
||||
amountInBaseUnits,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
from: normalizedOwnerAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
@@ -278,7 +277,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
|
||||
const txHash = await tokenContract.transfer.sendTransactionAsync(
|
||||
normalizedToAddress,
|
||||
amountInBaseUnits,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
from: normalizedFromAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
@@ -339,7 +338,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
|
||||
normalizedFromAddress,
|
||||
normalizedToAddress,
|
||||
amountInBaseUnits,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
from: normalizedSenderAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
|
@@ -34,6 +34,9 @@ export class ERC721ProxyWrapper extends ContractWrapper {
|
||||
*/
|
||||
public async getProxyIdAsync(): Promise<AssetProxyId> {
|
||||
const ERC721ProxyContractInstance = await this._getERC721ProxyContract();
|
||||
// Note(albrow): Below is a TSLint false positive. Code won't compile if
|
||||
// you remove the type assertion.
|
||||
/* tslint:disable-next-line:no-unnecessary-type-assertion */
|
||||
const proxyId = (await ERC721ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId;
|
||||
return proxyId;
|
||||
}
|
||||
|
@@ -18,12 +18,11 @@ import {
|
||||
} from '../types';
|
||||
import { assert } from '../utils/assert';
|
||||
import { constants } from '../utils/constants';
|
||||
import { utils } from '../utils/utils';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { ERC721ProxyWrapper } from './erc721_proxy_wrapper';
|
||||
|
||||
const removeUndefinedProperties = _.pickBy;
|
||||
|
||||
/**
|
||||
* This class includes all the functionality related to interacting with ERC721 token contracts.
|
||||
* All ERC721 method calls are supported, along with some convenience methods for getting/setting allowances
|
||||
@@ -31,8 +30,8 @@ const removeUndefinedProperties = _.pickBy;
|
||||
*/
|
||||
export class ERC721TokenWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = ERC721Token.compilerOutput.abi;
|
||||
private _tokenContractsByAddress: { [address: string]: ERC721TokenContract };
|
||||
private _erc721ProxyWrapper: ERC721ProxyWrapper;
|
||||
private readonly _tokenContractsByAddress: { [address: string]: ERC721TokenContract };
|
||||
private readonly _erc721ProxyWrapper: ERC721ProxyWrapper;
|
||||
/**
|
||||
* Instantiate ERC721TokenWrapper
|
||||
* @param web3Wrapper Web3Wrapper instance to use
|
||||
@@ -235,7 +234,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
const txHash = await tokenContract.setApprovalForAll.sendTransactionAsync(
|
||||
normalizedOperatorAddress,
|
||||
isApproved,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
from: normalizedOwnerAddress,
|
||||
@@ -295,7 +294,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
const txHash = await tokenContract.approve.sendTransactionAsync(
|
||||
normalizedApprovedAddress,
|
||||
tokenId,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
from: tokenOwnerAddress,
|
||||
@@ -366,7 +365,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
|
||||
ownerAddress,
|
||||
normalizedReceiverAddress,
|
||||
tokenId,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
from: normalizedSenderAddress,
|
||||
|
@@ -8,22 +8,21 @@ import * as _ from 'lodash';
|
||||
|
||||
import { BlockRange, ContractWrappersError, EventCallback, IndexedFilterValues, TransactionOpts } from '../types';
|
||||
import { assert } from '../utils/assert';
|
||||
import { utils } from '../utils/utils';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { ERC20TokenWrapper } from './erc20_token_wrapper';
|
||||
|
||||
const removeUndefinedProperties = _.pickBy;
|
||||
|
||||
/**
|
||||
* This class includes all the functionality related to interacting with a wrapped Ether ERC20 token contract.
|
||||
* The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
|
||||
*/
|
||||
export class EtherTokenWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = WETH9.compilerOutput.abi;
|
||||
private _etherTokenContractsByAddress: {
|
||||
private readonly _etherTokenContractsByAddress: {
|
||||
[address: string]: WETH9Contract;
|
||||
} = {};
|
||||
private _erc20TokenWrapper: ERC20TokenWrapper;
|
||||
private readonly _erc20TokenWrapper: ERC20TokenWrapper;
|
||||
/**
|
||||
* Instantiate EtherTokenWrapper.
|
||||
* @param web3Wrapper Web3Wrapper instance to use
|
||||
@@ -67,7 +66,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
|
||||
const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
|
||||
const txHash = await wethContract.deposit.sendTransactionAsync(
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
from: normalizedDepositorAddress,
|
||||
value: amountInWei,
|
||||
gas: txOpts.gasLimit,
|
||||
@@ -109,7 +108,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
|
||||
const txHash = await wethContract.withdraw.sendTransactionAsync(
|
||||
amountInWei,
|
||||
removeUndefinedProperties({
|
||||
utils.removeUndefinedProperties({
|
||||
from: normalizedWithdrawerAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
|
@@ -18,6 +18,7 @@ import { OrderFilledCancelledFetcher } from '../fetchers/order_filled_cancelled_
|
||||
import { methodOptsSchema } from '../schemas/method_opts_schema';
|
||||
import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema';
|
||||
import { txOptsSchema } from '../schemas/tx_opts_schema';
|
||||
import { validateOrderFillableOptsSchema } from '../schemas/validate_order_fillable_opts_schema';
|
||||
import {
|
||||
BlockRange,
|
||||
EventCallback,
|
||||
@@ -46,8 +47,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
public address: string;
|
||||
public zrxTokenAddress: string;
|
||||
private _exchangeContractIfExists?: ExchangeContract;
|
||||
private _erc721TokenWrapper: ERC721TokenWrapper;
|
||||
private _erc20TokenWrapper: ERC20TokenWrapper;
|
||||
private readonly _erc721TokenWrapper: ERC721TokenWrapper;
|
||||
private readonly _erc20TokenWrapper: ERC20TokenWrapper;
|
||||
/**
|
||||
* Instantiate ExchangeWrapper
|
||||
* @param web3Wrapper Web3Wrapper instance to use.
|
||||
@@ -1114,6 +1115,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
signedOrder: SignedOrder,
|
||||
opts: ValidateOrderFillableOpts = {},
|
||||
): Promise<void> {
|
||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||
assert.doesConformToSchema('opts', opts, validateOrderFillableOptsSchema);
|
||||
|
||||
const balanceAllowanceFetcher = new AssetBalanceAndProxyAllowanceFetcher(
|
||||
this._erc20TokenWrapper,
|
||||
this._erc721TokenWrapper,
|
||||
@@ -1124,7 +1128,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
|
||||
const expectedFillTakerTokenAmountIfExists = opts.expectedFillTakerTokenAmount;
|
||||
const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest);
|
||||
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher);
|
||||
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider());
|
||||
await orderValidationUtils.validateOrderFillableOrThrowAsync(
|
||||
exchangeTradeSimulator,
|
||||
signedOrder,
|
||||
@@ -1152,7 +1156,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
||||
const exchangeTradeSimulator = new ExchangeTransferSimulator(balanceAllowanceStore);
|
||||
|
||||
const filledCancelledFetcher = new OrderFilledCancelledFetcher(this, BlockParamLiteral.Latest);
|
||||
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher);
|
||||
const orderValidationUtils = new OrderValidationUtils(filledCancelledFetcher, this._web3Wrapper.getProvider());
|
||||
await orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||
exchangeTradeSimulator,
|
||||
this._web3Wrapper.getProvider(),
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { ForwarderContract } from '@0x/abi-gen-wrappers';
|
||||
import { Forwarder } from '@0x/contract-artifacts';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import { AssetProxyId, SignedOrder } from '@0x/types';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { ContractAbi } from 'ethereum-types';
|
||||
@@ -118,7 +118,7 @@ export class ForwarderWrapper extends ContractWrapper {
|
||||
optimizedFeeOrders,
|
||||
feeSignatures,
|
||||
formattedFeePercentage,
|
||||
feeRecipientAddress,
|
||||
normalizedFeeRecipientAddress,
|
||||
{
|
||||
value: ethAmount,
|
||||
from: normalizedTakerAddress,
|
||||
@@ -207,7 +207,7 @@ export class ForwarderWrapper extends ContractWrapper {
|
||||
optimizedFeeOrders,
|
||||
feeSignatures,
|
||||
formattedFeePercentage,
|
||||
feeRecipientAddress,
|
||||
normalizedFeeRecipientAddress,
|
||||
{
|
||||
value: ethAmount,
|
||||
from: normalizedTakerAddress,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
// tslint:disable:no-unnecessary-type-assertion
|
||||
import { AbstractOrderFilledCancelledFetcher } from '@0x/order-utils';
|
||||
import { AbstractOrderFilledCancelledFetcher, orderHashUtils } from '@0x/order-utils';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { BlockParamLiteral } from 'ethereum-types';
|
||||
|
||||
@@ -18,9 +19,18 @@ export class OrderFilledCancelledFetcher implements AbstractOrderFilledCancelled
|
||||
});
|
||||
return filledTakerAmount;
|
||||
}
|
||||
public async isOrderCancelledAsync(orderHash: string): Promise<boolean> {
|
||||
public async isOrderCancelledAsync(signedOrder: SignedOrder): Promise<boolean> {
|
||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const isCancelled = await this._exchange.isCancelledAsync(orderHash);
|
||||
return isCancelled;
|
||||
const orderEpoch = await this._exchange.getOrderEpochAsync(
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.senderAddress,
|
||||
{
|
||||
defaultBlock: this._stateLayer,
|
||||
},
|
||||
);
|
||||
const isCancelledByOrderEpoch = orderEpoch > signedOrder.salt;
|
||||
return isCancelled || isCancelledByOrderEpoch;
|
||||
}
|
||||
public getZRXAssetData(): string {
|
||||
const zrxAssetData = this._exchange.getZRXAssetData();
|
||||
|
@@ -39,6 +39,7 @@ export { TransactionEncoder } from './utils/transaction_encoder';
|
||||
|
||||
export {
|
||||
ContractWrappersError,
|
||||
ForwarderWrapperError,
|
||||
IndexedFilterValues,
|
||||
BlockRange,
|
||||
ContractWrappersConfig,
|
||||
|
@@ -0,0 +1,7 @@
|
||||
export const validateOrderFillableOptsSchema = {
|
||||
id: '/ValidateOrderFillableOpts',
|
||||
properties: {
|
||||
expectedFillTakerTokenAmount: { $ref: '/wholeNumberSchema' },
|
||||
},
|
||||
type: 'object',
|
||||
};
|
@@ -18,6 +18,10 @@ export enum ExchangeWrapperError {
|
||||
AssetDataMismatch = 'ASSET_DATA_MISMATCH',
|
||||
}
|
||||
|
||||
export enum ForwarderWrapperError {
|
||||
CompleteFillFailed = 'COMPLETE_FILL_FAILED',
|
||||
}
|
||||
|
||||
export enum ContractWrappersError {
|
||||
ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
|
||||
InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
|
||||
@@ -30,6 +34,7 @@ export enum ContractWrappersError {
|
||||
SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
|
||||
ERC721OwnerNotFound = 'ERC_721_OWNER_NOT_FOUND',
|
||||
ERC721NoApproval = 'ERC_721_NO_APPROVAL',
|
||||
SignatureRequestDenied = 'SIGNATURE_REQUEST_DENIED',
|
||||
}
|
||||
|
||||
export enum InternalContractWrappersError {
|
||||
|
@@ -14,4 +14,5 @@ export const constants = {
|
||||
ZERO_AMOUNT: new BigNumber(0),
|
||||
ONE_AMOUNT: new BigNumber(1),
|
||||
ETHER_TOKEN_DECIMALS: 18,
|
||||
USER_DENIED_SIGNATURE_PATTERN: 'User denied transaction signature',
|
||||
};
|
||||
|
@@ -29,6 +29,14 @@ const schemaErrorTransformer = (error: Error) => {
|
||||
return error;
|
||||
};
|
||||
|
||||
const signatureRequestErrorTransformer = (error: Error) => {
|
||||
if (_.includes(error.message, constants.USER_DENIED_SIGNATURE_PATTERN)) {
|
||||
const errMsg = ContractWrappersError.SignatureRequestDenied;
|
||||
return new Error(errMsg);
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
/**
|
||||
* Source: https://stackoverflow.com/a/29837695/3546986
|
||||
*/
|
||||
@@ -87,7 +95,11 @@ const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||
};
|
||||
|
||||
// _.flow(f, g) = f ∘ g
|
||||
const zeroExErrorTransformer = _.flow(schemaErrorTransformer, contractCallErrorTransformer);
|
||||
const zeroExErrorTransformer = _.flow(
|
||||
schemaErrorTransformer,
|
||||
contractCallErrorTransformer,
|
||||
signatureRequestErrorTransformer,
|
||||
);
|
||||
|
||||
export const decorators = {
|
||||
asyncZeroExErrorHandler: asyncErrorHandlerFactory(zeroExErrorTransformer),
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { constants } from './constants';
|
||||
|
||||
@@ -14,4 +15,7 @@ export const utils = {
|
||||
numberPercentageToEtherTokenAmountPercentage(percentage: number): BigNumber {
|
||||
return Web3Wrapper.toBaseUnitAmount(constants.ONE_AMOUNT, constants.ETHER_TOKEN_DECIMALS).mul(percentage);
|
||||
},
|
||||
removeUndefinedProperties<T extends object>(obj: T): Partial<T> {
|
||||
return _.pickBy(obj);
|
||||
},
|
||||
};
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { BlockchainLifecycle, callbackErrorReporter } from '@0x/dev-utils';
|
||||
import { FillScenarios } from '@0x/fill-scenarios';
|
||||
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
|
||||
import { DoneCallback, SignedOrder } from '@0x/types';
|
||||
import { DoneCallback, RevertReason, SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as chai from 'chai';
|
||||
import { BlockParamLiteral } from 'ethereum-types';
|
||||
@@ -282,6 +282,19 @@ describe('ExchangeWrapper', () => {
|
||||
expect(ordersInfo[1].orderHash).to.be.equal(anotherOrderHash);
|
||||
});
|
||||
});
|
||||
describe('#validateOrderFillableOrThrowAsync', () => {
|
||||
it('should throw if signature is invalid', async () => {
|
||||
const signedOrderWithInvalidSignature = {
|
||||
...signedOrder,
|
||||
signature:
|
||||
'0x1b61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403',
|
||||
};
|
||||
|
||||
expect(
|
||||
contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrderWithInvalidSignature),
|
||||
).to.eventually.to.be.rejectedWith(RevertReason.InvalidOrderSignature);
|
||||
});
|
||||
});
|
||||
describe('#isValidSignature', () => {
|
||||
it('should check if the signature is valid', async () => {
|
||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
|
115
packages/contracts/CHANGELOG.json
Normal file
115
packages/contracts/CHANGELOG.json
Normal file
@@ -0,0 +1,115 @@
|
||||
[
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Round up when calculating remaining amounts in marketBuy functions",
|
||||
"pr": 1162,
|
||||
"networks": {
|
||||
"1": "0x5468a1dc173652ee28d249c271fa9933144746b1",
|
||||
"3": "0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
"42": "0x17992e4ffb22730138e4b62aaa6367fa9d3699a6"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Forwarder",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x7afc2d5107af94c462a194d2c21b5bdd238709d6",
|
||||
"3": "0x3983e204b12b3c02fb0638caf2cd406a62e0ead3",
|
||||
"42": "0xd85e2fa7e7e252b27b01bf0d65c946959d2f45b8"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OrderValidator",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x9463e518dea6810309563c81d5266c1b1d149138",
|
||||
"3": "0x90431a90516ab49af23a0530e04e8c7836e7122f",
|
||||
"42": "0xb389da3d204b412df2f75c6afb3d0a7ce0bc283d"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Exchange",
|
||||
"version": "2.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x4f833a24e1f95d70f028921e27040ca56e09ab0b",
|
||||
"3": "0x4530c0483a1633c7a1c97d2c53721caff2caaaaf",
|
||||
"42": "0x35dd2932454449b14cee11a94d3674a936d5d7b2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ERC20Proxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
"3": "0xb1408f4c245a23c31b98d2c626777d4c0d766caa",
|
||||
"42": "0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ERC721Proxy",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x208e41fb445f1bb1b6780d58356e81405f3e6127",
|
||||
"3": "0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4",
|
||||
"42": "0x2a9127c745688a165106c11cd4d647d2220af821"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AssetProxyOwner",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v2 deploy",
|
||||
"networks": {
|
||||
"1": "0x17992e4ffb22730138e4b62aaa6367fa9d3699a6",
|
||||
"3": "0xf5fa5b5fed2727a0e44ac67f6772e97977aa358b",
|
||||
"42": "0x2c824d2882baa668e0d5202b1e7f2922278703f8"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ZRXToken",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "protocol v1 deploy",
|
||||
"networks": {
|
||||
"1": "0xe41d2489571d322189246dafa5ebde1f4699f498",
|
||||
"3": "0xff67881f8d12f372d91baae9752eb3631ff0ed00",
|
||||
"42": "0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@@ -1,32 +1,26 @@
|
||||
## Contracts
|
||||
|
||||
Smart contracts that implement the 0x protocol. Addresses of the deployed contracts can be found [here](https://0xproject.com/wiki#Deployed-Addresses).
|
||||
Smart contracts that implement the 0x protocol. Addresses of the deployed contracts can be found in the 0x [wiki](https://0xproject.com/wiki#Deployed-Addresses) or the [CHANGELOG](./CHANGELOG.json) of this package.
|
||||
|
||||
## Usage
|
||||
|
||||
### 2.0.0
|
||||
Contracts that make up and interact with version 2.0.0 of the protocol can be found in the [contracts](./contracts) directory. The contents of this directory are broken down into the following subdirectories:
|
||||
|
||||
Contracts that make up and interact with version 2.0.0 of the protocol can be found in the `src/2.0.0` directory. The contents of this directory are broken down into the following subdirectories:
|
||||
|
||||
* protocol
|
||||
* [protocol](./contracts/protocol)
|
||||
* This directory contains the contracts that make up version 2.0.0. A full specification can be found [here](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* extensions
|
||||
* [extensions](./contracts/extensions)
|
||||
* This directory contains contracts that interact with the 2.0.0 contracts and will be used in production, such as the [Forwarder](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarder-specification.md) contract.
|
||||
* examples
|
||||
* [examples](./contracts/examples)
|
||||
* This directory contains example implementations of contracts that interact with the protocol but are _not_ intended for use in production. Examples include [filter](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#filter-contracts) contracts, a [Wallet](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#wallet) contract, and a [Validator](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md#validator) contract, among others.
|
||||
* tokens
|
||||
* [tokens](./contracts/tokens)
|
||||
* This directory contains implementations of different tokens and token standards, including [wETH](https://weth.io/), ZRX, [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md), and [ERC721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md).
|
||||
* multisig
|
||||
* [multisig](./contracts/multisig)
|
||||
* This directory contains the [Gnosis MultiSigWallet](https://github.com/gnosis/MultiSigWallet) and a custom extension that adds a timelock to transactions within the MultiSigWallet.
|
||||
* utils
|
||||
* [utils](./contracts/utils)
|
||||
* This directory contains libraries and utils that are shared across all of the other directories.
|
||||
* test
|
||||
* [test](./contracts/test)
|
||||
* This directory contains mocks and other contracts that are used solely for testing contracts within the other directories.
|
||||
|
||||
### 1.0.0
|
||||
|
||||
Contracts that make up version 1.0.0 of the protocol can be found in `src/1.0.0`. These contracts are considered deprecated and will have limited support going forward.
|
||||
|
||||
## Bug bounty
|
||||
|
||||
A bug bounty for the 2.0.0 contracts is ongoing! Instructions can be found [here](https://0xproject.com/wiki#Bug-Bounty).
|
||||
|
@@ -155,8 +155,10 @@ contract MixinExchangeWrapper is
|
||||
uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount);
|
||||
|
||||
// Convert the remaining amount of makerAsset to buy into remaining amount
|
||||
// of takerAsset to sell, assuming entire amount can be sold in the current order
|
||||
uint256 remainingTakerAssetFillAmount = getPartialAmountFloor(
|
||||
// of takerAsset to sell, assuming entire amount can be sold in the current order.
|
||||
// We round up because the exchange rate computed by fillOrder rounds in favor
|
||||
// of the Maker. In this case we want to overestimate the amount of takerAsset.
|
||||
uint256 remainingTakerAssetFillAmount = getPartialAmountCeil(
|
||||
orders[i].takerAssetAmount,
|
||||
orders[i].makerAssetAmount,
|
||||
remainingMakerAssetFillAmount
|
||||
@@ -224,7 +226,9 @@ contract MixinExchangeWrapper is
|
||||
|
||||
// Convert the remaining amount of ZRX to buy into remaining amount
|
||||
// of WETH to sell, assuming entire amount can be sold in the current order.
|
||||
uint256 remainingWethSellAmount = getPartialAmountFloor(
|
||||
// We round up because the exchange rate computed by fillOrder rounds in favor
|
||||
// of the Maker. In this case we want to overestimate the amount of takerAsset.
|
||||
uint256 remainingWethSellAmount = getPartialAmountCeil(
|
||||
orders[i].takerAssetAmount,
|
||||
safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees
|
||||
remainingZrxBuyAmount
|
||||
@@ -233,7 +237,7 @@ contract MixinExchangeWrapper is
|
||||
// Attempt to sell the remaining amount of WETH.
|
||||
FillResults memory singleFillResult = fillOrderNoThrow(
|
||||
orders[i],
|
||||
safeAdd(remainingWethSellAmount, 1), // we add 1 wei to the fill amount to make up for rounding errors
|
||||
remainingWethSellAmount,
|
||||
signatures[i]
|
||||
);
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "contracts",
|
||||
"version": "2.1.50",
|
||||
"version": "2.1.52",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -23,7 +23,7 @@
|
||||
"compile": "sol-compiler --contracts-dir contracts",
|
||||
"clean": "shx rm -rf lib generated-artifacts generated-wrappers",
|
||||
"generate_contract_wrappers": "abi-gen --abis ${npm_package_config_abis} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output generated-wrappers --backend ethers",
|
||||
"lint": "tslint --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"lint": "tslint --format stylish --project . --exclude ./generated-wrappers/**/* --exclude ./generated-artifacts/**/* --exclude **/lib/**/* && yarn lint-contracts",
|
||||
"coverage:report:text": "istanbul report text",
|
||||
"coverage:report:html": "istanbul report html && open coverage/index.html",
|
||||
"profiler:report:html": "istanbul report html && open coverage/index.html",
|
||||
@@ -45,12 +45,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/abi-gen": "^1.0.14",
|
||||
"@0x/dev-utils": "^1.0.13",
|
||||
"@0x/sol-compiler": "^1.1.8",
|
||||
"@0x/sol-cov": "^2.1.8",
|
||||
"@0x/subproviders": "^2.1.0",
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/abi-gen": "^1.0.15",
|
||||
"@0x/dev-utils": "^1.0.15",
|
||||
"@0x/sol-compiler": "^1.1.10",
|
||||
"@0x/sol-cov": "^2.1.10",
|
||||
"@0x/subproviders": "^2.1.2",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/bn.js": "^4.11.0",
|
||||
"@types/ethereumjs-abi": "^0.6.0",
|
||||
"@types/lodash": "4.14.104",
|
||||
@@ -71,15 +71,15 @@
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/base-contract": "^3.0.2",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"@0x/base-contract": "^3.0.4",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"@types/js-combinatorics": "^0.5.29",
|
||||
"bn.js": "^4.11.8",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"ethereumjs-abi": "0.6.5",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"ethers": "~4.0.4",
|
||||
|
@@ -45,6 +45,7 @@ describe(ContractName.Forwarder, () => {
|
||||
|
||||
let weth: DummyERC20TokenContract;
|
||||
let zrxToken: DummyERC20TokenContract;
|
||||
let erc20TokenA: DummyERC20TokenContract;
|
||||
let erc721Token: DummyERC721TokenContract;
|
||||
let forwarderContract: ForwarderContract;
|
||||
let wethContract: WETH9Contract;
|
||||
@@ -77,7 +78,6 @@ describe(ContractName.Forwarder, () => {
|
||||
erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner);
|
||||
|
||||
const numDummyErc20ToDeploy = 3;
|
||||
let erc20TokenA;
|
||||
[erc20TokenA, zrxToken] = await erc20Wrapper.deployDummyTokensAsync(
|
||||
numDummyErc20ToDeploy,
|
||||
constants.DUMMY_TOKEN_DECIMALS,
|
||||
@@ -902,6 +902,269 @@ describe(ContractName.Forwarder, () => {
|
||||
);
|
||||
expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
it('Should buy slightly greater MakerAsset when exchange rate is rounded', async () => {
|
||||
// The 0x Protocol contracts round the exchange rate in favor of the Maker.
|
||||
// In this case, the taker must round up how much they're going to spend, which
|
||||
// in turn increases the amount of MakerAsset being purchased.
|
||||
// Example:
|
||||
// The taker wants to buy 5 units of the MakerAsset at a rate of 3M/2T.
|
||||
// For every 2 units of TakerAsset, the taker will receive 3 units of MakerAsset.
|
||||
// To purchase 5 units, the taker must spend 10/3 = 3.33 units of TakerAssset.
|
||||
// However, the Taker can only spend whole units.
|
||||
// Spending floor(10/3) = 3 units will yield a profit of Floor(3*3/2) = Floor(4.5) = 4 units of MakerAsset.
|
||||
// Spending ceil(10/3) = 4 units will yield a profit of Floor(4*3/2) = 6 units of MakerAsset.
|
||||
//
|
||||
// The forwarding contract will opt for the second option, which overbuys, to ensure the taker
|
||||
// receives at least the amount of MakerAsset they requested.
|
||||
//
|
||||
// Construct test case using values from example above
|
||||
orderWithoutFee = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber('30'),
|
||||
takerAssetAmount: new BigNumber('20'),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
|
||||
makerFee: new BigNumber(0),
|
||||
takerFee: new BigNumber(0),
|
||||
});
|
||||
const ordersWithoutFee = [orderWithoutFee];
|
||||
const feeOrders: SignedOrder[] = [];
|
||||
const desiredMakerAssetFillAmount = new BigNumber('5');
|
||||
const makerAssetFillAmount = new BigNumber('6');
|
||||
const ethValue = new BigNumber('4');
|
||||
// Execute test case
|
||||
tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
|
||||
ordersWithoutFee,
|
||||
feeOrders,
|
||||
desiredMakerAssetFillAmount,
|
||||
{
|
||||
value: ethValue,
|
||||
from: takerAddress,
|
||||
},
|
||||
);
|
||||
// Fetch end balances and construct expected outputs
|
||||
const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
|
||||
const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const primaryTakerAssetFillAmount = ethValue;
|
||||
const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
|
||||
// Validate test case
|
||||
expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
|
||||
expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
|
||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||
constants.ZERO_AMOUNT,
|
||||
);
|
||||
expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
it('Should buy slightly greater MakerAsset when exchange rate is rounded, and MakerAsset is ZRX', async () => {
|
||||
// See the test case above for a detailed description of this case.
|
||||
// The difference here is that the MakerAsset is ZRX. We expect the same result as above,
|
||||
// but this tests a different code path.
|
||||
//
|
||||
// Construct test case using values from example above
|
||||
orderWithoutFee = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber('30'),
|
||||
takerAssetAmount: new BigNumber('20'),
|
||||
makerAssetData: zrxAssetData,
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
|
||||
makerFee: new BigNumber(0),
|
||||
takerFee: new BigNumber(0),
|
||||
});
|
||||
const ordersWithoutFee = [orderWithoutFee];
|
||||
const feeOrders: SignedOrder[] = [];
|
||||
const desiredMakerAssetFillAmount = new BigNumber('5');
|
||||
const makerAssetFillAmount = new BigNumber('6');
|
||||
const ethValue = new BigNumber('4');
|
||||
// Execute test case
|
||||
tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
|
||||
ordersWithoutFee,
|
||||
feeOrders,
|
||||
desiredMakerAssetFillAmount,
|
||||
{
|
||||
value: ethValue,
|
||||
from: takerAddress,
|
||||
},
|
||||
);
|
||||
// Fetch end balances and construct expected outputs
|
||||
const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
|
||||
const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const primaryTakerAssetFillAmount = ethValue;
|
||||
const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
|
||||
// Validate test case
|
||||
expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
|
||||
expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
|
||||
expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
it('Should buy slightly greater MakerAsset when exchange rate is rounded (Regression Test)', async () => {
|
||||
// Order taken from a transaction on mainnet that failed due to a rounding error.
|
||||
orderWithoutFee = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber('268166666666666666666'),
|
||||
takerAssetAmount: new BigNumber('219090625878836371'),
|
||||
makerAssetData: assetDataUtils.encodeERC20AssetData(erc20TokenA.address),
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
|
||||
makerFee: new BigNumber(0),
|
||||
takerFee: new BigNumber(0),
|
||||
});
|
||||
const ordersWithoutFee = [orderWithoutFee];
|
||||
const feeOrders: SignedOrder[] = [];
|
||||
// The taker will receive more than the desired amount of makerAsset due to rounding
|
||||
const desiredMakerAssetFillAmount = new BigNumber('5000000000000000000');
|
||||
const ethValue = new BigNumber('4084971271824171');
|
||||
const makerAssetFillAmount = ethValue
|
||||
.times(orderWithoutFee.makerAssetAmount)
|
||||
.dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
|
||||
// Execute test case
|
||||
tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
|
||||
ordersWithoutFee,
|
||||
feeOrders,
|
||||
desiredMakerAssetFillAmount,
|
||||
{
|
||||
value: ethValue,
|
||||
from: takerAddress,
|
||||
},
|
||||
);
|
||||
// Fetch end balances and construct expected outputs
|
||||
const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
|
||||
const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const primaryTakerAssetFillAmount = ethValue;
|
||||
const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
|
||||
// Validate test case
|
||||
expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
|
||||
expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
|
||||
expect(newBalances[makerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][defaultMakerAssetAddress].plus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
expect(newBalances[forwarderContract.address][defaultMakerAssetAddress]).to.be.bignumber.equal(
|
||||
constants.ZERO_AMOUNT,
|
||||
);
|
||||
expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
it('Should buy slightly greater MakerAsset when exchange rate is rounded, and MakerAsset is ZRX (Regression Test)', async () => {
|
||||
// Order taken from a transaction on mainnet that failed due to a rounding error.
|
||||
orderWithoutFee = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber('268166666666666666666'),
|
||||
takerAssetAmount: new BigNumber('219090625878836371'),
|
||||
makerAssetData: zrxAssetData,
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
|
||||
makerFee: new BigNumber(0),
|
||||
takerFee: new BigNumber(0),
|
||||
});
|
||||
const ordersWithoutFee = [orderWithoutFee];
|
||||
const feeOrders: SignedOrder[] = [];
|
||||
// The taker will receive more than the desired amount of makerAsset due to rounding
|
||||
const desiredMakerAssetFillAmount = new BigNumber('5000000000000000000');
|
||||
const ethValue = new BigNumber('4084971271824171');
|
||||
const makerAssetFillAmount = ethValue
|
||||
.times(orderWithoutFee.makerAssetAmount)
|
||||
.dividedToIntegerBy(orderWithoutFee.takerAssetAmount);
|
||||
// Execute test case
|
||||
tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(
|
||||
ordersWithoutFee,
|
||||
feeOrders,
|
||||
desiredMakerAssetFillAmount,
|
||||
{
|
||||
value: ethValue,
|
||||
from: takerAddress,
|
||||
},
|
||||
);
|
||||
// Fetch end balances and construct expected outputs
|
||||
const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
|
||||
const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const primaryTakerAssetFillAmount = ethValue;
|
||||
const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
|
||||
// Validate test case
|
||||
expect(makerAssetFillAmount).to.be.bignumber.greaterThan(desiredMakerAssetFillAmount);
|
||||
expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
|
||||
expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
it('Should buy correct MakerAsset when exchange rate is NOT rounded, and MakerAsset is ZRX (Regression Test)', async () => {
|
||||
// An extra unit of TakerAsset was sent to the exchange contract to account for rounding errors, in Forwarder v1.
|
||||
// Specifically, the takerFillAmount was calculated using Floor(desiredMakerAmount * exchangeRate) + 1
|
||||
// We have since changed this to be Ceil(desiredMakerAmount * exchangeRate)
|
||||
// These calculations produce different results when `desiredMakerAmount * exchangeRate` is an integer.
|
||||
//
|
||||
// This test verifies that `ceil` is sufficient:
|
||||
// Let TakerAssetAmount = MakerAssetAmount * 2
|
||||
// -> exchangeRate = TakerAssetAmount / MakerAssetAmount = (2*MakerAssetAmount)/MakerAssetAmount = 2
|
||||
// .: desiredMakerAmount * exchangeRate is an integer.
|
||||
//
|
||||
// Construct test case using values from example above
|
||||
orderWithoutFee = await orderFactory.newSignedOrderAsync({
|
||||
makerAssetAmount: new BigNumber('30'),
|
||||
takerAssetAmount: new BigNumber('60'),
|
||||
makerAssetData: zrxAssetData,
|
||||
takerAssetData: assetDataUtils.encodeERC20AssetData(weth.address),
|
||||
makerFee: new BigNumber(0),
|
||||
takerFee: new BigNumber(0),
|
||||
});
|
||||
const ordersWithoutFee = [orderWithoutFee];
|
||||
const feeOrders: SignedOrder[] = [];
|
||||
const makerAssetFillAmount = new BigNumber('5');
|
||||
const ethValue = new BigNumber('10');
|
||||
// Execute test case
|
||||
tx = await forwarderWrapper.marketBuyOrdersWithEthAsync(ordersWithoutFee, feeOrders, makerAssetFillAmount, {
|
||||
value: ethValue,
|
||||
from: takerAddress,
|
||||
});
|
||||
// Fetch end balances and construct expected outputs
|
||||
const takerEthBalanceAfter = await web3Wrapper.getBalanceInWeiAsync(takerAddress);
|
||||
const forwarderEthBalance = await web3Wrapper.getBalanceInWeiAsync(forwarderContract.address);
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
const primaryTakerAssetFillAmount = ethValue;
|
||||
const totalEthSpent = primaryTakerAssetFillAmount.plus(gasPrice.times(tx.gasUsed));
|
||||
// Validate test case
|
||||
expect(takerEthBalanceAfter).to.be.bignumber.equal(takerEthBalanceBefore.minus(totalEthSpent));
|
||||
expect(newBalances[makerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][zrxToken.address].minus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[takerAddress][zrxToken.address]).to.be.bignumber.equal(
|
||||
erc20Balances[takerAddress][zrxToken.address].plus(makerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[makerAddress][weth.address]).to.be.bignumber.equal(
|
||||
erc20Balances[makerAddress][weth.address].plus(primaryTakerAssetFillAmount),
|
||||
);
|
||||
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
expect(forwarderEthBalance).to.be.bignumber.equal(constants.ZERO_AMOUNT);
|
||||
});
|
||||
});
|
||||
describe('marketBuyOrdersWithEth with extra fees', () => {
|
||||
it('should buy an asset and send fee to feeRecipient', async () => {
|
||||
|
@@ -212,13 +212,17 @@ export class ExchangeWrapper {
|
||||
return tx;
|
||||
}
|
||||
public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
|
||||
const filledAmount = new BigNumber(await this._exchange.filled.callAsync(orderHashHex));
|
||||
const filledAmount = await this._exchange.filled.callAsync(orderHashHex);
|
||||
return filledAmount;
|
||||
}
|
||||
public async isCancelledAsync(orderHashHex: string): Promise<boolean> {
|
||||
const isCancelled = await this._exchange.cancelled.callAsync(orderHashHex);
|
||||
return isCancelled;
|
||||
}
|
||||
public async getOrderEpochAsync(makerAddress: string, senderAddress: string): Promise<BigNumber> {
|
||||
const orderEpoch = await this._exchange.orderEpoch.callAsync(makerAddress, senderAddress);
|
||||
return orderEpoch;
|
||||
}
|
||||
public async getOrderInfoAsync(signedOrder: SignedOrder): Promise<OrderInfo> {
|
||||
const orderInfo = (await this._exchange.getOrderInfo.callAsync(signedOrder)) as OrderInfo;
|
||||
return orderInfo;
|
||||
|
@@ -392,7 +392,7 @@ export class FillOrderCombinatorialUtils {
|
||||
);
|
||||
|
||||
// 5. If I fill it by X, what are the resulting balances/allowances/filled amounts expected?
|
||||
const orderValidationUtils = new OrderValidationUtils(orderFilledCancelledFetcher);
|
||||
const orderValidationUtils = new OrderValidationUtils(orderFilledCancelledFetcher, provider);
|
||||
const lazyStore = new BalanceAndProxyAllowanceLazyStore(balanceAndProxyAllowanceFetcher);
|
||||
const exchangeTransferSimulator = new ExchangeTransferSimulator(lazyStore);
|
||||
|
||||
|
@@ -26,9 +26,12 @@ export class ForwarderWrapper {
|
||||
_.forEach(feeOrders, feeOrder => {
|
||||
const feeAvailable = feeOrder.makerAssetAmount.minus(feeOrder.takerFee);
|
||||
if (!remainingFeeAmount.isZero() && feeAvailable.gt(remainingFeeAmount)) {
|
||||
wethAmount = wethAmount
|
||||
.plus(feeOrder.takerAssetAmount.times(remainingFeeAmount).dividedToIntegerBy(feeAvailable))
|
||||
.plus(1);
|
||||
wethAmount = wethAmount.plus(
|
||||
feeOrder.takerAssetAmount
|
||||
.times(remainingFeeAmount)
|
||||
.dividedBy(feeAvailable)
|
||||
.ceil(),
|
||||
);
|
||||
remainingFeeAmount = new BigNumber(0);
|
||||
} else if (!remainingFeeAmount.isZero()) {
|
||||
wethAmount = wethAmount.plus(feeOrder.takerAssetAmount);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { AbstractOrderFilledCancelledFetcher } from '@0x/order-utils';
|
||||
import { AbstractOrderFilledCancelledFetcher, orderHashUtils } from '@0x/order-utils';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { ExchangeWrapper } from './exchange_wrapper';
|
||||
@@ -14,9 +15,15 @@ export class SimpleOrderFilledCancelledFetcher implements AbstractOrderFilledCan
|
||||
const filledTakerAmount = new BigNumber(await this._exchangeWrapper.getTakerAssetFilledAmountAsync(orderHash));
|
||||
return filledTakerAmount;
|
||||
}
|
||||
public async isOrderCancelledAsync(orderHash: string): Promise<boolean> {
|
||||
public async isOrderCancelledAsync(signedOrder: SignedOrder): Promise<boolean> {
|
||||
const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
|
||||
const isCancelled = await this._exchangeWrapper.isCancelledAsync(orderHash);
|
||||
return isCancelled;
|
||||
const orderEpoch = await this._exchangeWrapper.getOrderEpochAsync(
|
||||
signedOrder.makerAddress,
|
||||
signedOrder.senderAddress,
|
||||
);
|
||||
const isCancelledByOrderEpoch = orderEpoch > signedOrder.salt;
|
||||
return isCancelled || isCancelledByOrderEpoch;
|
||||
}
|
||||
public getZRXAssetData(): string {
|
||||
return this._zrxAssetData;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/dev-tools-pages",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -11,12 +11,12 @@
|
||||
"build:ci": "yarn build",
|
||||
"build:dev": "../../node_modules/.bin/webpack --mode development",
|
||||
"clean": "shx rm -f public/bundle*",
|
||||
"lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
|
||||
"lint": "tslint --format stylish --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
|
||||
"dev": "webpack-dev-server --mode development --content-base public"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@0x/react-shared": "^1.0.17",
|
||||
"@0x/react-shared": "^1.0.19",
|
||||
"basscss": "^8.0.3",
|
||||
"bowser": "^1.9.3",
|
||||
"less": "^2.7.2",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "1.0.15",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.0.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "1.0.13",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.15 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.14 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.13 - _October 18, 2018_
|
||||
|
||||
* Make web3-provider-engine types a 'dependency' so it's available to users of the library (#1105)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/dev-utils",
|
||||
"version": "1.0.13",
|
||||
"version": "1.0.15",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -17,7 +17,7 @@
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
|
||||
"clean": "shx rm -rf lib",
|
||||
"lint": "tslint --project ."
|
||||
"lint": "tslint --format stylish --project ."
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
@@ -41,14 +41,14 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/subproviders": "^2.1.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"@0x/subproviders": "^2.1.2",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"@types/web3-provider-engine": "^14.0.0",
|
||||
"chai": "^4.0.1",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"lodash": "^4.17.5"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "1.1.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "1.1.1",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.1.2 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.1.1 - _October 18, 2018_
|
||||
|
||||
* Add `JSONRPCResponseError` and error field on `JSONRPCResponsePayload`. (#1102)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ethereum-types",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -11,7 +11,7 @@
|
||||
"build": "tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"clean": "shx rm -rf lib generated_docs",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||
},
|
||||
"config": {
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/ethereum-types/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.11.0",
|
||||
|
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1542028948,
|
||||
"version": "1.0.10",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.0.9",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
],
|
||||
"timestamp": 1541740904
|
||||
},
|
||||
{
|
||||
"version": "1.0.8",
|
||||
"changes": [
|
||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v1.0.10 - _November 12, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.9 - _November 9, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v1.0.8 - _October 18, 2018_
|
||||
|
||||
* Updated to use new @0xproject/contract-artifacts and @0xproject/abi-gen-wrappers packages (#1105)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/fill-scenarios",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.10",
|
||||
"description": "0x order fill scenario generator",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
@@ -8,7 +8,7 @@
|
||||
"build": "yarn tsc -b",
|
||||
"build:ci": "yarn build",
|
||||
"clean": "shx rm -rf lib src/generated_contract_wrappers",
|
||||
"lint": "tslint --project ."
|
||||
"lint": "tslint --format stylish --project ."
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/fill-scenarios/README.md",
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@types/lodash": "4.14.104",
|
||||
"make-promises-safe": "^1.1.0",
|
||||
"shx": "^0.2.2",
|
||||
@@ -28,15 +28,15 @@
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0x/abi-gen-wrappers": "^1.0.1",
|
||||
"@0x/base-contract": "^3.0.2",
|
||||
"@0x/contract-artifacts": "^1.0.1",
|
||||
"@0x/order-utils": "^2.0.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"@0x/abi-gen-wrappers": "^1.0.3",
|
||||
"@0x/base-contract": "^3.0.4",
|
||||
"@0x/contract-artifacts": "^1.1.0",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"ethers": "~4.0.4",
|
||||
"lodash": "^4.17.5"
|
||||
},
|
||||
|
13
packages/instant/.dogfood.discharge.json
Normal file
13
packages/instant/.dogfood.discharge.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"domain": "0x-instant-dogfood",
|
||||
"build_command": "yarn build:umd:prod",
|
||||
"upload_directory": "public",
|
||||
"index_key": "index.html",
|
||||
"error_key": "index.html",
|
||||
"trailing_slashes": true,
|
||||
"cache": 3600,
|
||||
"aws_profile": "default",
|
||||
"aws_region": "us-east-1",
|
||||
"cdn": false,
|
||||
"dns_configured": true
|
||||
}
|
13
packages/instant/.staging.discharge.json
Normal file
13
packages/instant/.staging.discharge.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"domain": "0x-instant-staging",
|
||||
"build_command": "yarn build:umd:prod",
|
||||
"upload_directory": "public",
|
||||
"index_key": "index.html",
|
||||
"error_key": "index.html",
|
||||
"trailing_slashes": true,
|
||||
"cache": 3600,
|
||||
"aws_profile": "default",
|
||||
"aws_region": "us-east-1",
|
||||
"cdn": false,
|
||||
"dns_configured": true
|
||||
}
|
@@ -46,6 +46,26 @@ The package is also available as a UMD module named `zeroExInstant`.
|
||||
</body>
|
||||
```
|
||||
|
||||
## Deploying
|
||||
|
||||
You can deploy a work-in-progress version of 0x Instant at http://0x-instant-dogfood.s3-website-us-east-1.amazonaws.com for easy sharing.
|
||||
|
||||
To build and deploy the site run
|
||||
|
||||
```
|
||||
yarn deploy_dogfood
|
||||
```
|
||||
|
||||
We also have a staging bucket that is to be updated less frequently can be used to share instant externally: http://0x-instant-staging.s3-website-us-east-1.amazonaws.com/
|
||||
|
||||
To build and deploy to this bucket, run
|
||||
|
||||
```
|
||||
yarn deploy_staging
|
||||
```
|
||||
|
||||
**NOTE: On deploying the site, it will say the site is available at a non-existent URL. Please ignore and use the (now updated) URL above.**
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/instant",
|
||||
"version": "0.0.3",
|
||||
"version": "0.0.5",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -16,12 +16,14 @@
|
||||
"build:ci": "yarn build",
|
||||
"watch_without_deps": "tsc -w",
|
||||
"dev": "webpack-dev-server --mode development",
|
||||
"lint": "tslint --project .",
|
||||
"lint": "tslint --format stylish --project .",
|
||||
"test": "jest",
|
||||
"test:coverage": "jest --coverage",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
"test:circleci": "yarn test:coverage",
|
||||
"clean": "shx rm -rf lib coverage scripts",
|
||||
"deploy_dogfood": "discharge deploy -c .dogfood.discharge.json",
|
||||
"deploy_staging": "discharge deploy -c .staging.discharge.json",
|
||||
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
|
||||
},
|
||||
"config": {
|
||||
@@ -43,12 +45,17 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md",
|
||||
"dependencies": {
|
||||
"@0x/asset-buyer": "^2.1.0",
|
||||
"@0x/types": "^1.2.0",
|
||||
"@0x/typescript-typings": "^3.0.3",
|
||||
"@0x/utils": "^2.0.3",
|
||||
"@0x/web3-wrapper": "^3.1.0",
|
||||
"ethereum-types": "^1.1.1",
|
||||
"@0x/assert": "^1.0.16",
|
||||
"@0x/asset-buyer": "^2.2.1",
|
||||
"@0x/json-schemas": "^2.1.0",
|
||||
"@0x/order-utils": "^3.0.0",
|
||||
"@0x/subproviders": "^2.1.2",
|
||||
"@0x/types": "^1.2.1",
|
||||
"@0x/typescript-typings": "^3.0.4",
|
||||
"@0x/utils": "^2.0.4",
|
||||
"@0x/web3-wrapper": "^3.1.2",
|
||||
"copy-to-clipboard": "^3.0.8",
|
||||
"ethereum-types": "^1.1.2",
|
||||
"lodash": "^4.17.10",
|
||||
"polished": "^2.2.0",
|
||||
"react": "^16.5.2",
|
||||
@@ -56,11 +63,12 @@
|
||||
"react-redux": "^5.0.7",
|
||||
"redux": "^4.0.0",
|
||||
"redux-devtools-extension": "^2.13.5",
|
||||
"styled-components": "^3.4.9",
|
||||
"styled-components": "^4.0.2",
|
||||
"ts-optchain": "^0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0x/tslint-config": "^1.0.9",
|
||||
"@0x/tslint-config": "^1.0.10",
|
||||
"@static/discharge": "https://github.com/0xProject/discharge.git",
|
||||
"@types/enzyme": "^3.1.14",
|
||||
"@types/enzyme-adapter-react-16": "^1.0.3",
|
||||
"@types/jest": "^23.3.5",
|
||||
@@ -70,6 +78,7 @@
|
||||
"@types/react-dom": "^16.0.8",
|
||||
"@types/react-redux": "^6.0.9",
|
||||
"@types/redux": "^3.6.0",
|
||||
"@types/styled-components": "^4.0.1",
|
||||
"awesome-typescript-loader": "^5.2.1",
|
||||
"enzyme": "^3.6.0",
|
||||
"enzyme-adapter-react-16": "^1.5.0",
|
||||
|
25
packages/instant/public/external.css
Normal file
25
packages/instant/public/external.css
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
CSS file meant to represent an external (integrators) stylesheet and
|
||||
help ensure that instant looks consistent across environments.
|
||||
*/
|
||||
|
||||
button {
|
||||
font-size: 50px;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 100px;
|
||||
font-size: 50px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
p {
|
||||
background-color: green;
|
||||
margin: 10px;
|
||||
}
|
@@ -5,7 +5,10 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>0x Instant Dev Environment</title>
|
||||
<link rel="stylesheet" href="/external.css">
|
||||
<script type="text/javascript" src="/main.bundle.js" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/jsuri@1.3.1/Uri.js" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="https://unpkg.com/bignumber.js@4.1.0/bignumber.js" charset="utf-8"></script>
|
||||
<style>
|
||||
#zeroExInstantContainer {
|
||||
display: flex;
|
||||
@@ -24,9 +27,110 @@
|
||||
<body>
|
||||
<div id="zeroExInstantContainer"></div>
|
||||
<script>
|
||||
zeroExInstant.render({
|
||||
|
||||
const removeUndefined = (obj) => {
|
||||
for (let k in obj) if (obj[k] === undefined) delete obj[k];
|
||||
return obj;
|
||||
}
|
||||
BigNumber.config({
|
||||
EXPONENTIAL_AT: 1000,
|
||||
DECIMAL_PLACES: 78,
|
||||
});
|
||||
const providedOrders = [
|
||||
// Order selling REP
|
||||
{
|
||||
senderAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
|
||||
takerAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerFee: new BigNumber('0'),
|
||||
takerFee: new BigNumber('0'),
|
||||
makerAssetAmount: new BigNumber('200000000000000000000'),
|
||||
takerAssetAmount: new BigNumber('10000000000000000000'),
|
||||
makerAssetData: '0xf47261b00000000000000000000000008cb3971b8eb709c14616bd556ff6683019e90d9c',
|
||||
takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
expirationTimeSeconds: new BigNumber('1601535600'),
|
||||
feeRecipientAddress: '0x0000000000000000000000000000000000000000',
|
||||
salt: new BigNumber('3101985707338942582579795423923841749956600670712030922928319824580764688653'),
|
||||
signature: '0x1bd4d5686fea801fe33c68c4944356085e7e6cb553eb7073160abd815609f714e85fb47f44b7ffd0a2a1321ac40d72d55163869d0a50fdb5a402132150fe33a08403',
|
||||
exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
|
||||
},
|
||||
// Order selling ZRX
|
||||
{
|
||||
senderAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
|
||||
takerAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerFee: new BigNumber('0'),
|
||||
takerFee: new BigNumber('0'),
|
||||
makerAssetAmount: new BigNumber('300000000000000000000'),
|
||||
takerAssetAmount: new BigNumber('31000000000000000000'),
|
||||
makerAssetData: '0xf47261b00000000000000000000000002002d3812f58e35f0ea1ffbf80a75a38c32175fa',
|
||||
takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
expirationTimeSeconds: new BigNumber('2524636800'),
|
||||
feeRecipientAddress: '0x0000000000000000000000000000000000000000',
|
||||
salt: new BigNumber('64592004666704945574675477805199411288137454783320798602050822322450089238268'),
|
||||
signature: '0x1c13cacddca8d7d8248e91f412377e68f8f1f9891a59a6c1b2eea9f7b33558c30c4fb86a448e08ab7def40a28fb3a3062dcb33bb3c45302447fce5c4288b7c7f5b03',
|
||||
exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
|
||||
},
|
||||
// Order selling GNT
|
||||
{
|
||||
senderAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
|
||||
takerAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerFee: new BigNumber('0'),
|
||||
takerFee: new BigNumber('0'),
|
||||
makerAssetAmount: new BigNumber('250000000000000000000'),
|
||||
takerAssetAmount: new BigNumber('10000000000000000000'),
|
||||
makerAssetData: '0xf47261b000000000000000000000000031fb614e223706f15d0d3c5f4b08bdf0d5c78623',
|
||||
takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
expirationTimeSeconds: new BigNumber('1601535600'),
|
||||
feeRecipientAddress: '0x0000000000000000000000000000000000000000',
|
||||
salt: new BigNumber('40204378562212615907903051460421336779451270522691667164301816101569427926606'),
|
||||
signature: '0x1c788bf4b93769da1e8f195f52f0f59b4a298ac6da30cf6d05a87ed4be5ee974f61352ed1bc6a0844d0962b8c894c9ca08e452431255958a4e98dd93cbe1fbc73803',
|
||||
exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
|
||||
},
|
||||
// Order selling MKR
|
||||
{
|
||||
senderAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerAddress: '0x34a745008a643eebc58920eaa29fb1165b4a288e',
|
||||
takerAddress: '0x0000000000000000000000000000000000000000',
|
||||
makerFee: new BigNumber('0'),
|
||||
takerFee: new BigNumber('0'),
|
||||
makerAssetAmount: new BigNumber('200000000000000000000'),
|
||||
takerAssetAmount: new BigNumber('5000000000000000000'),
|
||||
makerAssetData: '0xf47261b00000000000000000000000007b6b10caa9e8e9552ba72638ea5b47c25afea1f3',
|
||||
takerAssetData: '0xf47261b0000000000000000000000000d0a1e359811322d97991e03f863a0c30c2cf029c',
|
||||
expirationTimeSeconds: new BigNumber('1601535600'),
|
||||
feeRecipientAddress: '0x0000000000000000000000000000000000000000',
|
||||
salt: new BigNumber('71338269924068280039932133924198049371838034090153601678083172009862985793828'),
|
||||
signature: '0x1bb3151d57ee1e8fa697767ce83ee4ba77d1ceb8cc1e79c7d77126b3687517704c50c6b3d9cb42c7e7d4478d574b297dfbd1626c5c18a7bc9c2a792c4c07f0797c03',
|
||||
exchangeAddress: '0x35dd2932454449b14cee11a94d3674a936d5d7b2'
|
||||
}
|
||||
];
|
||||
const queryParams = new Uri(window.location.search);
|
||||
const renderOptionsDefaults = {
|
||||
orderSource: 'https://api.radarrelay.com/0x/v2/',
|
||||
onClose: () => { console.log('0x Instant Closed') }
|
||||
}
|
||||
const orderSourceOverride = queryParams.getQueryParamValue('orderSource');
|
||||
const availableAssetDatasString = queryParams.getQueryParamValue('availableAssetDatas');
|
||||
const feeRecipientOverride = queryParams.getQueryParamValue('feeRecipient');
|
||||
const feePercentageOverride = +queryParams.getQueryParamValue('feePercentage');
|
||||
let affiliateInfoOverride;
|
||||
if (feeRecipientOverride !== undefined && feePercentageOverride !== undefined) {
|
||||
affiliateInfoOverride = {
|
||||
feeRecipient: feeRecipientOverride,
|
||||
feePercentage: feePercentageOverride
|
||||
};
|
||||
}
|
||||
const renderOptionsOverrides = {
|
||||
orderSource: orderSourceOverride === 'provided' ? providedOrders : orderSourceOverride,
|
||||
networkId: +queryParams.getQueryParamValue('networkId') || undefined,
|
||||
defaultAssetBuyAmount: +queryParams.getQueryParamValue('defaultAssetBuyAmount') || undefined,
|
||||
availableAssetDatas: availableAssetDatasString ? JSON.parse(availableAssetDatasString) : undefined,
|
||||
defaultSelectedAssetData: queryParams.getQueryParamValue('defaultSelectedAssetData'),
|
||||
affiliateInfo: affiliateInfoOverride,
|
||||
}
|
||||
const renderOptions = Object.assign({}, renderOptionsDefaults, removeUndefined(renderOptionsOverrides));
|
||||
zeroExInstant.render(renderOptions);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
@@ -1,49 +0,0 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ColorOption } from '../style/theme';
|
||||
import { util } from '../util/util';
|
||||
|
||||
import { Container, Input } from './ui';
|
||||
|
||||
export interface AmountInputProps {
|
||||
fontColor?: ColorOption;
|
||||
fontSize?: string;
|
||||
value?: BigNumber;
|
||||
onChange: (value?: BigNumber) => void;
|
||||
}
|
||||
|
||||
export class AmountInput extends React.Component<AmountInputProps> {
|
||||
public static defaultProps = {
|
||||
onChange: util.boundNoop,
|
||||
};
|
||||
public render(): React.ReactNode {
|
||||
const { fontColor, fontSize, value } = this.props;
|
||||
return (
|
||||
<Container borderBottom="1px solid rgba(255,255,255,0.3)" display="inline-block">
|
||||
<Input
|
||||
fontColor={fontColor}
|
||||
fontSize={fontSize}
|
||||
onChange={this._handleChange}
|
||||
value={!_.isUndefined(value) ? value.toString() : ''}
|
||||
placeholder="0.00"
|
||||
width="2.2em"
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
const value = event.target.value;
|
||||
let bigNumberValue;
|
||||
if (!_.isEmpty(value)) {
|
||||
try {
|
||||
bigNumberValue = new BigNumber(event.target.value);
|
||||
} catch {
|
||||
// We don't want to allow values that can't be a BigNumber, so don't even call onChange.
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.props.onChange(bigNumberValue);
|
||||
};
|
||||
}
|
32
packages/instant/src/components/amount_placeholder.tsx
Normal file
32
packages/instant/src/components/amount_placeholder.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { ColorOption } from '../style/theme';
|
||||
|
||||
import { Pulse } from './animations/pulse';
|
||||
|
||||
import { Text } from './ui/text';
|
||||
|
||||
interface PlainPlaceholder {
|
||||
color: ColorOption;
|
||||
}
|
||||
const PlainPlaceholder: React.StatelessComponent<PlainPlaceholder> = props => (
|
||||
<Text fontWeight="bold" fontColor={props.color}>
|
||||
—
|
||||
</Text>
|
||||
);
|
||||
|
||||
export interface AmountPlaceholderProps {
|
||||
color: ColorOption;
|
||||
isPulsating: boolean;
|
||||
}
|
||||
export const AmountPlaceholder: React.StatelessComponent<AmountPlaceholderProps> = props => {
|
||||
if (props.isPulsating) {
|
||||
return (
|
||||
<Pulse>
|
||||
<PlainPlaceholder color={props.color} />
|
||||
</Pulse>
|
||||
);
|
||||
} else {
|
||||
return <PlainPlaceholder color={props.color} />;
|
||||
}
|
||||
};
|
24
packages/instant/src/components/animations/full_rotation.tsx
Normal file
24
packages/instant/src/components/animations/full_rotation.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { keyframes, styled } from '../../style/theme';
|
||||
|
||||
interface FullRotationProps {
|
||||
height: string;
|
||||
width: string;
|
||||
}
|
||||
const rotatingKeyframes = keyframes`
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
`;
|
||||
|
||||
export const FullRotation =
|
||||
styled.div <
|
||||
FullRotationProps >
|
||||
`
|
||||
animation: ${rotatingKeyframes} 2s linear infinite;
|
||||
height: ${props => props.height};
|
||||
width: ${props => props.width};
|
||||
`;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user