Compare commits
792 Commits
@0xproject
...
@0xproject
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9b320e636 | ||
|
|
ecdc0636d8 | ||
|
|
ea12e34809 | ||
|
|
9fb7865292 | ||
|
|
12f30c78ff | ||
|
|
e3bed5cc71 | ||
|
|
0f8f5ca5ff | ||
|
|
0fe0433b9a | ||
|
|
ab1e38701d | ||
|
|
258fe8ea50 | ||
|
|
813824868e | ||
|
|
028184947f | ||
|
|
14c96e0b97 | ||
|
|
ef03d1ae13 | ||
|
|
f1613d36ac | ||
|
|
8314bbbbac | ||
|
|
462f1f00d8 | ||
|
|
1c80bba4dd | ||
|
|
d22cff0976 | ||
|
|
269b56b907 | ||
|
|
60ebfcf36d | ||
|
|
824c331ea0 | ||
|
|
b9e51d2fad | ||
|
|
9669a4d121 | ||
|
|
e929fb4337 | ||
|
|
80da9cd31f | ||
|
|
5ed7a1baba | ||
|
|
07c111d1f5 | ||
|
|
a2024da955 | ||
|
|
7418926ebb | ||
|
|
4cc33d270e | ||
|
|
f767f5c12c | ||
|
|
0ea3b10efd | ||
|
|
d634775d40 | ||
|
|
c4ab5bc653 | ||
|
|
1d3bdfc374 | ||
|
|
72fb1ee36f | ||
|
|
afbc4989d5 | ||
|
|
d2e422cd5e | ||
|
|
49c7365d93 | ||
|
|
c753e24f0a | ||
|
|
acfbba5476 | ||
|
|
e796734659 | ||
|
|
f172908bde | ||
|
|
16dc4e9f66 | ||
|
|
8eefc89d55 | ||
|
|
20d349cea7 | ||
|
|
22f408f713 | ||
|
|
1e0fa776c1 | ||
|
|
faf5c84082 | ||
|
|
b21f6e4d86 | ||
|
|
bc52303402 | ||
|
|
2da705e81c | ||
|
|
a0601cd052 | ||
|
|
ed2c06508b | ||
|
|
03b3d74748 | ||
|
|
0557d6a9bf | ||
|
|
d975c0cef3 | ||
|
|
188bf000b7 | ||
|
|
608442b2e8 | ||
|
|
aefc122caf | ||
|
|
a72eae7ea8 | ||
|
|
30e3afc0fb | ||
|
|
97809a03eb | ||
|
|
f894ffc0cc | ||
|
|
127fbc6e94 | ||
|
|
9f870b3d4e | ||
|
|
51b86742d1 | ||
|
|
3a85b3212b | ||
|
|
fd6445439e | ||
|
|
51fa8d3e24 | ||
|
|
7b8db1156d | ||
|
|
32ad34d224 | ||
|
|
cfbb1c440e | ||
|
|
ade2f96ca3 | ||
|
|
abb38e1bc0 | ||
|
|
0df36471b7 | ||
|
|
97312c2656 | ||
|
|
e9e4df4891 | ||
|
|
e0f80c5e6a | ||
|
|
f21b042ed1 | ||
|
|
d8c7c9803c | ||
|
|
302b9deef3 | ||
|
|
0c8264801a | ||
|
|
54d1a0359f | ||
|
|
b87e48c113 | ||
|
|
a874cd2424 | ||
|
|
d9e308e53a | ||
|
|
efc3536283 | ||
|
|
4b7e669d29 | ||
|
|
01c6efeaf1 | ||
|
|
22cf7bee5b | ||
|
|
ef890aeac4 | ||
|
|
91e8c00076 | ||
|
|
20bf4d8ef9 | ||
|
|
795da130a2 | ||
|
|
51a625d4af | ||
|
|
ab8544b0ff | ||
|
|
b68d16820f | ||
|
|
61d9cdced0 | ||
|
|
714f9ed207 | ||
|
|
ccccaf8e12 | ||
|
|
c3ce9d6104 | ||
|
|
d3f602f063 | ||
|
|
6b379a8a0f | ||
|
|
d1d636f1ca | ||
|
|
ba9d3cbdb8 | ||
|
|
bcf8d51806 | ||
|
|
66c0d6724a | ||
|
|
0f477607f9 | ||
|
|
c1635f2656 | ||
|
|
029d91bd7a | ||
|
|
03dbad6813 | ||
|
|
c65b2573c4 | ||
|
|
7fbee77875 | ||
|
|
3cc1a952ca | ||
|
|
9c8de3e933 | ||
|
|
cbdce6b67e | ||
|
|
a6746ae5cd | ||
|
|
7111f3ffc6 | ||
|
|
87a7a4ad2d | ||
|
|
1ee2d6ed54 | ||
|
|
1eba78e20a | ||
|
|
a1fb438a8c | ||
|
|
40d1b0a23c | ||
|
|
1c9a657693 | ||
|
|
11747c6cf4 | ||
|
|
2a7b3aecc3 | ||
|
|
75babed693 | ||
|
|
0a32ae6cb5 | ||
|
|
3d67f122a5 | ||
|
|
b0daec8384 | ||
|
|
f5b1fe0e6b | ||
|
|
139d289b01 | ||
|
|
fd242a9cba | ||
|
|
7efa17ef7d | ||
|
|
a0b9c7777b | ||
|
|
5204e4c08d | ||
|
|
1050ecdf3c | ||
|
|
5176d929fa | ||
|
|
d712dc47d9 | ||
|
|
8adc6f0faa | ||
|
|
4e783fba57 | ||
|
|
ade620f4f7 | ||
|
|
5915f8430c | ||
|
|
9e0f06d060 | ||
|
|
ce86ae0191 | ||
|
|
2bec5cb7fd | ||
|
|
cd766ea2a1 | ||
|
|
aeea3817a4 | ||
|
|
0f11ae1875 | ||
|
|
6e87e3e1ac | ||
|
|
4ba108d12f | ||
|
|
8ff17ff960 | ||
|
|
0d56daf7ab | ||
|
|
9db0bc262b | ||
|
|
f410903465 | ||
|
|
5f2c303bd8 | ||
|
|
6aa4984fed | ||
|
|
f5cd1ac82e | ||
|
|
54c0b7b261 | ||
|
|
a7902eca1f | ||
|
|
2b4bb579d4 | ||
|
|
52c956222e | ||
|
|
0900e0c85e | ||
|
|
a5653337c1 | ||
|
|
d097113639 | ||
|
|
9389d64392 | ||
|
|
931e7e7d71 | ||
|
|
cce2fb40a1 | ||
|
|
547cf4bef3 | ||
|
|
d528ce757c | ||
|
|
3b78188fec | ||
|
|
d91b30faef | ||
|
|
dc956020ef | ||
|
|
a52eb81380 | ||
|
|
ab0055d5c6 | ||
|
|
32c25a2034 | ||
|
|
c30b42434a | ||
|
|
3c797a6e11 | ||
|
|
9b864517e2 | ||
|
|
a858e2870b | ||
|
|
ce1542da4f | ||
|
|
d2ebf4a777 | ||
|
|
c5fcea1dbd | ||
|
|
5e8ef070e2 | ||
|
|
2d30c290e9 | ||
|
|
688b34710e | ||
|
|
afbfc8ba1c | ||
|
|
671f29774b | ||
|
|
4c99ac0ca2 | ||
|
|
0e690608d3 | ||
|
|
92f6391df5 | ||
|
|
f2af6e4b3a | ||
|
|
27c03cffe2 | ||
|
|
499915042e | ||
|
|
1a901554cc | ||
|
|
5b64b3ea93 | ||
|
|
6fc5c0cd46 | ||
|
|
328da21420 | ||
|
|
81062d20eb | ||
|
|
835d06dcdc | ||
|
|
8929543b55 | ||
|
|
f62044c1e3 | ||
|
|
a31f7a5112 | ||
|
|
fe68114f39 | ||
|
|
a5231df6d9 | ||
|
|
fd545ec00f | ||
|
|
73d8a2adf7 | ||
|
|
04d11d6fac | ||
|
|
2eede4a09e | ||
|
|
bc7e8ff471 | ||
|
|
73e81c62fb | ||
|
|
8c5dc7cecd | ||
|
|
300c9f09b9 | ||
|
|
06f4427939 | ||
|
|
b1dc20bbb3 | ||
|
|
4887d1d42f | ||
|
|
d247d72e3e | ||
|
|
50957e1d29 | ||
|
|
6aad12a52f | ||
|
|
db0944acde | ||
|
|
e553ef83de | ||
|
|
a619949a56 | ||
|
|
1346fa792a | ||
|
|
b763cdbd4c | ||
|
|
e4eac14dc9 | ||
|
|
bdda1f2992 | ||
|
|
9c7289d7a3 | ||
|
|
d861caca23 | ||
|
|
590033bcb2 | ||
|
|
af1e4574a8 | ||
|
|
7b806fe84d | ||
|
|
e54e2ac67b | ||
|
|
de9f0732a0 | ||
|
|
20acdbf6c3 | ||
|
|
6a6d2f73a8 | ||
|
|
f5a8f00af8 | ||
|
|
018a437d62 | ||
|
|
32d75b6483 | ||
|
|
cb6cace910 | ||
|
|
0326ddd79d | ||
|
|
d6f40a9281 | ||
|
|
687802394a | ||
|
|
ad570b8ae1 | ||
|
|
b9165c03af | ||
|
|
86d4ffe7e5 | ||
|
|
2dea179333 | ||
|
|
5a7908984e | ||
|
|
955fdf5d13 | ||
|
|
a6f40d4187 | ||
|
|
6daf754f5b | ||
|
|
da8cf9981e | ||
|
|
be64184cfa | ||
|
|
3031598843 | ||
|
|
b9b00e10d3 | ||
|
|
6c34255a3e | ||
|
|
41064adc66 | ||
|
|
2fcc36bbad | ||
|
|
762c0143eb | ||
|
|
6c6f34ee72 | ||
|
|
42b7b0dab9 | ||
|
|
e58e35e098 | ||
|
|
654b048602 | ||
|
|
3ece72af49 | ||
|
|
2ef31991c7 | ||
|
|
d3293a5571 | ||
|
|
854752acdf | ||
|
|
0c889385f1 | ||
|
|
6e1a549fcb | ||
|
|
5f0a2953c6 | ||
|
|
78b513c52a | ||
|
|
8ffce78827 | ||
|
|
d4852092b8 | ||
|
|
622ce0bf2e | ||
|
|
6a197a64e6 | ||
|
|
1e4c3ed22b | ||
|
|
e3521c6388 | ||
|
|
9d81e069dc | ||
|
|
8623a30763 | ||
|
|
6cf39896f1 | ||
|
|
44b6adaa29 | ||
|
|
762a6199b2 | ||
|
|
8da42b12f4 | ||
|
|
c473a0444c | ||
|
|
e693629bbd | ||
|
|
0dbe883c3b | ||
|
|
cc12bc9247 | ||
|
|
ddec01e6c1 | ||
|
|
03bc7bb935 | ||
|
|
5207dfdc0e | ||
|
|
fc40efb761 | ||
|
|
50556e2609 | ||
|
|
7a22298597 | ||
|
|
36cadaae46 | ||
|
|
09e921a562 | ||
|
|
13cbaf56b2 | ||
|
|
62910c8e89 | ||
|
|
f20e1acad9 | ||
|
|
5dea432ebf | ||
|
|
016d82d766 | ||
|
|
260c72cc20 | ||
|
|
3d7bcd7ecb | ||
|
|
ac9175bf88 | ||
|
|
294d3bbdc1 | ||
|
|
6db614251e | ||
|
|
bcc588efe7 | ||
|
|
f7b3fc58bc | ||
|
|
de40497330 | ||
|
|
d84bb7ed7e | ||
|
|
f02ada2d11 | ||
|
|
48970d3424 | ||
|
|
8940b1759d | ||
|
|
91a50d0f53 | ||
|
|
ed4f8c5b66 | ||
|
|
2f07ee0a8f | ||
|
|
8dd00a8eef | ||
|
|
d7845a177e | ||
|
|
7a3be0a320 | ||
|
|
14cebce304 | ||
|
|
9fcf9f2504 | ||
|
|
c466ab6cf2 | ||
|
|
01bf789ad4 | ||
|
|
1a1ab5af54 | ||
|
|
4089ad7b4b | ||
|
|
2adc299c78 | ||
|
|
3aef323c13 | ||
|
|
a655cd046c | ||
|
|
9c8701f5f6 | ||
|
|
7ac84aff0a | ||
|
|
fd13c8f68c | ||
|
|
532964af42 | ||
|
|
52d1407215 | ||
|
|
ecb7356345 | ||
|
|
edda7dae94 | ||
|
|
32da0a376a | ||
|
|
073e76ee90 | ||
|
|
ceba82260f | ||
|
|
a5a61c87fc | ||
|
|
d34feb1e0a | ||
|
|
6cc5e45183 | ||
|
|
618c7ef48a | ||
|
|
14047f9c7b | ||
|
|
f439f162d2 | ||
|
|
5b685b32bd | ||
|
|
6ce151c676 | ||
|
|
eb79b5d651 | ||
|
|
608e1c8960 | ||
|
|
f8772d8850 | ||
|
|
ce2f408864 | ||
|
|
c2a362e3ea | ||
|
|
eafdd4d42d | ||
|
|
1a2c58494f | ||
|
|
68c00976f1 | ||
|
|
aa2616b307 | ||
|
|
3062c18ebd | ||
|
|
a83f5241dc | ||
|
|
f89acb49be | ||
|
|
2b5f45676f | ||
|
|
aedd51a61b | ||
|
|
0b5a49c17d | ||
|
|
08f7666d21 | ||
|
|
81ff99276b | ||
|
|
e71862676c | ||
|
|
67777c586d | ||
|
|
9ada8e4ddf | ||
|
|
0142e7fa8f | ||
|
|
467e9abf5f | ||
|
|
512980d9bd | ||
|
|
e235a63119 | ||
|
|
4c28b66539 | ||
|
|
46d79e5115 | ||
|
|
d79994fbb2 | ||
|
|
518a2da027 | ||
|
|
71fa92dbeb | ||
|
|
172d2353dd | ||
|
|
3315006c45 | ||
|
|
6700745585 | ||
|
|
0ff18058ab | ||
|
|
1a11283086 | ||
|
|
ed559be47c | ||
|
|
a60dd1cbaf | ||
|
|
7ee37fb62a | ||
|
|
2970e103db | ||
|
|
78333b3026 | ||
|
|
1ca182e741 | ||
|
|
8419db53bb | ||
|
|
f76c9bc226 | ||
|
|
6a39a69afe | ||
|
|
2474d1d2f4 | ||
|
|
e4188f5d4c | ||
|
|
0fcbd02d50 | ||
|
|
4969797c23 | ||
|
|
0e932286d2 | ||
|
|
366a9502dd | ||
|
|
988a334758 | ||
|
|
4fe6269043 | ||
|
|
646927962a | ||
|
|
b56baefaa6 | ||
|
|
f49a507297 | ||
|
|
c20549e88d | ||
|
|
cd16986942 | ||
|
|
e481404a14 | ||
|
|
3dfde15133 | ||
|
|
4454cfa65d | ||
|
|
382839464f | ||
|
|
cce5585795 | ||
|
|
26a9fe9127 | ||
|
|
47a267c3fa | ||
|
|
36836eb942 | ||
|
|
aad0804a1e | ||
|
|
3c68d9c297 | ||
|
|
ffdc7d13a9 | ||
|
|
c5085d8364 | ||
|
|
00ad7bc470 | ||
|
|
360927ec77 | ||
|
|
b6f546ebe0 | ||
|
|
2a092143dc | ||
|
|
de50407953 | ||
|
|
57d5fbfbd8 | ||
|
|
92322c0e07 | ||
|
|
97ed453eb4 | ||
|
|
654b782810 | ||
|
|
51211a21ba | ||
|
|
133b6fe240 | ||
|
|
c824fe8718 | ||
|
|
26d3a487a5 | ||
|
|
e0a2afc068 | ||
|
|
f6e97bb284 | ||
|
|
6c8b998505 | ||
|
|
f9fab216e9 | ||
|
|
c308359f59 | ||
|
|
375d667144 | ||
|
|
84bd54ba40 | ||
|
|
73c36fe2d2 | ||
|
|
ec3e9efdaa | ||
|
|
d5c389b7dc | ||
|
|
7f233dcb15 | ||
|
|
6a2421c683 | ||
|
|
d66ca7b5cb | ||
|
|
5e38cbd69c | ||
|
|
b6d8dcb6e1 | ||
|
|
08ee1ab2e6 | ||
|
|
26edec5773 | ||
|
|
d72e06842f | ||
|
|
0a0da63ac7 | ||
|
|
873ec898d8 | ||
|
|
97a70d14a3 | ||
|
|
394fbebfa8 | ||
|
|
b79588c4a0 | ||
|
|
3b46e82625 | ||
|
|
dbaf1fcd43 | ||
|
|
4caf1271e4 | ||
|
|
6921943aff | ||
|
|
3ce90b8257 | ||
|
|
3866154b50 | ||
|
|
64ed2464cf | ||
|
|
e27780aee9 | ||
|
|
744e6e60c5 | ||
|
|
f70c1ff009 | ||
|
|
3a808fe7fd | ||
|
|
2ca169b3c4 | ||
|
|
098d486291 | ||
|
|
ec4fb70b80 | ||
|
|
2a82807be4 | ||
|
|
43ae868c69 | ||
|
|
1bc742aed1 | ||
|
|
6dc852774e | ||
|
|
7967ebed57 | ||
|
|
105b927397 | ||
|
|
9219f9d8ae | ||
|
|
f780e6f235 | ||
|
|
27670f4da6 | ||
|
|
e051743a3d | ||
|
|
fb03003b3a | ||
|
|
e52d0a3512 | ||
|
|
cba92a01b6 | ||
|
|
0a87364101 | ||
|
|
a89908540f | ||
|
|
c4e2dcafa4 | ||
|
|
0163984ea4 | ||
|
|
db3ce08cab | ||
|
|
1076959006 | ||
|
|
5127cbb22c | ||
|
|
9175b43542 | ||
|
|
562fec01d8 | ||
|
|
b8051c8fed | ||
|
|
4df66a4802 | ||
|
|
a2ff63daa5 | ||
|
|
7ce0f9682f | ||
|
|
3c6d0dc3e0 | ||
|
|
64a6fb2344 | ||
|
|
07734a5184 | ||
|
|
32d4994219 | ||
|
|
08d22d2f3c | ||
|
|
b7b0185baf | ||
|
|
7b0c13c121 | ||
|
|
a98ecc05af | ||
|
|
f7337c1a05 | ||
|
|
53e2cda4c8 | ||
|
|
8064914bb7 | ||
|
|
6bb2203f79 | ||
|
|
3d56817da1 | ||
|
|
31e3b9ff8b | ||
|
|
b2e32aaf58 | ||
|
|
699de9174e | ||
|
|
1dd9ec4d5a | ||
|
|
87d66ccf6c | ||
|
|
1134ff1075 | ||
|
|
178676ef8c | ||
|
|
94740155e5 | ||
|
|
9341afe764 | ||
|
|
7ce1e9b18d | ||
|
|
1821f60fb5 | ||
|
|
235d78565e | ||
|
|
db5880539b | ||
|
|
76f4d67f33 | ||
|
|
e59c57106c | ||
|
|
bb4c748bf1 | ||
|
|
92cb9c3807 | ||
|
|
1a4e99431b | ||
|
|
ec9d1ca57e | ||
|
|
71c9b98896 | ||
|
|
71bac8c60b | ||
|
|
7b0f7c2e5c | ||
|
|
ad67a6add5 | ||
|
|
1353723b58 | ||
|
|
f811c07454 | ||
|
|
bb85382824 | ||
|
|
3ed4a1ba20 | ||
|
|
c50da5d034 | ||
|
|
9b196ba68c | ||
|
|
df79fb19af | ||
|
|
f8bde5ab9b | ||
|
|
0cd37cbf7e | ||
|
|
d621e4201d | ||
|
|
82af1df3c3 | ||
|
|
ea8c2b8d69 | ||
|
|
8ddcb6c841 | ||
|
|
1681361aed | ||
|
|
6a6f98299d | ||
|
|
19ba272d62 | ||
|
|
2f8ceca2ef | ||
|
|
ba1baafca5 | ||
|
|
20a07494f6 | ||
|
|
c66477c690 | ||
|
|
5c612a186f | ||
|
|
943e556f43 | ||
|
|
4bf4f96f47 | ||
|
|
384cd2f605 | ||
|
|
425af46f98 | ||
|
|
c83ee04662 | ||
|
|
2054cd78da | ||
|
|
88982f98ff | ||
|
|
2ea0b839d3 | ||
|
|
afd83e59b8 | ||
|
|
7f84049538 | ||
|
|
98840c9c5f | ||
|
|
26cacfa247 | ||
|
|
4b2d27b5e5 | ||
|
|
69625946b1 | ||
|
|
f7fe9b0961 | ||
|
|
7fcd34eb36 | ||
|
|
1f5848ba82 | ||
|
|
bbd414bdcd | ||
|
|
a1737a28d0 | ||
|
|
66be42d1f8 | ||
|
|
c984c0f2c0 | ||
|
|
89d2bb7ecd | ||
|
|
9f8cad93f7 | ||
|
|
a207260fe0 | ||
|
|
1ef4a47255 | ||
|
|
b8aa68b4d1 | ||
|
|
61edbac6e5 | ||
|
|
d315133d34 | ||
|
|
82d59dbea8 | ||
|
|
42884e0871 | ||
|
|
7fb8b546f9 | ||
|
|
80fe1938b8 | ||
|
|
2409afae95 | ||
|
|
06705f9e88 | ||
|
|
2b408e71ac | ||
|
|
b097193486 | ||
|
|
543f2c91fe | ||
|
|
05c0088445 | ||
|
|
2f6f815d81 | ||
|
|
1e03fbe1a8 | ||
|
|
4409f11b24 | ||
|
|
7a216901be | ||
|
|
0e7c254b93 | ||
|
|
ba14850c9a | ||
|
|
59d3a21993 | ||
|
|
d2faa49bf4 | ||
|
|
438c0e27ea | ||
|
|
4c14372b4a | ||
|
|
8b4077d7de | ||
|
|
914b009361 | ||
|
|
b2a4b7eb88 | ||
|
|
daa50442c9 | ||
|
|
76fd7f47eb | ||
|
|
fbf840cb68 | ||
|
|
798a647b71 | ||
|
|
26a0b09064 | ||
|
|
98570b5da1 | ||
|
|
e923d7dafb | ||
|
|
64b6861880 | ||
|
|
c46e11cae2 | ||
|
|
82ccfa21e1 | ||
|
|
13f7fc1fd2 | ||
|
|
018cc14a87 | ||
|
|
3ce295a2af | ||
|
|
a30107ab86 | ||
|
|
d8df6968d3 | ||
|
|
0515c6acde | ||
|
|
607b44e01d | ||
|
|
5c0bae2070 | ||
|
|
4012e31115 | ||
|
|
2d8e9eda56 | ||
|
|
4375a0e07e | ||
|
|
a07cfb7abc | ||
|
|
c131d82699 | ||
|
|
de2dcbae5a | ||
|
|
b0000bb276 | ||
|
|
82789d5315 | ||
|
|
3df5882711 | ||
|
|
b6765b849c | ||
|
|
df94e5f164 | ||
|
|
79edc12c76 | ||
|
|
bd03151c2a | ||
|
|
7c0fdc7ecf | ||
|
|
b333ed91de | ||
|
|
6a073d5f86 | ||
|
|
c7159b2be4 | ||
|
|
2d98193c83 | ||
|
|
685756f9d5 | ||
|
|
535bb364b6 | ||
|
|
c740539f48 | ||
|
|
4cf331067b | ||
|
|
a3ba7683f4 | ||
|
|
5edfec68cf | ||
|
|
eb494f78fa | ||
|
|
d963941be0 | ||
|
|
8ab65fdde4 | ||
|
|
8e2c0bb977 | ||
|
|
f1f1064f70 | ||
|
|
88500e3714 | ||
|
|
eae2a4df8b | ||
|
|
ade8e95d2e | ||
|
|
a0b225b8b1 | ||
|
|
323e8756ba | ||
|
|
ada5428df7 | ||
|
|
7869c19245 | ||
|
|
5706b29c8c | ||
|
|
8ff7b2405f | ||
|
|
eaabe15863 | ||
|
|
63b2ae743b | ||
|
|
c5ea985a70 | ||
|
|
11b35b89f5 | ||
|
|
6d5b16725d | ||
|
|
c34897036e | ||
|
|
1e51af1d4b | ||
|
|
8ee6e26608 | ||
|
|
4d36f38f96 | ||
|
|
d31ca444e1 | ||
|
|
090b3014c0 | ||
|
|
491a322ceb | ||
|
|
12e16d532b | ||
|
|
7814a391d8 | ||
|
|
322151b0d5 | ||
|
|
4a136cafda | ||
|
|
d0df25d9e2 | ||
|
|
8d003dbc30 | ||
|
|
2c7358d64f | ||
|
|
94e260cec6 | ||
|
|
783ac3c105 | ||
|
|
d46e3f6778 | ||
|
|
6fe3158778 | ||
|
|
bbd12e33ec | ||
|
|
e4d55242d8 | ||
|
|
dedddcfcf5 | ||
|
|
613a78bcf6 | ||
|
|
f5decb1d7e | ||
|
|
47b4c236c3 | ||
|
|
39ccb2df0b | ||
|
|
5bfdffda11 | ||
|
|
247f8c8557 | ||
|
|
3ce449e167 | ||
|
|
663f9657ea | ||
|
|
457f951aaf | ||
|
|
feafd57027 | ||
|
|
5c0183c71e | ||
|
|
fb7d425244 | ||
|
|
3fab40efe5 | ||
|
|
0bbdbc9e63 | ||
|
|
9bc481ff62 | ||
|
|
32dea43d2e | ||
|
|
632da71a8d | ||
|
|
2ffab22185 | ||
|
|
5541327968 | ||
|
|
096eaa20d7 | ||
|
|
e5fe6b915e | ||
|
|
512bd84cc2 | ||
|
|
ebbcbeedd2 | ||
|
|
be17308e50 | ||
|
|
25fa29e6e1 | ||
|
|
bddc47f9b2 | ||
|
|
51948d7760 | ||
|
|
5817a30031 | ||
|
|
e216eb1e7b | ||
|
|
549c6afa0a | ||
|
|
6b08e6b809 | ||
|
|
0438fdde49 | ||
|
|
be4ea18119 | ||
|
|
a75d6531f2 | ||
|
|
da69ddc19b | ||
|
|
e92926e881 | ||
|
|
7dd208fb49 | ||
|
|
5305db689d | ||
|
|
2338c7a3b3 | ||
|
|
829bc96209 | ||
|
|
7454e16aae | ||
|
|
e4acad60e9 | ||
|
|
f35af1fb6d | ||
|
|
c0e008c601 | ||
|
|
9acf4458c0 | ||
|
|
70de264d4d | ||
|
|
1a0b9e4612 | ||
|
|
66dc70c057 | ||
|
|
6641f34d76 | ||
|
|
f3ae5d8160 | ||
|
|
d937541aa0 | ||
|
|
21707d7ff6 | ||
|
|
3002bc0eee | ||
|
|
df50232ed9 | ||
|
|
17d49067e9 | ||
|
|
9a2e023a51 | ||
|
|
9c747f3160 | ||
|
|
08ea71cb24 | ||
|
|
a96abe2422 | ||
|
|
84a4a888e6 | ||
|
|
e3299b546e | ||
|
|
f2e0f1b2f1 | ||
|
|
2a4456b9ca | ||
|
|
560a55bfd1 | ||
|
|
d32f0fad12 | ||
|
|
031e7d270d | ||
|
|
3b73a0e269 | ||
|
|
bdd299dd9e | ||
|
|
f97e605bf6 | ||
|
|
db9ff76754 | ||
|
|
190eafc30e | ||
|
|
d4ee0e8622 | ||
|
|
96c90e6295 | ||
|
|
ff95da411b | ||
|
|
8bac1706a1 | ||
|
|
2cc7289b7b | ||
|
|
81d6df925e | ||
|
|
677e77d0ae | ||
|
|
0d0c1af7f7 | ||
|
|
fb55def54f | ||
|
|
eea86757d5 | ||
|
|
7a41a5249f | ||
|
|
f9e05d0cad | ||
|
|
15a63c4bc5 | ||
|
|
4a2e4d2b55 | ||
|
|
12033abe09 | ||
|
|
f9410d5d00 | ||
|
|
c232a32991 | ||
|
|
57f37939d5 | ||
|
|
432ff58107 | ||
|
|
d31b051fc5 | ||
|
|
98405a39db | ||
|
|
6239686afa | ||
|
|
45186b70ec | ||
|
|
b4fead9606 | ||
|
|
61243b418e | ||
|
|
fe75660e88 | ||
|
|
946e6c1644 | ||
|
|
3eb232b3fc | ||
|
|
38de1c9a31 | ||
|
|
78dcb87a75 | ||
|
|
7e78f5941a | ||
|
|
82d1412d45 | ||
|
|
a8d328bfc9 | ||
|
|
20f9318597 | ||
|
|
b646c84414 | ||
|
|
7b7664bd66 | ||
|
|
ab5e021bda | ||
|
|
0fc9814004 | ||
|
|
e617da3bbf | ||
|
|
a59e9f024e | ||
|
|
4670cc1a5f |
@@ -53,9 +53,9 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
# HACK(albrow): we need to sleep 15 seconds to ensure the devnet is
|
||||
# HACK(albrow): we need to sleep 10 seconds to ensure the devnet is
|
||||
# initialized
|
||||
- run: sleep 15 && TEST_PROVIDER=geth yarn wsrun test contracts
|
||||
- run: sleep 10 && TEST_PROVIDER=geth yarn wsrun test contracts
|
||||
test-rest:
|
||||
docker:
|
||||
- image: circleci/node:9
|
||||
@@ -64,31 +64,41 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn wsrun test:circleci @0xproject/contract-wrappers
|
||||
- run: yarn wsrun test:circleci @0xproject/sol-compiler
|
||||
- run: yarn wsrun test:circleci @0xproject/0x.js
|
||||
- run: yarn wsrun test:circleci @0xproject/assert
|
||||
- run: yarn wsrun test:circleci @0xproject/base-contract
|
||||
- run: yarn wsrun test:circleci @0xproject/connect
|
||||
- run: yarn wsrun test:circleci @0xproject/contract-wrappers
|
||||
- run: yarn wsrun test:circleci @0xproject/dev-utils
|
||||
- run: yarn wsrun test:circleci @0xproject/json-schemas
|
||||
- run: yarn wsrun test:circleci @0xproject/subproviders
|
||||
- run: yarn wsrun test:circleci @0xproject/sol-cov
|
||||
- run: yarn wsrun test:circleci @0xproject/metacoin
|
||||
- run: yarn wsrun test:circleci @0xproject/order-utils
|
||||
- run: yarn wsrun test:circleci @0xproject/order-watcher
|
||||
- run: yarn wsrun test:circleci @0xproject/sol-compiler
|
||||
- run: yarn wsrun test:circleci @0xproject/sol-cov
|
||||
- run: yarn wsrun test:circleci @0xproject/sra-report
|
||||
- run: yarn wsrun test:circleci @0xproject/subproviders
|
||||
- run: yarn wsrun test:circleci @0xproject/web3-wrapper
|
||||
- save_cache:
|
||||
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
|
||||
key: coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/contract-wrappers/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/sol-compiler/coverage/lcov.info
|
||||
- ~/repo/packages/0x.js/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/assert/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/base-contract/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/connect/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/contract-wrappers/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
@@ -98,17 +108,37 @@ jobs:
|
||||
paths:
|
||||
- ~/repo/packages/json-schemas/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
|
||||
key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/subproviders/coverage/lcov.info
|
||||
- ~/repo/packages/metacoin/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/order-utils/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-order-watcher-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/order-watcher/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/sol-compiler/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/sol-cov/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
|
||||
key: coverage-sra-report-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/metacoin/coverage/lcov.info
|
||||
- ~/repo/packages/sra-report/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/subproviders/coverage/lcov.info
|
||||
- save_cache:
|
||||
key: coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo/packages/web3-wrapper/coverage/lcov.info
|
||||
static-tests:
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
@@ -127,9 +157,15 @@ jobs:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
|
||||
@@ -144,22 +180,31 @@ jobs:
|
||||
- coverage-json-schemas-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- coverage-order-watcher-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- coverage-sra-report-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- restore_cache:
|
||||
keys:
|
||||
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn report_coverage
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -67,6 +67,9 @@ generated_docs/
|
||||
|
||||
TODO.md
|
||||
|
||||
# VSCode file
|
||||
.vscode
|
||||
|
||||
packages/website/public/bundle*
|
||||
packages/react-docs/example/public/bundle*
|
||||
|
||||
@@ -81,14 +84,15 @@ packages/contract-wrappers/test/artifacts/
|
||||
|
||||
# generated contract wrappers
|
||||
packages/0x.js/src/generated_contract_wrappers/
|
||||
packages/contracts/src/generated_contract_wrappers/
|
||||
packages/contracts/generated_contract_wrappers/
|
||||
packages/contract-wrappers/src/contract_wrappers/generated/
|
||||
packages/metacoin/src/contract_wrappers
|
||||
packages/fill-scenarios/src/generated_contract_wrappers/
|
||||
packages/order-watcher/src/generated_contract_wrappers/
|
||||
packages/order-utils/src/generated_contract_wrappers/
|
||||
packages/migrations/src/v1/contract_wrappers
|
||||
packages/migrations/src/v2/contract_wrappers
|
||||
packages/migrations/src/1.0.0/contract_wrappers
|
||||
packages/migrations/src/2.0.0/contract_wrappers
|
||||
packages/migrations/src/2.0.0-beta-testnet/contract_wrappers
|
||||
|
||||
# solc-bin in sol-compiler
|
||||
packages/sol-compiler/solc_bin/
|
||||
|
||||
@@ -3,12 +3,13 @@ lib
|
||||
/packages/contract-wrappers/src/contract_wrappers/generated/
|
||||
/packages/metacoin/src/contract_wrappers
|
||||
/packages/0x.js/src/generated_contract_wrappers/
|
||||
/packages/contracts/src/generated_contract_wrappers/
|
||||
/packages/contracts/generated_contract_wrappers/
|
||||
/packages/fill-scenarios/src/generated_contract_wrappers/
|
||||
/packages/order-watcher/src/generated_contract_wrappers/
|
||||
/packages/order-utils/src/generated_contract_wrappers/
|
||||
/packages/migrations/src/v1/contract_wrappers
|
||||
/packages/migrations/src/v2/contract_wrappers
|
||||
/packages/migrations/src/1.0.0/contract_wrappers
|
||||
/packages/migrations/src/2.0.0/contract_wrappers
|
||||
/packages/migrations/src/2.0.0-beta-testnet/contract_wrappers
|
||||
/packages/0x.js/test/artifacts
|
||||
/packages/contracts/src/artifacts
|
||||
/packages/metacoin/artifacts
|
||||
@@ -16,5 +17,6 @@ lib
|
||||
/packages/order-watcher/test/artifacts
|
||||
/packages/migrations/artifacts/1.0.0
|
||||
/packages/migrations/artifacts/2.0.0
|
||||
/packages/migrations/artifacts/2.0.0-beta-testnet
|
||||
package.json
|
||||
scripts/postpublish_utils.js
|
||||
|
||||
@@ -21,6 +21,18 @@ If you're adding a new public function/member, make sure you document it with Ja
|
||||
|
||||
If the sub-package you are modifying has a `CHANGELOG.md` file, make sure to add an entry in it for the change made to the package. For published packages, only changes that modify the public interface or behavior of the package need a CHANGELOG entry.
|
||||
|
||||
#### Enabling code coverage checks on your fork
|
||||
|
||||
If you simply fork the repo and then create a PR sourced from it, your PR will fail its test coverage check. This is because the 0x CircleCI configuration sets the `COVERALLS_REPO_TOKEN` environment variable to the token for 0xProject/0x-monorepo, but when running the check against your fork the token needs to match the repo that is your fork, rather than the 0x repo.
|
||||
|
||||
To facilitate this check, after creating your fork, but before creating the branch for your PR, do the following:
|
||||
|
||||
1. Log in to [coveralls.io](https://coveralls.io/), go to Add Repos, and enable your fork. Then go to the settings for that repo, and copy the Repo Token identifier.
|
||||
2. Log in to [CircleCI](https://circleci.com/login), go to Add Projects, click the Set Up Project button corresponding to your fork, and then click Start Building. (Aside from step 3 below, no actual set up is needed, since it will use the `.circleci/config.yml` file in 0x-monorepo, so you can ignore all of the instruction/explanation given on the page with the Start Building button.)
|
||||
3. In CircleCI, configure your project to add an Environment Variable, with name `COVERALLS_REPO_TOKEN`, and for the value paste in the Repo Token you copied in step 1.
|
||||
|
||||
Now, when you push to your branch, CircleCI will automatically run all of the checks in your own instance, and the coverage check will work since it has the proper Repo Token, and the PR will magically refer to your own checks rather than running them in the 0x CircleCI instance.
|
||||
|
||||
### Styleguide
|
||||
|
||||
We use [TSLint](https://palantir.github.io/tslint/) with [custom configs](https://github.com/0xProject/0x-monorepo/tree/development/packages/tslint-config) to keep our code style consistent.
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
<!--- Thank you for taking the time to submit a Pull Request -->
|
||||
|
||||
<!--- Provide a general summary of the issue in the Title above -->
|
||||
|
||||
## Description
|
||||
|
||||
<!--- Describe your changes in detail -->
|
||||
|
||||
## Motivation and Context
|
||||
## Testing instructions
|
||||
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
|
||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
## How Has This Been Tested?
|
||||
|
||||
<!--- Please describe in detail how you tested your changes. -->
|
||||
|
||||
<!--- Include details of your testing environment, and the tests you ran to -->
|
||||
|
||||
<!--- see how your change affects other areas of the code, etc. -->
|
||||
<!--- Please describe how reviewers can test your changes -->
|
||||
|
||||
## Types of changes
|
||||
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
|
||||
This repository is a monorepo including the 0x protocol smart contracts and numerous developer tools. Each public sub-package is independently published to NPM.
|
||||
|
||||
If you're developing on 0x now or are interested in using 0x infrastructure in the future, please join our [developer mailing list][dev-mailing-list-url] for updates.
|
||||
|
||||
[website-url]: https://0xproject.com/
|
||||
[whitepaper-url]: https://0xproject.com/pdfs/0x_white_paper.pdf
|
||||
[dev-mailing-list-url]: http://eepurl.com/dx4cPf
|
||||
|
||||
[](https://circleci.com/gh/0xProject/0x-monorepo)
|
||||
[](https://coveralls.io/github/0xProject/0x-monorepo?branch=development)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"private": true,
|
||||
"name": "0x-monorepo",
|
||||
"engines": {
|
||||
"node" : ">=6.12"
|
||||
"node": ">=6.12"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
@@ -25,12 +25,13 @@
|
||||
"build": "wsrun build $PKG --fast-exit -r --stages",
|
||||
"build:monorepo_scripts": "PKG=@0xproject/monorepo-scripts yarn build",
|
||||
"clean": "wsrun clean $PKG --fast-exit -r --parallel",
|
||||
"remove_node_modules": "lerna clean --yes; rm -rf node_modules",
|
||||
"rebuild": "run-s clean build",
|
||||
"test": "wsrun test $PKG --fast-exit --serial --exclude-missing",
|
||||
"stage_docs": "wsrun docs:stage $PKG --fast-exit --parallel --exclude-missing",
|
||||
"lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing",
|
||||
"comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete.",
|
||||
"postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils"
|
||||
"postinstall": "rm -rf `pwd`/packages/order-utils/node_modules/@0xproject; mkdir `pwd`/packages/order-utils/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/order-utils/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/assert `pwd`/packages/order-utils/node_modules/@0xproject/assert; ln -s `pwd`/packages/types `pwd`/packages/order-utils/node_modules/@0xproject/types; rm -f `pwd`/packages/contracts/node_modules/@0xproject/types; ln -s `pwd`/packages/types `pwd`/packages/contracts/node_modules/@0xproject/types; rm -rf `pwd`/packages/fill-scenarios/node_modules/@0xproject; mkdir -p `pwd`/packages/fill-scenarios/node_modules/@0xproject; ln -s `pwd`/packages/types `pwd`/packages/fill-scenarios/node_modules/@0xproject/types; ln -s `pwd`/packages/json-schemas `pwd`/packages/fill-scenarios/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/order-utils `pwd`/packages/fill-scenarios/node_modules/@0xproject/order-utils; rm -rf `pwd`/packages/contract-wrappers/node_modules/@0xproject; mkdir -p `pwd`/packages/contract-wrappers/node_modules/@0xproject; ln -s `pwd`/packages/order-utils `pwd`/packages/contract-wrappers/node_modules/@0xproject/order-utils; ln -s `pwd`/packages/assert `pwd`/packages/contract-wrappers/node_modules/@0xproject/assert; ln -s `pwd`/packages/json-schemas `pwd`/packages/contract-wrappers/node_modules/@0xproject/json-schemas; ln -s `pwd`/packages/types `pwd`/packages/contract-wrappers/node_modules/@0xproject/types; ln -s `pwd`/packages/fill-scenarios `pwd`/packages/contract-wrappers/node_modules/@0xproject/fill-scenarios; rm -rf `pwd`/packages/assert/node_modules/@0xproject; mkdir -p `pwd`/packages/assert/node_modules/@0xproject; ln -s `pwd`/packages/json-schemas `pwd`/packages/assert/node_modules/@0xproject/json-schemas"
|
||||
},
|
||||
"config": {
|
||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||
@@ -38,7 +39,7 @@
|
||||
"devDependencies": {
|
||||
"async-child-process": "^1.1.1",
|
||||
"coveralls": "^3.0.0",
|
||||
"ganache-cli": "^6.1.0",
|
||||
"ganache-cli": "6.1.3",
|
||||
"lcov-result-merger": "^3.0.0",
|
||||
"lerna": "^2.5.1",
|
||||
"npm-run-all": "^4.1.2",
|
||||
@@ -47,7 +48,6 @@
|
||||
"source-map-support": "^0.5.6"
|
||||
},
|
||||
"resolutions": {
|
||||
"ethereumjs-tx": "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default",
|
||||
"ethers": "0xproject/ethers.js#eip-838-reasons"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,40 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.38.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527617805,
|
||||
"version": "0.38.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527617227,
|
||||
"version": "0.38.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527616612,
|
||||
"version": "0.38.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.38.0",
|
||||
"changes": [
|
||||
|
||||
@@ -5,12 +5,28 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.38.4 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.38.3 - _May 29, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.38.2 - _May 29, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.38.1 - _May 29, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.38.0 - _May 22, 2018_
|
||||
|
||||
* Renamed createOrderStateWatcher to createOrderWatcherAsync since it is now async (#579)
|
||||
* Renamed ZeroExError to ContractWrappersErrors since they now lives in the @0xproject/contract-wrappers subpackage (#579)
|
||||
|
||||
## v0.37.2 - _May 4, 2018_
|
||||
## v0.37.2 - _May 5, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "0x.js",
|
||||
"version": "0.38.0",
|
||||
"version": "0.38.4",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -30,7 +30,7 @@
|
||||
"clean": "shx rm -rf _bundles lib test_temp scripts src/generated_contract_wrappers",
|
||||
"build:umd:prod": "NODE_ENV=production webpack",
|
||||
"build:commonjs": "tsc && copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"run_mocha": "mocha --require source-map-support/register lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
|
||||
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
|
||||
"docs:stage": "node scripts/stage_docs.js",
|
||||
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
|
||||
@@ -69,12 +69,12 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@0xproject/abi-gen": "^0.3.0",
|
||||
"@0xproject/dev-utils": "^0.4.2",
|
||||
"@0xproject/migrations": "^0.0.6",
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/sol-compiler": "^0.5.0",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"@0xproject/abi-gen": "^0.3.2",
|
||||
"@0xproject/dev-utils": "^0.4.4",
|
||||
"@0xproject/migrations": "^0.0.8",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "^8.0.53",
|
||||
@@ -100,18 +100,18 @@
|
||||
"webpack": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/assert": "^0.2.10",
|
||||
"@0xproject/base-contract": "^0.3.2",
|
||||
"@0xproject/contract-wrappers": "^0.0.2",
|
||||
"@0xproject/order-utils": "0.0.5",
|
||||
"@0xproject/order-watcher": "^0.0.2",
|
||||
"@0xproject/sol-compiler": "^0.5.0",
|
||||
"@0xproject/types": "0.7.0",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"ethers": "^3.0.15",
|
||||
"@0xproject/assert": "^0.2.12",
|
||||
"@0xproject/base-contract": "^0.3.4",
|
||||
"@0xproject/contract-wrappers": "^0.0.5",
|
||||
"@0xproject/order-utils": "^0.0.7",
|
||||
"@0xproject/order-watcher": "^0.0.6",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/types": "^0.8.1",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"ethers": "3.0.22",
|
||||
"lodash": "^4.17.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -19,6 +19,8 @@ export {
|
||||
TransactionReceiptWithDecodedLogs,
|
||||
} from '@0xproject/types';
|
||||
|
||||
export { OrderWatcherConfig } from '@0xproject/order-watcher';
|
||||
|
||||
export {
|
||||
EventCallback,
|
||||
ContractEvent,
|
||||
|
||||
@@ -3,7 +3,6 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as _ from 'lodash';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { ApprovalContractEventArgs, LogWithDecodedArgs, TokenEvents, ZeroEx } from '../src';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { web3Factory } from '@0xproject/dev-utils';
|
||||
import 'make-promises-safe';
|
||||
|
||||
import { ZeroEx } from '../src';
|
||||
|
||||
|
||||
@@ -1,4 +1,35 @@
|
||||
[
|
||||
{
|
||||
"version": "0.4.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Convert e_r_c to erc in generated file names",
|
||||
"pr": 822
|
||||
},
|
||||
{
|
||||
"note": "Remove the output directory before writing to it",
|
||||
"pr": 822
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.3.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.3.1",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Incorrect publish that was unpublished"
|
||||
}
|
||||
],
|
||||
"timestamp": 1527810075
|
||||
},
|
||||
{
|
||||
"version": "0.3.0",
|
||||
"changes": [
|
||||
|
||||
@@ -5,11 +5,19 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.3.2 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.3.1 - _June 1, 2018_
|
||||
|
||||
* Incorrect publish that was unpublished
|
||||
|
||||
## v0.3.0 - _May 22, 2018_
|
||||
|
||||
* Properly export the executable binary (#588)
|
||||
|
||||
## v0.2.13 - _May 4, 2018_
|
||||
## v0.2.13 - _May 5, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/abi-gen",
|
||||
"version": "0.3.0",
|
||||
"version": "0.3.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -27,21 +27,23 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
|
||||
"dependencies": {
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"chalk": "^2.3.0",
|
||||
"glob": "^7.1.2",
|
||||
"handlebars": "^4.0.11",
|
||||
"lodash": "^4.17.4",
|
||||
"rimraf": "^2.6.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
"to-snake-case": "^1.0.0",
|
||||
"yargs": "^10.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/glob": "^5.0.33",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"@types/handlebars": "^4.0.36",
|
||||
"@types/mkdirp": "^0.5.1",
|
||||
"@types/node": "^8.0.53",
|
||||
|
||||
@@ -8,6 +8,7 @@ import { sync as globSync } from 'glob';
|
||||
import * as Handlebars from 'handlebars';
|
||||
import * as _ from 'lodash';
|
||||
import * as mkdirp from 'mkdirp';
|
||||
import * as rimraf from 'rimraf';
|
||||
import * as yargs from 'yargs';
|
||||
|
||||
import toSnakeCase = require('to-snake-case');
|
||||
@@ -72,9 +73,9 @@ function registerPartials(partialsGlob: string): void {
|
||||
|
||||
function writeOutputFile(name: string, renderedTsCode: string): void {
|
||||
let fileName = toSnakeCase(name);
|
||||
if (fileName === 'z_r_x_token') {
|
||||
fileName = 'zrx_token';
|
||||
}
|
||||
// HACK: Snake case doesn't make a lot of sense for abbreviated names but we can't reliably detect abbreviations
|
||||
// so we special-case the abbreviations we use.
|
||||
fileName = fileName.replace('z_r_x', 'zrx').replace('e_r_c', 'erc');
|
||||
const filePath = `${args.output}/${fileName}.ts`;
|
||||
fs.writeFileSync(filePath, renderedTsCode);
|
||||
logUtils.log(`Created: ${chalk.bold(filePath)}`);
|
||||
@@ -96,6 +97,7 @@ if (_.isEmpty(abiFileNames)) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
logUtils.log(`Found ${chalk.green(`${abiFileNames.length}`)} ${chalk.bold('ABI')} files`);
|
||||
rimraf.sync(args.output);
|
||||
mkdirp.sync(args.output);
|
||||
}
|
||||
for (const abiFileName of abiFileNames) {
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
[
|
||||
{
|
||||
"version": "0.2.13",
|
||||
"changes": [
|
||||
{
|
||||
"note":
|
||||
"Fix bug in string enum assertion. We erroneously were checking against the enum keys, not values",
|
||||
"pr": 821
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.2.12",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "0.2.11",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Incorrect publish that was unpublished"
|
||||
}
|
||||
],
|
||||
"timestamp": 1527810075
|
||||
},
|
||||
{
|
||||
"timestamp": 1527008270,
|
||||
"version": "0.2.10",
|
||||
|
||||
@@ -5,11 +5,19 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.2.12 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.2.11 - _June 1, 2018_
|
||||
|
||||
* Incorrect publish that was unpublished
|
||||
|
||||
## v0.2.10 - _May 22, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.2.9 - _May 4, 2018_
|
||||
## v0.2.9 - _May 5, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/assert",
|
||||
"version": "0.2.10",
|
||||
"version": "0.3.0",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -12,7 +12,7 @@
|
||||
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"clean": "shx rm -rf lib test_temp scripts",
|
||||
"lint": "tslint --project .",
|
||||
"run_mocha": "mocha --require source-map-support/register lib/test/**/*_test.js --exit",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
|
||||
"prepublishOnly": "run-p build",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
@@ -31,8 +31,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/valid-url": "^1.0.2",
|
||||
@@ -48,9 +48,9 @@
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/json-schemas": "0.7.22",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/json-schemas": "^1.0.0",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"lodash": "^4.17.4",
|
||||
"valid-url": "^1.0.9"
|
||||
},
|
||||
|
||||
@@ -41,8 +41,8 @@ export const assert = {
|
||||
value: string,
|
||||
stringEnum: any /* There is no base type for every string enum */,
|
||||
): void {
|
||||
const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]);
|
||||
const enumValues = _.keys(stringEnum);
|
||||
const enumValues = _.values(stringEnum);
|
||||
const doesBelongToStringEnum = _.includes(enumValues, value);
|
||||
const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`);
|
||||
const enumValuesAsString = enumValuesAsStrings.join(', ');
|
||||
assert.assert(
|
||||
|
||||
@@ -2,7 +2,6 @@ import { schemas } from '@0xproject/json-schemas';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { assert } from '../src/index';
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
[
|
||||
{
|
||||
"version": "0.3.4",
|
||||
"changes": [
|
||||
{
|
||||
"note":
|
||||
"Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201"
|
||||
}
|
||||
],
|
||||
"timestamp": 1529397769
|
||||
},
|
||||
{
|
||||
"timestamp": 1527810075,
|
||||
"version": "0.3.3",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Incorrect publish that was unpublished"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527008270,
|
||||
"version": "0.3.2",
|
||||
|
||||
@@ -5,11 +5,19 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.3.4 - _June 19, 2018_
|
||||
|
||||
* Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201
|
||||
|
||||
## v0.3.3 - _June 1, 2018_
|
||||
|
||||
* Incorrect publish that was unpublished
|
||||
|
||||
## v0.3.2 - _May 22, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.3.1 - _May 4, 2018_
|
||||
## v0.3.1 - _May 5, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/base-contract",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.4",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -14,7 +14,7 @@
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s clean build test",
|
||||
"test:circleci": "yarn test:coverage",
|
||||
"run_mocha": "mocha --require source-map-support/register lib/test/**/*_test.js --bail --exit",
|
||||
"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/**/*",
|
||||
@@ -30,8 +30,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/lodash": "4.14.104",
|
||||
"chai": "^4.0.1",
|
||||
"copyfiles": "^1.2.0",
|
||||
@@ -43,11 +43,11 @@
|
||||
"typescript": "2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ethereum-types": "^0.0.1",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
"ethers": "^3.0.15",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"ethers": "3.0.22",
|
||||
"lodash": "^4.17.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -80,7 +80,7 @@ export class BaseContract {
|
||||
// Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged
|
||||
} as any;
|
||||
if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) {
|
||||
txDataWithDefaults.gas = await estimateGasAsync(txData);
|
||||
txDataWithDefaults.gas = await estimateGasAsync(txDataWithDefaults as any);
|
||||
}
|
||||
return txDataWithDefaults;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { formatABIDataItem } from '../src/utils';
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
[
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.6.15",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527616612,
|
||||
"version": "0.6.14",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527008270,
|
||||
"version": "0.6.13",
|
||||
|
||||
@@ -5,11 +5,19 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.6.15 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.6.14 - _May 29, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.6.13 - _May 22, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.6.12 - _May 4, 2018_
|
||||
## v0.6.12 - _May 5, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/connect",
|
||||
"version": "0.6.13",
|
||||
"version": "0.6.15",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -20,7 +20,7 @@
|
||||
"clean": "shx rm -rf lib test_temp scripts",
|
||||
"copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
|
||||
"lint": "tslint --project .",
|
||||
"run_mocha": "mocha --require source-map-support/register lib/test/**/*_test.js --exit",
|
||||
"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",
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
@@ -51,19 +51,19 @@
|
||||
},
|
||||
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
|
||||
"dependencies": {
|
||||
"@0xproject/assert": "^0.2.10",
|
||||
"@0xproject/json-schemas": "0.7.22",
|
||||
"@0xproject/types": "^0.7.0",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/assert": "^0.2.12",
|
||||
"@0xproject/json-schemas": "0.8.1",
|
||||
"@0xproject/types": "^0.8.1",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"isomorphic-fetch": "^2.2.1",
|
||||
"lodash": "^4.17.4",
|
||||
"query-string": "^5.0.1",
|
||||
"websocket": "^1.0.25"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/fetch-mock": "^5.12.1",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
|
||||
@@ -3,7 +3,6 @@ import * as chai from 'chai';
|
||||
import * as chaiAsPromised from 'chai-as-promised';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import * as fetchMock from 'fetch-mock';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { HttpClient } from '../src/index';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import * as chai from 'chai';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { orderbookChannelMessageParser } from '../src/utils/orderbook_channel_message_parser';
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as chai from 'chai';
|
||||
import * as dirtyChai from 'dirty-chai';
|
||||
import * as _ from 'lodash';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
[
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Update blockstream to v5.0 and propogate up caught errors to active subscriptions"
|
||||
},
|
||||
{
|
||||
"note": "Update to v2 of 0x rpotocol",
|
||||
"pr": 822
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1529397769,
|
||||
"version": "0.0.5",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1527617227,
|
||||
"version": "0.0.4",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Expose 'abi' ContractAbi property on all contract wrappers"
|
||||
|
||||
@@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v0.0.5 - _June 19, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.0.4 - _May 29, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.0.3 - _May 29, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v0.0.2 - _May 22, 2018_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0xproject/contract-wrappers",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.6",
|
||||
"description": "Smart TS wrappers for 0x smart contracts",
|
||||
"keywords": [
|
||||
"0xproject",
|
||||
@@ -13,23 +13,20 @@
|
||||
"scripts": {
|
||||
"watch_without_deps": "yarn pre_build && tsc -w",
|
||||
"build": "yarn pre_build && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
|
||||
"pre_build": "run-s generate_contract_wrappers update_test_artifacts update_compact_artifacts",
|
||||
"generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
|
||||
"pre_build": "run-s generate_contract_wrappers update_artifacts",
|
||||
"generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token|ZRXToken|ERC20Token|ERC721Token|WETH9|ERC20Proxy|ERC721Proxy).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers",
|
||||
"lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*",
|
||||
"test:circleci": "run-s test:coverage",
|
||||
"test": "yarn run_mocha",
|
||||
"rebuild_and_test": "run-s build test",
|
||||
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
|
||||
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
|
||||
"update_compact_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts",
|
||||
"update_test_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/1.0.0/$i.json test/artifacts; done;",
|
||||
"update_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts",
|
||||
"clean": "shx rm -rf _bundles lib test_temp scripts test/artifacts src/contract_wrappers/generated",
|
||||
"run_mocha": "mocha --require source-map-support/register lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
|
||||
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
|
||||
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
|
||||
},
|
||||
"config": {
|
||||
"compact_artifacts": "Exchange DummyToken ZRXToken Token EtherToken TokenTransferProxy TokenRegistry",
|
||||
"contracts": "Exchange DummyToken ZRXToken Token WETH9 TokenTransferProxy_v1 MultiSigWallet MultiSigWalletWithTimeLock MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress MaliciousToken TokenRegistry Arbitrage EtherDelta AccountLevels",
|
||||
"postpublish": {
|
||||
"assets": [
|
||||
"packages/contract-wrappers/_bundles/index.js",
|
||||
@@ -46,13 +43,13 @@
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@0xproject/abi-gen": "^0.3.0",
|
||||
"@0xproject/dev-utils": "^0.4.2",
|
||||
"@0xproject/migrations": "^0.0.6",
|
||||
"@0xproject/monorepo-scripts": "^0.1.20",
|
||||
"@0xproject/sol-compiler": "^0.5.0",
|
||||
"@0xproject/subproviders": "^0.10.2",
|
||||
"@0xproject/tslint-config": "^0.4.18",
|
||||
"@0xproject/abi-gen": "^0.3.2",
|
||||
"@0xproject/dev-utils": "^0.4.4",
|
||||
"@0xproject/migrations": "^0.0.8",
|
||||
"@0xproject/monorepo-scripts": "^0.2.1",
|
||||
"@0xproject/sol-compiler": "^0.5.2",
|
||||
"@0xproject/subproviders": "^0.10.4",
|
||||
"@0xproject/tslint-config": "^0.4.20",
|
||||
"@types/lodash": "4.14.104",
|
||||
"@types/mocha": "^2.2.42",
|
||||
"@types/node": "^8.0.53",
|
||||
@@ -74,22 +71,22 @@
|
||||
"source-map-support": "^0.5.0",
|
||||
"tslint": "5.8.0",
|
||||
"typescript": "2.7.1",
|
||||
"web3-provider-engine": "^14.0.4"
|
||||
"web3-provider-engine": "14.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@0xproject/assert": "^0.2.10",
|
||||
"@0xproject/base-contract": "^0.3.2",
|
||||
"@0xproject/fill-scenarios": "^0.0.2",
|
||||
"@0xproject/json-schemas": "0.7.22",
|
||||
"@0xproject/order-utils": "0.0.5",
|
||||
"@0xproject/types": "0.7.0",
|
||||
"@0xproject/typescript-typings": "^0.3.2",
|
||||
"@0xproject/utils": "^0.6.2",
|
||||
"@0xproject/web3-wrapper": "^0.6.4",
|
||||
"ethereum-types": "^0.0.1",
|
||||
"ethereumjs-blockstream": "^2.0.6",
|
||||
"@0xproject/assert": "^0.3.0",
|
||||
"@0xproject/base-contract": "^0.3.4",
|
||||
"@0xproject/order-utils": "^1.0.0",
|
||||
"@0xproject/typescript-typings": "^0.4.1",
|
||||
"@0xproject/utils": "^0.7.1",
|
||||
"@0xproject/web3-wrapper": "^0.7.1",
|
||||
"@0xproject/fill-scenarios": "^1.0.0",
|
||||
"@0xproject/json-schemas": "^1.0.0",
|
||||
"@0xproject/types": "^1.0.0",
|
||||
"ethereum-types": "^0.0.2",
|
||||
"ethereumjs-blockstream": "5.0.0",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"ethers": "^3.0.15",
|
||||
"ethers": "3.0.22",
|
||||
"js-sha3": "^0.7.0",
|
||||
"lodash": "^4.17.4",
|
||||
"uuid": "^3.1.0"
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import { Artifact } from '@0xproject/types';
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
|
||||
import * as DummyERC20Token from './artifacts/DummyERC20Token.json';
|
||||
import * as DummyERC721Token from './artifacts/DummyERC721Token.json';
|
||||
import * as ERC20Proxy from './artifacts/ERC20Proxy.json';
|
||||
import * as ERC20Token from './artifacts/ERC20Token.json';
|
||||
import * as ERC721Proxy from './artifacts/ERC721Proxy.json';
|
||||
import * as ERC721Token from './artifacts/ERC721Token.json';
|
||||
import * as Exchange from './artifacts/Exchange.json';
|
||||
import * as EtherToken from './artifacts/WETH9.json';
|
||||
import * as ZRXToken from './artifacts/ZRXToken.json';
|
||||
|
||||
import * as DummyToken from './compact_artifacts/DummyToken.json';
|
||||
import * as EtherToken from './compact_artifacts/EtherToken.json';
|
||||
import * as Exchange from './compact_artifacts/Exchange.json';
|
||||
import * as Token from './compact_artifacts/Token.json';
|
||||
import * as TokenRegistry from './compact_artifacts/TokenRegistry.json';
|
||||
import * as TokenTransferProxy from './compact_artifacts/TokenTransferProxy.json';
|
||||
import * as ZRX from './compact_artifacts/ZRX.json';
|
||||
export const artifacts = {
|
||||
ZRX: (ZRX as any) as Artifact,
|
||||
DummyToken: (DummyToken as any) as Artifact,
|
||||
Token: (Token as any) as Artifact,
|
||||
Exchange: (Exchange as any) as Artifact,
|
||||
EtherToken: (EtherToken as any) as Artifact,
|
||||
TokenRegistry: (TokenRegistry as any) as Artifact,
|
||||
TokenTransferProxy: (TokenTransferProxy as any) as Artifact,
|
||||
ZRXToken: (ZRXToken as any) as ContractArtifact,
|
||||
DummyERC20Token: (DummyERC20Token as any) as ContractArtifact,
|
||||
DummyERC721Token: (DummyERC721Token as any) as ContractArtifact,
|
||||
ERC20Token: (ERC20Token as any) as ContractArtifact,
|
||||
ERC721Token: (ERC721Token as any) as ContractArtifact,
|
||||
Exchange: (Exchange as any) as ContractArtifact,
|
||||
EtherToken: (EtherToken as any) as ContractArtifact,
|
||||
ERC20Proxy: (ERC20Proxy as any) as ContractArtifact,
|
||||
ERC721Proxy: (ERC721Proxy as any) as ContractArtifact,
|
||||
};
|
||||
|
||||
306
packages/contract-wrappers/src/artifacts/DummyERC20Token.json
Normal file
306
packages/contract-wrappers/src/artifacts/DummyERC20Token.json
Normal file
@@ -0,0 +1,306 @@
|
||||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "DummyERC20Token",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setBalance",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "_totalSupply",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
368
packages/contract-wrappers/src/artifacts/DummyERC721Token.json
Normal file
368
packages/contract-wrappers/src/artifacts/DummyERC721Token.json
Normal file
@@ -0,0 +1,368 @@
|
||||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "DummyERC721Token",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getApproved",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "safeTransferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "exists",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ownerOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setApprovalForAll",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "safeTransferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_operator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isApprovedForAll",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_approved",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "ApprovalForAll",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
210
packages/contract-wrappers/src/artifacts/ERC20Proxy.json
Normal file
210
packages/contract-wrappers/src/artifacts/ERC20Proxy.json
Normal file
@@ -0,0 +1,210 @@
|
||||
{
|
||||
"contractName": "ERC20Proxy",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "authorities",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "removeAuthorizedAddressAtIndex",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "assetData",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getProxyId",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "authorized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getAuthorizedAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AuthorizedAddressAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AuthorizedAddressRemoved",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": {
|
||||
"50": { "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48" }
|
||||
}
|
||||
}
|
||||
174
packages/contract-wrappers/src/artifacts/ERC20Token.json
Normal file
174
packages/contract-wrappers/src/artifacts/ERC20Token.json
Normal file
@@ -0,0 +1,174 @@
|
||||
{
|
||||
"contractName": "ERC20Token",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "supply",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "remaining",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
210
packages/contract-wrappers/src/artifacts/ERC721Proxy.json
Normal file
210
packages/contract-wrappers/src/artifacts/ERC721Proxy.json
Normal file
@@ -0,0 +1,210 @@
|
||||
{
|
||||
"contractName": "ERC20Proxy",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "authorities",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "removeAuthorizedAddressAtIndex",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "assetData",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getProxyId",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "authorized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getAuthorizedAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AuthorizedAddressAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AuthorizedAddressRemoved",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": {
|
||||
"50": { "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401" }
|
||||
}
|
||||
}
|
||||
322
packages/contract-wrappers/src/artifacts/ERC721Token.json
Normal file
322
packages/contract-wrappers/src/artifacts/ERC721Token.json
Normal file
@@ -0,0 +1,322 @@
|
||||
{
|
||||
"schemaVersion": "2.0.0",
|
||||
"contractName": "ERC721Token",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getApproved",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "safeTransferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "exists",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ownerOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setApprovalForAll",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "_data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "safeTransferFrom",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_operator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isApprovedForAll",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_approved",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_approved",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "ApprovalForAll",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
1908
packages/contract-wrappers/src/artifacts/Exchange.json
Normal file
1908
packages/contract-wrappers/src/artifacts/Exchange.json
Normal file
File diff suppressed because it is too large
Load Diff
301
packages/contract-wrappers/src/artifacts/WETH9.json
Normal file
301
packages/contract-wrappers/src/artifacts/WETH9.json
Normal file
@@ -0,0 +1,301 @@
|
||||
{
|
||||
"contractName": "WETH9",
|
||||
"compilerOutput": {
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "guy",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "wad",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "src",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "dst",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "wad",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "wad",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "dst",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "wad",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "deposit",
|
||||
"outputs": [],
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"payable": true,
|
||||
"stateMutability": "payable",
|
||||
"type": "fallback"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Deposit",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdrawal",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
||||
},
|
||||
"3": {
|
||||
"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
|
||||
},
|
||||
"4": {
|
||||
"address": "0xc778417e063141139fce010982780140aa0cd5ab"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"contract_name": "ZRX",
|
||||
"contractName": "ZRXToken",
|
||||
"compilerOutput": {
|
||||
"abi": []
|
||||
},
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
|
||||
@@ -14,7 +17,7 @@
|
||||
"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
|
||||
"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"contract_name": "DummyToken",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setBalance",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
{
|
||||
"contract_name": "EtherToken",
|
||||
"abi": [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [],
|
||||
"name": "deposit",
|
||||
"outputs": [],
|
||||
"payable": true,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"payable": true,
|
||||
"type": "fallback"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Deposit",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdrawal",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
||||
},
|
||||
"3": {
|
||||
"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
|
||||
},
|
||||
"4": {
|
||||
"address": "0xc778417e063141139fce010982780140aa0cd5ab"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
{
|
||||
"contract_name": "Token",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "supply",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "success",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "remaining",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "_spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "_value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,547 +0,0 @@
|
||||
{
|
||||
"contract_name": "TokenRegistry",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "removeToken",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenAddressByName",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenAddressBySymbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "setTokenSwarmHash",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getTokenMetaData",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "_decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "_ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "_swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "addToken",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setTokenName",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "tokens",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "tokenAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenByName",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getTokenAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_ipfsHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "setTokenIpfsHash",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getTokenBySymbol",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setTokenSymbol",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogAddToken",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "ipfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "swarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogRemoveToken",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newName",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenNameChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldSymbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSymbol",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenSymbolChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldIpfsHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newIpfsHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenIpfsHashChange",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "oldSwarmHash",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"name": "newSwarmHash",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "LogTokenSwarmHashChange",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
|
||||
},
|
||||
"3": {
|
||||
"address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
|
||||
},
|
||||
"4": {
|
||||
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
|
||||
},
|
||||
"42": {
|
||||
"address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
{
|
||||
"contract_name": "TokenTransferProxy",
|
||||
"abi": [
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "authorities",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeAuthorizedAddress",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "authorized",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [],
|
||||
"name": "getAuthorizedAddresses",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"constant": false,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"payable": false,
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "LogAuthorizedAddressAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"name": "caller",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "LogAuthorizedAddressRemoved",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"networks": {
|
||||
"1": {
|
||||
"address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
|
||||
},
|
||||
"3": {
|
||||
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
|
||||
},
|
||||
"4": {
|
||||
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
|
||||
},
|
||||
"42": {
|
||||
"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
|
||||
},
|
||||
"50": {
|
||||
"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { constants } from './utils/constants';
|
||||
|
||||
import { artifacts } from './artifacts';
|
||||
import { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper';
|
||||
import { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper';
|
||||
import { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper';
|
||||
import { ERC721TokenWrapper } from './contract_wrappers/erc721_token_wrapper';
|
||||
import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
|
||||
import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
|
||||
import { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper';
|
||||
import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper';
|
||||
import { TokenWrapper } from './contract_wrappers/token_wrapper';
|
||||
import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema';
|
||||
import { contractWrappersPrivateNetworkConfigSchema } from './schemas/contract_wrappers_private_network_config_schema';
|
||||
import { contractWrappersPublicNetworkConfigSchema } from './schemas/contract_wrappers_public_network_config_schema';
|
||||
@@ -22,24 +25,28 @@ export class ContractWrappers {
|
||||
*/
|
||||
public exchange: ExchangeWrapper;
|
||||
/**
|
||||
* An instance of the TokenRegistryWrapper class containing methods for interacting with the 0x
|
||||
* TokenRegistry smart contract.
|
||||
* An instance of the ERC20TokenWrapper class containing methods for interacting with any ERC20 token smart contract.
|
||||
*/
|
||||
public tokenRegistry: TokenRegistryWrapper;
|
||||
public erc20Token: ERC20TokenWrapper;
|
||||
/**
|
||||
* An instance of the TokenWrapper class containing methods for interacting with any ERC20 token smart contract.
|
||||
* An instance of the ERC721TokenWrapper class containing methods for interacting with any ERC721 token smart contract.
|
||||
*/
|
||||
public token: TokenWrapper;
|
||||
public erc721Token: ERC721TokenWrapper;
|
||||
/**
|
||||
* An instance of the EtherTokenWrapper class containing methods for interacting with the
|
||||
* wrapped ETH ERC20 token smart contract.
|
||||
*/
|
||||
public etherToken: EtherTokenWrapper;
|
||||
/**
|
||||
* An instance of the TokenTransferProxyWrapper class containing methods for interacting with the
|
||||
* tokenTransferProxy smart contract.
|
||||
* An instance of the ERC20ProxyWrapper class containing methods for interacting with the
|
||||
* erc20Proxy smart contract.
|
||||
*/
|
||||
public proxy: TokenTransferProxyWrapper;
|
||||
public erc20Proxy: ERC20ProxyWrapper;
|
||||
/**
|
||||
* An instance of the ERC721ProxyWrapper class containing methods for interacting with the
|
||||
* erc721Proxy smart contract.
|
||||
*/
|
||||
public erc721Proxy: ERC721ProxyWrapper;
|
||||
private _web3Wrapper: Web3Wrapper;
|
||||
/**
|
||||
* Instantiates a new ContractWrappers instance.
|
||||
@@ -55,7 +62,7 @@ export class ContractWrappers {
|
||||
contractWrappersPublicNetworkConfigSchema,
|
||||
]);
|
||||
const artifactJSONs = _.values(artifacts);
|
||||
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
|
||||
const abiArrays = _.map(artifactJSONs, artifact => artifact.compilerOutput.abi);
|
||||
const txDefaults = {
|
||||
gasPrice: config.gasPrice,
|
||||
};
|
||||
@@ -63,25 +70,40 @@ export class ContractWrappers {
|
||||
_.forEach(abiArrays, abi => {
|
||||
this._web3Wrapper.abiDecoder.addABI(abi);
|
||||
});
|
||||
this.proxy = new TokenTransferProxyWrapper(
|
||||
const blockPollingIntervalMs = _.isUndefined(config.blockPollingIntervalMs)
|
||||
? constants.DEFAULT_BLOCK_POLLING_INTERVAL
|
||||
: config.blockPollingIntervalMs;
|
||||
this.erc20Proxy = new ERC20ProxyWrapper(this._web3Wrapper, config.networkId, config.erc20ProxyContractAddress);
|
||||
this.erc721Proxy = new ERC721ProxyWrapper(
|
||||
this._web3Wrapper,
|
||||
config.networkId,
|
||||
config.tokenTransferProxyContractAddress,
|
||||
config.erc721ProxyContractAddress,
|
||||
);
|
||||
this.erc20Token = new ERC20TokenWrapper(
|
||||
this._web3Wrapper,
|
||||
config.networkId,
|
||||
this.erc20Proxy,
|
||||
blockPollingIntervalMs,
|
||||
);
|
||||
this.erc721Token = new ERC721TokenWrapper(
|
||||
this._web3Wrapper,
|
||||
config.networkId,
|
||||
this.erc721Proxy,
|
||||
blockPollingIntervalMs,
|
||||
);
|
||||
this.etherToken = new EtherTokenWrapper(
|
||||
this._web3Wrapper,
|
||||
config.networkId,
|
||||
this.erc20Token,
|
||||
blockPollingIntervalMs,
|
||||
);
|
||||
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this.proxy);
|
||||
this.exchange = new ExchangeWrapper(
|
||||
this._web3Wrapper,
|
||||
config.networkId,
|
||||
this.token,
|
||||
config.exchangeContractAddress,
|
||||
config.zrxContractAddress,
|
||||
blockPollingIntervalMs,
|
||||
);
|
||||
this.tokenRegistry = new TokenRegistryWrapper(
|
||||
this._web3Wrapper,
|
||||
config.networkId,
|
||||
config.tokenRegistryContractAddress,
|
||||
);
|
||||
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this.token);
|
||||
}
|
||||
/**
|
||||
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
|
||||
@@ -93,12 +115,10 @@ export class ContractWrappers {
|
||||
this._web3Wrapper.setProvider(provider);
|
||||
(this.exchange as any)._invalidateContractInstances();
|
||||
(this.exchange as any)._setNetworkId(networkId);
|
||||
(this.tokenRegistry as any)._invalidateContractInstance();
|
||||
(this.tokenRegistry as any)._setNetworkId(networkId);
|
||||
(this.token as any)._invalidateContractInstances();
|
||||
(this.token as any)._setNetworkId(networkId);
|
||||
(this.proxy as any)._invalidateContractInstance();
|
||||
(this.proxy as any)._setNetworkId(networkId);
|
||||
(this.erc20Token as any)._invalidateContractInstances();
|
||||
(this.erc20Token as any)._setNetworkId(networkId);
|
||||
(this.erc20Proxy as any)._invalidateContractInstance();
|
||||
(this.erc20Proxy as any)._setNetworkId(networkId);
|
||||
(this.etherToken as any)._invalidateContractInstance();
|
||||
(this.etherToken as any)._setNetworkId(networkId);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import {
|
||||
Artifact,
|
||||
BlockParamLiteral,
|
||||
ContractAbi,
|
||||
FilterObject,
|
||||
LogEntry,
|
||||
LogWithDecodedArgs,
|
||||
RawLog,
|
||||
} from '@0xproject/types';
|
||||
import { intervalUtils } from '@0xproject/utils';
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
import { AbiDecoder, intervalUtils } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Block, BlockAndLogStreamer } from 'ethereumjs-blockstream';
|
||||
import { BlockParamLiteral, ContractAbi, FilterObject, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types';
|
||||
import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
@@ -19,7 +12,6 @@ import {
|
||||
ContractWrappersError,
|
||||
EventCallback,
|
||||
IndexedFilterValues,
|
||||
InternalContractWrappersError,
|
||||
} from '../types';
|
||||
import { constants } from '../utils/constants';
|
||||
import { filterUtils } from '../utils/filter_utils';
|
||||
@@ -29,9 +21,10 @@ const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
|
||||
} = {
|
||||
ZRX: ContractWrappersError.ZRXContractDoesNotExist,
|
||||
EtherToken: ContractWrappersError.EtherTokenContractDoesNotExist,
|
||||
Token: ContractWrappersError.TokenContractDoesNotExist,
|
||||
TokenRegistry: ContractWrappersError.TokenRegistryContractDoesNotExist,
|
||||
TokenTransferProxy: ContractWrappersError.TokenTransferProxyContractDoesNotExist,
|
||||
ERC20Token: ContractWrappersError.ERC20TokenContractDoesNotExist,
|
||||
ERC20Proxy: ContractWrappersError.ERC20ProxyContractDoesNotExist,
|
||||
ERC721Token: ContractWrappersError.ERC721TokenContractDoesNotExist,
|
||||
ERC721Proxy: ContractWrappersError.ERC721ProxyContractDoesNotExist,
|
||||
Exchange: ContractWrappersError.ExchangeContractDoesNotExist,
|
||||
};
|
||||
|
||||
@@ -39,7 +32,8 @@ export abstract class ContractWrapper {
|
||||
public abstract abi: ContractAbi;
|
||||
protected _web3Wrapper: Web3Wrapper;
|
||||
protected _networkId: number;
|
||||
private _blockAndLogStreamerIfExists?: BlockAndLogStreamer;
|
||||
private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined;
|
||||
private _blockPollingIntervalMs: number;
|
||||
private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer;
|
||||
private _filters: { [filterToken: string]: FilterObject };
|
||||
private _filterCallbacks: {
|
||||
@@ -47,9 +41,12 @@ export abstract class ContractWrapper {
|
||||
};
|
||||
private _onLogAddedSubscriptionToken: string | undefined;
|
||||
private _onLogRemovedSubscriptionToken: string | undefined;
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number) {
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) {
|
||||
this._web3Wrapper = web3Wrapper;
|
||||
this._networkId = networkId;
|
||||
this._blockPollingIntervalMs = _.isUndefined(blockPollingIntervalMs)
|
||||
? constants.DEFAULT_BLOCK_POLLING_INTERVAL
|
||||
: blockPollingIntervalMs;
|
||||
this._filters = {};
|
||||
this._filterCallbacks = {};
|
||||
this._blockAndLogStreamerIfExists = undefined;
|
||||
@@ -107,14 +104,12 @@ export abstract class ContractWrapper {
|
||||
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
||||
log: LogEntry,
|
||||
): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||
if (_.isUndefined(this._web3Wrapper.abiDecoder)) {
|
||||
throw new Error(InternalContractWrappersError.NoAbiDecoder);
|
||||
}
|
||||
const logWithDecodedArgs = this._web3Wrapper.abiDecoder.tryToDecodeLogOrNoop(log);
|
||||
const abiDecoder = new AbiDecoder([this.abi]);
|
||||
const logWithDecodedArgs = abiDecoder.tryToDecodeLogOrNoop(log);
|
||||
return logWithDecodedArgs;
|
||||
}
|
||||
protected async _getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifact: Artifact,
|
||||
artifact: ContractArtifact,
|
||||
addressIfExists?: string,
|
||||
): Promise<[ContractAbi, string]> {
|
||||
let contractAddress: string;
|
||||
@@ -128,12 +123,12 @@ export abstract class ContractWrapper {
|
||||
}
|
||||
const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress);
|
||||
if (!doesContractExist) {
|
||||
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
||||
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contractName]);
|
||||
}
|
||||
const abiAndAddress: [ContractAbi, string] = [artifact.abi, contractAddress];
|
||||
const abiAndAddress: [ContractAbi, string] = [artifact.compilerOutput.abi, contractAddress];
|
||||
return abiAndAddress;
|
||||
}
|
||||
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
||||
protected _getContractAddress(artifact: ContractArtifact, addressIfExists?: string): string {
|
||||
if (_.isUndefined(addressIfExists)) {
|
||||
const contractAddress = artifact.networks[this._networkId].address;
|
||||
if (_.isUndefined(contractAddress)) {
|
||||
@@ -163,12 +158,13 @@ export abstract class ContractWrapper {
|
||||
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
|
||||
this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
|
||||
this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
|
||||
this._onBlockAndLogStreamerError.bind(this),
|
||||
);
|
||||
const catchAllLogFilter = {};
|
||||
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
|
||||
this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||
this._reconcileBlockAsync.bind(this),
|
||||
constants.DEFAULT_BLOCK_POLLING_INTERVAL,
|
||||
this._blockPollingIntervalMs,
|
||||
this._onReconcileBlockError.bind(this),
|
||||
);
|
||||
let isRemoved = false;
|
||||
@@ -180,6 +176,14 @@ export abstract class ContractWrapper {
|
||||
this._onLogStateChanged.bind(this, isRemoved),
|
||||
);
|
||||
}
|
||||
private _onBlockAndLogStreamerError(err: Error): void {
|
||||
// Propogate all Blockstream subscriber errors to all
|
||||
// top-level subscriptions
|
||||
const filterCallbacks = _.values(this._filterCallbacks);
|
||||
_.each(filterCallbacks, filterCallback => {
|
||||
filterCallback(err);
|
||||
});
|
||||
}
|
||||
private _onReconcileBlockError(err: Error): void {
|
||||
const filterTokens = _.keys(this._filterCallbacks);
|
||||
_.each(filterTokens, filterToken => {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { AssetProxyId } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { ContractAbi } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { assert } from '../utils/assert';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { ERC20ProxyContract } from './generated/erc20_proxy';
|
||||
|
||||
/**
|
||||
* This class includes the functionality related to interacting with the ERC20Proxy contract.
|
||||
*/
|
||||
export class ERC20ProxyWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi;
|
||||
private _erc20ProxyContractIfExists?: ERC20ProxyContract;
|
||||
private _contractAddressIfExists?: string;
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
|
||||
super(web3Wrapper, networkId);
|
||||
this._contractAddressIfExists = contractAddressIfExists;
|
||||
}
|
||||
/**
|
||||
* Get the 4 bytes ID of this asset proxy
|
||||
* @return Proxy id
|
||||
*/
|
||||
public async getProxyIdAsync(): Promise<AssetProxyId> {
|
||||
const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync();
|
||||
const proxyId = (await ERC20ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId;
|
||||
return proxyId;
|
||||
}
|
||||
/**
|
||||
* Check if the Exchange contract address is authorized by the ERC20Proxy contract.
|
||||
* @param exchangeContractAddress The hex encoded address of the Exchange contract to call.
|
||||
* @return Whether the exchangeContractAddress is authorized.
|
||||
*/
|
||||
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
||||
assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress);
|
||||
const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase();
|
||||
const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync();
|
||||
const isAuthorized = await ERC20ProxyContractInstance.authorized.callAsync(normalizedExchangeContractAddress);
|
||||
return isAuthorized;
|
||||
}
|
||||
/**
|
||||
* Get the list of all Exchange contract addresses authorized by the ERC20Proxy contract.
|
||||
* @return The list of authorized addresses.
|
||||
*/
|
||||
public async getAuthorizedAddressesAsync(): Promise<string[]> {
|
||||
const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync();
|
||||
const authorizedAddresses = await ERC20ProxyContractInstance.getAuthorizedAddresses.callAsync();
|
||||
return authorizedAddresses;
|
||||
}
|
||||
/**
|
||||
* Retrieves the Ethereum address of the ERC20Proxy contract deployed on the network
|
||||
* that the user-passed web3 provider is connected to.
|
||||
* @returns The Ethereum address of the ERC20Proxy contract being used.
|
||||
*/
|
||||
public getContractAddress(): string {
|
||||
const contractAddress = this._getContractAddress(artifacts.ERC20Proxy, this._contractAddressIfExists);
|
||||
return contractAddress;
|
||||
}
|
||||
// HACK: We don't want this method to be visible to the other units within that package but not to the end user.
|
||||
// TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused.
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _invalidateContractInstance(): void {
|
||||
delete this._erc20ProxyContractIfExists;
|
||||
}
|
||||
private async _getERC20ProxyContractAsync(): Promise<ERC20ProxyContract> {
|
||||
if (!_.isUndefined(this._erc20ProxyContractIfExists)) {
|
||||
return this._erc20ProxyContractIfExists;
|
||||
}
|
||||
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifacts.ERC20Proxy,
|
||||
this._contractAddressIfExists,
|
||||
);
|
||||
const contractInstance = new ERC20ProxyContract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
this._web3Wrapper.getContractDefaults(),
|
||||
);
|
||||
this._erc20ProxyContractIfExists = contractInstance;
|
||||
return this._erc20ProxyContractIfExists;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import { schemas } from '@0xproject/json-schemas';
|
||||
import { ContractAbi, LogWithDecodedArgs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { methodOptsSchema } from '../schemas/method_opts_schema';
|
||||
import { txOptsSchema } from '../schemas/tx_opts_schema';
|
||||
import {
|
||||
BlockRange,
|
||||
ContractWrappersError,
|
||||
@@ -17,23 +19,30 @@ import { assert } from '../utils/assert';
|
||||
import { constants } from '../utils/constants';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { TokenContract, TokenContractEventArgs, TokenEvents } from './generated/token';
|
||||
import { TokenTransferProxyWrapper } from './token_transfer_proxy_wrapper';
|
||||
import { ERC20ProxyWrapper } from './erc20_proxy_wrapper';
|
||||
import { ERC20TokenContract, ERC20TokenEventArgs, ERC20TokenEvents } from './generated/erc20_token';
|
||||
|
||||
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
|
||||
* to the 0x Proxy smart contract.
|
||||
* to the 0x ERC20 Proxy smart contract.
|
||||
*/
|
||||
export class TokenWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.Token.abi;
|
||||
export class ERC20TokenWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.ERC20Token.compilerOutput.abi;
|
||||
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
||||
private _tokenContractsByAddress: { [address: string]: TokenContract };
|
||||
private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenTransferProxyWrapper: TokenTransferProxyWrapper) {
|
||||
super(web3Wrapper, networkId);
|
||||
private _tokenContractsByAddress: { [address: string]: ERC20TokenContract };
|
||||
private _erc20ProxyWrapper: ERC20ProxyWrapper;
|
||||
constructor(
|
||||
web3Wrapper: Web3Wrapper,
|
||||
networkId: number,
|
||||
erc20ProxyWrapper: ERC20ProxyWrapper,
|
||||
blockPollingIntervalMs?: number,
|
||||
) {
|
||||
super(web3Wrapper, networkId, blockPollingIntervalMs);
|
||||
this._tokenContractsByAddress = {};
|
||||
this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
|
||||
this._erc20ProxyWrapper = erc20ProxyWrapper;
|
||||
}
|
||||
/**
|
||||
* Retrieves an owner's ERC20 token balance.
|
||||
@@ -45,17 +54,18 @@ export class TokenWrapper extends ContractWrapper {
|
||||
public async getBalanceAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
methodOpts?: MethodOpts,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<BigNumber> {
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
||||
|
||||
const txData = {};
|
||||
let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, defaultBlock);
|
||||
let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, methodOpts.defaultBlock);
|
||||
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||
balance = new BigNumber(balance);
|
||||
return balance;
|
||||
@@ -78,20 +88,25 @@ export class TokenWrapper extends ContractWrapper {
|
||||
amountInBaseUnits: BigNumber,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedSpenderAddress = spenderAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
const normalizedSpenderAddress = spenderAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, {
|
||||
from: normalizedOwnerAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
});
|
||||
const txHash = await tokenContract.approve.sendTransactionAsync(
|
||||
normalizedSpenderAddress,
|
||||
amountInBaseUnits,
|
||||
removeUndefinedProperties({
|
||||
from: normalizedOwnerAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
@@ -112,16 +127,10 @@ export class TokenWrapper extends ContractWrapper {
|
||||
spenderAddress: string,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
const normalizedSpenderAddress = spenderAddress.toLowerCase();
|
||||
const txHash = await this.setAllowanceAsync(
|
||||
normalizedTokenAddress,
|
||||
normalizedOwnerAddress,
|
||||
normalizedSpenderAddress,
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||
txOpts,
|
||||
);
|
||||
@@ -139,23 +148,24 @@ export class TokenWrapper extends ContractWrapper {
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
spenderAddress: string,
|
||||
methodOpts?: MethodOpts,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<BigNumber> {
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
const normalizedSpenderAddress = spenderAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
||||
|
||||
const txData = {};
|
||||
let allowanceInBaseUnits = await tokenContract.allowance.callAsync(
|
||||
normalizedOwnerAddress,
|
||||
normalizedSpenderAddress,
|
||||
txData,
|
||||
defaultBlock,
|
||||
methodOpts.defaultBlock,
|
||||
);
|
||||
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
|
||||
@@ -170,20 +180,10 @@ export class TokenWrapper extends ContractWrapper {
|
||||
public async getProxyAllowanceAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
methodOpts?: MethodOpts,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<BigNumber> {
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
|
||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||
const allowanceInBaseUnits = await this.getAllowanceAsync(
|
||||
normalizedTokenAddress,
|
||||
normalizedOwnerAddress,
|
||||
proxyAddress,
|
||||
methodOpts,
|
||||
);
|
||||
const proxyAddress = this._erc20ProxyWrapper.getContractAddress();
|
||||
const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts);
|
||||
return allowanceInBaseUnits;
|
||||
}
|
||||
/**
|
||||
@@ -202,16 +202,10 @@ export class TokenWrapper extends ContractWrapper {
|
||||
amountInBaseUnits: BigNumber,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||
|
||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||
const proxyAddress = this._erc20ProxyWrapper.getContractAddress();
|
||||
const txHash = await this.setAllowanceAsync(
|
||||
normalizedTokenAddress,
|
||||
normalizedOwnerAddress,
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
proxyAddress,
|
||||
amountInBaseUnits,
|
||||
txOpts,
|
||||
@@ -234,13 +228,9 @@ export class TokenWrapper extends ContractWrapper {
|
||||
ownerAddress: string,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
const txHash = await this.setProxyAllowanceAsync(
|
||||
normalizedTokenAddress,
|
||||
normalizedOwnerAddress,
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||
txOpts,
|
||||
);
|
||||
@@ -263,12 +253,13 @@ export class TokenWrapper extends ContractWrapper {
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('toAddress', toAddress);
|
||||
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
||||
assert.isETHAddressHex('toAddress', toAddress);
|
||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedFromAddress = fromAddress.toLowerCase();
|
||||
const normalizedToAddress = toAddress.toLowerCase();
|
||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
|
||||
@@ -277,11 +268,15 @@ export class TokenWrapper extends ContractWrapper {
|
||||
throw new Error(ContractWrappersError.InsufficientBalanceForTransfer);
|
||||
}
|
||||
|
||||
const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, {
|
||||
from: normalizedFromAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
});
|
||||
const txHash = await tokenContract.transfer.sendTransactionAsync(
|
||||
normalizedToAddress,
|
||||
amountInBaseUnits,
|
||||
removeUndefinedProperties({
|
||||
from: normalizedFromAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
@@ -306,15 +301,16 @@ export class TokenWrapper extends ContractWrapper {
|
||||
amountInBaseUnits: BigNumber,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('toAddress', toAddress);
|
||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
||||
assert.isETHAddressHex('toAddress', toAddress);
|
||||
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
|
||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
|
||||
const normalizedToAddress = toAddress.toLowerCase();
|
||||
const normalizedFromAddress = fromAddress.toLowerCase();
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedSenderAddress = senderAddress.toLowerCase();
|
||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
|
||||
@@ -336,11 +332,11 @@ export class TokenWrapper extends ContractWrapper {
|
||||
normalizedFromAddress,
|
||||
normalizedToAddress,
|
||||
amountInBaseUnits,
|
||||
{
|
||||
removeUndefinedProperties({
|
||||
from: normalizedSenderAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
},
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
@@ -353,22 +349,22 @@ export class TokenWrapper extends ContractWrapper {
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends TokenContractEventArgs>(
|
||||
public subscribe<ArgsType extends ERC20TokenEventArgs>(
|
||||
tokenAddress: string,
|
||||
eventName: TokenEvents,
|
||||
eventName: ERC20TokenEvents,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
): string {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
assert.isFunction('callback', callback);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const subscriptionToken = this._subscribe<ArgsType>(
|
||||
normalizedTokenAddress,
|
||||
eventName,
|
||||
indexFilterValues,
|
||||
artifacts.Token.abi,
|
||||
artifacts.ERC20Token.compilerOutput.abi,
|
||||
callback,
|
||||
);
|
||||
return subscriptionToken;
|
||||
@@ -378,6 +374,7 @@ export class TokenWrapper extends ContractWrapper {
|
||||
* @param subscriptionToken Subscription token returned by `subscribe()`
|
||||
*/
|
||||
public unsubscribe(subscriptionToken: string): void {
|
||||
assert.isValidSubscriptionToken('subscriptionToken', subscriptionToken);
|
||||
this._unsubscribe(subscriptionToken);
|
||||
}
|
||||
/**
|
||||
@@ -395,42 +392,44 @@ export class TokenWrapper extends ContractWrapper {
|
||||
* the value is the value you are interested in. E.g `{_from: aUserAddressHex}`
|
||||
* @return Array of logs that match the parameters
|
||||
*/
|
||||
public async getLogsAsync<ArgsType extends TokenContractEventArgs>(
|
||||
public async getLogsAsync<ArgsType extends ERC20TokenEventArgs>(
|
||||
tokenAddress: string,
|
||||
eventName: TokenEvents,
|
||||
eventName: ERC20TokenEvents,
|
||||
blockRange: BlockRange,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents);
|
||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const logs = await this._getLogsAsync<ArgsType>(
|
||||
normalizedTokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
indexFilterValues,
|
||||
artifacts.Token.abi,
|
||||
artifacts.ERC20Token.compilerOutput.abi,
|
||||
);
|
||||
return logs;
|
||||
}
|
||||
// HACK: We don't want this method to be visible to the other units within that package but not to the end user.
|
||||
// TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused.
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _invalidateContractInstances(): void {
|
||||
this.unsubscribeAll();
|
||||
this._tokenContractsByAddress = {};
|
||||
}
|
||||
private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
|
||||
private async _getTokenContractAsync(tokenAddress: string): Promise<ERC20TokenContract> {
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress];
|
||||
if (!_.isUndefined(tokenContract)) {
|
||||
return tokenContract;
|
||||
}
|
||||
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifacts.Token,
|
||||
artifacts.ERC20Token,
|
||||
normalizedTokenAddress,
|
||||
);
|
||||
const contractInstance = new TokenContract(
|
||||
const contractInstance = new ERC20TokenContract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
@@ -0,0 +1,85 @@
|
||||
import { AssetProxyId } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { ContractAbi } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { assert } from '../utils/assert';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { ERC721ProxyContract } from './generated/erc721_proxy';
|
||||
|
||||
/**
|
||||
* This class includes the functionality related to interacting with the ERC721Proxy contract.
|
||||
*/
|
||||
export class ERC721ProxyWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.ERC20Proxy.compilerOutput.abi;
|
||||
private _erc721ProxyContractIfExists?: ERC721ProxyContract;
|
||||
private _contractAddressIfExists?: string;
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
|
||||
super(web3Wrapper, networkId);
|
||||
this._contractAddressIfExists = contractAddressIfExists;
|
||||
}
|
||||
/**
|
||||
* Get the 4 bytes ID of this asset proxy
|
||||
* @return Proxy id
|
||||
*/
|
||||
public async getProxyIdAsync(): Promise<AssetProxyId> {
|
||||
const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync();
|
||||
const proxyId = (await ERC721ProxyContractInstance.getProxyId.callAsync()) as AssetProxyId;
|
||||
return proxyId;
|
||||
}
|
||||
/**
|
||||
* Check if the Exchange contract address is authorized by the ERC721Proxy contract.
|
||||
* @param exchangeContractAddress The hex encoded address of the Exchange contract to call.
|
||||
* @return Whether the exchangeContractAddress is authorized.
|
||||
*/
|
||||
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
||||
assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress);
|
||||
const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase();
|
||||
const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync();
|
||||
const isAuthorized = await ERC721ProxyContractInstance.authorized.callAsync(normalizedExchangeContractAddress);
|
||||
return isAuthorized;
|
||||
}
|
||||
/**
|
||||
* Get the list of all Exchange contract addresses authorized by the ERC721Proxy contract.
|
||||
* @return The list of authorized addresses.
|
||||
*/
|
||||
public async getAuthorizedAddressesAsync(): Promise<string[]> {
|
||||
const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync();
|
||||
const authorizedAddresses = await ERC721ProxyContractInstance.getAuthorizedAddresses.callAsync();
|
||||
return authorizedAddresses;
|
||||
}
|
||||
/**
|
||||
* Retrieves the Ethereum address of the ERC721Proxy contract deployed on the network
|
||||
* that the user-passed web3 provider is connected to.
|
||||
* @returns The Ethereum address of the ERC721Proxy contract being used.
|
||||
*/
|
||||
public getContractAddress(): string {
|
||||
const contractAddress = this._getContractAddress(artifacts.ERC721Proxy, this._contractAddressIfExists);
|
||||
return contractAddress;
|
||||
}
|
||||
// HACK: We don't want this method to be visible to the other units within that package but not to the end user.
|
||||
// TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused.
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _invalidateContractInstance(): void {
|
||||
delete this._erc721ProxyContractIfExists;
|
||||
}
|
||||
private async _getERC721ProxyContractAsync(): Promise<ERC721ProxyContract> {
|
||||
if (!_.isUndefined(this._erc721ProxyContractIfExists)) {
|
||||
return this._erc721ProxyContractIfExists;
|
||||
}
|
||||
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifacts.ERC721Proxy,
|
||||
this._contractAddressIfExists,
|
||||
);
|
||||
const contractInstance = new ERC721ProxyContract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
this._web3Wrapper.getContractDefaults(),
|
||||
);
|
||||
this._erc721ProxyContractIfExists = contractInstance;
|
||||
return this._erc721ProxyContractIfExists;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,467 @@
|
||||
import { schemas } from '@0xproject/json-schemas';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { constants } from '../../test/utils/constants';
|
||||
import { artifacts } from '../artifacts';
|
||||
import { methodOptsSchema } from '../schemas/method_opts_schema';
|
||||
import { txOptsSchema } from '../schemas/tx_opts_schema';
|
||||
import {
|
||||
BlockRange,
|
||||
ContractWrappersError,
|
||||
EventCallback,
|
||||
IndexedFilterValues,
|
||||
MethodOpts,
|
||||
TransactionOpts,
|
||||
} from '../types';
|
||||
import { assert } from '../utils/assert';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { ERC721ProxyWrapper } from './erc721_proxy_wrapper';
|
||||
import { ERC721TokenContract, ERC721TokenEventArgs, ERC721TokenEvents } from './generated/erc721_token';
|
||||
|
||||
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
|
||||
* to the 0x ERC721 Proxy smart contract.
|
||||
*/
|
||||
export class ERC721TokenWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.ERC721Token.compilerOutput.abi;
|
||||
private _tokenContractsByAddress: { [address: string]: ERC721TokenContract };
|
||||
private _erc721ProxyWrapper: ERC721ProxyWrapper;
|
||||
constructor(
|
||||
web3Wrapper: Web3Wrapper,
|
||||
networkId: number,
|
||||
erc721ProxyWrapper: ERC721ProxyWrapper,
|
||||
blockPollingIntervalMs?: number,
|
||||
) {
|
||||
super(web3Wrapper, networkId, blockPollingIntervalMs);
|
||||
this._tokenContractsByAddress = {};
|
||||
this._erc721ProxyWrapper = erc721ProxyWrapper;
|
||||
}
|
||||
/**
|
||||
* Count all NFTs assigned to an owner
|
||||
* NFTs assigned to the zero address are considered invalid, and this function throws for queries about the zero address.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param ownerAddress The hex encoded user Ethereum address whose balance you would like to check.
|
||||
* @param methodOpts Optional arguments this method accepts.
|
||||
* @return The number of NFTs owned by `ownerAddress`, possibly zero
|
||||
*/
|
||||
public async getTokenCountAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<BigNumber> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
|
||||
const txData = {};
|
||||
let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, methodOpts.defaultBlock);
|
||||
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||
balance = new BigNumber(balance);
|
||||
return balance;
|
||||
}
|
||||
/**
|
||||
* Find the owner of an NFT
|
||||
* NFTs assigned to zero address are considered invalid, and queries about them do throw.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param tokenId The identifier for an NFT
|
||||
* @param methodOpts Optional arguments this method accepts.
|
||||
* @return The address of the owner of the NFT
|
||||
*/
|
||||
public async getOwnerOfAsync(
|
||||
tokenAddress: string,
|
||||
tokenId: BigNumber,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isBigNumber('tokenId', tokenId);
|
||||
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
|
||||
const txData = {};
|
||||
try {
|
||||
const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId, txData, methodOpts.defaultBlock);
|
||||
return tokenOwner;
|
||||
} catch (err) {
|
||||
throw new Error(ContractWrappersError.ERC721OwnerNotFound);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Query if an address is an authorized operator for all NFT's of `ownerAddress`
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param ownerAddress The hex encoded user Ethereum address of the token owner.
|
||||
* @param operatorAddress The hex encoded user Ethereum address of the operator you'd like to check if approved.
|
||||
* @param methodOpts Optional arguments this method accepts.
|
||||
* @return True if `operatorAddress` is an approved operator for `ownerAddress`, false otherwise
|
||||
*/
|
||||
public async isApprovedForAllAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
operatorAddress: string,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<boolean> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||
assert.isETHAddressHex('operatorAddress', operatorAddress);
|
||||
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
const normalizedOperatorAddress = operatorAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
|
||||
const txData = {};
|
||||
const isApprovedForAll = await tokenContract.isApprovedForAll.callAsync(
|
||||
normalizedOwnerAddress,
|
||||
normalizedOperatorAddress,
|
||||
txData,
|
||||
methodOpts.defaultBlock,
|
||||
);
|
||||
return isApprovedForAll;
|
||||
}
|
||||
/**
|
||||
* Query if 0x proxy is an authorized operator for all NFT's of `ownerAddress`
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param ownerAddress The hex encoded user Ethereum address of the token owner.
|
||||
* @param methodOpts Optional arguments this method accepts.
|
||||
* @return True if `operatorAddress` is an approved operator for `ownerAddress`, false otherwise
|
||||
*/
|
||||
public async isProxyApprovedForAllAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<boolean> {
|
||||
const proxyAddress = this._erc721ProxyWrapper.getContractAddress();
|
||||
const isProxyApprovedForAll = await this.isApprovedForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
proxyAddress,
|
||||
methodOpts,
|
||||
);
|
||||
return isProxyApprovedForAll;
|
||||
}
|
||||
/**
|
||||
* Get the approved address for a single NFT. Returns undefined if no approval was set
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param tokenId The identifier for an NFT
|
||||
* @param methodOpts Optional arguments this method accepts.
|
||||
* @return The approved address for this NFT, or the undefined if there is none
|
||||
*/
|
||||
public async getApprovedIfExistsAsync(
|
||||
tokenAddress: string,
|
||||
tokenId: BigNumber,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<string | undefined> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isBigNumber('tokenId', tokenId);
|
||||
assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
|
||||
const txData = {};
|
||||
const approvedAddress = await tokenContract.getApproved.callAsync(tokenId, txData, methodOpts.defaultBlock);
|
||||
if (approvedAddress === constants.NULL_ADDRESS) {
|
||||
return undefined;
|
||||
}
|
||||
return approvedAddress;
|
||||
}
|
||||
/**
|
||||
* Checks if 0x proxy is approved for a single NFT
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param tokenId The identifier for an NFT
|
||||
* @param methodOpts Optional arguments this method accepts.
|
||||
* @return True if 0x proxy is approved
|
||||
*/
|
||||
public async isProxyApprovedAsync(
|
||||
tokenAddress: string,
|
||||
tokenId: BigNumber,
|
||||
methodOpts: MethodOpts = {},
|
||||
): Promise<boolean> {
|
||||
const proxyAddress = this._erc721ProxyWrapper.getContractAddress();
|
||||
const approvedAddress = await this.getApprovedIfExistsAsync(tokenAddress, tokenId, methodOpts);
|
||||
const isProxyApproved = approvedAddress === proxyAddress;
|
||||
return isProxyApproved;
|
||||
}
|
||||
/**
|
||||
* Enable or disable approval for a third party ("operator") to manage all of `ownerAddress`'s assets.
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* Emits the ApprovalForAll event.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param ownerAddress The hex encoded user Ethereum address of the token owner.
|
||||
* @param operatorAddress The hex encoded user Ethereum address of the operator you'd like to set approval for.
|
||||
* @param isApproved The boolean variable to set the approval to.
|
||||
* @param txOpts Transaction parameters.
|
||||
* @return Transaction hash.
|
||||
*/
|
||||
public async setApprovalForAllAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
operatorAddress: string,
|
||||
isApproved: boolean,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
||||
assert.isETHAddressHex('operatorAddress', operatorAddress);
|
||||
assert.isBoolean('isApproved', isApproved);
|
||||
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||
const normalizedOperatorAddress = operatorAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const txHash = await tokenContract.setApprovalForAll.sendTransactionAsync(
|
||||
normalizedOperatorAddress,
|
||||
isApproved,
|
||||
removeUndefinedProperties({
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
from: normalizedOwnerAddress,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
* Enable or disable approval for a third party ("operator") to manage all of `ownerAddress`'s assets.
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* Emits the ApprovalForAll event.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param ownerAddress The hex encoded user Ethereum address of the token owner.
|
||||
* @param operatorAddress The hex encoded user Ethereum address of the operator you'd like to set approval for.
|
||||
* @param isApproved The boolean variable to set the approval to.
|
||||
* @param txOpts Transaction parameters.
|
||||
* @return Transaction hash.
|
||||
*/
|
||||
public async setProxyApprovalForAllAsync(
|
||||
tokenAddress: string,
|
||||
ownerAddress: string,
|
||||
isApproved: boolean,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
const proxyAddress = this._erc721ProxyWrapper.getContractAddress();
|
||||
const txHash = await this.setApprovalForAllAsync(tokenAddress, ownerAddress, proxyAddress, isApproved, txOpts);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
* Set or reaffirm the approved address for an NFT
|
||||
* The zero address indicates there is no approved address. Throws unless `msg.sender` is the current NFT owner,
|
||||
* or an authorized operator of the current owner.
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* Emits the Approval event.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param approvedAddress The hex encoded user Ethereum address you'd like to set approval for.
|
||||
* @param tokenId The identifier for an NFT
|
||||
* @param txOpts Transaction parameters.
|
||||
* @return Transaction hash.
|
||||
*/
|
||||
public async setApprovalAsync(
|
||||
tokenAddress: string,
|
||||
approvedAddress: string,
|
||||
tokenId: BigNumber,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('approvedAddress', approvedAddress);
|
||||
assert.isBigNumber('tokenId', tokenId);
|
||||
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedApprovedAddress = approvedAddress.toLowerCase();
|
||||
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const tokenOwnerAddress = await tokenContract.ownerOf.callAsync(tokenId);
|
||||
await assert.isSenderAddressAsync('tokenOwnerAddress', tokenOwnerAddress, this._web3Wrapper);
|
||||
const txHash = await tokenContract.approve.sendTransactionAsync(
|
||||
normalizedApprovedAddress,
|
||||
tokenId,
|
||||
removeUndefinedProperties({
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
from: tokenOwnerAddress,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
* Set or reaffirm 0x proxy as an approved address for an NFT
|
||||
* Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner.
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* Emits the Approval event.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param tokenId The identifier for an NFT
|
||||
* @param txOpts Transaction parameters.
|
||||
* @return Transaction hash.
|
||||
*/
|
||||
public async setProxyApprovalAsync(
|
||||
tokenAddress: string,
|
||||
tokenId: BigNumber,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
const proxyAddress = this._erc721ProxyWrapper.getContractAddress();
|
||||
const txHash = await this.setApprovalAsync(tokenAddress, proxyAddress, tokenId, txOpts);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
* Enable or disable approval for a third party ("operator") to manage all of `ownerAddress`'s assets.
|
||||
* Throws if `_tokenId` is not a valid NFT
|
||||
* Emits the ApprovalForAll event.
|
||||
* @param tokenAddress The hex encoded contract Ethereum address where the ERC721 token is deployed.
|
||||
* @param receiverAddress The hex encoded Ethereum address of the user to send the NFT to.
|
||||
* @param senderAddress The hex encoded Ethereum address of the user to send the NFT to.
|
||||
* @param tokenId The identifier for an NFT
|
||||
* @param txOpts Transaction parameters.
|
||||
* @return Transaction hash.
|
||||
*/
|
||||
public async transferFromAsync(
|
||||
tokenAddress: string,
|
||||
receiverAddress: string,
|
||||
senderAddress: string,
|
||||
tokenId: BigNumber,
|
||||
txOpts: TransactionOpts = {},
|
||||
): Promise<string> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.isETHAddressHex('receiverAddress', receiverAddress);
|
||||
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
|
||||
assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const normalizedReceiverAddress = receiverAddress.toLowerCase();
|
||||
const normalizedSenderAddress = senderAddress.toLowerCase();
|
||||
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||
const ownerAddress = await this.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
const isApprovedForAll = await this.isApprovedForAllAsync(
|
||||
normalizedTokenAddress,
|
||||
ownerAddress,
|
||||
normalizedSenderAddress,
|
||||
);
|
||||
if (!isApprovedForAll) {
|
||||
const approvedAddress = await this.getApprovedIfExistsAsync(normalizedTokenAddress, tokenId);
|
||||
if (approvedAddress !== senderAddress) {
|
||||
throw new Error(ContractWrappersError.ERC721NoApproval);
|
||||
}
|
||||
}
|
||||
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
||||
ownerAddress,
|
||||
normalizedReceiverAddress,
|
||||
tokenId,
|
||||
removeUndefinedProperties({
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
from: normalizedSenderAddress,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
* Subscribe to an event type emitted by the Token contract.
|
||||
* @param tokenAddress The hex encoded address where the ERC721 token is deployed.
|
||||
* @param eventName The token contract event you would like to subscribe to.
|
||||
* @param indexFilterValues An object where the keys are indexed args returned by the event and
|
||||
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends ERC721TokenEventArgs>(
|
||||
tokenAddress: string,
|
||||
eventName: ERC721TokenEvents,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
): string {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
assert.isFunction('callback', callback);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const subscriptionToken = this._subscribe<ArgsType>(
|
||||
normalizedTokenAddress,
|
||||
eventName,
|
||||
indexFilterValues,
|
||||
artifacts.ERC721Token.compilerOutput.abi,
|
||||
callback,
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
/**
|
||||
* Cancel a subscription
|
||||
* @param subscriptionToken Subscription token returned by `subscribe()`
|
||||
*/
|
||||
public unsubscribe(subscriptionToken: string): void {
|
||||
assert.isValidSubscriptionToken('subscriptionToken', subscriptionToken);
|
||||
this._unsubscribe(subscriptionToken);
|
||||
}
|
||||
/**
|
||||
* Cancels all existing subscriptions
|
||||
*/
|
||||
public unsubscribeAll(): void {
|
||||
super._unsubscribeAll();
|
||||
}
|
||||
/**
|
||||
* Gets historical logs without creating a subscription
|
||||
* @param tokenAddress An address of the token that emitted the logs.
|
||||
* @param eventName The token contract event you would like to subscribe to.
|
||||
* @param blockRange Block range to get logs from.
|
||||
* @param indexFilterValues An object where the keys are indexed args returned by the event and
|
||||
* the value is the value you are interested in. E.g `{_from: aUserAddressHex}`
|
||||
* @return Array of logs that match the parameters
|
||||
*/
|
||||
public async getLogsAsync<ArgsType extends ERC721TokenEventArgs>(
|
||||
tokenAddress: string,
|
||||
eventName: ERC721TokenEvents,
|
||||
blockRange: BlockRange,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents);
|
||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
const logs = await this._getLogsAsync<ArgsType>(
|
||||
normalizedTokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
indexFilterValues,
|
||||
artifacts.ERC721Token.compilerOutput.abi,
|
||||
);
|
||||
return logs;
|
||||
}
|
||||
// HACK: We don't want this method to be visible to the other units within that package but not to the end user.
|
||||
// TS doesn't give that possibility and therefore we make it private and access it over an any cast. Because of that tslint sees it as unused.
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _invalidateContractInstances(): void {
|
||||
this.unsubscribeAll();
|
||||
this._tokenContractsByAddress = {};
|
||||
}
|
||||
private async _getTokenContractAsync(tokenAddress: string): Promise<ERC721TokenContract> {
|
||||
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||
let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress];
|
||||
if (!_.isUndefined(tokenContract)) {
|
||||
return tokenContract;
|
||||
}
|
||||
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifacts.ERC721Token,
|
||||
normalizedTokenAddress,
|
||||
);
|
||||
const contractInstance = new ERC721TokenContract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
this._web3Wrapper.getContractDefaults(),
|
||||
);
|
||||
tokenContract = contractInstance;
|
||||
this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract;
|
||||
return tokenContract;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { schemas } from '@0xproject/json-schemas';
|
||||
import { ContractAbi, LogWithDecodedArgs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
@@ -9,22 +9,29 @@ import { BlockRange, ContractWrappersError, EventCallback, IndexedFilterValues,
|
||||
import { assert } from '../utils/assert';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { EtherTokenContract, EtherTokenContractEventArgs, EtherTokenEvents } from './generated/ether_token';
|
||||
import { TokenWrapper } from './token_wrapper';
|
||||
import { ERC20TokenWrapper } from './erc20_token_wrapper';
|
||||
import { WETH9Contract, WETH9EventArgs, WETH9Events } from './generated/weth9';
|
||||
|
||||
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 = artifacts.EtherToken.abi;
|
||||
public abi: ContractAbi = artifacts.EtherToken.compilerOutput.abi;
|
||||
private _etherTokenContractsByAddress: {
|
||||
[address: string]: EtherTokenContract;
|
||||
[address: string]: WETH9Contract;
|
||||
} = {};
|
||||
private _tokenWrapper: TokenWrapper;
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenWrapper: TokenWrapper) {
|
||||
super(web3Wrapper, networkId);
|
||||
this._tokenWrapper = tokenWrapper;
|
||||
private _erc20TokenWrapper: ERC20TokenWrapper;
|
||||
constructor(
|
||||
web3Wrapper: Web3Wrapper,
|
||||
networkId: number,
|
||||
erc20TokenWrapper: ERC20TokenWrapper,
|
||||
blockPollingIntervalMs?: number,
|
||||
) {
|
||||
super(web3Wrapper, networkId, blockPollingIntervalMs);
|
||||
this._erc20TokenWrapper = erc20TokenWrapper;
|
||||
}
|
||||
/**
|
||||
* Deposit ETH into the Wrapped ETH smart contract and issues the equivalent number of wrapped ETH tokens
|
||||
@@ -52,12 +59,14 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
assert.assert(ethBalanceInWei.gte(amountInWei), ContractWrappersError.InsufficientEthBalanceForDeposit);
|
||||
|
||||
const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
|
||||
const txHash = await wethContract.deposit.sendTransactionAsync({
|
||||
from: normalizedDepositorAddress,
|
||||
value: amountInWei,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
});
|
||||
const txHash = await wethContract.deposit.sendTransactionAsync(
|
||||
removeUndefinedProperties({
|
||||
from: normalizedDepositorAddress,
|
||||
value: amountInWei,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
@@ -81,7 +90,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||
const normalizedWithdrawerAddress = withdrawer.toLowerCase();
|
||||
|
||||
const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(
|
||||
const WETHBalanceInBaseUnits = await this._erc20TokenWrapper.getBalanceAsync(
|
||||
normalizedEtherTokenAddress,
|
||||
normalizedWithdrawerAddress,
|
||||
);
|
||||
@@ -91,11 +100,14 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
);
|
||||
|
||||
const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
|
||||
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
|
||||
from: normalizedWithdrawerAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
});
|
||||
const txHash = await wethContract.withdraw.sendTransactionAsync(
|
||||
amountInWei,
|
||||
removeUndefinedProperties({
|
||||
from: normalizedWithdrawerAddress,
|
||||
gas: txOpts.gasLimit,
|
||||
gasPrice: txOpts.gasPrice,
|
||||
}),
|
||||
);
|
||||
return txHash;
|
||||
}
|
||||
/**
|
||||
@@ -107,15 +119,15 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
* the value is the value you are interested in. E.g `{_owner: aUserAddressHex}`
|
||||
* @return Array of logs that match the parameters
|
||||
*/
|
||||
public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
|
||||
public async getLogsAsync<ArgsType extends WETH9EventArgs>(
|
||||
etherTokenAddress: string,
|
||||
eventName: EtherTokenEvents,
|
||||
eventName: WETH9Events,
|
||||
blockRange: BlockRange,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, WETH9Events);
|
||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
const logs = await this._getLogsAsync<ArgsType>(
|
||||
@@ -123,7 +135,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
eventName,
|
||||
blockRange,
|
||||
indexFilterValues,
|
||||
artifacts.EtherToken.abi,
|
||||
artifacts.EtherToken.compilerOutput.abi,
|
||||
);
|
||||
return logs;
|
||||
}
|
||||
@@ -136,22 +148,22 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
* @param callback Callback that gets called when a log is added/removed
|
||||
* @return Subscription token used later to unsubscribe
|
||||
*/
|
||||
public subscribe<ArgsType extends EtherTokenContractEventArgs>(
|
||||
public subscribe<ArgsType extends WETH9EventArgs>(
|
||||
etherTokenAddress: string,
|
||||
eventName: EtherTokenEvents,
|
||||
eventName: WETH9Events,
|
||||
indexFilterValues: IndexedFilterValues,
|
||||
callback: EventCallback<ArgsType>,
|
||||
): string {
|
||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||
assert.doesBelongToStringEnum('eventName', eventName, WETH9Events);
|
||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||
assert.isFunction('callback', callback);
|
||||
const subscriptionToken = this._subscribe<ArgsType>(
|
||||
normalizedEtherTokenAddress,
|
||||
eventName,
|
||||
indexFilterValues,
|
||||
artifacts.EtherToken.abi,
|
||||
artifacts.EtherToken.compilerOutput.abi,
|
||||
callback,
|
||||
);
|
||||
return subscriptionToken;
|
||||
@@ -161,6 +173,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
* @param subscriptionToken Subscription token returned by `subscribe()`
|
||||
*/
|
||||
public unsubscribe(subscriptionToken: string): void {
|
||||
assert.isValidSubscriptionToken('subscriptionToken', subscriptionToken);
|
||||
this._unsubscribe(subscriptionToken);
|
||||
}
|
||||
/**
|
||||
@@ -187,7 +200,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
this.unsubscribeAll();
|
||||
this._etherTokenContractsByAddress = {};
|
||||
}
|
||||
private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
|
||||
private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<WETH9Contract> {
|
||||
let etherTokenContract = this._etherTokenContractsByAddress[etherTokenAddress];
|
||||
if (!_.isUndefined(etherTokenContract)) {
|
||||
return etherTokenContract;
|
||||
@@ -196,7 +209,7 @@ export class EtherTokenWrapper extends ContractWrapper {
|
||||
artifacts.EtherToken,
|
||||
etherTokenAddress,
|
||||
);
|
||||
const contractInstance = new EtherTokenContract(
|
||||
const contractInstance = new WETH9Contract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,133 +0,0 @@
|
||||
import { ContractAbi, Token } from '@0xproject/types';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { TokenMetadata } from '../types';
|
||||
import { assert } from '../utils/assert';
|
||||
import { constants } from '../utils/constants';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { TokenRegistryContract } from './generated/token_registry';
|
||||
|
||||
/**
|
||||
* This class includes all the functionality related to interacting with the 0x Token Registry smart contract.
|
||||
*/
|
||||
export class TokenRegistryWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.TokenRegistry.abi;
|
||||
private _tokenRegistryContractIfExists?: TokenRegistryContract;
|
||||
private _contractAddressIfExists?: string;
|
||||
private static _createTokenFromMetadata(metadata: TokenMetadata): Token | undefined {
|
||||
if (metadata[0] === constants.NULL_ADDRESS) {
|
||||
return undefined;
|
||||
}
|
||||
const token = {
|
||||
address: metadata[0],
|
||||
name: metadata[1],
|
||||
symbol: metadata[2],
|
||||
decimals: metadata[3],
|
||||
};
|
||||
return token;
|
||||
}
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
|
||||
super(web3Wrapper, networkId);
|
||||
this._contractAddressIfExists = contractAddressIfExists;
|
||||
}
|
||||
/**
|
||||
* Retrieves all the tokens currently listed in the Token Registry smart contract
|
||||
* @return An array of objects that conform to the Token interface.
|
||||
*/
|
||||
public async getTokensAsync(): Promise<Token[]> {
|
||||
const addresses = await this.getTokenAddressesAsync();
|
||||
const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (address: string) =>
|
||||
this.getTokenIfExistsAsync(address),
|
||||
);
|
||||
const tokens = await Promise.all(tokenPromises);
|
||||
return tokens as Token[];
|
||||
}
|
||||
/**
|
||||
* Retrieves all the addresses of the tokens currently listed in the Token Registry smart contract
|
||||
* @return An array of token addresses.
|
||||
*/
|
||||
public async getTokenAddressesAsync(): Promise<string[]> {
|
||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||
const addresses = await tokenRegistryContract.getTokenAddresses.callAsync();
|
||||
const lowerCaseAddresses = _.map(addresses, address => address.toLowerCase());
|
||||
return lowerCaseAddresses;
|
||||
}
|
||||
/**
|
||||
* Retrieves a token by address currently listed in the Token Registry smart contract
|
||||
* @return An object that conforms to the Token interface or undefined if token not found.
|
||||
*/
|
||||
public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> {
|
||||
assert.isETHAddressHex('address', address);
|
||||
const normalizedAddress = address.toLowerCase();
|
||||
|
||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||
const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress);
|
||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||
return token;
|
||||
}
|
||||
public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> {
|
||||
assert.isString('symbol', symbol);
|
||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||
const addressIfExists = await tokenRegistryContract.getTokenAddressBySymbol.callAsync(symbol);
|
||||
if (addressIfExists === constants.NULL_ADDRESS) {
|
||||
return undefined;
|
||||
}
|
||||
return addressIfExists;
|
||||
}
|
||||
public async getTokenAddressByNameIfExistsAsync(name: string): Promise<string | undefined> {
|
||||
assert.isString('name', name);
|
||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||
const addressIfExists = await tokenRegistryContract.getTokenAddressByName.callAsync(name);
|
||||
if (addressIfExists === constants.NULL_ADDRESS) {
|
||||
return undefined;
|
||||
}
|
||||
return addressIfExists;
|
||||
}
|
||||
public async getTokenBySymbolIfExistsAsync(symbol: string): Promise<Token | undefined> {
|
||||
assert.isString('symbol', symbol);
|
||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||
const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
|
||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||
return token;
|
||||
}
|
||||
public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> {
|
||||
assert.isString('name', name);
|
||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||
const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
|
||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||
return token;
|
||||
}
|
||||
/**
|
||||
* Retrieves the Ethereum address of the TokenRegistry contract deployed on the network
|
||||
* that the user-passed web3 provider is connected to.
|
||||
* @returns The Ethereum address of the TokenRegistry contract being used.
|
||||
*/
|
||||
public getContractAddress(): string {
|
||||
const contractAddress = this._getContractAddress(artifacts.TokenRegistry, this._contractAddressIfExists);
|
||||
return contractAddress;
|
||||
}
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _invalidateContractInstance(): void {
|
||||
delete this._tokenRegistryContractIfExists;
|
||||
}
|
||||
private async _getTokenRegistryContractAsync(): Promise<TokenRegistryContract> {
|
||||
if (!_.isUndefined(this._tokenRegistryContractIfExists)) {
|
||||
return this._tokenRegistryContractIfExists;
|
||||
}
|
||||
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifacts.TokenRegistry,
|
||||
this._contractAddressIfExists,
|
||||
);
|
||||
const contractInstance = new TokenRegistryContract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
this._web3Wrapper.getContractDefaults(),
|
||||
);
|
||||
this._tokenRegistryContractIfExists = contractInstance;
|
||||
return this._tokenRegistryContractIfExists;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { ContractAbi } from '@0xproject/types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { artifacts } from '../artifacts';
|
||||
import { assert } from '../utils/assert';
|
||||
|
||||
import { ContractWrapper } from './contract_wrapper';
|
||||
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
|
||||
|
||||
/**
|
||||
* This class includes the functionality related to interacting with the TokenTransferProxy contract.
|
||||
*/
|
||||
export class TokenTransferProxyWrapper extends ContractWrapper {
|
||||
public abi: ContractAbi = artifacts.TokenTransferProxy.abi;
|
||||
private _tokenTransferProxyContractIfExists?: TokenTransferProxyContract;
|
||||
private _contractAddressIfExists?: string;
|
||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, contractAddressIfExists?: string) {
|
||||
super(web3Wrapper, networkId);
|
||||
this._contractAddressIfExists = contractAddressIfExists;
|
||||
}
|
||||
/**
|
||||
* Check if the Exchange contract address is authorized by the TokenTransferProxy contract.
|
||||
* @param exchangeContractAddress The hex encoded address of the Exchange contract to call.
|
||||
* @return Whether the exchangeContractAddress is authorized.
|
||||
*/
|
||||
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
||||
assert.isETHAddressHex('exchangeContractAddress', exchangeContractAddress);
|
||||
const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase();
|
||||
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
|
||||
const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(
|
||||
normalizedExchangeContractAddress,
|
||||
);
|
||||
return isAuthorized;
|
||||
}
|
||||
/**
|
||||
* Get the list of all Exchange contract addresses authorized by the TokenTransferProxy contract.
|
||||
* @return The list of authorized addresses.
|
||||
*/
|
||||
public async getAuthorizedAddressesAsync(): Promise<string[]> {
|
||||
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
|
||||
const authorizedAddresses = await tokenTransferProxyContractInstance.getAuthorizedAddresses.callAsync();
|
||||
return authorizedAddresses;
|
||||
}
|
||||
/**
|
||||
* Retrieves the Ethereum address of the TokenTransferProxy contract deployed on the network
|
||||
* that the user-passed web3 provider is connected to.
|
||||
* @returns The Ethereum address of the TokenTransferProxy contract being used.
|
||||
*/
|
||||
public getContractAddress(): string {
|
||||
const contractAddress = this._getContractAddress(artifacts.TokenTransferProxy, this._contractAddressIfExists);
|
||||
return contractAddress;
|
||||
}
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
private _invalidateContractInstance(): void {
|
||||
delete this._tokenTransferProxyContractIfExists;
|
||||
}
|
||||
private async _getTokenTransferProxyContractAsync(): Promise<TokenTransferProxyContract> {
|
||||
if (!_.isUndefined(this._tokenTransferProxyContractIfExists)) {
|
||||
return this._tokenTransferProxyContractIfExists;
|
||||
}
|
||||
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
|
||||
artifacts.TokenTransferProxy,
|
||||
this._contractAddressIfExists,
|
||||
);
|
||||
const contractInstance = new TokenTransferProxyContract(
|
||||
abi,
|
||||
address,
|
||||
this._web3Wrapper.getProvider(),
|
||||
this._web3Wrapper.getContractDefaults(),
|
||||
);
|
||||
this._tokenTransferProxyContractIfExists = contractInstance;
|
||||
return this._tokenTransferProxyContractIfExists;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { AbstractBalanceAndProxyAllowanceFetcher } from '@0xproject/order-utils';
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
|
||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||
|
||||
export class SimpleBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher {
|
||||
private _tokenWrapper: TokenWrapper;
|
||||
private _defaultBlock: BlockParamLiteral;
|
||||
constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
|
||||
this._tokenWrapper = token;
|
||||
this._defaultBlock = defaultBlock;
|
||||
}
|
||||
public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const balance = this._tokenWrapper.getBalanceAsync(tokenAddress, userAddress, methodOpts);
|
||||
return balance;
|
||||
}
|
||||
public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const proxyAllowance = this._tokenWrapper.getProxyAllowanceAsync(tokenAddress, userAddress, methodOpts);
|
||||
return proxyAllowance;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils';
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
|
||||
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
|
||||
|
||||
export class SimpleOrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher {
|
||||
private _exchangeWrapper: ExchangeWrapper;
|
||||
private _defaultBlock: BlockParamLiteral;
|
||||
constructor(exchange: ExchangeWrapper, defaultBlock: BlockParamLiteral) {
|
||||
this._exchangeWrapper = exchange;
|
||||
this._defaultBlock = defaultBlock;
|
||||
}
|
||||
public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const filledTakerAmount = this._exchangeWrapper.getFilledTakerAmountAsync(orderHash, methodOpts);
|
||||
return filledTakerAmount;
|
||||
}
|
||||
public async getCancelledTakerAmountAsync(orderHash: string): Promise<BigNumber> {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const cancelledTakerAmount = this._exchangeWrapper.getCancelledTakerAmountAsync(orderHash, methodOpts);
|
||||
return cancelledTakerAmount;
|
||||
}
|
||||
public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
|
||||
const unavailableTakerAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
||||
return unavailableTakerAmount;
|
||||
}
|
||||
public getZRXTokenAddress(): string {
|
||||
const zrxToken = this._exchangeWrapper.getZRXTokenAddress();
|
||||
return zrxToken;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
export { ContractWrappers } from './contract_wrappers';
|
||||
export { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
|
||||
export { TokenWrapper } from './contract_wrappers/token_wrapper';
|
||||
export { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper';
|
||||
export { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper';
|
||||
export { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
|
||||
export { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper';
|
||||
export { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper';
|
||||
|
||||
export {
|
||||
ContractWrappersError,
|
||||
@@ -12,7 +10,6 @@ export {
|
||||
Token,
|
||||
IndexedFilterValues,
|
||||
BlockRange,
|
||||
OrderCancellationRequest,
|
||||
OrderFillRequest,
|
||||
ContractEventArgs,
|
||||
ContractWrappersConfig,
|
||||
@@ -22,47 +19,51 @@ export {
|
||||
LogEvent,
|
||||
DecodedLogEvent,
|
||||
OnOrderStateChangeCallback,
|
||||
OrderStatus,
|
||||
OrderInfo,
|
||||
} from './types';
|
||||
|
||||
export { Order, SignedOrder, ECSignature, OrderStateValid, OrderStateInvalid, OrderState } from '@0xproject/types';
|
||||
|
||||
export {
|
||||
BlockParamLiteral,
|
||||
FilterObject,
|
||||
BlockParam,
|
||||
ContractEventArg,
|
||||
ExchangeContractErrs,
|
||||
LogWithDecodedArgs,
|
||||
Order,
|
||||
Provider,
|
||||
SignedOrder,
|
||||
ECSignature,
|
||||
OrderStateValid,
|
||||
OrderStateInvalid,
|
||||
OrderState,
|
||||
TransactionReceipt,
|
||||
TransactionReceiptWithDecodedLogs,
|
||||
} from '@0xproject/types';
|
||||
} from 'ethereum-types';
|
||||
|
||||
export {
|
||||
EtherTokenContractEventArgs,
|
||||
WithdrawalContractEventArgs,
|
||||
DepositContractEventArgs,
|
||||
EtherTokenEvents,
|
||||
} from './contract_wrappers/generated/ether_token';
|
||||
WETH9Events,
|
||||
WETH9WithdrawalEventArgs,
|
||||
WETH9ApprovalEventArgs,
|
||||
WETH9EventArgs,
|
||||
WETH9DepositEventArgs,
|
||||
WETH9TransferEventArgs,
|
||||
} from './contract_wrappers/generated/weth9';
|
||||
|
||||
export {
|
||||
TransferContractEventArgs,
|
||||
ApprovalContractEventArgs,
|
||||
TokenContractEventArgs,
|
||||
TokenEvents,
|
||||
} from './contract_wrappers/generated/token';
|
||||
ERC20TokenTransferEventArgs,
|
||||
ERC20TokenApprovalEventArgs,
|
||||
ERC20TokenEvents,
|
||||
ERC20TokenEventArgs,
|
||||
} from './contract_wrappers/generated/erc20_token';
|
||||
|
||||
export {
|
||||
LogErrorContractEventArgs,
|
||||
LogCancelContractEventArgs,
|
||||
LogFillContractEventArgs,
|
||||
ExchangeContractEventArgs,
|
||||
ERC721TokenApprovalEventArgs,
|
||||
ERC721TokenApprovalForAllEventArgs,
|
||||
ERC721TokenTransferEventArgs,
|
||||
ERC721TokenEvents,
|
||||
} from './contract_wrappers/generated/erc721_token';
|
||||
|
||||
export {
|
||||
ExchangeCancelUpToEventArgs,
|
||||
ExchangeAssetProxyRegisteredEventArgs,
|
||||
ExchangeFillEventArgs,
|
||||
ExchangeCancelEventArgs,
|
||||
ExchangeEventArgs,
|
||||
ExchangeEvents,
|
||||
} from './contract_wrappers/generated/exchange';
|
||||
|
||||
export { BalanceAndProxyAllowanceLazyStore } from './stores/balance_proxy_allowance_lazy_store';
|
||||
export { OrderFilledCancelledLazyStore } from './stores/order_filled_cancelled_lazy_store';
|
||||
|
||||
@@ -10,6 +10,7 @@ export const contractWrappersPrivateNetworkConfigSchema = {
|
||||
exchangeContractAddress: { $ref: '/Address' },
|
||||
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||
tokenTransferProxyContractAddress: { $ref: '/Address' },
|
||||
blockPollingIntervalMs: { type: 'number' },
|
||||
orderWatcherConfig: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
||||
@@ -24,6 +24,7 @@ export const contractWrappersPublicNetworkConfigSchema = {
|
||||
exchangeContractAddress: { $ref: '/Address' },
|
||||
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||
tokenTransferProxyContractAddress: { $ref: '/Address' },
|
||||
blockPollingIntervalMs: { type: 'number' },
|
||||
orderWatcherConfig: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const methodOptsSchema = {
|
||||
id: '/MethodOpts',
|
||||
properties: {
|
||||
defaultBlock: { $ref: '/BlockParam' },
|
||||
},
|
||||
type: 'object',
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const orderTxOptsSchema = {
|
||||
id: '/OrderTxOpts',
|
||||
allOf: [{ $ref: '/TxOpts' }],
|
||||
properties: {
|
||||
shouldValidate: { type: 'boolean' },
|
||||
},
|
||||
type: 'object',
|
||||
};
|
||||
8
packages/contract-wrappers/src/schemas/tx_opts_schema.ts
Normal file
8
packages/contract-wrappers/src/schemas/tx_opts_schema.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export const txOptsSchema = {
|
||||
id: '/TxOpts',
|
||||
properties: {
|
||||
gasPrice: { $ref: '/Number' },
|
||||
gasLimit: { type: 'number' },
|
||||
},
|
||||
type: 'object',
|
||||
};
|
||||
@@ -1,91 +0,0 @@
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
|
||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||
|
||||
/**
|
||||
* Copy on read store for balances/proxyAllowances of tokens/accounts
|
||||
*/
|
||||
export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProxyAllowanceLazyStore {
|
||||
private _tokenWrapper: TokenWrapper;
|
||||
private _defaultBlock: BlockParamLiteral;
|
||||
private _balance: {
|
||||
[tokenAddress: string]: {
|
||||
[userAddress: string]: BigNumber;
|
||||
};
|
||||
};
|
||||
private _proxyAllowance: {
|
||||
[tokenAddress: string]: {
|
||||
[userAddress: string]: BigNumber;
|
||||
};
|
||||
};
|
||||
constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {
|
||||
this._tokenWrapper = token;
|
||||
this._defaultBlock = defaultBlock;
|
||||
this._balance = {};
|
||||
this._proxyAllowance = {};
|
||||
}
|
||||
public async getBalanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
||||
if (_.isUndefined(this._balance[tokenAddress]) || _.isUndefined(this._balance[tokenAddress][userAddress])) {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const balance = await this._tokenWrapper.getBalanceAsync(tokenAddress, userAddress, methodOpts);
|
||||
this.setBalance(tokenAddress, userAddress, balance);
|
||||
}
|
||||
const cachedBalance = this._balance[tokenAddress][userAddress];
|
||||
return cachedBalance;
|
||||
}
|
||||
public setBalance(tokenAddress: string, userAddress: string, balance: BigNumber): void {
|
||||
if (_.isUndefined(this._balance[tokenAddress])) {
|
||||
this._balance[tokenAddress] = {};
|
||||
}
|
||||
this._balance[tokenAddress][userAddress] = balance;
|
||||
}
|
||||
public deleteBalance(tokenAddress: string, userAddress: string): void {
|
||||
if (!_.isUndefined(this._balance[tokenAddress])) {
|
||||
delete this._balance[tokenAddress][userAddress];
|
||||
if (_.isEmpty(this._balance[tokenAddress])) {
|
||||
delete this._balance[tokenAddress];
|
||||
}
|
||||
}
|
||||
}
|
||||
public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
||||
if (
|
||||
_.isUndefined(this._proxyAllowance[tokenAddress]) ||
|
||||
_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
|
||||
) {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const proxyAllowance = await this._tokenWrapper.getProxyAllowanceAsync(
|
||||
tokenAddress,
|
||||
userAddress,
|
||||
methodOpts,
|
||||
);
|
||||
this.setProxyAllowance(tokenAddress, userAddress, proxyAllowance);
|
||||
}
|
||||
const cachedProxyAllowance = this._proxyAllowance[tokenAddress][userAddress];
|
||||
return cachedProxyAllowance;
|
||||
}
|
||||
public setProxyAllowance(tokenAddress: string, userAddress: string, proxyAllowance: BigNumber): void {
|
||||
if (_.isUndefined(this._proxyAllowance[tokenAddress])) {
|
||||
this._proxyAllowance[tokenAddress] = {};
|
||||
}
|
||||
this._proxyAllowance[tokenAddress][userAddress] = proxyAllowance;
|
||||
}
|
||||
public deleteProxyAllowance(tokenAddress: string, userAddress: string): void {
|
||||
if (!_.isUndefined(this._proxyAllowance[tokenAddress])) {
|
||||
delete this._proxyAllowance[tokenAddress][userAddress];
|
||||
if (_.isEmpty(this._proxyAllowance[tokenAddress])) {
|
||||
delete this._proxyAllowance[tokenAddress];
|
||||
}
|
||||
}
|
||||
}
|
||||
public deleteAll(): void {
|
||||
this._balance = {};
|
||||
this._proxyAllowance = {};
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils';
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
|
||||
|
||||
/**
|
||||
* Copy on read store for filled/cancelled taker amounts
|
||||
*/
|
||||
export class OrderFilledCancelledLazyStore implements AbstractOrderFilledCancelledFetcher {
|
||||
private _exchangeWrapper: ExchangeWrapper;
|
||||
private _defaultBlock: BlockParamLiteral;
|
||||
private _filledTakerAmount: {
|
||||
[orderHash: string]: BigNumber;
|
||||
};
|
||||
private _cancelledTakerAmount: {
|
||||
[orderHash: string]: BigNumber;
|
||||
};
|
||||
constructor(exchange: ExchangeWrapper, defaultBlock: BlockParamLiteral) {
|
||||
this._exchangeWrapper = exchange;
|
||||
this._defaultBlock = defaultBlock;
|
||||
this._filledTakerAmount = {};
|
||||
this._cancelledTakerAmount = {};
|
||||
}
|
||||
public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> {
|
||||
if (_.isUndefined(this._filledTakerAmount[orderHash])) {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const filledTakerAmount = await this._exchangeWrapper.getFilledTakerAmountAsync(orderHash, methodOpts);
|
||||
this.setFilledTakerAmount(orderHash, filledTakerAmount);
|
||||
}
|
||||
const cachedFilled = this._filledTakerAmount[orderHash];
|
||||
return cachedFilled;
|
||||
}
|
||||
public setFilledTakerAmount(orderHash: string, filledTakerAmount: BigNumber): void {
|
||||
this._filledTakerAmount[orderHash] = filledTakerAmount;
|
||||
}
|
||||
public deleteFilledTakerAmount(orderHash: string): void {
|
||||
delete this._filledTakerAmount[orderHash];
|
||||
}
|
||||
public async getCancelledTakerAmountAsync(orderHash: string): Promise<BigNumber> {
|
||||
if (_.isUndefined(this._cancelledTakerAmount[orderHash])) {
|
||||
const methodOpts = {
|
||||
defaultBlock: this._defaultBlock,
|
||||
};
|
||||
const cancelledTakerAmount = await this._exchangeWrapper.getCancelledTakerAmountAsync(
|
||||
orderHash,
|
||||
methodOpts,
|
||||
);
|
||||
this.setCancelledTakerAmount(orderHash, cancelledTakerAmount);
|
||||
}
|
||||
const cachedCancelled = this._cancelledTakerAmount[orderHash];
|
||||
return cachedCancelled;
|
||||
}
|
||||
public setCancelledTakerAmount(orderHash: string, cancelledTakerAmount: BigNumber): void {
|
||||
this._cancelledTakerAmount[orderHash] = cancelledTakerAmount;
|
||||
}
|
||||
public deleteCancelledTakerAmount(orderHash: string): void {
|
||||
delete this._cancelledTakerAmount[orderHash];
|
||||
}
|
||||
public deleteAll(): void {
|
||||
this._filledTakerAmount = {};
|
||||
this._cancelledTakerAmount = {};
|
||||
}
|
||||
public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
|
||||
const unavailableTakerAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
||||
return unavailableTakerAmount;
|
||||
}
|
||||
public getZRXTokenAddress(): string {
|
||||
const zrxToken = this._exchangeWrapper.getZRXTokenAddress();
|
||||
return zrxToken;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,25 @@
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
|
||||
import {
|
||||
BlockParam,
|
||||
ContractEventArg,
|
||||
LogEntryEvent,
|
||||
LogWithDecodedArgs,
|
||||
Order,
|
||||
OrderState,
|
||||
SignedOrder,
|
||||
} from '@0xproject/types';
|
||||
import { OrderState, SignedOrder } from '@0xproject/types';
|
||||
import { BlockParam, ContractEventArg, DecodedLogArgs, LogEntryEvent, LogWithDecodedArgs } from 'ethereum-types';
|
||||
|
||||
import { EtherTokenContractEventArgs, EtherTokenEvents } from './contract_wrappers/generated/ether_token';
|
||||
import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/generated/exchange';
|
||||
import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token';
|
||||
import { ERC20TokenEventArgs, ERC20TokenEvents } from './contract_wrappers/generated/erc20_token';
|
||||
import { ERC721TokenEventArgs, ERC721TokenEvents } from './contract_wrappers/generated/erc721_token';
|
||||
import { ExchangeEventArgs, ExchangeEvents } from './contract_wrappers/generated/exchange';
|
||||
import { WETH9EventArgs, WETH9Events } from './contract_wrappers/generated/weth9';
|
||||
|
||||
export enum ExchangeWrapperError {
|
||||
AssetDataMismatch = 'ASSET_DATA_MISMATCH',
|
||||
}
|
||||
|
||||
export enum ContractWrappersError {
|
||||
ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
|
||||
ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
|
||||
EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
|
||||
TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
|
||||
TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
|
||||
TokenContractDoesNotExist = 'TOKEN_CONTRACT_DOES_NOT_EXIST',
|
||||
ERC20ProxyContractDoesNotExist = 'ERC20_PROXY_CONTRACT_DOES_NOT_EXIST',
|
||||
ERC721ProxyContractDoesNotExist = 'ERC721_PROXY_CONTRACT_DOES_NOT_EXIST',
|
||||
ERC20TokenContractDoesNotExist = 'ERC20_TOKEN_CONTRACT_DOES_NOT_EXIST',
|
||||
ERC721TokenContractDoesNotExist = 'ERC721_TOKEN_CONTRACT_DOES_NOT_EXIST',
|
||||
ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
|
||||
InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
|
||||
InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER',
|
||||
@@ -30,30 +29,24 @@ export enum ContractWrappersError {
|
||||
OutOfGas = 'OUT_OF_GAS',
|
||||
SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND',
|
||||
SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
|
||||
ERC721OwnerNotFound = 'ERC_721_OWNER_NOT_FOUND',
|
||||
ERC721NoApproval = 'ERC_721_NO_APPROVAL',
|
||||
}
|
||||
|
||||
export enum InternalContractWrappersError {
|
||||
NoAbiDecoder = 'NO_ABI_DECODER',
|
||||
ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY',
|
||||
WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
|
||||
}
|
||||
|
||||
export type LogEvent = LogEntryEvent;
|
||||
export interface DecodedLogEvent<ArgsType> {
|
||||
export interface DecodedLogEvent<ArgsType extends DecodedLogArgs> {
|
||||
isRemoved: boolean;
|
||||
log: LogWithDecodedArgs<ArgsType>;
|
||||
}
|
||||
|
||||
export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void;
|
||||
|
||||
export enum ExchangeContractErrCodes {
|
||||
ERROR_FILL_EXPIRED, // Order has already expired
|
||||
ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled
|
||||
ERROR_FILL_TRUNCATION, // Rounding error too large
|
||||
ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer
|
||||
ERROR_CANCEL_EXPIRED, // Order has already expired
|
||||
ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled
|
||||
}
|
||||
export type EventCallback<ArgsType extends DecodedLogArgs> = (
|
||||
err: null | Error,
|
||||
log?: DecodedLogEvent<ArgsType>,
|
||||
) => void;
|
||||
|
||||
export interface ContractEvent {
|
||||
logIndex: number;
|
||||
@@ -67,7 +60,7 @@ export interface ContractEvent {
|
||||
args: ContractEventArgs;
|
||||
}
|
||||
|
||||
export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
|
||||
export type ContractEventArgs = ExchangeEventArgs | ERC20TokenEventArgs | ERC721TokenEventArgs | WETH9EventArgs;
|
||||
|
||||
// [address, name, symbol, decimals, ipfsHash, swarmHash]
|
||||
export type TokenMetadata = [string, string, string, number, string, string];
|
||||
@@ -90,7 +83,7 @@ export interface TokenAddressBySymbol {
|
||||
[symbol: string]: string;
|
||||
}
|
||||
|
||||
export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents;
|
||||
export type ContractEvents = ERC20TokenEvents | ERC721TokenEvents | ExchangeEvents | WETH9Events;
|
||||
|
||||
export interface IndexedFilterValues {
|
||||
[index: string]: ContractEventArg;
|
||||
@@ -101,14 +94,9 @@ export interface BlockRange {
|
||||
toBlock: BlockParam;
|
||||
}
|
||||
|
||||
export interface OrderCancellationRequest {
|
||||
order: Order | SignedOrder;
|
||||
takerTokenCancelAmount: BigNumber;
|
||||
}
|
||||
|
||||
export interface OrderFillRequest {
|
||||
signedOrder: SignedOrder;
|
||||
takerTokenFillAmount: BigNumber;
|
||||
takerAssetFillAmount: BigNumber;
|
||||
}
|
||||
|
||||
export type AsyncMethod = (...args: any[]) => Promise<any>;
|
||||
@@ -119,17 +107,19 @@ export type SyncMethod = (...args: any[]) => any;
|
||||
* gasPrice: Gas price to use with every transaction
|
||||
* exchangeContractAddress: The address of an exchange contract to use
|
||||
* zrxContractAddress: The address of the ZRX contract to use
|
||||
* tokenRegistryContractAddress: The address of a token registry contract to use
|
||||
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
|
||||
* erc20ProxyContractAddress: The address of the erc20 token transfer proxy contract to use
|
||||
* erc721ProxyContractAddress: The address of the erc721 token transfer proxy contract to use
|
||||
* orderWatcherConfig: All the configs related to the orderWatcher
|
||||
* blockPollingIntervalMs: The interval to use for block polling in event watching methods (defaults to 1000)
|
||||
*/
|
||||
export interface ContractWrappersConfig {
|
||||
networkId: number;
|
||||
gasPrice?: BigNumber;
|
||||
exchangeContractAddress?: string;
|
||||
zrxContractAddress?: string;
|
||||
tokenRegistryContractAddress?: string;
|
||||
tokenTransferProxyContractAddress?: string;
|
||||
erc20ProxyContractAddress?: string;
|
||||
erc721ProxyContractAddress?: string;
|
||||
blockPollingIntervalMs?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,3 +170,19 @@ export enum TransferType {
|
||||
}
|
||||
|
||||
export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void;
|
||||
|
||||
export interface OrderInfo {
|
||||
orderStatus: number;
|
||||
orderHash: string;
|
||||
orderTakerAssetFilledAmount: BigNumber;
|
||||
}
|
||||
|
||||
export enum OrderStatus {
|
||||
INVALID,
|
||||
INVALID_MAKER_ASSET_AMOUNT,
|
||||
INVALID_TAKER_ASSET_AMOUNT,
|
||||
FILLABLE,
|
||||
EXPIRED,
|
||||
FULLY_FILLED,
|
||||
CANCELLED,
|
||||
}
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
import { assert as sharedAssert } from '@0xproject/assert';
|
||||
// We need those two unused imports because they're actually used by sharedAssert which gets injected here
|
||||
// tslint:disable:no-unused-variable
|
||||
import { Schema } from '@0xproject/json-schemas';
|
||||
import { ECSignature } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Schema } from '@0xproject/json-schemas'; // tslint:disable-line:no-unused-variable
|
||||
import { isValidSignatureAsync } from '@0xproject/order-utils';
|
||||
import { ECSignature } from '@0xproject/types'; // tslint:disable-line:no-unused-variable
|
||||
import { BigNumber } from '@0xproject/utils'; // tslint:disable-line:no-unused-variable
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
// tslint:enable:no-unused-variable
|
||||
|
||||
import { isValidSignature } from '@0xproject/order-utils';
|
||||
import { Provider } from 'ethereum-types';
|
||||
|
||||
export const assert = {
|
||||
...sharedAssert,
|
||||
isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string): void {
|
||||
const isValid = isValidSignature(orderHash, ecSignature, signerAddress);
|
||||
async isValidSignatureAsync(
|
||||
provider: Provider,
|
||||
orderHash: string,
|
||||
signature: string,
|
||||
signerAddress: string,
|
||||
): Promise<void> {
|
||||
const isValid = await isValidSignatureAsync(provider, orderHash, signature, signerAddress);
|
||||
this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`);
|
||||
},
|
||||
isValidSubscriptionToken(variableName: string, subscriptionToken: string): void {
|
||||
const uuidRegex = new RegExp('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$');
|
||||
const isValid = uuidRegex.test(subscriptionToken);
|
||||
this.assert(isValid, `Expected ${variableName} to be a valid subscription token`);
|
||||
},
|
||||
async isSenderAddressAsync(
|
||||
variableName: string,
|
||||
senderAddressHex: string,
|
||||
|
||||
@@ -4,6 +4,7 @@ export const constants = {
|
||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
TESTRPC_NETWORK_ID: 50,
|
||||
INVALID_JUMP_PATTERN: 'invalid JUMP at',
|
||||
REVERT: 'revert',
|
||||
OUT_OF_GAS_PATTERN: 'out of gas',
|
||||
INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { RevertReason } from '@0xproject/types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { AsyncMethod, ContractWrappersError, SyncMethod } from '../types';
|
||||
@@ -13,6 +14,10 @@ const contractCallErrorTransformer = (error: Error) => {
|
||||
if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) {
|
||||
return new Error(ContractWrappersError.OutOfGas);
|
||||
}
|
||||
if (_.includes(error.message, constants.REVERT)) {
|
||||
const revertReason = error.message.split(constants.REVERT)[1].trim();
|
||||
return new Error(revertReason);
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
@@ -30,8 +35,8 @@ const schemaErrorTransformer = (error: Error) => {
|
||||
*/
|
||||
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||
const asyncErrorHandlingDecorator = (
|
||||
target: object,
|
||||
key: string | symbol,
|
||||
_target: object,
|
||||
_key: string | symbol,
|
||||
descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
||||
) => {
|
||||
const originalMethod = descriptor.value as AsyncMethod;
|
||||
@@ -57,8 +62,8 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||
|
||||
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||
const syncErrorHandlingDecorator = (
|
||||
target: object,
|
||||
key: string | symbol,
|
||||
_target: object,
|
||||
_key: string | symbol,
|
||||
descriptor: TypedPropertyDescriptor<SyncMethod>,
|
||||
) => {
|
||||
const originalMethod = descriptor.value as SyncMethod;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { BlockParamLiteral, ExchangeContractErrs } from '@0xproject/types';
|
||||
import { ExchangeContractErrs } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
|
||||
import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store';
|
||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||
import { TradeSide, TransferType } from '../types';
|
||||
import { constants } from '../utils/constants';
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
// tslint:disable:no-unused-variable
|
||||
import {
|
||||
ConstructorAbi,
|
||||
ContractAbi,
|
||||
EventAbi,
|
||||
FallbackAbi,
|
||||
FilterObject,
|
||||
LogEntry,
|
||||
MethodAbi,
|
||||
} from '@0xproject/types';
|
||||
// tslint:enable:no-unused-variable
|
||||
import { ConstructorAbi, ContractAbi, EventAbi, FallbackAbi, FilterObject, LogEntry, MethodAbi } from 'ethereum-types';
|
||||
import * as ethUtil from 'ethereumjs-util';
|
||||
import * as jsSHA3 from 'js-sha3';
|
||||
import * as _ from 'lodash';
|
||||
@@ -30,7 +20,7 @@ export const filterUtils = {
|
||||
blockRange?: BlockRange,
|
||||
): FilterObject {
|
||||
const eventAbi = _.find(abi, { name: eventName }) as EventAbi;
|
||||
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName);
|
||||
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi);
|
||||
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
||||
const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues);
|
||||
const topics = [topicForEventSignature, ...topicsForIndexedArgs];
|
||||
@@ -46,7 +36,7 @@ export const filterUtils = {
|
||||
}
|
||||
return filter;
|
||||
},
|
||||
getEventSignatureFromAbiByName(eventAbi: EventAbi, eventName: ContractEvents): string {
|
||||
getEventSignatureFromAbiByName(eventAbi: EventAbi): string {
|
||||
const types = _.map(eventAbi.inputs, 'type');
|
||||
const signature = `${eventAbi.name}(${types.join(',')})`;
|
||||
return signature;
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
import { getOrderHashHex, isValidSignature, OrderError } from '@0xproject/order-utils';
|
||||
import { ExchangeContractErrs, Order, SignedOrder } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import { ExchangeContract } from '../contract_wrappers/generated/exchange';
|
||||
import { TradeSide, TransferType } from '../types';
|
||||
import { constants } from '../utils/constants';
|
||||
import { utils } from '../utils/utils';
|
||||
|
||||
import { ExchangeTransferSimulator } from './exchange_transfer_simulator';
|
||||
|
||||
export class OrderValidationUtils {
|
||||
private _exchangeContract: ExchangeContract;
|
||||
public static validateCancelOrderThrowIfInvalid(
|
||||
order: Order,
|
||||
cancelTakerTokenAmount: BigNumber,
|
||||
unavailableTakerTokenAmount: BigNumber,
|
||||
): void {
|
||||
if (cancelTakerTokenAmount.eq(0)) {
|
||||
throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
|
||||
}
|
||||
if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) {
|
||||
throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
|
||||
}
|
||||
const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
|
||||
if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
|
||||
throw new Error(ExchangeContractErrs.OrderCancelExpired);
|
||||
}
|
||||
}
|
||||
public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||
signedOrder: SignedOrder,
|
||||
fillTakerTokenAmount: BigNumber,
|
||||
senderAddress: string,
|
||||
zrxTokenAddress: string,
|
||||
): Promise<void> {
|
||||
const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
|
||||
fillTakerTokenAmount,
|
||||
signedOrder.takerTokenAmount,
|
||||
signedOrder.makerTokenAmount,
|
||||
);
|
||||
await exchangeTradeEmulator.transferFromAsync(
|
||||
signedOrder.makerTokenAddress,
|
||||
signedOrder.maker,
|
||||
senderAddress,
|
||||
fillMakerTokenAmount,
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
await exchangeTradeEmulator.transferFromAsync(
|
||||
signedOrder.takerTokenAddress,
|
||||
senderAddress,
|
||||
signedOrder.maker,
|
||||
fillTakerTokenAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||
fillTakerTokenAmount,
|
||||
signedOrder.takerTokenAmount,
|
||||
signedOrder.makerFee,
|
||||
);
|
||||
await exchangeTradeEmulator.transferFromAsync(
|
||||
zrxTokenAddress,
|
||||
signedOrder.maker,
|
||||
signedOrder.feeRecipient,
|
||||
makerFeeAmount,
|
||||
TradeSide.Maker,
|
||||
TransferType.Fee,
|
||||
);
|
||||
const takerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||
fillTakerTokenAmount,
|
||||
signedOrder.takerTokenAmount,
|
||||
signedOrder.takerFee,
|
||||
);
|
||||
await exchangeTradeEmulator.transferFromAsync(
|
||||
zrxTokenAddress,
|
||||
senderAddress,
|
||||
signedOrder.feeRecipient,
|
||||
takerFeeAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Fee,
|
||||
);
|
||||
}
|
||||
private static _validateRemainingFillAmountNotZeroOrThrow(
|
||||
takerTokenAmount: BigNumber,
|
||||
unavailableTakerTokenAmount: BigNumber,
|
||||
): void {
|
||||
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
|
||||
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||
}
|
||||
}
|
||||
private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber): void {
|
||||
const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
|
||||
if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
|
||||
throw new Error(ExchangeContractErrs.OrderFillExpired);
|
||||
}
|
||||
}
|
||||
private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
|
||||
const fillMakerTokenAmount = numerator
|
||||
.mul(target)
|
||||
.div(denominator)
|
||||
.round(0);
|
||||
return fillMakerTokenAmount;
|
||||
}
|
||||
constructor(exchangeContract: ExchangeContract) {
|
||||
this._exchangeContract = exchangeContract;
|
||||
}
|
||||
public async validateOrderFillableOrThrowAsync(
|
||||
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||
signedOrder: SignedOrder,
|
||||
zrxTokenAddress: string,
|
||||
expectedFillTakerTokenAmount?: BigNumber,
|
||||
): Promise<void> {
|
||||
const orderHash = getOrderHashHex(signedOrder);
|
||||
const unavailableTakerTokenAmount = await this._exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
||||
orderHash,
|
||||
);
|
||||
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
||||
signedOrder.takerTokenAmount,
|
||||
unavailableTakerTokenAmount,
|
||||
);
|
||||
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
||||
let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||
if (!_.isUndefined(expectedFillTakerTokenAmount)) {
|
||||
fillTakerTokenAmount = expectedFillTakerTokenAmount;
|
||||
}
|
||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTradeEmulator,
|
||||
signedOrder,
|
||||
fillTakerTokenAmount,
|
||||
signedOrder.taker,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
}
|
||||
public async validateFillOrderThrowIfInvalidAsync(
|
||||
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||
signedOrder: SignedOrder,
|
||||
fillTakerTokenAmount: BigNumber,
|
||||
takerAddress: string,
|
||||
zrxTokenAddress: string,
|
||||
): Promise<BigNumber> {
|
||||
if (fillTakerTokenAmount.eq(0)) {
|
||||
throw new Error(ExchangeContractErrs.OrderFillAmountZero);
|
||||
}
|
||||
const orderHash = getOrderHashHex(signedOrder);
|
||||
if (!isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) {
|
||||
throw new Error(OrderError.InvalidSignature);
|
||||
}
|
||||
const unavailableTakerTokenAmount = await this._exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
||||
orderHash,
|
||||
);
|
||||
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
||||
signedOrder.takerTokenAmount,
|
||||
unavailableTakerTokenAmount,
|
||||
);
|
||||
if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
|
||||
throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
||||
}
|
||||
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
||||
const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||
const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
|
||||
? remainingTakerTokenAmount
|
||||
: fillTakerTokenAmount;
|
||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTradeEmulator,
|
||||
signedOrder,
|
||||
filledTakerTokenAmount,
|
||||
takerAddress,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
|
||||
const wouldRoundingErrorOccur = await this._exchangeContract.isRoundingError.callAsync(
|
||||
filledTakerTokenAmount,
|
||||
signedOrder.takerTokenAmount,
|
||||
signedOrder.makerTokenAmount,
|
||||
);
|
||||
if (wouldRoundingErrorOccur) {
|
||||
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
||||
}
|
||||
return filledTakerTokenAmount;
|
||||
}
|
||||
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
||||
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||
signedOrder: SignedOrder,
|
||||
fillTakerTokenAmount: BigNumber,
|
||||
takerAddress: string,
|
||||
zrxTokenAddress: string,
|
||||
): Promise<void> {
|
||||
const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
|
||||
exchangeTradeEmulator,
|
||||
signedOrder,
|
||||
fillTakerTokenAmount,
|
||||
takerAddress,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
if (filledTakerTokenAmount !== fillTakerTokenAmount) {
|
||||
throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import { web3Factory } from '@0xproject/dev-utils';
|
||||
import 'make-promises-safe';
|
||||
|
||||
import { ContractWrappers } from '../src';
|
||||
|
||||
@@ -11,7 +10,8 @@ chaiSetup.configure();
|
||||
// Those tests are slower cause they're talking to a remote node
|
||||
const TIMEOUT = 10000;
|
||||
|
||||
describe('Artifacts', () => {
|
||||
// TODO: Re-enable those tests after final kovan and ropsten deployments are done.
|
||||
describe.skip('Artifacts', () => {
|
||||
describe('contracts are deployed on kovan', () => {
|
||||
const kovanRpcUrl = constants.KOVAN_RPC_URL;
|
||||
const provider = web3Factory.getRpcProvider({ rpcUrl: kovanRpcUrl });
|
||||
@@ -19,14 +19,11 @@ describe('Artifacts', () => {
|
||||
networkId: constants.KOVAN_NETWORK_ID,
|
||||
};
|
||||
const contractWrappers = new ContractWrappers(provider, config);
|
||||
it('token registry contract is deployed', async () => {
|
||||
await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync();
|
||||
it('erc20 proxy contract is deployed', async () => {
|
||||
await (contractWrappers.erc20Proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('proxy contract is deployed', async () => {
|
||||
await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('exchange contract is deployed', async () => {
|
||||
await (contractWrappers.exchange as any)._getExchangeContractAsync();
|
||||
it('erc721 proxy contract is deployed', async () => {
|
||||
await (contractWrappers.erc721Proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
});
|
||||
describe('contracts are deployed on ropsten', () => {
|
||||
@@ -36,14 +33,11 @@ describe('Artifacts', () => {
|
||||
networkId: constants.ROPSTEN_NETWORK_ID,
|
||||
};
|
||||
const contractWrappers = new ContractWrappers(provider, config);
|
||||
it('token registry contract is deployed', async () => {
|
||||
await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync();
|
||||
it('erc20 proxy contract is deployed', async () => {
|
||||
await (contractWrappers.erc20Proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('proxy contract is deployed', async () => {
|
||||
await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
it('exchange contract is deployed', async () => {
|
||||
await (contractWrappers.exchange as any)._getExchangeContractAsync();
|
||||
it('erc721 proxy contract is deployed', async () => {
|
||||
await (contractWrappers.erc721Proxy as any)._getTokenTransferProxyContractAsync();
|
||||
}).timeout(TIMEOUT);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import * as chai from 'chai';
|
||||
import 'make-promises-safe';
|
||||
|
||||
import { ContractWrappers } from '../src';
|
||||
|
||||
@@ -10,7 +9,7 @@ import { provider } from './utils/web3_wrapper';
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('TokenTransferProxyWrapper', () => {
|
||||
describe('ERC20ProxyWrapper', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
const config = {
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
@@ -20,15 +19,15 @@ describe('TokenTransferProxyWrapper', () => {
|
||||
});
|
||||
describe('#isAuthorizedAsync', () => {
|
||||
it('should return false if the address is not authorized', async () => {
|
||||
const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
|
||||
const isAuthorized = await contractWrappers.erc20Proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
|
||||
expect(isAuthorized).to.be.false();
|
||||
});
|
||||
});
|
||||
describe('#getAuthorizedAddressesAsync', () => {
|
||||
it('should return the list of authorized addresses', async () => {
|
||||
const authorizedAddresses = await contractWrappers.proxy.getAuthorizedAddressesAsync();
|
||||
const authorizedAddresses = await contractWrappers.erc20Proxy.getAuthorizedAddressesAsync();
|
||||
for (const authorizedAddress of authorizedAddresses) {
|
||||
const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(authorizedAddress);
|
||||
const isAuthorized = await contractWrappers.erc20Proxy.isAuthorizedAsync(authorizedAddress);
|
||||
expect(isAuthorized).to.be.true();
|
||||
}
|
||||
});
|
||||
@@ -1,38 +1,36 @@
|
||||
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
|
||||
import { EmptyWalletSubprovider } from '@0xproject/subproviders';
|
||||
import { DoneCallback, Provider } from '@0xproject/types';
|
||||
import { DoneCallback } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import 'make-promises-safe';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import 'mocha';
|
||||
import Web3ProviderEngine = require('web3-provider-engine');
|
||||
|
||||
import {
|
||||
ApprovalContractEventArgs,
|
||||
BlockParamLiteral,
|
||||
BlockRange,
|
||||
ContractWrappers,
|
||||
ContractWrappersError,
|
||||
DecodedLogEvent,
|
||||
Token,
|
||||
TokenEvents,
|
||||
TransferContractEventArgs,
|
||||
ERC20TokenApprovalEventArgs,
|
||||
ERC20TokenEvents,
|
||||
ERC20TokenTransferEventArgs,
|
||||
} from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { TokenUtils } from './utils/token_utils';
|
||||
import { tokenUtils } from './utils/token_utils';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
describe('TokenWrapper', () => {
|
||||
describe('ERC20Wrapper', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
let userAddresses: string[];
|
||||
let tokens: Token[];
|
||||
let tokenUtils: TokenUtils;
|
||||
let tokens: string[];
|
||||
let coinbase: string;
|
||||
let addressWithoutFunds: string;
|
||||
const config = {
|
||||
@@ -41,8 +39,7 @@ describe('TokenWrapper', () => {
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
|
||||
tokenUtils = new TokenUtils(tokens);
|
||||
tokens = tokenUtils.getDummyERC20TokenAddresses();
|
||||
coinbase = userAddresses[0];
|
||||
addressWithoutFunds = userAddresses[1];
|
||||
});
|
||||
@@ -53,26 +50,26 @@ describe('TokenWrapper', () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
describe('#transferAsync', () => {
|
||||
let token: Token;
|
||||
let tokenAddress: string;
|
||||
let transferAmount: BigNumber;
|
||||
before(() => {
|
||||
token = tokens[0];
|
||||
tokenAddress = tokens[0];
|
||||
transferAmount = new BigNumber(42);
|
||||
});
|
||||
it('should successfully transfer tokens', async () => {
|
||||
const fromAddress = coinbase;
|
||||
const toAddress = addressWithoutFunds;
|
||||
const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
|
||||
const preBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
|
||||
expect(preBalance).to.be.bignumber.equal(0);
|
||||
await contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
|
||||
const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
|
||||
await contractWrappers.erc20Token.transferAsync(tokenAddress, fromAddress, toAddress, transferAmount);
|
||||
const postBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
|
||||
return expect(postBalance).to.be.bignumber.equal(transferAmount);
|
||||
});
|
||||
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
|
||||
const fromAddress = addressWithoutFunds;
|
||||
const toAddress = coinbase;
|
||||
return expect(
|
||||
contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
|
||||
contractWrappers.erc20Token.transferAsync(tokenAddress, fromAddress, toAddress, transferAmount),
|
||||
).to.be.rejectedWith(ContractWrappersError.InsufficientBalanceForTransfer);
|
||||
});
|
||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||
@@ -80,16 +77,21 @@ describe('TokenWrapper', () => {
|
||||
const fromAddress = coinbase;
|
||||
const toAddress = coinbase;
|
||||
return expect(
|
||||
contractWrappers.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
|
||||
).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
|
||||
contractWrappers.erc20Token.transferAsync(
|
||||
nonExistentTokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
transferAmount,
|
||||
),
|
||||
).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist);
|
||||
});
|
||||
});
|
||||
describe('#transferFromAsync', () => {
|
||||
let token: Token;
|
||||
let tokenAddress: string;
|
||||
let toAddress: string;
|
||||
let senderAddress: string;
|
||||
before(async () => {
|
||||
token = tokens[0];
|
||||
tokenAddress = tokens[0];
|
||||
toAddress = addressWithoutFunds;
|
||||
senderAddress = userAddresses[2];
|
||||
});
|
||||
@@ -97,19 +99,19 @@ describe('TokenWrapper', () => {
|
||||
const fromAddress = coinbase;
|
||||
const transferAmount = new BigNumber(42);
|
||||
|
||||
const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress);
|
||||
const fromAddressBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, fromAddress);
|
||||
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
|
||||
|
||||
const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
const fromAddressAllowance = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
);
|
||||
expect(fromAddressAllowance).to.be.bignumber.equal(0);
|
||||
|
||||
return expect(
|
||||
contractWrappers.token.transferFromAsync(
|
||||
token.address,
|
||||
contractWrappers.erc20Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
senderAddress,
|
||||
@@ -121,11 +123,11 @@ describe('TokenWrapper', () => {
|
||||
const fromAddress = coinbase;
|
||||
const transferAmount = new BigNumber(42);
|
||||
|
||||
await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(tokenAddress, fromAddress, toAddress, transferAmount);
|
||||
|
||||
return expect(
|
||||
contractWrappers.token.transferFromAsync(
|
||||
token.address,
|
||||
contractWrappers.erc20Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
senderAddress,
|
||||
@@ -137,20 +139,25 @@ describe('TokenWrapper', () => {
|
||||
const fromAddress = addressWithoutFunds;
|
||||
const transferAmount = new BigNumber(42);
|
||||
|
||||
const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress);
|
||||
const fromAddressBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, fromAddress);
|
||||
expect(fromAddressBalance).to.be.bignumber.equal(0);
|
||||
|
||||
await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
||||
const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
senderAddress,
|
||||
transferAmount,
|
||||
);
|
||||
const fromAddressAllowance = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
senderAddress,
|
||||
);
|
||||
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
|
||||
|
||||
return expect(
|
||||
contractWrappers.token.transferFromAsync(
|
||||
token.address,
|
||||
contractWrappers.erc20Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
senderAddress,
|
||||
@@ -161,42 +168,47 @@ describe('TokenWrapper', () => {
|
||||
it('should successfully transfer tokens', async () => {
|
||||
const fromAddress = coinbase;
|
||||
|
||||
const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
|
||||
const preBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
|
||||
expect(preBalance).to.be.bignumber.equal(0);
|
||||
|
||||
const transferAmount = new BigNumber(42);
|
||||
await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
senderAddress,
|
||||
transferAmount,
|
||||
);
|
||||
|
||||
await contractWrappers.token.transferFromAsync(
|
||||
token.address,
|
||||
await contractWrappers.erc20Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
senderAddress,
|
||||
transferAmount,
|
||||
);
|
||||
const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
|
||||
const postBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
|
||||
return expect(postBalance).to.be.bignumber.equal(transferAmount);
|
||||
});
|
||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||
const fromAddress = coinbase;
|
||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||
return expect(
|
||||
contractWrappers.token.transferFromAsync(
|
||||
contractWrappers.erc20Token.transferFromAsync(
|
||||
nonExistentTokenAddress,
|
||||
fromAddress,
|
||||
toAddress,
|
||||
senderAddress,
|
||||
new BigNumber(42),
|
||||
),
|
||||
).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
|
||||
).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist);
|
||||
});
|
||||
});
|
||||
describe('#getBalanceAsync', () => {
|
||||
describe('With provider with accounts', () => {
|
||||
it('should return the balance for an existing ERC20 token', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const balance = await contractWrappers.token.getBalanceAsync(token.address, ownerAddress);
|
||||
const balance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, ownerAddress);
|
||||
const expectedBalance = new BigNumber('1000000000000000000000000000');
|
||||
return expect(balance).to.be.bignumber.equal(expectedBalance);
|
||||
});
|
||||
@@ -204,13 +216,13 @@ describe('TokenWrapper', () => {
|
||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||
const ownerAddress = coinbase;
|
||||
return expect(
|
||||
contractWrappers.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress),
|
||||
).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
|
||||
contractWrappers.erc20Token.getBalanceAsync(nonExistentTokenAddress, ownerAddress),
|
||||
).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist);
|
||||
});
|
||||
it('should return a balance of 0 for a non-existent owner address', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
|
||||
const balance = await contractWrappers.token.getBalanceAsync(token.address, nonExistentOwner);
|
||||
const balance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, nonExistentOwner);
|
||||
const expectedBalance = new BigNumber(0);
|
||||
return expect(balance).to.be.bignumber.equal(expectedBalance);
|
||||
});
|
||||
@@ -222,9 +234,12 @@ describe('TokenWrapper', () => {
|
||||
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
|
||||
});
|
||||
it('should return balance even when called with provider instance without addresses', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const balance = await zeroExContractWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
|
||||
const balance = await zeroExContractWithoutAccounts.erc20Token.getBalanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
);
|
||||
const expectedBalance = new BigNumber('1000000000000000000000000000');
|
||||
return expect(balance).to.be.bignumber.equal(expectedBalance);
|
||||
});
|
||||
@@ -232,12 +247,12 @@ describe('TokenWrapper', () => {
|
||||
});
|
||||
describe('#setAllowanceAsync', () => {
|
||||
it("should set the spender's allowance", async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const spenderAddress = addressWithoutFunds;
|
||||
|
||||
const allowanceBeforeSet = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
const allowanceBeforeSet = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
);
|
||||
@@ -245,15 +260,15 @@ describe('TokenWrapper', () => {
|
||||
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
|
||||
|
||||
const amountInBaseUnits = new BigNumber(50);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
token.address,
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
amountInBaseUnits,
|
||||
);
|
||||
|
||||
const allowanceAfterSet = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
const allowanceAfterSet = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
);
|
||||
@@ -263,44 +278,50 @@ describe('TokenWrapper', () => {
|
||||
});
|
||||
describe('#setUnlimitedAllowanceAsync', () => {
|
||||
it("should set the unlimited spender's allowance", async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const spenderAddress = addressWithoutFunds;
|
||||
|
||||
await contractWrappers.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
|
||||
const allowance = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
await contractWrappers.erc20Token.setUnlimitedAllowanceAsync(tokenAddress, ownerAddress, spenderAddress);
|
||||
const allowance = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
);
|
||||
return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
return expect(allowance).to.be.bignumber.equal(
|
||||
contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||
);
|
||||
});
|
||||
it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
|
||||
const transferAmount = new BigNumber(5);
|
||||
const zrx = tokenUtils.getProtocolTokenOrThrow();
|
||||
const zrxAddress = tokenUtils.getProtocolTokenAddress();
|
||||
const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
zrx.address,
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
zrxAddress,
|
||||
coinbase,
|
||||
userWithNormalAllowance,
|
||||
transferAmount,
|
||||
);
|
||||
await contractWrappers.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
|
||||
await contractWrappers.erc20Token.setUnlimitedAllowanceAsync(
|
||||
zrxAddress,
|
||||
coinbase,
|
||||
userWithUnlimitedAllowance,
|
||||
);
|
||||
|
||||
const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
|
||||
const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
|
||||
userWithUnlimitedAllowance,
|
||||
);
|
||||
|
||||
await contractWrappers.token.transferFromAsync(
|
||||
zrx.address,
|
||||
await contractWrappers.erc20Token.transferFromAsync(
|
||||
zrxAddress,
|
||||
coinbase,
|
||||
userWithNormalAllowance,
|
||||
userWithNormalAllowance,
|
||||
transferAmount,
|
||||
);
|
||||
await contractWrappers.token.transferFromAsync(
|
||||
zrx.address,
|
||||
await contractWrappers.erc20Token.transferFromAsync(
|
||||
zrxAddress,
|
||||
coinbase,
|
||||
userWithUnlimitedAllowance,
|
||||
userWithUnlimitedAllowance,
|
||||
@@ -324,20 +345,20 @@ describe('TokenWrapper', () => {
|
||||
describe('#getAllowanceAsync', () => {
|
||||
describe('With provider with accounts', () => {
|
||||
it('should get the proxy allowance', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const spenderAddress = addressWithoutFunds;
|
||||
|
||||
const amountInBaseUnits = new BigNumber(50);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
token.address,
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
amountInBaseUnits,
|
||||
);
|
||||
|
||||
const allowance = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
const allowance = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
);
|
||||
@@ -345,11 +366,11 @@ describe('TokenWrapper', () => {
|
||||
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
|
||||
});
|
||||
it('should return 0 if no allowance set yet', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const spenderAddress = addressWithoutFunds;
|
||||
const allowance = await contractWrappers.token.getAllowanceAsync(
|
||||
token.address,
|
||||
const allowance = await contractWrappers.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
);
|
||||
@@ -364,20 +385,20 @@ describe('TokenWrapper', () => {
|
||||
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
|
||||
});
|
||||
it('should get the proxy allowance', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
const spenderAddress = addressWithoutFunds;
|
||||
|
||||
const amountInBaseUnits = new BigNumber(50);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
token.address,
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
amountInBaseUnits,
|
||||
);
|
||||
|
||||
const allowance = await zeroExContractWithoutAccounts.token.getAllowanceAsync(
|
||||
token.address,
|
||||
const allowance = await zeroExContractWithoutAccounts.erc20Token.getAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
spenderAddress,
|
||||
);
|
||||
@@ -388,42 +409,50 @@ describe('TokenWrapper', () => {
|
||||
});
|
||||
describe('#getProxyAllowanceAsync', () => {
|
||||
it('should get the proxy allowance', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
|
||||
const amountInBaseUnits = new BigNumber(50);
|
||||
await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
|
||||
await contractWrappers.erc20Token.setProxyAllowanceAsync(tokenAddress, ownerAddress, amountInBaseUnits);
|
||||
|
||||
const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
|
||||
const allowance = await contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
|
||||
const expectedAllowance = amountInBaseUnits;
|
||||
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
|
||||
});
|
||||
});
|
||||
describe('#setProxyAllowanceAsync', () => {
|
||||
it('should set the proxy allowance', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
|
||||
const allowanceBeforeSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
|
||||
const allowanceBeforeSet = await contractWrappers.erc20Token.getProxyAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
);
|
||||
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
|
||||
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
|
||||
|
||||
const amountInBaseUnits = new BigNumber(50);
|
||||
await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
|
||||
await contractWrappers.erc20Token.setProxyAllowanceAsync(tokenAddress, ownerAddress, amountInBaseUnits);
|
||||
|
||||
const allowanceAfterSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
|
||||
const allowanceAfterSet = await contractWrappers.erc20Token.getProxyAllowanceAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
);
|
||||
const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
|
||||
return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
|
||||
});
|
||||
});
|
||||
describe('#setUnlimitedProxyAllowanceAsync', () => {
|
||||
it('should set the unlimited proxy allowance', async () => {
|
||||
const token = tokens[0];
|
||||
const tokenAddress = tokens[0];
|
||||
const ownerAddress = coinbase;
|
||||
|
||||
await contractWrappers.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
|
||||
const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
|
||||
return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, ownerAddress);
|
||||
const allowance = await contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
|
||||
return expect(allowance).to.be.bignumber.equal(
|
||||
contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('#subscribe', () => {
|
||||
@@ -432,11 +461,10 @@ describe('TokenWrapper', () => {
|
||||
const transferAmount = new BigNumber(42);
|
||||
const allowanceAmount = new BigNumber(42);
|
||||
before(() => {
|
||||
const token = tokens[0];
|
||||
tokenAddress = token.address;
|
||||
tokenAddress = tokens[0];
|
||||
});
|
||||
afterEach(() => {
|
||||
contractWrappers.token.unsubscribeAll();
|
||||
contractWrappers.erc20Token.unsubscribeAll();
|
||||
});
|
||||
// Hack: Mocha does not allow a test to be both async and have a `done` callback
|
||||
// Since we need to await the receipt of the event in the `subscribe` callback,
|
||||
@@ -446,7 +474,7 @@ describe('TokenWrapper', () => {
|
||||
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
|
||||
(logEvent: DecodedLogEvent<ERC20TokenTransferEventArgs>) => {
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
expect(logEvent.log.logIndex).to.be.equal(0);
|
||||
expect(logEvent.log.transactionIndex).to.be.equal(0);
|
||||
@@ -457,14 +485,24 @@ describe('TokenWrapper', () => {
|
||||
expect(args._value).to.be.bignumber.equal(transferAmount);
|
||||
},
|
||||
);
|
||||
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
|
||||
await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Transfer,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.erc20Token.transferAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
transferAmount,
|
||||
);
|
||||
})().catch(done);
|
||||
});
|
||||
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||
(logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => {
|
||||
expect(logEvent).to.not.be.undefined();
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
const args = logEvent.log.args;
|
||||
@@ -473,8 +511,13 @@ describe('TokenWrapper', () => {
|
||||
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
||||
},
|
||||
);
|
||||
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
@@ -485,42 +528,52 @@ describe('TokenWrapper', () => {
|
||||
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||
(_logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => {
|
||||
done(new Error('Expected this subscription to have been cancelled'));
|
||||
},
|
||||
);
|
||||
contractWrappers.token.subscribe(
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
TokenEvents.Transfer,
|
||||
ERC20TokenEvents.Transfer,
|
||||
indexFilterValues,
|
||||
callbackNeverToBeCalled,
|
||||
);
|
||||
const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)();
|
||||
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
|
||||
contractWrappers.token.subscribe(
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
TokenEvents.Transfer,
|
||||
ERC20TokenEvents.Transfer,
|
||||
indexFilterValues,
|
||||
callbackToBeCalled,
|
||||
);
|
||||
await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||
await contractWrappers.erc20Token.transferAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
transferAmount,
|
||||
);
|
||||
})().catch(done);
|
||||
});
|
||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||
(_logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => {
|
||||
done(new Error('Expected this subscription to have been cancelled'));
|
||||
},
|
||||
);
|
||||
const subscriptionToken = contractWrappers.token.subscribe(
|
||||
const subscriptionToken = contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
TokenEvents.Transfer,
|
||||
ERC20TokenEvents.Transfer,
|
||||
indexFilterValues,
|
||||
callbackNeverToBeCalled,
|
||||
);
|
||||
contractWrappers.token.unsubscribe(subscriptionToken);
|
||||
await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||
contractWrappers.erc20Token.unsubscribe(subscriptionToken);
|
||||
await contractWrappers.erc20Token.transferAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
transferAmount,
|
||||
);
|
||||
done();
|
||||
})().catch(done);
|
||||
});
|
||||
@@ -534,16 +587,15 @@ describe('TokenWrapper', () => {
|
||||
};
|
||||
let txHash: string;
|
||||
before(() => {
|
||||
const token = tokens[0];
|
||||
tokenAddress = token.address;
|
||||
tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress();
|
||||
tokenAddress = tokens[0];
|
||||
tokenTransferProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
|
||||
});
|
||||
it('should get logs with decoded args emitted by Approval', async () => {
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const eventName = TokenEvents.Approval;
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const eventName = ERC20TokenEvents.Approval;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
|
||||
const logs = await contractWrappers.erc20Token.getLogsAsync<ERC20TokenApprovalEventArgs>(
|
||||
tokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
@@ -554,14 +606,14 @@ describe('TokenWrapper', () => {
|
||||
expect(logs[0].event).to.be.equal(eventName);
|
||||
expect(args._owner).to.be.equal(coinbase);
|
||||
expect(args._spender).to.be.equal(tokenTransferProxyAddress);
|
||||
expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
});
|
||||
it('should only get the logs with the correct event name', async () => {
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const differentEventName = TokenEvents.Transfer;
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const differentEventName = ERC20TokenEvents.Transfer;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.token.getLogsAsync(
|
||||
const logs = await contractWrappers.erc20Token.getLogsAsync(
|
||||
tokenAddress,
|
||||
differentEventName,
|
||||
blockRange,
|
||||
@@ -570,15 +622,18 @@ describe('TokenWrapper', () => {
|
||||
expect(logs).to.have.length(0);
|
||||
});
|
||||
it('should only get the logs with the correct indexed fields', async () => {
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const eventName = TokenEvents.Approval;
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
|
||||
tokenAddress,
|
||||
addressWithoutFunds,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const eventName = ERC20TokenEvents.Approval;
|
||||
const indexFilterValues = {
|
||||
_owner: coinbase,
|
||||
};
|
||||
const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
|
||||
const logs = await contractWrappers.erc20Token.getLogsAsync<ERC20TokenApprovalEventArgs>(
|
||||
tokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
35
packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts
Normal file
35
packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import * as chai from 'chai';
|
||||
|
||||
import { ContractWrappers } from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { provider } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
describe('ERC721ProxyWrapper', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
const config = {
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
};
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
});
|
||||
describe('#isAuthorizedAsync', () => {
|
||||
it('should return false if the address is not authorized', async () => {
|
||||
const isAuthorized = await contractWrappers.erc721Proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
|
||||
expect(isAuthorized).to.be.false();
|
||||
});
|
||||
});
|
||||
describe('#getAuthorizedAddressesAsync', () => {
|
||||
it('should return the list of authorized addresses', async () => {
|
||||
const authorizedAddresses = await contractWrappers.erc721Proxy.getAuthorizedAddressesAsync();
|
||||
for (const authorizedAddress of authorizedAddresses) {
|
||||
const isAuthorized = await contractWrappers.erc721Proxy.isAuthorizedAsync(authorizedAddress);
|
||||
expect(isAuthorized).to.be.true();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
472
packages/contract-wrappers/test/erc721_wrapper_test.ts
Normal file
472
packages/contract-wrappers/test/erc721_wrapper_test.ts
Normal file
@@ -0,0 +1,472 @@
|
||||
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
|
||||
import { EmptyWalletSubprovider } from '@0xproject/subproviders';
|
||||
import { DoneCallback } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import { Provider } from 'ethereum-types';
|
||||
import 'mocha';
|
||||
import Web3ProviderEngine = require('web3-provider-engine');
|
||||
|
||||
import {
|
||||
BlockParamLiteral,
|
||||
BlockRange,
|
||||
ContractWrappers,
|
||||
ContractWrappersError,
|
||||
DecodedLogEvent,
|
||||
ERC721TokenApprovalEventArgs,
|
||||
ERC721TokenApprovalForAllEventArgs,
|
||||
ERC721TokenEvents,
|
||||
ERC721TokenTransferEventArgs,
|
||||
} from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { tokenUtils } from './utils/token_utils';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
describe('ERC721Wrapper', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
let userAddresses: string[];
|
||||
let tokens: string[];
|
||||
let ownerAddress: string;
|
||||
let tokenAddress: string;
|
||||
let anotherOwnerAddress: string;
|
||||
let operatorAddress: string;
|
||||
let approvedAddress: string;
|
||||
let receiverAddress: string;
|
||||
const config = {
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
};
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
tokens = tokenUtils.getDummyERC721TokenAddresses();
|
||||
tokenAddress = tokens[0];
|
||||
[ownerAddress, operatorAddress, anotherOwnerAddress, approvedAddress, receiverAddress] = userAddresses;
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
describe('#transferFromAsync', () => {
|
||||
it('should fail to transfer NFT if fromAddress has no approvals set', async () => {
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
return expect(
|
||||
contractWrappers.erc721Token.transferFromAsync(tokenAddress, receiverAddress, approvedAddress, tokenId),
|
||||
).to.be.rejectedWith(ContractWrappersError.ERC721NoApproval);
|
||||
});
|
||||
it('should successfully transfer tokens when sender is an approved address', async () => {
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
let txHash = await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const owner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
expect(owner).to.be.equal(ownerAddress);
|
||||
txHash = await contractWrappers.erc721Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
receiverAddress,
|
||||
approvedAddress,
|
||||
tokenId,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const newOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
expect(newOwner).to.be.equal(receiverAddress);
|
||||
});
|
||||
it('should successfully transfer tokens when sender is an approved operator', async () => {
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
const isApprovedForAll = true;
|
||||
let txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const owner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
expect(owner).to.be.equal(ownerAddress);
|
||||
txHash = await contractWrappers.erc721Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
receiverAddress,
|
||||
operatorAddress,
|
||||
tokenId,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const newOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
expect(newOwner).to.be.equal(receiverAddress);
|
||||
});
|
||||
});
|
||||
describe('#getTokenCountAsync', () => {
|
||||
describe('With provider with accounts', () => {
|
||||
it('should return the count for an existing ERC721 token', async () => {
|
||||
let tokenCount = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, ownerAddress);
|
||||
expect(tokenCount).to.be.bignumber.equal(0);
|
||||
await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
tokenCount = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, ownerAddress);
|
||||
expect(tokenCount).to.be.bignumber.equal(1);
|
||||
});
|
||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||
return expect(
|
||||
contractWrappers.erc721Token.getTokenCountAsync(nonExistentTokenAddress, ownerAddress),
|
||||
).to.be.rejectedWith(ContractWrappersError.ERC721TokenContractDoesNotExist);
|
||||
});
|
||||
it('should return a balance of 0 for a non-existent owner address', async () => {
|
||||
const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
|
||||
const balance = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, nonExistentOwner);
|
||||
const expectedBalance = new BigNumber(0);
|
||||
return expect(balance).to.be.bignumber.equal(expectedBalance);
|
||||
});
|
||||
});
|
||||
describe('With provider without accounts', () => {
|
||||
let zeroExContractWithoutAccounts: ContractWrappers;
|
||||
before(async () => {
|
||||
const emptyWalletProvider = addEmptyWalletSubprovider(provider);
|
||||
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
|
||||
});
|
||||
it('should return balance even when called with provider instance without addresses', async () => {
|
||||
const balance = await zeroExContractWithoutAccounts.erc721Token.getTokenCountAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
);
|
||||
return expect(balance).to.be.bignumber.equal(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#getOwnerOfAsync', () => {
|
||||
it('should return the owner for an existing ERC721 token', async () => {
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
const tokenOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
|
||||
expect(tokenOwner).to.be.bignumber.equal(ownerAddress);
|
||||
});
|
||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||
const fakeTokenId = new BigNumber(42);
|
||||
return expect(
|
||||
contractWrappers.erc721Token.getOwnerOfAsync(nonExistentTokenAddress, fakeTokenId),
|
||||
).to.be.rejectedWith(ContractWrappersError.ERC721TokenContractDoesNotExist);
|
||||
});
|
||||
it('should return undefined not 0 for a non-existent ERC721', async () => {
|
||||
const fakeTokenId = new BigNumber(42);
|
||||
return expect(contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, fakeTokenId)).to.be.rejectedWith(
|
||||
ContractWrappersError.ERC721OwnerNotFound,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('#setApprovalForAllAsync/isApprovedForAllAsync', () => {
|
||||
it('should check if operator address is approved', async () => {
|
||||
let isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
);
|
||||
expect(isApprovedForAll).to.be.false();
|
||||
// set
|
||||
isApprovedForAll = true;
|
||||
let txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
);
|
||||
expect(isApprovedForAll).to.be.true();
|
||||
// unset
|
||||
txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
false,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
);
|
||||
expect(isApprovedForAll).to.be.false();
|
||||
});
|
||||
});
|
||||
describe('#setProxyApprovalForAllAsync/isProxyApprovedForAllAsync', () => {
|
||||
it('should check if proxy address is approved', async () => {
|
||||
let isApprovedForAll = true;
|
||||
const txHash = await contractWrappers.erc721Token.setProxyApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
isApprovedForAll = await contractWrappers.erc721Token.isProxyApprovedForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
);
|
||||
expect(isApprovedForAll).to.be.true();
|
||||
});
|
||||
});
|
||||
describe('#setApprovalAsync/getApprovedIfExistsAsync', () => {
|
||||
it("should set the spender's approval", async () => {
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
|
||||
const approvalBeforeSet = await contractWrappers.erc721Token.getApprovedIfExistsAsync(
|
||||
tokenAddress,
|
||||
tokenId,
|
||||
);
|
||||
expect(approvalBeforeSet).to.be.undefined();
|
||||
await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId);
|
||||
const approvalAfterSet = await contractWrappers.erc721Token.getApprovedIfExistsAsync(tokenAddress, tokenId);
|
||||
expect(approvalAfterSet).to.be.equal(approvedAddress);
|
||||
});
|
||||
});
|
||||
describe('#setProxyApprovalAsync/isProxyApprovedAsync', () => {
|
||||
it('should set the proxy approval', async () => {
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
|
||||
const approvalBeforeSet = await contractWrappers.erc721Token.isProxyApprovedAsync(tokenAddress, tokenId);
|
||||
expect(approvalBeforeSet).to.be.false();
|
||||
await contractWrappers.erc721Token.setProxyApprovalAsync(tokenAddress, tokenId);
|
||||
const approvalAfterSet = await contractWrappers.erc721Token.isProxyApprovedAsync(tokenAddress, tokenId);
|
||||
expect(approvalAfterSet).to.be.true();
|
||||
});
|
||||
});
|
||||
describe('#subscribe', () => {
|
||||
const indexFilterValues = {};
|
||||
afterEach(() => {
|
||||
contractWrappers.erc721Token.unsubscribeAll();
|
||||
});
|
||||
// Hack: Mocha does not allow a test to be both async and have a `done` callback
|
||||
// Since we need to await the receipt of the event in the `subscribe` callback,
|
||||
// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
|
||||
// wrap the rest of the test in an async block
|
||||
// Source: https://github.com/mochajs/mocha/issues/2407
|
||||
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ERC721TokenTransferEventArgs>) => {
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
expect(logEvent.log.logIndex).to.be.equal(0);
|
||||
expect(logEvent.log.transactionIndex).to.be.equal(0);
|
||||
expect(logEvent.log.blockNumber).to.be.a('number');
|
||||
const args = logEvent.log.args;
|
||||
expect(args._from).to.be.equal(ownerAddress);
|
||||
expect(args._to).to.be.equal(receiverAddress);
|
||||
expect(args._tokenId).to.be.bignumber.equal(tokenId);
|
||||
},
|
||||
);
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
const isApprovedForAll = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
contractWrappers.erc721Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC721TokenEvents.Transfer,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await contractWrappers.erc721Token.transferFromAsync(
|
||||
tokenAddress,
|
||||
receiverAddress,
|
||||
operatorAddress,
|
||||
tokenId,
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
})().catch(done);
|
||||
});
|
||||
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ERC721TokenApprovalEventArgs>) => {
|
||||
expect(logEvent).to.not.be.undefined();
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
const args = logEvent.log.args;
|
||||
expect(args._owner).to.be.equal(ownerAddress);
|
||||
expect(args._approved).to.be.equal(approvedAddress);
|
||||
expect(args._tokenId).to.be.bignumber.equal(tokenId);
|
||||
},
|
||||
);
|
||||
contractWrappers.erc721Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC721TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
})().catch(done);
|
||||
});
|
||||
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ERC721TokenApprovalEventArgs>) => {
|
||||
done(new Error('Expected this subscription to have been cancelled'));
|
||||
},
|
||||
);
|
||||
contractWrappers.erc721Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC721TokenEvents.Transfer,
|
||||
indexFilterValues,
|
||||
callbackNeverToBeCalled,
|
||||
);
|
||||
const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)();
|
||||
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
|
||||
contractWrappers.erc721Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC721TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callbackToBeCalled,
|
||||
);
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
done();
|
||||
})().catch(done);
|
||||
});
|
||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ERC721TokenApprovalForAllEventArgs>) => {
|
||||
done(new Error('Expected this subscription to have been cancelled'));
|
||||
},
|
||||
);
|
||||
const subscriptionToken = contractWrappers.erc721Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC721TokenEvents.ApprovalForAll,
|
||||
indexFilterValues,
|
||||
callbackNeverToBeCalled,
|
||||
);
|
||||
contractWrappers.erc721Token.unsubscribe(subscriptionToken);
|
||||
|
||||
const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
|
||||
const isApproved = true;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(
|
||||
await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApproved,
|
||||
),
|
||||
constants.AWAIT_TRANSACTION_MINED_MS,
|
||||
);
|
||||
done();
|
||||
})().catch(done);
|
||||
});
|
||||
});
|
||||
describe('#getLogsAsync', () => {
|
||||
let tokenTransferProxyAddress: string;
|
||||
const blockRange: BlockRange = {
|
||||
fromBlock: 0,
|
||||
toBlock: BlockParamLiteral.Latest,
|
||||
};
|
||||
let txHash: string;
|
||||
before(() => {
|
||||
tokenTransferProxyAddress = contractWrappers.erc721Proxy.getContractAddress();
|
||||
});
|
||||
it('should get logs with decoded args emitted by ApprovalForAll', async () => {
|
||||
const isApprovedForAll = true;
|
||||
txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const eventName = ERC721TokenEvents.ApprovalForAll;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.erc721Token.getLogsAsync<ERC721TokenApprovalForAllEventArgs>(
|
||||
tokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
indexFilterValues,
|
||||
);
|
||||
expect(logs).to.have.length(1);
|
||||
const args = logs[0].args;
|
||||
expect(logs[0].event).to.be.equal(eventName);
|
||||
expect(args._owner).to.be.equal(ownerAddress);
|
||||
expect(args._operator).to.be.equal(operatorAddress);
|
||||
expect(args._approved).to.be.equal(isApprovedForAll);
|
||||
});
|
||||
it('should only get the logs with the correct event name', async () => {
|
||||
const isApprovedForAll = true;
|
||||
txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const differentEventName = ERC721TokenEvents.Transfer;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.erc721Token.getLogsAsync(
|
||||
tokenAddress,
|
||||
differentEventName,
|
||||
blockRange,
|
||||
indexFilterValues,
|
||||
);
|
||||
expect(logs).to.have.length(0);
|
||||
});
|
||||
it('should only get the logs with the correct indexed fields', async () => {
|
||||
const isApprovedForAll = true;
|
||||
txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
ownerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
|
||||
tokenAddress,
|
||||
anotherOwnerAddress,
|
||||
operatorAddress,
|
||||
isApprovedForAll,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const eventName = ERC721TokenEvents.ApprovalForAll;
|
||||
const indexFilterValues = {
|
||||
_owner: anotherOwnerAddress,
|
||||
};
|
||||
const logs = await contractWrappers.erc721Token.getLogsAsync<ERC721TokenApprovalForAllEventArgs>(
|
||||
tokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
indexFilterValues,
|
||||
);
|
||||
expect(logs).to.have.length(1);
|
||||
const args = logs[0].args;
|
||||
expect(args._owner).to.be.equal(anotherOwnerAddress);
|
||||
});
|
||||
});
|
||||
});
|
||||
// tslint:disable:max-file-line-count
|
||||
|
||||
function addEmptyWalletSubprovider(p: Provider): Provider {
|
||||
const providerEngine = new Web3ProviderEngine();
|
||||
providerEngine.addProvider(new EmptyWalletSubprovider());
|
||||
const currentSubproviders = (p as any)._providers;
|
||||
for (const subprovider of currentSubproviders) {
|
||||
providerEngine.addProvider(subprovider);
|
||||
}
|
||||
providerEngine.start();
|
||||
return providerEngine;
|
||||
}
|
||||
@@ -3,26 +3,24 @@ import { DoneCallback } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import {
|
||||
ApprovalContractEventArgs,
|
||||
BlockParamLiteral,
|
||||
BlockRange,
|
||||
ContractWrappers,
|
||||
ContractWrappersError,
|
||||
DecodedLogEvent,
|
||||
DepositContractEventArgs,
|
||||
EtherTokenEvents,
|
||||
Token,
|
||||
TransferContractEventArgs,
|
||||
WithdrawalContractEventArgs,
|
||||
WETH9ApprovalEventArgs,
|
||||
WETH9DepositEventArgs,
|
||||
WETH9Events,
|
||||
WETH9TransferEventArgs,
|
||||
WETH9WithdrawalEventArgs,
|
||||
} from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { TokenUtils } from './utils/token_utils';
|
||||
import { tokenUtils } from './utils/token_utils';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -37,7 +35,6 @@ const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
|
||||
|
||||
describe('EtherTokenWrapper', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
let tokens: Token[];
|
||||
let userAddresses: string[];
|
||||
let addressWithETH: string;
|
||||
let wethContractAddress: string;
|
||||
@@ -55,7 +52,6 @@ describe('EtherTokenWrapper', () => {
|
||||
const withdrawalAmount = new BigNumber(42);
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, zeroExConfig);
|
||||
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
addressWithETH = userAddresses[0];
|
||||
wethContractAddress = contractWrappers.etherToken.getContractAddressIfExists() as string;
|
||||
@@ -86,7 +82,10 @@ describe('EtherTokenWrapper', () => {
|
||||
describe('#depositAsync', () => {
|
||||
it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
|
||||
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
|
||||
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
|
||||
const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync(
|
||||
wethContractAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
expect(preETHBalance).to.be.bignumber.gt(0);
|
||||
expect(preWETHBalance).to.be.bignumber.equal(0);
|
||||
|
||||
@@ -95,10 +94,10 @@ describe('EtherTokenWrapper', () => {
|
||||
depositWeiAmount,
|
||||
addressWithETH,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
|
||||
const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
|
||||
const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
|
||||
const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync(
|
||||
wethContractAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
@@ -127,7 +126,10 @@ describe('EtherTokenWrapper', () => {
|
||||
|
||||
const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
|
||||
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
|
||||
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
|
||||
const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync(
|
||||
wethContractAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
let gasCost = expectedPreETHBalance.minus(preETHBalance);
|
||||
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
|
||||
expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
|
||||
@@ -137,10 +139,10 @@ describe('EtherTokenWrapper', () => {
|
||||
depositWeiAmount,
|
||||
addressWithETH,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
|
||||
const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
|
||||
const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
|
||||
const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync(
|
||||
wethContractAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
@@ -151,7 +153,10 @@ describe('EtherTokenWrapper', () => {
|
||||
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
|
||||
});
|
||||
it('should throw if user has insufficient WETH balance for withdrawal', async () => {
|
||||
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
|
||||
const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync(
|
||||
wethContractAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
expect(preWETHBalance).to.be.bignumber.equal(0);
|
||||
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
@@ -165,10 +170,8 @@ describe('EtherTokenWrapper', () => {
|
||||
describe('#subscribe', () => {
|
||||
const indexFilterValues = {};
|
||||
let etherTokenAddress: string;
|
||||
before(() => {
|
||||
const tokenUtils = new TokenUtils(tokens);
|
||||
const etherToken = tokenUtils.getWethTokenOrThrow();
|
||||
etherTokenAddress = etherToken.address;
|
||||
before(async () => {
|
||||
etherTokenAddress = tokenUtils.getWethTokenAddress();
|
||||
});
|
||||
afterEach(() => {
|
||||
contractWrappers.etherToken.unsubscribeAll();
|
||||
@@ -181,7 +184,7 @@ describe('EtherTokenWrapper', () => {
|
||||
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
|
||||
(logEvent: DecodedLogEvent<WETH9TransferEventArgs>) => {
|
||||
expect(logEvent).to.not.be.undefined();
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
expect(logEvent.log.logIndex).to.be.equal(0);
|
||||
@@ -196,11 +199,11 @@ describe('EtherTokenWrapper', () => {
|
||||
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||
contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Transfer,
|
||||
WETH9Events.Transfer,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.token.transferAsync(
|
||||
await contractWrappers.erc20Token.transferAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
addressWithoutFunds,
|
||||
@@ -211,7 +214,7 @@ describe('EtherTokenWrapper', () => {
|
||||
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||
(logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => {
|
||||
expect(logEvent).to.not.be.undefined();
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
const args = logEvent.log.args;
|
||||
@@ -222,11 +225,11 @@ describe('EtherTokenWrapper', () => {
|
||||
);
|
||||
contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Approval,
|
||||
WETH9Events.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
addressWithoutFunds,
|
||||
@@ -237,7 +240,7 @@ describe('EtherTokenWrapper', () => {
|
||||
it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
|
||||
(logEvent: DecodedLogEvent<WETH9DepositEventArgs>) => {
|
||||
expect(logEvent).to.not.be.undefined();
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
const args = logEvent.log.args;
|
||||
@@ -247,7 +250,7 @@ describe('EtherTokenWrapper', () => {
|
||||
);
|
||||
contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Deposit,
|
||||
WETH9Events.Deposit,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
@@ -257,7 +260,7 @@ describe('EtherTokenWrapper', () => {
|
||||
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
|
||||
(logEvent: DecodedLogEvent<WETH9WithdrawalEventArgs>) => {
|
||||
expect(logEvent).to.not.be.undefined();
|
||||
expect(logEvent.isRemoved).to.be.false();
|
||||
const args = logEvent.log.args;
|
||||
@@ -268,7 +271,7 @@ describe('EtherTokenWrapper', () => {
|
||||
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
|
||||
contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Withdrawal,
|
||||
WETH9Events.Withdrawal,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
@@ -278,13 +281,13 @@ describe('EtherTokenWrapper', () => {
|
||||
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||
(_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => {
|
||||
done(new Error('Expected this subscription to have been cancelled'));
|
||||
},
|
||||
);
|
||||
contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Transfer,
|
||||
WETH9Events.Transfer,
|
||||
indexFilterValues,
|
||||
callbackNeverToBeCalled,
|
||||
);
|
||||
@@ -293,11 +296,11 @@ describe('EtherTokenWrapper', () => {
|
||||
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||
contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Transfer,
|
||||
WETH9Events.Transfer,
|
||||
indexFilterValues,
|
||||
callbackToBeCalled,
|
||||
);
|
||||
await contractWrappers.token.transferAsync(
|
||||
await contractWrappers.erc20Token.transferAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
addressWithoutFunds,
|
||||
@@ -308,19 +311,19 @@ describe('EtherTokenWrapper', () => {
|
||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
|
||||
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||
(_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => {
|
||||
done(new Error('Expected this subscription to have been cancelled'));
|
||||
},
|
||||
);
|
||||
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||
const subscriptionToken = contractWrappers.etherToken.subscribe(
|
||||
etherTokenAddress,
|
||||
EtherTokenEvents.Transfer,
|
||||
WETH9Events.Transfer,
|
||||
indexFilterValues,
|
||||
callbackNeverToBeCalled,
|
||||
);
|
||||
contractWrappers.etherToken.unsubscribe(subscriptionToken);
|
||||
await contractWrappers.token.transferAsync(
|
||||
await contractWrappers.erc20Token.transferAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
addressWithoutFunds,
|
||||
@@ -332,7 +335,7 @@ describe('EtherTokenWrapper', () => {
|
||||
});
|
||||
describe('#getLogsAsync', () => {
|
||||
let etherTokenAddress: string;
|
||||
let tokenTransferProxyAddress: string;
|
||||
let erc20ProxyAddress: string;
|
||||
const blockRange: BlockRange = {
|
||||
fromBlock: 0,
|
||||
toBlock: BlockParamLiteral.Latest,
|
||||
@@ -340,17 +343,18 @@ describe('EtherTokenWrapper', () => {
|
||||
let txHash: string;
|
||||
before(() => {
|
||||
addressWithETH = userAddresses[0];
|
||||
const tokenUtils = new TokenUtils(tokens);
|
||||
const etherToken = tokenUtils.getWethTokenOrThrow();
|
||||
etherTokenAddress = etherToken.address;
|
||||
tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress();
|
||||
etherTokenAddress = tokenUtils.getWethTokenAddress();
|
||||
erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
|
||||
});
|
||||
it('should get logs with decoded args emitted by Approval', async () => {
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const eventName = EtherTokenEvents.Approval;
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const eventName = WETH9Events.Approval;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>(
|
||||
etherTokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
@@ -360,14 +364,14 @@ describe('EtherTokenWrapper', () => {
|
||||
const args = logs[0].args;
|
||||
expect(logs[0].event).to.be.equal(eventName);
|
||||
expect(args._owner).to.be.equal(addressWithETH);
|
||||
expect(args._spender).to.be.equal(tokenTransferProxyAddress);
|
||||
expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
expect(args._spender).to.be.equal(erc20ProxyAddress);
|
||||
expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
|
||||
});
|
||||
it('should get logs with decoded args emitted by Deposit', async () => {
|
||||
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
|
||||
const eventName = EtherTokenEvents.Deposit;
|
||||
const eventName = WETH9Events.Deposit;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync<DepositContractEventArgs>(
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync<WETH9DepositEventArgs>(
|
||||
etherTokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
@@ -380,9 +384,12 @@ describe('EtherTokenWrapper', () => {
|
||||
expect(args._value).to.be.bignumber.equal(depositAmount);
|
||||
});
|
||||
it('should only get the logs with the correct event name', async () => {
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const differentEventName = EtherTokenEvents.Transfer;
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const differentEventName = WETH9Events.Transfer;
|
||||
const indexFilterValues = {};
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync(
|
||||
etherTokenAddress,
|
||||
@@ -393,18 +400,21 @@ describe('EtherTokenWrapper', () => {
|
||||
expect(logs).to.have.length(0);
|
||||
});
|
||||
it('should only get the logs with the correct indexed fields', async () => {
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
|
||||
etherTokenAddress,
|
||||
addressWithETH,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
|
||||
etherTokenAddress,
|
||||
addressWithoutFunds,
|
||||
);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
const eventName = EtherTokenEvents.Approval;
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
|
||||
const eventName = WETH9Events.Approval;
|
||||
const indexFilterValues = {
|
||||
_owner: addressWithETH,
|
||||
};
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
||||
const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>(
|
||||
etherTokenAddress,
|
||||
eventName,
|
||||
blockRange,
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { BlockParamLiteral, Token } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import 'make-promises-safe';
|
||||
|
||||
import { ContractWrappers, ExchangeContractErrs } from '../src';
|
||||
import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store';
|
||||
import { TradeSide, TransferType } from '../src/types';
|
||||
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
describe('ExchangeTransferSimulator', () => {
|
||||
const config = {
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
};
|
||||
const contractWrappers = new ContractWrappers(provider, config);
|
||||
const transferAmount = new BigNumber(5);
|
||||
let userAddresses: string[];
|
||||
let tokens: Token[];
|
||||
let coinbase: string;
|
||||
let sender: string;
|
||||
let recipient: string;
|
||||
let exampleTokenAddress: string;
|
||||
let exchangeTransferSimulator: ExchangeTransferSimulator;
|
||||
let txHash: string;
|
||||
before(async () => {
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
[coinbase, sender, recipient] = userAddresses;
|
||||
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
|
||||
exampleTokenAddress = tokens[0].address;
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
describe('#transferFromAsync', () => {
|
||||
beforeEach(() => {
|
||||
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||
contractWrappers.token,
|
||||
BlockParamLiteral.Latest,
|
||||
);
|
||||
exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||
});
|
||||
it("throws if the user doesn't have enough allowance", async () => {
|
||||
return expect(
|
||||
exchangeTransferSimulator.transferFromAsync(
|
||||
exampleTokenAddress,
|
||||
sender,
|
||||
recipient,
|
||||
transferAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
|
||||
});
|
||||
it("throws if the user doesn't have enough balance", async () => {
|
||||
txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
return expect(
|
||||
exchangeTransferSimulator.transferFromAsync(
|
||||
exampleTokenAddress,
|
||||
sender,
|
||||
recipient,
|
||||
transferAmount,
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
|
||||
});
|
||||
it('updates balances and proxyAllowance after transfer', async () => {
|
||||
txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
await exchangeTransferSimulator.transferFromAsync(
|
||||
exampleTokenAddress,
|
||||
sender,
|
||||
recipient,
|
||||
transferAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
const store = (exchangeTransferSimulator as any)._store;
|
||||
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
||||
const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
|
||||
const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
|
||||
expect(senderBalance).to.be.bignumber.equal(0);
|
||||
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
|
||||
expect(senderProxyAllowance).to.be.bignumber.equal(0);
|
||||
});
|
||||
it("doesn't update proxyAllowance after transfer if unlimited", async () => {
|
||||
txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
|
||||
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
await exchangeTransferSimulator.transferFromAsync(
|
||||
exampleTokenAddress,
|
||||
sender,
|
||||
recipient,
|
||||
transferAmount,
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
);
|
||||
const store = (exchangeTransferSimulator as any)._store;
|
||||
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
||||
const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
|
||||
const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
|
||||
expect(senderBalance).to.be.bignumber.equal(0);
|
||||
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
|
||||
expect(senderProxyAllowance).to.be.bignumber.equal(
|
||||
contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
import { devConstants } from '@0xproject/dev-utils';
|
||||
import { runV1MigrationsAsync } from '@0xproject/migrations';
|
||||
import { runV2MigrationsAsync } from '@0xproject/migrations';
|
||||
|
||||
import { provider } from './utils/web3_wrapper';
|
||||
|
||||
@@ -12,6 +12,6 @@ before('migrate contracts', async function(): Promise<void> {
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
};
|
||||
const artifactsDir = `../migrations/artifacts/1.0.0`;
|
||||
await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
|
||||
const artifactsDir = `../migrations/artifacts/2.0.0`;
|
||||
await runV2MigrationsAsync(provider, artifactsDir, txDefaults);
|
||||
});
|
||||
|
||||
@@ -1,540 +0,0 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { FillScenarios } from '@0xproject/fill-scenarios';
|
||||
import { OrderError } from '@0xproject/order-utils';
|
||||
import { BlockParamLiteral } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as chai from 'chai';
|
||||
import 'make-promises-safe';
|
||||
import * as Sinon from 'sinon';
|
||||
|
||||
import { ContractWrappers, ExchangeContractErrs, SignedOrder, Token } from '../src';
|
||||
import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store';
|
||||
import { TradeSide, TransferType } from '../src/types';
|
||||
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
||||
import { OrderValidationUtils } from '../src/utils/order_validation_utils';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { TokenUtils } from './utils/token_utils';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
describe('OrderValidation', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
let userAddresses: string[];
|
||||
let tokens: Token[];
|
||||
let tokenUtils: TokenUtils;
|
||||
let exchangeContractAddress: string;
|
||||
let zrxTokenAddress: string;
|
||||
let fillScenarios: FillScenarios;
|
||||
let makerTokenAddress: string;
|
||||
let takerTokenAddress: string;
|
||||
let coinbase: string;
|
||||
let makerAddress: string;
|
||||
let takerAddress: string;
|
||||
let feeRecipient: string;
|
||||
const fillableAmount = new BigNumber(5);
|
||||
const fillTakerAmount = new BigNumber(5);
|
||||
const config = {
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
};
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
exchangeContractAddress = contractWrappers.exchange.getContractAddress();
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
|
||||
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
|
||||
tokenUtils = new TokenUtils(tokens);
|
||||
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
|
||||
fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
|
||||
const [makerToken, takerToken] = tokenUtils.getDummyTokens();
|
||||
makerTokenAddress = makerToken.address;
|
||||
takerTokenAddress = takerToken.address;
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
describe('validateOrderFillableOrThrowAsync', () => {
|
||||
it('should succeed if the order is fillable', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||
});
|
||||
it('should succeed if the maker is buying ZRX and has no ZRX balance', async () => {
|
||||
const makerFee = new BigNumber(2);
|
||||
const takerFee = new BigNumber(2);
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress,
|
||||
zrxTokenAddress,
|
||||
makerFee,
|
||||
takerFee,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
feeRecipient,
|
||||
);
|
||||
const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress);
|
||||
await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
|
||||
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||
});
|
||||
it('should succeed if the maker is buying ZRX and has no ZRX balance and there is no specified taker', async () => {
|
||||
const makerFee = new BigNumber(2);
|
||||
const takerFee = new BigNumber(2);
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress,
|
||||
zrxTokenAddress,
|
||||
makerFee,
|
||||
takerFee,
|
||||
makerAddress,
|
||||
constants.NULL_ADDRESS,
|
||||
fillableAmount,
|
||||
feeRecipient,
|
||||
);
|
||||
const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress);
|
||||
await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
|
||||
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||
});
|
||||
it('should succeed if the order is asymmetric and fillable', async () => {
|
||||
const makerFillableAmount = fillableAmount;
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
const takerFillableAmount = fillableAmount.minus(4);
|
||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
makerFillableAmount,
|
||||
takerFillableAmount,
|
||||
);
|
||||
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||
});
|
||||
it('should throw when the order is fully filled or cancelled', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||
return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
|
||||
ExchangeContractErrs.OrderRemainingFillAmountZero,
|
||||
);
|
||||
});
|
||||
it('should throw when order is expired', async () => {
|
||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
expirationInPast,
|
||||
);
|
||||
return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
|
||||
ExchangeContractErrs.OrderFillExpired,
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('validateFillOrderAndThrowIfInvalidAsync', () => {
|
||||
it('should throw when the fill amount is zero', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
const zeroFillAmount = new BigNumber(0);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
zeroFillAmount,
|
||||
takerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||
});
|
||||
it('should throw when the signature is invalid', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
// 27 <--> 28
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
fillableAmount,
|
||||
takerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(OrderError.InvalidSignature);
|
||||
});
|
||||
it('should throw when the order is fully filled or cancelled', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
fillableAmount,
|
||||
takerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||
});
|
||||
it('should throw when sender is not a taker', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
const nonTakerAddress = userAddresses[6];
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
fillTakerAmount,
|
||||
nonTakerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
||||
});
|
||||
it('should throw when order is expired', async () => {
|
||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
expirationInPast,
|
||||
);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
fillTakerAmount,
|
||||
takerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
||||
});
|
||||
it('should throw when there a rounding error would have occurred', async () => {
|
||||
const makerAmount = new BigNumber(3);
|
||||
const takerAmount = new BigNumber(5);
|
||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
makerAmount,
|
||||
takerAmount,
|
||||
);
|
||||
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
fillTakerAmountThatCausesRoundingError,
|
||||
takerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
|
||||
});
|
||||
});
|
||||
describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
|
||||
it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
const tooLargeFillAmount = new BigNumber(7);
|
||||
const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
|
||||
await contractWrappers.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
|
||||
await contractWrappers.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
|
||||
await contractWrappers.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
|
||||
await contractWrappers.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
|
||||
|
||||
return expect(
|
||||
contractWrappers.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||
signedOrder,
|
||||
tooLargeFillAmount,
|
||||
takerAddress,
|
||||
),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
||||
});
|
||||
});
|
||||
describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
|
||||
let signedOrder: SignedOrder;
|
||||
const cancelAmount = new BigNumber(3);
|
||||
beforeEach(async () => {
|
||||
[coinbase, makerAddress, takerAddress] = userAddresses;
|
||||
const [makerToken, takerToken] = tokenUtils.getDummyTokens();
|
||||
makerTokenAddress = makerToken.address;
|
||||
takerTokenAddress = takerToken.address;
|
||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
);
|
||||
});
|
||||
it('should throw when cancel amount is zero', async () => {
|
||||
const zeroCancelAmount = new BigNumber(0);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||
});
|
||||
it('should throw when order is expired', async () => {
|
||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
expirationInPast,
|
||||
);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
|
||||
});
|
||||
it('should throw when order is already cancelled or filled', async () => {
|
||||
await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||
return expect(
|
||||
contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
|
||||
).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
|
||||
});
|
||||
});
|
||||
describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
|
||||
let exchangeTransferSimulator: ExchangeTransferSimulator;
|
||||
let transferFromAsync: Sinon.SinonSpy;
|
||||
const bigNumberMatch = (expected: BigNumber) => {
|
||||
return Sinon.match((value: BigNumber) => value.eq(expected));
|
||||
};
|
||||
beforeEach('create exchangeTransferSimulator', async () => {
|
||||
const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||
contractWrappers.token,
|
||||
BlockParamLiteral.Latest,
|
||||
);
|
||||
exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
|
||||
transferFromAsync = Sinon.spy();
|
||||
exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
|
||||
});
|
||||
it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
|
||||
const makerFee = new BigNumber(2);
|
||||
const takerFee = new BigNumber(2);
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerFee,
|
||||
takerFee,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
feeRecipient,
|
||||
);
|
||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTransferSimulator,
|
||||
signedOrder,
|
||||
fillableAmount,
|
||||
takerAddress,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(0)
|
||||
.calledWith(
|
||||
makerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
bigNumberMatch(fillableAmount),
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
),
|
||||
).to.be.true();
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(1)
|
||||
.calledWith(
|
||||
takerTokenAddress,
|
||||
takerAddress,
|
||||
makerAddress,
|
||||
bigNumberMatch(fillableAmount),
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
),
|
||||
).to.be.true();
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(2)
|
||||
.calledWith(
|
||||
zrxTokenAddress,
|
||||
makerAddress,
|
||||
feeRecipient,
|
||||
bigNumberMatch(makerFee),
|
||||
TradeSide.Maker,
|
||||
TransferType.Fee,
|
||||
),
|
||||
).to.be.true();
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(3)
|
||||
.calledWith(
|
||||
zrxTokenAddress,
|
||||
takerAddress,
|
||||
feeRecipient,
|
||||
bigNumberMatch(takerFee),
|
||||
TradeSide.Taker,
|
||||
TransferType.Fee,
|
||||
),
|
||||
).to.be.true();
|
||||
});
|
||||
it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
|
||||
const makerFee = new BigNumber(2);
|
||||
const takerFee = new BigNumber(2);
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerFee,
|
||||
takerFee,
|
||||
makerAddress,
|
||||
constants.NULL_ADDRESS,
|
||||
fillableAmount,
|
||||
feeRecipient,
|
||||
);
|
||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTransferSimulator,
|
||||
signedOrder,
|
||||
fillableAmount,
|
||||
takerAddress,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(0)
|
||||
.calledWith(
|
||||
makerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
bigNumberMatch(fillableAmount),
|
||||
TradeSide.Maker,
|
||||
TransferType.Trade,
|
||||
),
|
||||
).to.be.true();
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(1)
|
||||
.calledWith(
|
||||
takerTokenAddress,
|
||||
takerAddress,
|
||||
makerAddress,
|
||||
bigNumberMatch(fillableAmount),
|
||||
TradeSide.Taker,
|
||||
TransferType.Trade,
|
||||
),
|
||||
).to.be.true();
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(2)
|
||||
.calledWith(
|
||||
zrxTokenAddress,
|
||||
makerAddress,
|
||||
feeRecipient,
|
||||
bigNumberMatch(makerFee),
|
||||
TradeSide.Maker,
|
||||
TransferType.Fee,
|
||||
),
|
||||
).to.be.true();
|
||||
expect(
|
||||
transferFromAsync
|
||||
.getCall(3)
|
||||
.calledWith(
|
||||
zrxTokenAddress,
|
||||
takerAddress,
|
||||
feeRecipient,
|
||||
bigNumberMatch(takerFee),
|
||||
TradeSide.Taker,
|
||||
TransferType.Fee,
|
||||
),
|
||||
).to.be.true();
|
||||
});
|
||||
it('should correctly round the fillMakerTokenAmount', async () => {
|
||||
const makerTokenAmount = new BigNumber(3);
|
||||
const takerTokenAmount = new BigNumber(1);
|
||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
makerTokenAmount,
|
||||
takerTokenAmount,
|
||||
);
|
||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTransferSimulator,
|
||||
signedOrder,
|
||||
takerTokenAmount,
|
||||
takerAddress,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||
const makerFillAmount = transferFromAsync.getCall(0).args[3];
|
||||
expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
|
||||
});
|
||||
it('should correctly round the makerFeeAmount', async () => {
|
||||
const makerFee = new BigNumber(2);
|
||||
const takerFee = new BigNumber(4);
|
||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||
makerTokenAddress,
|
||||
takerTokenAddress,
|
||||
makerFee,
|
||||
takerFee,
|
||||
makerAddress,
|
||||
takerAddress,
|
||||
fillableAmount,
|
||||
constants.NULL_ADDRESS,
|
||||
);
|
||||
const fillTakerTokenAmount = fillableAmount.div(2).round(0);
|
||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||
exchangeTransferSimulator,
|
||||
signedOrder,
|
||||
fillTakerTokenAmount,
|
||||
takerAddress,
|
||||
zrxTokenAddress,
|
||||
);
|
||||
const makerPartialFee = makerFee.div(2);
|
||||
const takerPartialFee = takerFee.div(2);
|
||||
// tslint:disable-next-line:custom-no-magic-numbers
|
||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||
const partialMakerFee = transferFromAsync.getCall(2).args[3];
|
||||
expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
|
||||
const partialTakerFee = transferFromAsync.getCall(3).args[3];
|
||||
expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
|
||||
});
|
||||
});
|
||||
}); // tslint:disable-line:max-file-line-count
|
||||
@@ -2,14 +2,14 @@ import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils
|
||||
import { DoneCallback } from '@0xproject/types';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
import * as Sinon from 'sinon';
|
||||
|
||||
import { ApprovalContractEventArgs, ContractWrappers, DecodedLogEvent, Token, TokenEvents } from '../src';
|
||||
import { ContractWrappers, DecodedLogEvent, ERC20TokenApprovalEventArgs, ERC20TokenEvents, Token } from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { tokenUtils } from './utils/token_utils';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
@@ -18,7 +18,6 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
describe('SubscriptionTest', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
let userAddresses: string[];
|
||||
let tokens: Token[];
|
||||
let coinbase: string;
|
||||
let addressWithoutFunds: string;
|
||||
const config = {
|
||||
@@ -27,7 +26,6 @@ describe('SubscriptionTest', () => {
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
|
||||
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
|
||||
coinbase = userAddresses[0];
|
||||
addressWithoutFunds = userAddresses[1];
|
||||
});
|
||||
@@ -43,11 +41,11 @@ describe('SubscriptionTest', () => {
|
||||
const allowanceAmount = new BigNumber(42);
|
||||
let stubs: Sinon.SinonStub[] = [];
|
||||
before(() => {
|
||||
const token = tokens[0];
|
||||
tokenAddress = token.address;
|
||||
const tokenAddresses = tokenUtils.getDummyERC20TokenAddresses();
|
||||
tokenAddress = tokenAddresses[0];
|
||||
});
|
||||
afterEach(() => {
|
||||
contractWrappers.token.unsubscribeAll();
|
||||
contractWrappers.erc20Token.unsubscribeAll();
|
||||
_.each(stubs, s => s.restore());
|
||||
stubs = [];
|
||||
});
|
||||
@@ -56,8 +54,13 @@ describe('SubscriptionTest', () => {
|
||||
const errMsg = 'Error fetching block';
|
||||
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
|
||||
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
|
||||
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
@@ -70,8 +73,13 @@ describe('SubscriptionTest', () => {
|
||||
const errMsg = 'Error fetching logs';
|
||||
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
|
||||
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
|
||||
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||
await contractWrappers.token.setAllowanceAsync(
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
await contractWrappers.erc20Token.setAllowanceAsync(
|
||||
tokenAddress,
|
||||
coinbase,
|
||||
addressWithoutFunds,
|
||||
@@ -81,14 +89,20 @@ describe('SubscriptionTest', () => {
|
||||
});
|
||||
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
||||
(async () => {
|
||||
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
||||
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||
const callback = (err: Error | null, _logEvent?: DecodedLogEvent<ERC20TokenApprovalEventArgs>) =>
|
||||
_.noop;
|
||||
contractWrappers.erc20Token.subscribe(
|
||||
tokenAddress,
|
||||
ERC20TokenEvents.Approval,
|
||||
indexFilterValues,
|
||||
callback,
|
||||
);
|
||||
stubs = [
|
||||
Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(
|
||||
new Error('JSON RPC error'),
|
||||
),
|
||||
];
|
||||
contractWrappers.token.unsubscribeAll();
|
||||
contractWrappers.erc20Token.unsubscribeAll();
|
||||
done();
|
||||
})().catch(done);
|
||||
});
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
|
||||
import * as chai from 'chai';
|
||||
import * as _ from 'lodash';
|
||||
import 'make-promises-safe';
|
||||
import 'mocha';
|
||||
|
||||
import { ContractWrappers, Token } from '../src';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import { constants } from './utils/constants';
|
||||
import { provider, web3Wrapper } from './utils/web3_wrapper';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
|
||||
|
||||
const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
|
||||
|
||||
describe('TokenRegistryWrapper', () => {
|
||||
let contractWrappers: ContractWrappers;
|
||||
let tokens: Token[];
|
||||
const tokenAddressBySymbol: { [symbol: string]: string } = {};
|
||||
const tokenAddressByName: { [symbol: string]: string } = {};
|
||||
const tokenBySymbol: { [symbol: string]: Token } = {};
|
||||
const tokenByName: { [symbol: string]: Token } = {};
|
||||
const registeredSymbol = 'ZRX';
|
||||
const registeredName = '0x Protocol Token';
|
||||
const unregisteredSymbol = 'MAL';
|
||||
const unregisteredName = 'Malicious Token';
|
||||
const config = {
|
||||
networkId: constants.TESTRPC_NETWORK_ID,
|
||||
};
|
||||
before(async () => {
|
||||
contractWrappers = new ContractWrappers(provider, config);
|
||||
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
|
||||
_.map(tokens, token => {
|
||||
tokenAddressBySymbol[token.symbol] = token.address;
|
||||
tokenAddressByName[token.name] = token.address;
|
||||
tokenBySymbol[token.symbol] = token;
|
||||
tokenByName[token.name] = token;
|
||||
});
|
||||
});
|
||||
beforeEach(async () => {
|
||||
await blockchainLifecycle.startAsync();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await blockchainLifecycle.revertAsync();
|
||||
});
|
||||
describe('#getTokensAsync', () => {
|
||||
it('should return all the tokens added to the tokenRegistry during the migration', async () => {
|
||||
expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
|
||||
|
||||
const schemaValidator = new SchemaValidator();
|
||||
_.each(tokens, token => {
|
||||
const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
|
||||
expect(validationResult.errors).to.have.lengthOf(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#getTokenAddressesAsync', () => {
|
||||
it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
|
||||
const tokenAddresses = await contractWrappers.tokenRegistry.getTokenAddressesAsync();
|
||||
expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
|
||||
|
||||
const schemaValidator = new SchemaValidator();
|
||||
_.each(tokenAddresses, tokenAddress => {
|
||||
const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
|
||||
expect(validationResult.errors).to.have.lengthOf(0);
|
||||
expect(tokenAddress).to.not.be.equal(constants.NULL_ADDRESS);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#getTokenAddressBySymbol', () => {
|
||||
it('should return correct address for a token in the registry', async () => {
|
||||
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(
|
||||
registeredSymbol,
|
||||
);
|
||||
expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
|
||||
});
|
||||
it('should return undefined for a token out of registry', async () => {
|
||||
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(
|
||||
unregisteredSymbol,
|
||||
);
|
||||
expect(tokenAddress).to.be.undefined();
|
||||
});
|
||||
});
|
||||
describe('#getTokenAddressByName', () => {
|
||||
it('should return correct address for a token in the registry', async () => {
|
||||
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync(
|
||||
registeredName,
|
||||
);
|
||||
expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
|
||||
});
|
||||
it('should return undefined for a token out of registry', async () => {
|
||||
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync(
|
||||
unregisteredName,
|
||||
);
|
||||
expect(tokenAddress).to.be.undefined();
|
||||
});
|
||||
});
|
||||
describe('#getTokenBySymbol', () => {
|
||||
it('should return correct token for a token in the registry', async () => {
|
||||
const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
|
||||
expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
|
||||
});
|
||||
it('should return undefined for a token out of registry', async () => {
|
||||
const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
|
||||
expect(token).to.be.undefined();
|
||||
});
|
||||
});
|
||||
describe('#getTokenByName', () => {
|
||||
it('should return correct token for a token in the registry', async () => {
|
||||
const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
|
||||
expect(token).to.be.deep.equal(tokenByName[registeredName]);
|
||||
});
|
||||
it('should return undefined for a token out of registry', async () => {
|
||||
const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
|
||||
expect(token).to.be.undefined();
|
||||
});
|
||||
});
|
||||
describe('#getTokenIfExistsAsync', () => {
|
||||
it('should return the token added to the tokenRegistry during the migration', async () => {
|
||||
const aToken = tokens[0];
|
||||
|
||||
const token = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(aToken.address);
|
||||
const schemaValidator = new SchemaValidator();
|
||||
const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
|
||||
expect(validationResult.errors).to.have.lengthOf(0);
|
||||
});
|
||||
it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
|
||||
const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
|
||||
const tokenIfExists = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
|
||||
expect(tokenIfExists).to.be.undefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,9 +1,18 @@
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
|
||||
export const constants = {
|
||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||
ROPSTEN_NETWORK_ID: 3,
|
||||
KOVAN_NETWORK_ID: 42,
|
||||
TESTRPC_NETWORK_ID: 50,
|
||||
AWAIT_TRANSACTION_MINED_MS: 0,
|
||||
KOVAN_RPC_URL: 'https://kovan.infura.io/',
|
||||
ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
|
||||
ZRX_DECIMALS: 18,
|
||||
DUMMY_TOKEN_NAME: '',
|
||||
DUMMY_TOKEN_SYMBOL: '',
|
||||
DUMMY_TOKEN_DECIMALS: 18,
|
||||
DUMMY_TOKEN_TOTAL_SUPPLY: new BigNumber(10 ** 27), // tslint:disable-line:custom-no-magic-numbers
|
||||
NUM_DUMMY_ERC20_TO_DEPLOY: 3,
|
||||
NUM_DUMMY_ERC721_TO_DEPLOY: 1,
|
||||
};
|
||||
|
||||
@@ -1,33 +1,47 @@
|
||||
import * as _ from 'lodash';
|
||||
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
|
||||
import { BigNumber } from '@0xproject/utils';
|
||||
|
||||
import { InternalContractWrappersError, Token } from '../../src/types';
|
||||
import { artifacts } from '../../src/artifacts';
|
||||
import { DummyERC721TokenContract } from '../../src/contract_wrappers/generated/dummy_erc721_token';
|
||||
|
||||
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
|
||||
const WETH_TOKEN_SYMBOL = 'WETH';
|
||||
import { constants } from './constants';
|
||||
import { provider, txDefaults, web3Wrapper } from './web3_wrapper';
|
||||
|
||||
export class TokenUtils {
|
||||
private _tokens: Token[];
|
||||
constructor(tokens: Token[]) {
|
||||
this._tokens = tokens;
|
||||
}
|
||||
public getProtocolTokenOrThrow(): Token {
|
||||
const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
|
||||
if (_.isUndefined(zrxToken)) {
|
||||
throw new Error(InternalContractWrappersError.ZrxNotInTokenRegistry);
|
||||
}
|
||||
return zrxToken;
|
||||
}
|
||||
public getWethTokenOrThrow(): Token {
|
||||
const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
|
||||
if (_.isUndefined(wethToken)) {
|
||||
throw new Error(InternalContractWrappersError.WethNotInTokenRegistry);
|
||||
}
|
||||
return wethToken;
|
||||
}
|
||||
public getDummyTokens(): Token[] {
|
||||
const dummyTokens = _.filter(this._tokens, token => {
|
||||
return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
|
||||
});
|
||||
return dummyTokens;
|
||||
}
|
||||
}
|
||||
// Those addresses come from migrations. They're deterministic so it's relatively safe to hard-code them here.
|
||||
// Before we were fetching them from the TokenRegistry but now we can't as it's deprecated and removed.
|
||||
const DUMMY_ERC_20_ADRESSES = [
|
||||
'0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f',
|
||||
'0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db',
|
||||
'0xf22469f31527adc53284441bae1665a7b9214dba',
|
||||
'0x10add991de718a69dec2117cb6aa28098836511b',
|
||||
'0x8d61158a366019ac78db4149d75fff9dda51160d',
|
||||
];
|
||||
|
||||
const DUMMY_ERC_721_ADRESSES = ['0x131855dda0aaff096f6854854c55a4debf61077a'];
|
||||
|
||||
export const tokenUtils = {
|
||||
getProtocolTokenAddress(): string {
|
||||
return artifacts.ZRXToken.networks[constants.TESTRPC_NETWORK_ID].address;
|
||||
},
|
||||
getWethTokenAddress(): string {
|
||||
return artifacts.EtherToken.networks[constants.TESTRPC_NETWORK_ID].address;
|
||||
},
|
||||
getDummyERC20TokenAddresses(): string[] {
|
||||
return DUMMY_ERC_20_ADRESSES;
|
||||
},
|
||||
getDummyERC721TokenAddresses(): string[] {
|
||||
return DUMMY_ERC_721_ADRESSES;
|
||||
},
|
||||
async mintDummyERC721Async(address: string, tokenOwner: string): Promise<BigNumber> {
|
||||
const erc721 = new DummyERC721TokenContract(
|
||||
artifacts.DummyERC721Token.compilerOutput.abi,
|
||||
address,
|
||||
provider,
|
||||
txDefaults,
|
||||
);
|
||||
const tokenId = generatePseudoRandomSalt();
|
||||
const txHash = await erc721.mint.sendTransactionAsync(tokenOwner, tokenId);
|
||||
web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
return tokenId;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { web3Factory } from '@0xproject/dev-utils';
|
||||
import { Provider } from '@0xproject/types';
|
||||
import { devConstants, web3Factory } from '@0xproject/dev-utils';
|
||||
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||
import { Provider } from 'ethereum-types';
|
||||
|
||||
const txDefaults = {
|
||||
from: devConstants.TESTRPC_FIRST_ADDRESS,
|
||||
gas: devConstants.GAS_LIMIT,
|
||||
};
|
||||
const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
|
||||
const web3Wrapper = new Web3Wrapper(provider);
|
||||
|
||||
export { provider, web3Wrapper };
|
||||
export { provider, web3Wrapper, txDefaults };
|
||||
|
||||
17
packages/contract_templates/README.md
Normal file
17
packages/contract_templates/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
These templates are used with [abi-gen](https://github.com/0xProject/0x-monorepo/tree/development/packages/abi-gen).
|
||||
|
||||
To successfully compile the generated TypeScript contract wrappers, you must:
|
||||
|
||||
* Install the packages on which the main contract template directly depends: `yarn add @0xproject/base-contract @0xproject/sol-compiler @0xproject/utils @0xproject/web3-wrapper ethereum-types ethers lodash`
|
||||
* Install the packages on which the main contract template *in*directly depends: `yarn add @types/lodash`
|
||||
* Ensure that your TypeScript configuration includes the following:
|
||||
|
||||
```
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2015"],
|
||||
"typeRoots": [
|
||||
"node_modules/@0xproject/typescript-typings/types",
|
||||
"node_modules/@types"
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -1,8 +1,4 @@
|
||||
/**
|
||||
* This file is auto-generated using abi-gen. Don't edit directly.
|
||||
* Templates can be found at https://github.com/0xProject/0x-monorepo/tree/development/packages/contract_templates.
|
||||
*/
|
||||
// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma whitespace
|
||||
// tslint:disable:no-consecutive-blank-lines ordered-imports align trailing-comma whitespace class-name
|
||||
// tslint:disable:no-unused-variable
|
||||
import { BaseContract } from '@0xproject/base-contract';
|
||||
import { ContractArtifact } from '@0xproject/sol-compiler';
|
||||
@@ -14,9 +10,9 @@ import * as _ from 'lodash';
|
||||
// tslint:enable:no-unused-variable
|
||||
|
||||
{{#if events}}
|
||||
export type {{contractName}}ContractEventArgs =
|
||||
export type {{contractName}}EventArgs =
|
||||
{{#each events}}
|
||||
| {{name}}ContractEventArgs{{#if @last}};{{/if}}
|
||||
| {{@root.contractName}}{{name}}EventArgs{{#if @last}};{{/if}}
|
||||
{{/each}}
|
||||
|
||||
export enum {{contractName}}Events {
|
||||
@@ -31,6 +27,7 @@ export enum {{contractName}}Events {
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
/* istanbul ignore next */
|
||||
// tslint:disable:no-parameter-reassignment
|
||||
// tslint:disable-next-line:class-name
|
||||
export class {{contractName}}Contract extends BaseContract {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
public {{this.name}} = {
|
||||
public {{this.tsName}} = {
|
||||
{{> callAsync}}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{{#hasReturnValue}}
|
||||
async callAsync(
|
||||
{{> typed_params inputs=inputs}}
|
||||
callData: Partial<CallData> = {},
|
||||
@@ -15,6 +14,7 @@ async callAsync(
|
||||
const callDataWithDefaults = await BaseContract._applyDefaultsToTxDataAsync(
|
||||
{
|
||||
to: self.address,
|
||||
...callData,
|
||||
data: encodedData,
|
||||
},
|
||||
self._web3Wrapper.getContractDefaults(),
|
||||
@@ -26,4 +26,3 @@ async callAsync(
|
||||
resultArray = BaseContract._formatABIDataItemList(outputAbi, resultArray, BaseContract._bnToBigNumber.bind(this));
|
||||
return resultArray{{#singleReturnValue}}[0]{{/singleReturnValue}};
|
||||
},
|
||||
{{/hasReturnValue}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface {{name}}ContractEventArgs extends DecodedLogArgs {
|
||||
export interface {{@root.contractName}}{{name}}EventArgs extends DecodedLogArgs {
|
||||
{{#each inputs}}
|
||||
{{name}}: {{#returnType type components}}{{/returnType}};
|
||||
{{/each}}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{{#each inputs}}
|
||||
{{name}},
|
||||
{{name}}{{#if @last}}{{else}},{{/if}}
|
||||
{{/each}}
|
||||
|
||||
20
packages/contracts/.solhint.json
Normal file
20
packages/contracts/.solhint.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "default",
|
||||
"rules": {
|
||||
"avoid-low-level-calls": false,
|
||||
"avoid-tx-origin": "warn",
|
||||
"bracket-align": false,
|
||||
"code-complexity": false,
|
||||
"const-name-snakecase": "error",
|
||||
"expression-indent": "error",
|
||||
"function-max-lines": false,
|
||||
"func-order": "error",
|
||||
"indent": ["error", 4],
|
||||
"max-line-length": ["warn", 160],
|
||||
"no-inline-assembly": false,
|
||||
"quotes": ["error", "double"],
|
||||
"separate-by-one-line-in-contract": "error",
|
||||
"space-after-comma": "error",
|
||||
"statement-indent": "error"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user