Compare commits
243 Commits
0x.js@0.29
...
@0xproject
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
633e3129d4 | ||
|
|
877bdce4c8 | ||
|
|
6e1fbd2d97 | ||
|
|
36bfe62a8f | ||
|
|
8a858501f2 | ||
|
|
e1af25c8a6 | ||
|
|
6091f818da | ||
|
|
a45f9b4802 | ||
|
|
9ccf63b44a | ||
|
|
d34135ae43 | ||
|
|
a81f6f9ad1 | ||
|
|
8a80b10cc2 | ||
|
|
22b1ee132a | ||
|
|
ab7f681f15 | ||
|
|
2ac806ef08 | ||
|
|
13ec8ed03c | ||
|
|
fb77817c2d | ||
|
|
ceb8a492b1 | ||
|
|
cfc868bf4d | ||
|
|
7b4e2257d8 | ||
|
|
4ac6e5477d | ||
|
|
614ea14a7f | ||
|
|
ce45f99006 | ||
|
|
9203813a61 | ||
|
|
ba987b0574 | ||
|
|
b20f34adb7 | ||
|
|
63d0d810b1 | ||
|
|
5491400684 | ||
|
|
6a5165e9b3 | ||
|
|
9a7c4442d2 | ||
|
|
0e5363b5c3 | ||
|
|
d41bce36be | ||
|
|
1380cd811e | ||
|
|
d99bb3a87c | ||
|
|
4b9501318d | ||
|
|
e5eec04f92 | ||
|
|
f9c21efc30 | ||
|
|
ae72b71895 | ||
|
|
87e3fe725d | ||
|
|
807d9e3eef | ||
|
|
9e569b3791 | ||
|
|
024f093585 | ||
|
|
996e9e9102 | ||
|
|
d58bfb46cf | ||
|
|
eb0d7df50b | ||
|
|
547bee38c0 | ||
|
|
60614ba250 | ||
|
|
278f68ae77 | ||
|
|
b4375d6f64 | ||
|
|
9f47c72d31 | ||
|
|
de3bf03f42 | ||
|
|
59a39ac57d | ||
|
|
df9c2b193e | ||
|
|
3894311d68 | ||
|
|
35501dd4fc | ||
|
|
e2ca713658 | ||
|
|
a45de6d427 | ||
|
|
a350638526 | ||
|
|
59f9605ed9 | ||
|
|
9521bf8d4f | ||
|
|
7c1c94d39b | ||
|
|
8a74963815 | ||
|
|
3ebd8b7f45 | ||
|
|
ae8cb2e6a8 | ||
|
|
1ccb978612 | ||
|
|
7040a01cf2 | ||
|
|
6bc0e815e9 | ||
|
|
593f7e826c | ||
|
|
835fa0af13 | ||
|
|
0e3bd0c6c1 | ||
|
|
86668eb7b9 | ||
|
|
771f65c858 | ||
|
|
89d6326a83 | ||
|
|
8b81ea162f | ||
|
|
a53e6db537 | ||
|
|
62e3feeb94 | ||
|
|
a950494503 | ||
|
|
3cb310122e | ||
|
|
feace988b4 | ||
|
|
6a56f20928 | ||
|
|
80a46d14be | ||
|
|
fbcbf066cd | ||
|
|
4d30e1115f | ||
|
|
897cfb491c | ||
|
|
c2c7512431 | ||
|
|
568cf4d182 | ||
|
|
f54330f1c5 | ||
|
|
97e01d7a42 | ||
|
|
4be3e000e1 | ||
|
|
b47baa9ee1 | ||
|
|
f6c98112df | ||
|
|
94d29ab22e | ||
|
|
b0b179550a | ||
|
|
41c7ab4f9c | ||
|
|
432c7c63fe | ||
|
|
2bba1ae292 | ||
|
|
7830d518e0 | ||
|
|
571b3c4da8 | ||
|
|
5b6f8d4c3f | ||
|
|
ae57b21b98 | ||
|
|
292c3bbff8 | ||
|
|
065570ebf5 | ||
|
|
1f5dfd71d5 | ||
|
|
31b3ac4b98 | ||
|
|
7f4a383d75 | ||
|
|
de943c5f30 | ||
|
|
e34b0af251 | ||
|
|
fa7237fde7 | ||
|
|
ed530cef72 | ||
|
|
0f8b2703d1 | ||
|
|
a2176f566b | ||
|
|
bef056b084 | ||
|
|
c8c86c44f8 | ||
|
|
f917a4a34a | ||
|
|
78fd942faa | ||
|
|
a3274ac9b1 | ||
|
|
2e67d69434 | ||
|
|
c2d6e78b2a | ||
|
|
7233a11ba0 | ||
|
|
3a1360ce11 | ||
|
|
ba761044a6 | ||
|
|
d8636a2c5d | ||
|
|
9889c8f9e0 | ||
|
|
7e2e392ecc | ||
|
|
6912a67eba | ||
|
|
6abc83de83 | ||
|
|
0ca66a1469 | ||
|
|
a88be1af44 | ||
|
|
ae47fda257 | ||
|
|
6eb5411029 | ||
|
|
73d13d61a7 | ||
|
|
fdf213ef72 | ||
|
|
22fe605b1e | ||
|
|
bcc902a889 | ||
|
|
24ff2ec30c | ||
|
|
4e0c67e2a1 | ||
|
|
0cc21db654 | ||
|
|
dd5d1c00e5 | ||
|
|
cad2555c03 | ||
|
|
005d8184aa | ||
|
|
c228eddc57 | ||
|
|
ae37f8d9b6 | ||
|
|
6a8113af1d | ||
|
|
0c8cf12650 | ||
|
|
2e29a51ccf | ||
|
|
162f1d94dc | ||
|
|
a76bce1f32 | ||
|
|
be20e04c7b | ||
|
|
d9df82f31d | ||
|
|
6210333628 | ||
|
|
a552a790d3 | ||
|
|
9acb745956 | ||
|
|
875edaf96f | ||
|
|
a9afc0f3f0 | ||
|
|
3bbeaabe26 | ||
|
|
c04cbb480a | ||
|
|
2c241c294e | ||
|
|
ce851f3c28 | ||
|
|
817a6d1828 | ||
|
|
4d0735e7f6 | ||
|
|
80291930f0 | ||
|
|
cf8678b979 | ||
|
|
67722c0fb8 | ||
|
|
0b6e246c04 | ||
|
|
3992295678 | ||
|
|
da404b9acc | ||
|
|
da8db153be | ||
|
|
2c90f7324b | ||
|
|
2cdb0de1c3 | ||
|
|
66bd798e80 | ||
|
|
cf37dfb257 | ||
|
|
217f84204e | ||
|
|
fbbe0ec3db | ||
|
|
1ec34767f9 | ||
|
|
14e94a5376 | ||
|
|
08508afdb2 | ||
|
|
4220f25e01 | ||
|
|
4ff5afecc8 | ||
|
|
2eabb439d9 | ||
|
|
2bc9d5d490 | ||
|
|
9e1c142f02 | ||
|
|
1a38893b52 | ||
|
|
f28d75cf7c | ||
|
|
a3c9d0ace5 | ||
|
|
aea1799a64 | ||
|
|
ef76c4c62b | ||
|
|
210e7c5579 | ||
|
|
3fa0046542 | ||
|
|
d6754685cc | ||
|
|
bb5721700b | ||
|
|
5c4a1dcbd5 | ||
|
|
4f488dee61 | ||
|
|
0d33758104 | ||
|
|
15b5fcbaf9 | ||
|
|
0718b0d5b0 | ||
|
|
0af2ba1b7d | ||
|
|
ea2fdecb83 | ||
|
|
07eb250083 | ||
|
|
ee04717e1b | ||
|
|
d7d22c36ed | ||
|
|
36bf91f920 | ||
|
|
98e9c3b800 | ||
|
|
a7f1137db8 | ||
|
|
f86159e717 | ||
|
|
6e93223ea3 | ||
|
|
a6d677043f | ||
|
|
eb1bf198ac | ||
|
|
0a2f82a19d | ||
|
|
27d9fba785 | ||
|
|
e6a783aff8 | ||
|
|
a767c353d2 | ||
|
|
a39d3d7233 | ||
|
|
40c7ee6355 | ||
|
|
eb760aa33f | ||
|
|
262c34abac | ||
|
|
8019b1b823 | ||
|
|
7a56e83fa3 | ||
|
|
a1c38d9cb2 | ||
|
|
734cf5819a | ||
|
|
35e0b6143a | ||
|
|
e019ae4aed | ||
|
|
c700046b76 | ||
|
|
326a6b729f | ||
|
|
e2ef0c5b94 | ||
|
|
c49f68ef3e | ||
|
|
d0f66f8624 | ||
|
|
4dfa720f2d | ||
|
|
f3b8bac477 | ||
|
|
ce6abad97f | ||
|
|
807e908f78 | ||
|
|
94c75b5262 | ||
|
|
eb0dd6b6e9 | ||
|
|
1c542c3e0d | ||
|
|
d46fcb33c5 | ||
|
|
d5e0da0eb6 | ||
|
|
e744e4cd98 | ||
|
|
9a96e8c704 | ||
|
|
31a94f468e | ||
|
|
7422b9b53b | ||
|
|
161a9d6ad2 | ||
|
|
8fe81c9d09 | ||
|
|
9f3acf8e28 | ||
|
|
31c9c82f6c |
@@ -6,23 +6,117 @@ jobs:
|
|||||||
- image: circleci/node:6.12
|
- image: circleci/node:6.12
|
||||||
environment:
|
environment:
|
||||||
CONTRACTS_COMMIT_HASH: '9ed05f5'
|
CONTRACTS_COMMIT_HASH: '9ed05f5'
|
||||||
|
working_directory: ~/repo
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
|
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
|
||||||
|
- restore_cache:
|
||||||
|
key: dependency-cache-{{ checksum "package.json" }}
|
||||||
- run:
|
- run:
|
||||||
name: yarn
|
name: yarn
|
||||||
command: yarn
|
command: yarn --frozen-lockfile
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: dependency-cache-{{ checksum "package.json" }}
|
key: dependency-cache-{{ checksum "package.json" }}
|
||||||
paths:
|
paths:
|
||||||
- ~/.cache/yarn
|
- ./node_modules
|
||||||
- run: wget https://s3.amazonaws.com/testrpc-shapshots/${CONTRACTS_COMMIT_HASH}.zip
|
- run: wget https://s3.amazonaws.com/testrpc-shapshots/${CONTRACTS_COMMIT_HASH}.zip
|
||||||
- run: unzip ${CONTRACTS_COMMIT_HASH}.zip -d testrpc_snapshot
|
- run: unzip ${CONTRACTS_COMMIT_HASH}.zip -d testrpc_snapshot
|
||||||
- run: node ./node_modules/lerna/bin/lerna.js bootstrap
|
- run: node ./node_modules/lerna/bin/lerna.js bootstrap
|
||||||
- run: yarn lerna:run build
|
- run: yarn lerna:run build
|
||||||
|
- save_cache:
|
||||||
|
key: repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
|
paths:
|
||||||
|
- ~/repo
|
||||||
|
test-0xjs:
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:6.12
|
||||||
|
working_directory: ~/repo
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- run:
|
- run:
|
||||||
name: testrpc
|
name: testrpc
|
||||||
command: npm run testrpc -- --db testrpc_snapshot
|
command: npm run testrpc -- --db testrpc_snapshot
|
||||||
background: true
|
background: true
|
||||||
- run: yarn lerna:run test:circleci
|
- run: yarn lerna:run --scope 0x.js test:circleci
|
||||||
|
test-contracts:
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:6.12
|
||||||
|
working_directory: ~/repo
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
|
- run:
|
||||||
|
name: testrpc
|
||||||
|
command: npm run testrpc -- --db testrpc_snapshot
|
||||||
|
background: true
|
||||||
|
- run: yarn lerna:run --scope contracts test:circleci
|
||||||
|
test-deployer:
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:6.12
|
||||||
|
working_directory: ~/repo
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
|
- run:
|
||||||
|
name: testrpc
|
||||||
|
command: npm run testrpc -- --db testrpc_snapshot
|
||||||
|
background: true
|
||||||
|
- run: yarn lerna:run --scope @0xproject/deployer test:circleci
|
||||||
|
test-rest:
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:6.12
|
||||||
|
working_directory: ~/repo
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
|
- run:
|
||||||
|
name: testrpc
|
||||||
|
command: npm run testrpc -- --db testrpc_snapshot
|
||||||
|
background: true
|
||||||
|
- run: yarn lerna:run --ignore contracts --ignore 0x.js --ignore @0xproject/deployer test:circleci
|
||||||
|
lint:
|
||||||
|
working_directory: ~/repo
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:6.12
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
- run: yarn lerna:run lint
|
- run: yarn lerna:run lint
|
||||||
|
prettier:
|
||||||
|
working_directory: ~/repo
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:6.12
|
||||||
|
steps:
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||||
|
- run: yarn prettier:ci
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
main:
|
||||||
|
jobs:
|
||||||
|
- build
|
||||||
|
- test-0xjs:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
- test-contracts:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
- test-deployer:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
- test-rest:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
- prettier:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
- lint:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
|||||||
4
.prettierignore
Normal file
4
.prettierignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
lib
|
||||||
|
generated
|
||||||
|
.nyc_output
|
||||||
|
/packages/contracts/build/contracts
|
||||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"printWidth": 120,
|
||||||
|
"trailingComma": all,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
0x Contribution Guide
|
## 0x Contribution Guide
|
||||||
---------------------
|
|
||||||
|
|
||||||
Thank you for your interest in contributing to 0x protocol! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes!
|
Thank you for your interest in contributing to 0x protocol! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes!
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
This PR:
|
This PR:
|
||||||
*
|
|
||||||
|
\*
|
||||||
|
|||||||
58
README.md
58
README.md
@@ -11,43 +11,47 @@ This repository contains all the 0x developer tools written in TypeScript. Our h
|
|||||||
|
|
||||||
[](https://circleci.com/gh/0xProject/0x.js)
|
[](https://circleci.com/gh/0xProject/0x.js)
|
||||||
[](https://coveralls.io/github/0xProject/0x.js?branch=master)
|
[](https://coveralls.io/github/0xProject/0x.js?branch=master)
|
||||||
[](https://chat.0xproject.com)
|
||||||
)](https://chat.0xproject.com)
|
|
||||||
[](https://gitter.im/0xProject/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/0xProject/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[](https://opensource.org/licenses/Apache-2.0)
|
[](https://opensource.org/licenses/Apache-2.0)
|
||||||
[](https://greenkeeper.io/)
|
[](https://greenkeeper.io/)
|
||||||
|
|
||||||
### Published Packages
|
### Published Packages
|
||||||
|
|
||||||
| Package | Version | Description |
|
| Package | Version | Description |
|
||||||
|---------|---------|-------------|
|
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
||||||
| [`0x.js`](/packages/0x.js) | [](https://www.npmjs.com/package/0x.js) | A Javascript library for interacting with the 0x protocol |
|
| [`0x.js`](/packages/0x.js) | [](https://www.npmjs.com/package/0x.js) | A Javascript library for interacting with the 0x protocol |
|
||||||
| [`@0xproject/abi-gen`](/packages/abi-gen) | [](https://www.npmjs.com/package/@0xproject/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
|
| [`chai-as-promised-typescript-typings`](/packages/chai-as-promised-typescript-typings) | [](https://www.npmjs.com/package/chai-as-promised-typescript-typings) | Chai as promised typescript typings |
|
||||||
| [`@0xproject/assert`](/packages/assert) | [](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages |
|
| [`chai-typescript-typings`](/packages/chai-typescript-typings) | [](https://www.npmjs.com/package/chai-typescript-typings) | Chai typescript typings |
|
||||||
| [`@0xproject/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the standard relayer api |
|
| [`web3-typescript-typings`](/packages/web3-typescript-typings) | [](https://www.npmjs.com/package/web3-typescript-typings) | Web3 typescript typings |
|
||||||
| [`@0xproject/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas |
|
| [`@0xproject/abi-gen`](/packages/abi-gen) | [](https://www.npmjs.com/package/@0xproject/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
|
||||||
| [`@0xproject/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
|
| [`@0xproject/assert`](/packages/assert) | [](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages |
|
||||||
| [`@0xproject/tslint-config`](/packages/tslint-config) | [](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules |
|
| [`@0xproject/connect`](/packages/connect) | [](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the standard relayer api |
|
||||||
| [`@0xproject/types`](/packages/types) | [](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations |
|
| [`@0xproject/dev-utils`](/packages/dev-utils) | [](https://www.npmjs.com/package/@0xproject/dev-utils) | Dev utils to be shared across 0x projects and packages |
|
||||||
| [`@0xproject/utils`](/packages/utils) | [](https://www.npmjs.com/package/@0xproject/utils) | Shared utilities |
|
| [`@0xproject/json-schemas`](/packages/json-schemas) | [](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas |
|
||||||
| [`@0xproject/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0xproject/web3-wrapper) | Web3 wrapper |
|
| [`@0xproject/subproviders`](/packages/subproviders) | [](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
|
||||||
|
| [`@0xproject/tslint-config`](/packages/tslint-config) | [](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules |
|
||||||
|
| [`@0xproject/types`](/packages/types) | [](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations |
|
||||||
|
| [`@0xproject/utils`](/packages/utils) | [](https://www.npmjs.com/package/@0xproject/utils) | Shared utilities |
|
||||||
|
| [`@0xproject/web3-wrapper`](/packages/web3-wrapper) | [](https://www.npmjs.com/package/@0xproject/web3-wrapper) | Web3 wrapper |
|
||||||
|
|
||||||
### Private Packages
|
### Private Packages
|
||||||
|
|
||||||
| Package | Description |
|
| Package | Description |
|
||||||
|---------|-------------|
|
| ----------------------------------------------------------- | ---------------------------------------------------------------- |
|
||||||
| [`@0xproject/contracts`](/packages/contracts) | 0x solidity smart contracts & tests |
|
| [`@0xproject/contracts`](/packages/contracts) | 0x solidity smart contracts & tests |
|
||||||
| [`@0xproject/kovan_faucets`](/packages/kovan-faucets) | A faucet micro-service that dispenses test ERC20 tokens or Ether |
|
| [`@0xproject/kovan_faucets`](/packages/kovan-faucets) | A faucet micro-service that dispenses test ERC20 tokens or Ether |
|
||||||
| [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts) | Shared monorepo scripts |
|
| [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts) | Shared monorepo scripts |
|
||||||
| [`@0xproject/website`](/packages/website) | 0x website & Portal DApp |
|
| [`@0xproject/website`](/packages/website) | 0x website & Portal DApp |
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Dedicated documentation pages:
|
Dedicated documentation pages:
|
||||||
- [0x.js Library](https://0xproject.com/docs/0xjs)
|
|
||||||
- [0x Connect](https://0xproject.com/docs/connect)
|
* [0x.js Library](https://0xproject.com/docs/0xjs)
|
||||||
- [Smart contracts](https://0xproject.com/docs/contracts)
|
* [0x Connect](https://0xproject.com/docs/connect)
|
||||||
- [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
|
* [Smart contracts](https://0xproject.com/docs/contracts)
|
||||||
|
* [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -58,11 +62,13 @@ Please read our [contribution guidelines](./CONTRIBUTING.md) before getting star
|
|||||||
### Install dependencies
|
### Install dependencies
|
||||||
|
|
||||||
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
|
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn config set workspaces-experimental true
|
yarn config set workspaces-experimental true
|
||||||
```
|
```
|
||||||
|
|
||||||
Then install dependencies
|
Then install dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
@@ -78,6 +84,7 @@ yarn lerna:run build
|
|||||||
### Lint
|
### Lint
|
||||||
|
|
||||||
Lint all packages
|
Lint all packages
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn lerna:run lint
|
yarn lerna:run lint
|
||||||
```
|
```
|
||||||
@@ -87,11 +94,13 @@ yarn lerna:run lint
|
|||||||
Before running the tests, you will need to spin up a [TestRPC](https://www.npmjs.com/package/ethereumjs-testrpc) instance and deploy all the 0x smart contracts.
|
Before running the tests, you will need to spin up a [TestRPC](https://www.npmjs.com/package/ethereumjs-testrpc) instance and deploy all the 0x smart contracts.
|
||||||
|
|
||||||
In a separate terminal, start TestRPC (a convenience command is provided as part of this repo)
|
In a separate terminal, start TestRPC (a convenience command is provided as part of this repo)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn testrpc
|
yarn testrpc
|
||||||
```
|
```
|
||||||
|
|
||||||
Then in your main terminal run
|
Then in your main terminal run
|
||||||
|
|
||||||
```
|
```
|
||||||
cd packages/contracts
|
cd packages/contracts
|
||||||
yarn migrate
|
yarn migrate
|
||||||
@@ -99,6 +108,7 @@ cd ..
|
|||||||
```
|
```
|
||||||
|
|
||||||
And finally from the root project directory run
|
And finally from the root project directory run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn lerna:run test
|
yarn lerna:run test
|
||||||
```
|
```
|
||||||
|
|||||||
12
lerna.json
12
lerna.json
@@ -1,9 +1,7 @@
|
|||||||
{
|
{
|
||||||
"lerna": "2.5.1",
|
"lerna": "2.5.1",
|
||||||
"packages": [
|
"packages": ["packages/*"],
|
||||||
"packages/*"
|
"version": "independent",
|
||||||
],
|
"npmClient": "yarn",
|
||||||
"version": "independent",
|
"useWorkspaces": true
|
||||||
"npmClient": "yarn",
|
|
||||||
"useWorkspaces": true
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -1,23 +1,25 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "0x.js",
|
"name": "0x.js",
|
||||||
"workspaces": [
|
"workspaces": ["packages/*"],
|
||||||
"packages/*"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
|
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
|
||||||
|
"prettier": "prettier --write '**/*.{ts,tsx,json,md}'",
|
||||||
|
"prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}'",
|
||||||
"lerna:run": "lerna run",
|
"lerna:run": "lerna run",
|
||||||
"lerna:rebuild": "lerna run clean; lerna run build;",
|
"lerna:rebuild": "lerna run clean; lerna run build;",
|
||||||
"lerna:publish": "yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
|
"lerna:publish":
|
||||||
|
"yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/utils": "^0.1.0",
|
"@0xproject/utils": "^0.2.0",
|
||||||
"async-child-process": "^1.1.1",
|
"async-child-process": "^1.1.1",
|
||||||
"ethereumjs-testrpc": "6.0.3",
|
"ethereumjs-testrpc": "^6.0.3",
|
||||||
"lerna": "^2.5.1",
|
"lerna": "^2.5.1",
|
||||||
|
"prettier": "1.9.2",
|
||||||
"publish-release": "0xproject/publish-release",
|
"publish-release": "0xproject/publish-release",
|
||||||
"semver-sort": "^0.0.4"
|
"semver-sort": "^0.0.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,27 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
v0.29.0 - _December 28, 2017_
|
## v0.30.1 - _January 18, 2018_
|
||||||
------------------------
|
|
||||||
|
* Fix a bug allowing negative fill values (#212)
|
||||||
|
* Fix a bug that made it impossible to pass a custom ZRX address (#341)
|
||||||
|
|
||||||
|
## v0.30.0 - _January 17, 2018_
|
||||||
|
|
||||||
|
* Add an error parameter to the order watcher callback (#312)
|
||||||
|
* Fix a bug making it impossible to catch some errors from awaitTransactionMinedAsync (#312)
|
||||||
|
* Fix a bug in fillOrdersUpTo validation making it impossible to fill up to if user doesn't have enough balance to fully fill all the orders (#321)
|
||||||
|
|
||||||
|
## v0.29.1 - _January 11, 2018_
|
||||||
|
|
||||||
|
* Fixed bignumber config issue #301 (#305)
|
||||||
|
|
||||||
|
## v0.29.0 - _December 28, 2017_
|
||||||
|
|
||||||
* Assert baseUnit amount supplied to `toUnitAmount` is integer amount. (#287)
|
* Assert baseUnit amount supplied to `toUnitAmount` is integer amount. (#287)
|
||||||
* `toBaseUnitAmount` throws if amount supplied has too many decimals (#287)
|
* `toBaseUnitAmount` throws if amount supplied has too many decimals (#287)
|
||||||
|
|
||||||
v0.28.0 - _December 20, 2017_
|
## v0.28.0 - _December 20, 2017_
|
||||||
------------------------
|
|
||||||
* Add `etherTokenAddress` arg to `depositAsync` and `withdrawAsync` methods on `zeroEx.etherToken` (#267)
|
* Add `etherTokenAddress` arg to `depositAsync` and `withdrawAsync` methods on `zeroEx.etherToken` (#267)
|
||||||
* Removed accidentally included `unsubscribeAll` method from `zeroEx.proxy`, `zeroEx.etherToken` and `zeroEx.tokenRegistry` (#267)
|
* Removed accidentally included `unsubscribeAll` method from `zeroEx.proxy`, `zeroEx.etherToken` and `zeroEx.tokenRegistry` (#267)
|
||||||
* Removed `etherTokenContractAddress` from `ZeroEx` constructor arg `ZeroExConfig` (#267)
|
* Removed `etherTokenContractAddress` from `ZeroEx` constructor arg `ZeroExConfig` (#267)
|
||||||
@@ -17,12 +32,12 @@ v0.28.0 - _December 20, 2017_
|
|||||||
* Support `Deposit` and `Withdraw` events on etherToken (#277)
|
* Support `Deposit` and `Withdraw` events on etherToken (#277)
|
||||||
* Improve the error message when taker is not a string (#278)
|
* Improve the error message when taker is not a string (#278)
|
||||||
|
|
||||||
v0.27.1 - _November 28, 2017_
|
## v0.27.1 - _November 28, 2017_
|
||||||
------------------------
|
|
||||||
* Export `TransactionOpts` type
|
* Export `TransactionOpts` type
|
||||||
|
|
||||||
v0.27.0 - _November 28, 2017_
|
## v0.27.0 - _November 28, 2017_
|
||||||
------------------------
|
|
||||||
* Make `ZeroExConfig` required parameter of `ZeroEx` constructor (#233)
|
* Make `ZeroExConfig` required parameter of `ZeroEx` constructor (#233)
|
||||||
* Add a required property `networkId` to `ZeroExConfig` (#233)
|
* Add a required property `networkId` to `ZeroExConfig` (#233)
|
||||||
* Make all `getContractAddress` functions, `zeroEx.exchange.subscribe`, `zeroEx.exchange.getZRXTokenAddress` sync (#233)
|
* Make all `getContractAddress` functions, `zeroEx.exchange.subscribe`, `zeroEx.exchange.getZRXTokenAddress` sync (#233)
|
||||||
@@ -33,66 +48,66 @@ v0.27.0 - _November 28, 2017_
|
|||||||
* All transaction sending methods now call `estimateGas` if no gas amount was supplied (#235)
|
* All transaction sending methods now call `estimateGas` if no gas amount was supplied (#235)
|
||||||
* Modify order validation methods to validate against the `latest` block, not against the `pending` block (#236)
|
* Modify order validation methods to validate against the `latest` block, not against the `pending` block (#236)
|
||||||
|
|
||||||
v0.26.0 - _November 21, 2017_
|
## v0.26.0 - _November 21, 2017_
|
||||||
------------------------
|
|
||||||
* Add post-formatter for logs converting `blockNumber`, `logIndex`, `transactionIndex` from hexes to numbers (#231)
|
* Add post-formatter for logs converting `blockNumber`, `logIndex`, `transactionIndex` from hexes to numbers (#231)
|
||||||
* Remove support for Async callback types when used in Subscribe functions (#222)
|
* Remove support for Async callback types when used in Subscribe functions (#222)
|
||||||
* In OrderWatcher subscribe to ZRX Token Transfer and Approval events when maker token is different (#225)
|
* In OrderWatcher subscribe to ZRX Token Transfer and Approval events when maker token is different (#225)
|
||||||
|
|
||||||
v0.25.1 - _November 13, 2017_
|
## v0.25.1 - _November 13, 2017_
|
||||||
------------------------
|
|
||||||
* Standardise on Cancelled over Canceled (#217)
|
* Standardise on Cancelled over Canceled (#217)
|
||||||
* Add missing `DecodedLogEvent` type to exported types (#205)
|
* Add missing `DecodedLogEvent` type to exported types (#205)
|
||||||
* Normalized the transactionReceipt status to be `null|0|1`, 1 meaning transaction execution successful, 0 unsuccessful and `null` if it is a pre-byzantinium transaction. (#200)
|
* Normalized the transactionReceipt status to be `null|0|1`, 1 meaning transaction execution successful, 0 unsuccessful and `null` if it is a pre-byzantinium transaction. (#200)
|
||||||
|
|
||||||
v0.23.0 - _November 12, 2017_
|
## v0.23.0 - _November 12, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed unhandled promise rejection error in subscribe methods (#209)
|
* Fixed unhandled promise rejection error in subscribe methods (#209)
|
||||||
* Subscribe callbacks now receive an error object as their first argument
|
* Subscribe callbacks now receive an error object as their first argument
|
||||||
|
|
||||||
v0.22.6 - _November 10, 2017_
|
## v0.22.6 - _November 10, 2017_
|
||||||
------------------------
|
|
||||||
* Add a timeout parameter to transaction awaiting (#206)
|
* Add a timeout parameter to transaction awaiting (#206)
|
||||||
|
|
||||||
v0.22.5 - _November 7, 2017_
|
## v0.22.5 - _November 7, 2017_
|
||||||
------------------------
|
|
||||||
* Re-publish v0.22.4 to fix publishing issue
|
* Re-publish v0.22.4 to fix publishing issue
|
||||||
|
|
||||||
v0.22.4 - _October 25, 2017_
|
## v0.22.4 - _October 25, 2017_
|
||||||
------------------------
|
|
||||||
* Upgraded bignumber.js to a new version that ships with native typings
|
* Upgraded bignumber.js to a new version that ships with native typings
|
||||||
|
|
||||||
v0.22.3 - _October 25, 2017_
|
## v0.22.3 - _October 25, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed an issue with new version of testrpc and unlimited proxy allowance (#199)
|
* Fixed an issue with new version of testrpc and unlimited proxy allowance (#199)
|
||||||
|
|
||||||
v0.22.2 - _October 24, 2017_
|
## v0.22.2 - _October 24, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed rounding of maker fill amount and incorrect validation of partial fees (#197)
|
* Fixed rounding of maker fill amount and incorrect validation of partial fees (#197)
|
||||||
|
|
||||||
v0.22.0 - _October 16, 2017_
|
## v0.22.0 - _October 16, 2017_
|
||||||
------------------------
|
|
||||||
* Started using `OrderFillRequest` interface instead of `OrderFillOrKillRequest` interface for `zeroEx.exchange.batchFillOrKill` (#187)
|
* Started using `OrderFillRequest` interface instead of `OrderFillOrKillRequest` interface for `zeroEx.exchange.batchFillOrKill` (#187)
|
||||||
* Removed `OrderFillOrKillRequest` (#187)
|
* Removed `OrderFillOrKillRequest` (#187)
|
||||||
|
|
||||||
v0.21.4 - _October 13, 2017_
|
## v0.21.4 - _October 13, 2017_
|
||||||
------------------------
|
|
||||||
* Made 0x.js more type-safe by making `getLogsAsync` and `subscribe/subscribeAsync` generics parametrized with arg type (#194)
|
* Made 0x.js more type-safe by making `getLogsAsync` and `subscribe/subscribeAsync` generics parametrized with arg type (#194)
|
||||||
|
|
||||||
v0.21.3 - _October 12, 2017_
|
## v0.21.3 - _October 12, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed a bug causing order fills to throw `INSUFFICIENT_TAKER_ALLOWANCE` (#193)
|
* Fixed a bug causing order fills to throw `INSUFFICIENT_TAKER_ALLOWANCE` (#193)
|
||||||
|
|
||||||
v0.21.2 - _October 11, 2017_
|
## v0.21.2 - _October 11, 2017_
|
||||||
------------------------
|
|
||||||
* Exported `ContractEventArg` as a public type (#190)
|
* Exported `ContractEventArg` as a public type (#190)
|
||||||
|
|
||||||
v0.21.1 - _October 11, 2017_
|
## v0.21.1 - _October 11, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed a bug in subscriptions (#189)
|
* Fixed a bug in subscriptions (#189)
|
||||||
|
|
||||||
v0.21.0 - _October 10, 2017_
|
## v0.21.0 - _October 10, 2017_
|
||||||
------------------------
|
|
||||||
* Complete rewrite of subscription logic (#182)
|
* Complete rewrite of subscription logic (#182)
|
||||||
* Subscriptions no longer return historical logs. If you want them - use `getLogsAsync`
|
* Subscriptions no longer return historical logs. If you want them - use `getLogsAsync`
|
||||||
* Subscriptions now use [ethereumjs-blockstream](https://github.com/ethereumjs/ethereumjs-blockstream) under the hood
|
* Subscriptions now use [ethereumjs-blockstream](https://github.com/ethereumjs/ethereumjs-blockstream) under the hood
|
||||||
@@ -106,77 +121,77 @@ v0.21.0 - _October 10, 2017_
|
|||||||
* Renamed `zeroEx.token.stopWatchingAllEventsAsync` to `zeroEx.token.unsubscribeAll`
|
* Renamed `zeroEx.token.stopWatchingAllEventsAsync` to `zeroEx.token.unsubscribeAll`
|
||||||
* Fixed the batch fills validation by emulating all balance & proxy allowance changes (#185)
|
* Fixed the batch fills validation by emulating all balance & proxy allowance changes (#185)
|
||||||
|
|
||||||
v0.20.0 - _October 5, 2017_
|
## v0.20.0 - _October 5, 2017_
|
||||||
------------------------
|
|
||||||
* Add `zeroEx.token.getLogsAsync` (#178)
|
* Add `zeroEx.token.getLogsAsync` (#178)
|
||||||
* Add `zeroEx.exchange.getLogsAsync` (#178)
|
* Add `zeroEx.exchange.getLogsAsync` (#178)
|
||||||
* Fixed fees validation when one of the tokens transferred is ZRX (#181)
|
* Fixed fees validation when one of the tokens transferred is ZRX (#181)
|
||||||
|
|
||||||
v0.19.0 - _September 29, 2017_
|
## v0.19.0 - _September 29, 2017_
|
||||||
------------------------
|
|
||||||
* Made order validation optional (#172)
|
* Made order validation optional (#172)
|
||||||
* Added Ropsten testnet support (#173)
|
* Added Ropsten testnet support (#173)
|
||||||
* Fixed a bug causing awaitTransactionMinedAsync to DDos backend nodes (#175)
|
* Fixed a bug causing awaitTransactionMinedAsync to DDos backend nodes (#175)
|
||||||
|
|
||||||
v0.18.0 - _September 26, 2017_
|
## v0.18.0 - _September 26, 2017_
|
||||||
------------------------
|
|
||||||
* Added `zeroEx.exchange.validateOrderFillableOrThrowAsync` to simplify orderbook pruning (#170)
|
* Added `zeroEx.exchange.validateOrderFillableOrThrowAsync` to simplify orderbook pruning (#170)
|
||||||
|
|
||||||
v0.17.0 - _September 26, 2017_
|
## v0.17.0 - _September 26, 2017_
|
||||||
------------------------
|
|
||||||
* Made `zeroEx.exchange.getZRXTokenAddressAsync` public (#171)
|
* Made `zeroEx.exchange.getZRXTokenAddressAsync` public (#171)
|
||||||
|
|
||||||
v0.16.0 - _September 20, 2017_
|
## v0.16.0 - _September 20, 2017_
|
||||||
------------------------
|
|
||||||
* Added the ability to specify custom contract addresses to be used with 0x.js (#165)
|
* Added the ability to specify custom contract addresses to be used with 0x.js (#165)
|
||||||
* ZeroExConfig.exchangeContractAddress
|
* ZeroExConfig.exchangeContractAddress
|
||||||
* ZeroExConfig.tokenRegistryContractAddress
|
* ZeroExConfig.tokenRegistryContractAddress
|
||||||
* ZeroExConfig.etherTokenContractAddress
|
* ZeroExConfig.etherTokenContractAddress
|
||||||
* Added `zeroEx.tokenRegistry.getContractAddressAsync` (#165)
|
* Added `zeroEx.tokenRegistry.getContractAddressAsync` (#165)
|
||||||
|
|
||||||
v0.15.0 - _September 8, 2017_
|
## v0.15.0 - _September 8, 2017_
|
||||||
------------------------
|
|
||||||
* Added the ability to specify a historical `blockNumber` at which to query the blockchain's state when calling a token or exchange method (#161)
|
* Added the ability to specify a historical `blockNumber` at which to query the blockchain's state when calling a token or exchange method (#161)
|
||||||
|
|
||||||
v0.14.2 - _September 7, 2017_
|
## v0.14.2 - _September 7, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed an issue with bignumber.js types not found (#160)
|
* Fixed an issue with bignumber.js types not found (#160)
|
||||||
|
|
||||||
v0.14.1 - _September 7, 2017_
|
## v0.14.1 - _September 7, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed an issue with Artifact type not found (#159)
|
* Fixed an issue with Artifact type not found (#159)
|
||||||
|
|
||||||
v0.14.0 - _September 6, 2017_
|
## v0.14.0 - _September 6, 2017_
|
||||||
------------------------
|
|
||||||
* Added `zeroEx.exchange.throwLogErrorsAsErrors` method to public interface (#157)
|
* Added `zeroEx.exchange.throwLogErrorsAsErrors` method to public interface (#157)
|
||||||
* Fixed an issue with overlapping async intervals in `zeroEx.awaitTransactionMinedAsync` (#157)
|
* Fixed an issue with overlapping async intervals in `zeroEx.awaitTransactionMinedAsync` (#157)
|
||||||
* Fixed an issue with log decoder returning `BigNumber`s as `strings` (#157)
|
* Fixed an issue with log decoder returning `BigNumber`s as `strings` (#157)
|
||||||
|
|
||||||
v0.13.0 - _September 6, 2017_
|
## v0.13.0 - _September 6, 2017_
|
||||||
------------------------
|
|
||||||
* Made all the functions submitting transactions to the network to immediately return transaction hash (#151)
|
* Made all the functions submitting transactions to the network to immediately return transaction hash (#151)
|
||||||
* Added `zeroEx.awaitTransactionMinedAsync` (#151)
|
* Added `zeroEx.awaitTransactionMinedAsync` (#151)
|
||||||
* Added `TransactionReceiptWithDecodedLogs`, `LogWithDecodedArgs`, `DecodedLogArgs` to public types (#151)
|
* Added `TransactionReceiptWithDecodedLogs`, `LogWithDecodedArgs`, `DecodedLogArgs` to public types (#151)
|
||||||
* Added signature validation to `validateFillOrderThrowIfInvalidAsync` (#152)
|
* Added signature validation to `validateFillOrderThrowIfInvalidAsync` (#152)
|
||||||
|
|
||||||
v0.12.1 - _September 2, 2017_
|
## v0.12.1 - _September 2, 2017_
|
||||||
------------------------
|
|
||||||
* Added the support for web3@1.x.x provider (#142)
|
* Added the support for web3@1.x.x provider (#142)
|
||||||
* Added the optional `zeroExConfig` parameter to the constructor of `ZeroEx` (#139)
|
* Added the optional `zeroExConfig` parameter to the constructor of `ZeroEx` (#139)
|
||||||
* Added the ability to specify `gasPrice` when instantiating `ZeroEx` (#139)
|
* Added the ability to specify `gasPrice` when instantiating `ZeroEx` (#139)
|
||||||
|
|
||||||
v0.11.0 - _August 24, 2017_
|
## v0.11.0 - _August 24, 2017_
|
||||||
------------------------
|
|
||||||
* Added `zeroEx.token.setUnlimitedProxyAllowanceAsync` (#137)
|
* Added `zeroEx.token.setUnlimitedProxyAllowanceAsync` (#137)
|
||||||
* Added `zeroEx.token.setUnlimitedAllowanceAsync` (#137)
|
* Added `zeroEx.token.setUnlimitedAllowanceAsync` (#137)
|
||||||
* Added `zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS` (#137)
|
* Added `zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS` (#137)
|
||||||
|
|
||||||
v0.10.4 - _Aug 24, 2017_
|
## v0.10.4 - _Aug 24, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed a bug where checksummed addresses were being pulled from artifacts and not lower-cased. (#135)
|
* Fixed a bug where checksummed addresses were being pulled from artifacts and not lower-cased. (#135)
|
||||||
|
|
||||||
v0.10.1 - _Aug 24, 2017_
|
## v0.10.1 - _Aug 24, 2017_
|
||||||
------------------------
|
|
||||||
* Added `zeroEx.exchange.validateFillOrderThrowIfInvalidAsync` (#128)
|
* Added `zeroEx.exchange.validateFillOrderThrowIfInvalidAsync` (#128)
|
||||||
* Added `zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync` (#128)
|
* Added `zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync` (#128)
|
||||||
* Added `zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync` (#128)
|
* Added `zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync` (#128)
|
||||||
@@ -190,21 +205,21 @@ v0.10.1 - _Aug 24, 2017_
|
|||||||
* Added clear error message when checksummed address is passed to a public method (#124)
|
* Added clear error message when checksummed address is passed to a public method (#124)
|
||||||
* Fixes the description of `shouldThrowOnInsufficientBalanceOrAllowance` in docs (#127)
|
* Fixes the description of `shouldThrowOnInsufficientBalanceOrAllowance` in docs (#127)
|
||||||
|
|
||||||
v0.9.3 - _Aug 22, 2017_
|
## v0.9.3 - _Aug 22, 2017_
|
||||||
------------------------
|
|
||||||
* Update contract artifacts to include latest Kovan and Mainnet deploys (#118)
|
* Update contract artifacts to include latest Kovan and Mainnet deploys (#118)
|
||||||
|
|
||||||
v0.9.2 - _Aug 21, 2017_
|
## v0.9.2 - _Aug 21, 2017_
|
||||||
------------------------
|
|
||||||
* *This version was unpublished because of a publishing issue.*
|
* *This version was unpublished because of a publishing issue.*
|
||||||
* Update contract artifacts to include latest Kovan and Mainnet deploys (#118)
|
* Update contract artifacts to include latest Kovan and Mainnet deploys (#118)
|
||||||
|
|
||||||
v0.9.1 - _Aug. 16, 2017_
|
## v0.9.1 - _Aug. 16, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed the bug causing `zeroEx.token.getBalanceAsync()` to fail if no addresses available (#120)
|
* Fixed the bug causing `zeroEx.token.getBalanceAsync()` to fail if no addresses available (#120)
|
||||||
|
|
||||||
v0.9.0 - _Jul. 26, 2017_
|
## v0.9.0 - _Jul. 26, 2017_
|
||||||
------------------------
|
|
||||||
* Migrated to the new version of smart contracts (#101)
|
* Migrated to the new version of smart contracts (#101)
|
||||||
* Removed the ability to call methods on multiple authorized Exchange smart contracts (#106)
|
* Removed the ability to call methods on multiple authorized Exchange smart contracts (#106)
|
||||||
* Made `zeroEx.getOrderHashHex` a static method (#107)
|
* Made `zeroEx.getOrderHashHex` a static method (#107)
|
||||||
@@ -214,8 +229,8 @@ v0.9.0 - _Jul. 26, 2017_
|
|||||||
* Updated to typescript v2.4 (#104)
|
* Updated to typescript v2.4 (#104)
|
||||||
* Fixed an issue with incorrect balance/allowance validation when ZRX is one of the tokens traded (#109)
|
* Fixed an issue with incorrect balance/allowance validation when ZRX is one of the tokens traded (#109)
|
||||||
|
|
||||||
v0.8.0 - _Jul. 4, 2017_
|
## v0.8.0 - _Jul. 4, 2017_
|
||||||
------------------------
|
|
||||||
* Added the ability to call methods on different authorized versions of the Exchange smart contract (#82)
|
* Added the ability to call methods on different authorized versions of the Exchange smart contract (#82)
|
||||||
* Updated contract artifacts to reflect latest changes to the smart contracts (0xproject/contracts#59)
|
* Updated contract artifacts to reflect latest changes to the smart contracts (0xproject/contracts#59)
|
||||||
* Added `zeroEx.proxy.isAuthorizedAsync` and `zeroEx.proxy.getAuthorizedAddressesAsync` (#89)
|
* Added `zeroEx.proxy.isAuthorizedAsync` and `zeroEx.proxy.getAuthorizedAddressesAsync` (#89)
|
||||||
@@ -227,35 +242,35 @@ v0.8.0 - _Jul. 4, 2017_
|
|||||||
* `zeroEx.tokenRegistry.invalidateContractInstance`
|
* `zeroEx.tokenRegistry.invalidateContractInstance`
|
||||||
* Fixed the bug where `zeroEx.setProviderAsync` didn't invalidate etherToken contract's instance
|
* Fixed the bug where `zeroEx.setProviderAsync` didn't invalidate etherToken contract's instance
|
||||||
|
|
||||||
v0.7.1 - _Jun. 26, 2017_
|
## v0.7.1 - _Jun. 26, 2017_
|
||||||
------------------------
|
|
||||||
* Added the ability to convert Ether to wrapped Ether tokens and back via `zeroEx.etherToken.depostAsync` and `zeroEx.etherToken.withdrawAsync` (#81)
|
* Added the ability to convert Ether to wrapped Ether tokens and back via `zeroEx.etherToken.depostAsync` and `zeroEx.etherToken.withdrawAsync` (#81)
|
||||||
|
|
||||||
v0.7.0 - _Jun. 22, 2017_
|
## v0.7.0 - _Jun. 22, 2017_
|
||||||
------------------------
|
|
||||||
* Added Kovan smart contract artifacts (#78)
|
* Added Kovan smart contract artifacts (#78)
|
||||||
* Started returning fillAmount from `fillOrderAsync` and `fillUpToAsync` (#72)
|
* Started returning fillAmount from `fillOrderAsync` and `fillUpToAsync` (#72)
|
||||||
* Started returning cancelledAmount from `cancelOrderAsync` (#72)
|
* Started returning cancelledAmount from `cancelOrderAsync` (#72)
|
||||||
* Renamed type `LogCancelArgs` to `LogCancelContractEventArgs` and `LogFillArgs` to `LogFillContractEventArgs`
|
* Renamed type `LogCancelArgs` to `LogCancelContractEventArgs` and `LogFillArgs` to `LogFillContractEventArgs`
|
||||||
|
|
||||||
v0.6.2 - _Jun. 21, 2017_
|
## v0.6.2 - _Jun. 21, 2017_
|
||||||
------------------------
|
|
||||||
* Reduced bundle size
|
* Reduced bundle size
|
||||||
* Improved documentation
|
* Improved documentation
|
||||||
|
|
||||||
v0.6.1 - _Jun. 19, 2017_
|
## v0.6.1 - _Jun. 19, 2017_
|
||||||
------------------------
|
|
||||||
* Improved documentation
|
* Improved documentation
|
||||||
|
|
||||||
v0.6.0 - _Jun. 19, 2017_
|
## v0.6.0 - _Jun. 19, 2017_
|
||||||
------------------------
|
|
||||||
* Made `ZeroEx` class accept `Web3Provider` instance instead of `Web3` instance
|
* Made `ZeroEx` class accept `Web3Provider` instance instead of `Web3` instance
|
||||||
* Added types for contract event arguments
|
* Added types for contract event arguments
|
||||||
|
|
||||||
v0.5.2 - _Jun. 15, 2017_
|
## v0.5.2 - _Jun. 15, 2017_
|
||||||
------------------------
|
|
||||||
* Fixed the bug in `postpublish` script that caused that only unminified UMD bundle was uploaded to release page
|
* Fixed the bug in `postpublish` script that caused that only unminified UMD bundle was uploaded to release page
|
||||||
|
|
||||||
v0.5.1 - _Jun. 15, 2017_
|
## v0.5.1 - _Jun. 15, 2017_
|
||||||
------------------------
|
|
||||||
* Added `postpublish` script to publish to Github Releases with assets.
|
* Added `postpublish` script to publish to Github Releases with assets.
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
0x.js
|
## 0x.js
|
||||||
-----
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
0x.js ships as both a [UMD](https://github.com/umdjs/umd) module and a [CommonJS](https://en.wikipedia.org/wiki/CommonJS) package.
|
0x.js ships as both a [UMD](https://github.com/umdjs/umd) module and a [CommonJS](https://en.wikipedia.org/wiki/CommonJS) package.
|
||||||
|
|
||||||
#### CommonJS *(recommended)*:
|
#### CommonJS _(recommended)_:
|
||||||
|
|
||||||
**Install**
|
**Install**
|
||||||
|
|
||||||
@@ -16,7 +15,7 @@ npm install 0x.js --save
|
|||||||
**Import**
|
**Import**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import {ZeroEx} from '0x.js';
|
import { ZeroEx } from '0x.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
#### UMD:
|
#### UMD:
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
* Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/abi-gen-templates.
|
* Templates can be found at https://github.com/0xProject/0x.js/tree/development/packages/abi-gen-templates.
|
||||||
*/
|
*/
|
||||||
// tslint:disable-next-line:no-unused-variable
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import {TxData, TxDataPayable} from '@0xproject/types';
|
import { TxData, TxDataPayable } from '@0xproject/types';
|
||||||
import {classUtils, promisify} from '@0xproject/utils';
|
import { BigNumber, classUtils, promisify } from '@0xproject/utils';
|
||||||
import {BigNumber} from 'bignumber.js';
|
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {BaseContract} from './base_contract';
|
import {BaseContract} from './base_contract';
|
||||||
|
|||||||
@@ -1,104 +1,94 @@
|
|||||||
{
|
{
|
||||||
"name": "0x.js",
|
"name": "0x.js",
|
||||||
"version": "0.29.0",
|
"version": "0.30.0",
|
||||||
"description": "A javascript library for interacting with the 0x protocol",
|
"description": "A javascript library for interacting with the 0x protocol",
|
||||||
"keywords": [
|
"keywords": ["0x.js", "0xproject", "ethereum", "tokens", "exchange"],
|
||||||
"0x.js",
|
"main": "lib/src/index.js",
|
||||||
"0xproject",
|
"types": "lib/src/index.d.ts",
|
||||||
"ethereum",
|
"scripts": {
|
||||||
"tokens",
|
"prebuild": "run-s clean generate_contract_wrappers",
|
||||||
"exchange"
|
"build": "run-p build:umd:prod build:commonjs; exit 0;",
|
||||||
],
|
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
|
||||||
"main": "lib/src/index.js",
|
"upload_docs_json":
|
||||||
"types": "lib/src/index.d.ts",
|
"aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
|
||||||
"scripts": {
|
"generate_contract_wrappers":
|
||||||
"prebuild": "run-s clean generate_contract_wrappers",
|
"node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated",
|
||||||
"build": "run-p build:umd:prod build:commonjs; exit 0;",
|
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
||||||
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_DIR",
|
"test:circleci": "run-s test:coverage report_test_coverage",
|
||||||
"upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
|
"test": "run-s clean test:commonjs",
|
||||||
"generate_contract_wrappers": "node ../abi-gen/lib/index.js --abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --templates contract_templates --output src/contract_wrappers/generated",
|
"test:coverage": "nyc npm run test --all",
|
||||||
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
"report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||||
"test:circleci": "run-s test:coverage report_test_coverage && if [ $CIRCLE_BRANCH = \"development\" ]; then yarn test:umd; fi",
|
"update_contracts":
|
||||||
"test": "run-s clean test:commonjs",
|
"for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
|
||||||
"test:umd": "./scripts/test_umd.sh",
|
"clean": "shx rm -rf _bundles lib test_temp",
|
||||||
"test:coverage": "nyc npm run test --all",
|
"build:umd:prod": "NODE_ENV=production webpack",
|
||||||
"report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
|
"build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
|
||||||
"update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
|
"test:commonjs": "run-s build:commonjs run_mocha",
|
||||||
"clean": "shx rm -rf _bundles lib test_temp",
|
"run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
|
||||||
"build:umd:dev": "webpack",
|
},
|
||||||
"build:umd:prod": "NODE_ENV=production webpack",
|
"config": {
|
||||||
"build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
|
"artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
|
||||||
"test:commonjs": "run-s build:commonjs run_mocha",
|
},
|
||||||
"pretest:umd": "run-s clean build:umd:dev build:commonjs",
|
"repository": {
|
||||||
"substitute_umd_bundle": "shx mv _bundles/* lib/src",
|
"type": "git",
|
||||||
"run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
|
"url": "https://github.com/0xProject/0x.js"
|
||||||
},
|
},
|
||||||
"config": {
|
"license": "Apache-2.0",
|
||||||
"artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
|
"engines": {
|
||||||
},
|
"node": ">=6.0.0"
|
||||||
"repository": {
|
},
|
||||||
"type": "git",
|
"devDependencies": {
|
||||||
"url": "https://github.com/0xProject/0x.js"
|
"@0xproject/abi-gen": "^0.1.2",
|
||||||
},
|
"@0xproject/dev-utils": "^0.0.5",
|
||||||
"license": "Apache-2.0",
|
"@0xproject/tslint-config": "^0.4.2",
|
||||||
"engines": {
|
"@0xproject/types": "^0.1.4",
|
||||||
"node": ">=6.0.0"
|
"@types/bintrees": "^1.0.2",
|
||||||
},
|
"@types/jsonschema": "^1.1.1",
|
||||||
"devDependencies": {
|
"@types/lodash": "^4.14.86",
|
||||||
"@0xproject/abi-gen": "^0.0.4",
|
"@types/mocha": "^2.2.42",
|
||||||
"@0xproject/dev-utils": "^0.0.3",
|
"@types/node": "^8.0.53",
|
||||||
"@0xproject/tslint-config": "^0.4.0",
|
"@types/sinon": "^2.2.2",
|
||||||
"@0xproject/types": "^0.1.2",
|
"@types/uuid": "^3.4.2",
|
||||||
"@types/bintrees": "^1.0.2",
|
"awesome-typescript-loader": "^3.1.3",
|
||||||
"@types/jsonschema": "^1.1.1",
|
"chai": "^4.0.1",
|
||||||
"@types/lodash": "^4.14.86",
|
"chai-as-promised": "^7.1.0",
|
||||||
"@types/mocha": "^2.2.42",
|
"chai-as-promised-typescript-typings": "^0.0.4",
|
||||||
"@types/node": "^8.0.53",
|
"chai-bignumber": "^2.0.1",
|
||||||
"@types/sinon": "^2.2.2",
|
"chai-typescript-typings": "^0.0.2",
|
||||||
"@types/uuid": "^3.4.2",
|
"copyfiles": "^1.2.0",
|
||||||
"awesome-typescript-loader": "^3.1.3",
|
"coveralls": "^3.0.0",
|
||||||
"chai": "^4.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"chai-as-promised": "^7.1.0",
|
"json-loader": "^0.5.4",
|
||||||
"chai-as-promised-typescript-typings": "^0.0.3",
|
"mocha": "^4.0.1",
|
||||||
"chai-bignumber": "^2.0.1",
|
"npm-run-all": "^4.1.2",
|
||||||
"chai-typescript-typings": "^0.0.1",
|
"nyc": "^11.0.1",
|
||||||
"copyfiles": "^1.2.0",
|
"opn-cli": "^3.1.0",
|
||||||
"coveralls": "^3.0.0",
|
"request": "^2.81.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"request-promise-native": "^1.0.4",
|
||||||
"json-loader": "^0.5.4",
|
"shx": "^0.2.2",
|
||||||
"mocha": "^4.0.1",
|
"sinon": "^4.0.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"source-map-support": "^0.5.0",
|
||||||
"nyc": "^11.0.1",
|
"truffle-hdwallet-provider": "^0.0.3",
|
||||||
"opn-cli": "^3.1.0",
|
"tslint": "5.8.0",
|
||||||
"request": "^2.81.0",
|
"typedoc": "~0.8.0",
|
||||||
"request-promise-native": "^1.0.4",
|
"typescript": "~2.6.1",
|
||||||
"shx": "^0.2.2",
|
"web3-provider-engine": "^13.0.1",
|
||||||
"sinon": "^4.0.0",
|
"web3-typescript-typings": "^0.9.4",
|
||||||
"source-map-support": "^0.5.0",
|
"webpack": "^3.1.0"
|
||||||
"truffle-hdwallet-provider": "^0.0.3",
|
},
|
||||||
"tslint": "5.8.0",
|
"dependencies": {
|
||||||
"typedoc": "~0.8.0",
|
"@0xproject/assert": "^0.0.11",
|
||||||
"typescript": "~2.6.1",
|
"@0xproject/json-schemas": "^0.7.3",
|
||||||
"web3-provider-engine": "^13.0.1",
|
"@0xproject/utils": "^0.2.0",
|
||||||
"web3-typescript-typings": "^0.7.2",
|
"@0xproject/web3-wrapper": "^0.1.5",
|
||||||
"webpack": "^3.1.0"
|
"bintrees": "^1.0.2",
|
||||||
},
|
"bn.js": "^4.11.8",
|
||||||
"dependencies": {
|
"ethereumjs-abi": "^0.6.4",
|
||||||
"@0xproject/assert": "^0.0.9",
|
"ethereumjs-blockstream": "^2.0.6",
|
||||||
"@0xproject/json-schemas": "^0.7.1",
|
"ethereumjs-util": "^5.1.1",
|
||||||
"@0xproject/utils": "^0.1.2",
|
"js-sha3": "^0.6.1",
|
||||||
"@0xproject/web3-wrapper": "^0.1.2",
|
"lodash": "^4.17.4",
|
||||||
"bignumber.js": "~4.1.0",
|
"uuid": "^3.1.0",
|
||||||
"bintrees": "^1.0.2",
|
"web3": "^0.20.0"
|
||||||
"bn.js": "^4.11.8",
|
}
|
||||||
"compare-versions": "^3.0.1",
|
|
||||||
"ethereumjs-abi": "^0.6.4",
|
|
||||||
"ethereumjs-blockstream": "^2.0.6",
|
|
||||||
"ethereumjs-util": "^5.1.1",
|
|
||||||
"find-versions": "^2.0.0",
|
|
||||||
"js-sha3": "^0.6.1",
|
|
||||||
"lodash": "^4.17.4",
|
|
||||||
"uuid": "^3.1.0",
|
|
||||||
"web3": "^0.20.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,21 @@ const S3BucketPath = 's3://0xjs-docs-jsons/';
|
|||||||
|
|
||||||
let tag;
|
let tag;
|
||||||
let version;
|
let version;
|
||||||
postpublish_utils.getLatestTagAndVersionAsync(subPackageName)
|
postpublish_utils
|
||||||
|
.getLatestTagAndVersionAsync(subPackageName)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
tag = result.tag;
|
tag = result.tag;
|
||||||
version = result.version;
|
version = result.version;
|
||||||
const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
|
const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
|
||||||
const assets = [
|
const assets = [__dirname + '/../_bundles/index.js', __dirname + '/../_bundles/index.min.js'];
|
||||||
__dirname + '/../_bundles/index.js',
|
return postpublish_utils.publishReleaseNotes(tag, releaseName, assets);
|
||||||
__dirname + '/../_bundles/index.min.js',
|
|
||||||
];
|
|
||||||
return postpublish_utils.publishReleaseNotes(tag, releaseName, assets);
|
|
||||||
})
|
})
|
||||||
.then(function(release) {
|
.then(function(release) {
|
||||||
console.log('POSTPUBLISH: Release successful, generating docs...');
|
console.log('POSTPUBLISH: Release successful, generating docs...');
|
||||||
const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
|
const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
|
||||||
return execAsync(
|
return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_DIR=' + __dirname + '/.. yarn docs:json', {
|
||||||
'JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_DIR=' + __dirname + '/.. yarn docs:json',
|
cwd,
|
||||||
{
|
});
|
||||||
cwd,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
if (result.stderr !== '') {
|
if (result.stderr !== '') {
|
||||||
@@ -39,6 +34,7 @@ postpublish_utils.getLatestTagAndVersionAsync(subPackageName)
|
|||||||
return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', {
|
return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', {
|
||||||
cwd,
|
cwd,
|
||||||
});
|
});
|
||||||
}).catch (function(err) {
|
})
|
||||||
|
.catch(function(err) {
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# This script runs umd tests and cleans up after them while preserving the `return_code` for CI
|
|
||||||
# UMD tests should only be run after building the commonjs because they reuse some of the commonjs build artifacts
|
|
||||||
run-s substitute_umd_bundle run_mocha
|
|
||||||
return_code=$?
|
|
||||||
exit $return_code
|
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
import {schemas, SchemaValidator} from '@0xproject/json-schemas';
|
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
|
||||||
import {bigNumberConfigs, intervalUtils} from '@0xproject/utils';
|
import { BigNumber, intervalUtils } from '@0xproject/utils';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {artifacts} from './artifacts';
|
import { artifacts } from './artifacts';
|
||||||
import {EtherTokenWrapper} from './contract_wrappers/ether_token_wrapper';
|
import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
|
||||||
import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper';
|
import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
|
||||||
import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper';
|
import { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper';
|
||||||
import {TokenTransferProxyWrapper} from './contract_wrappers/token_transfer_proxy_wrapper';
|
import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper';
|
||||||
import {TokenWrapper} from './contract_wrappers/token_wrapper';
|
import { TokenWrapper } from './contract_wrappers/token_wrapper';
|
||||||
import {OrderStateWatcher} from './order_watcher/order_state_watcher';
|
import { OrderStateWatcher } from './order_watcher/order_state_watcher';
|
||||||
import {zeroExConfigSchema} from './schemas/zero_ex_config_schema';
|
import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
|
||||||
import {
|
import {
|
||||||
ECSignature,
|
ECSignature,
|
||||||
Order,
|
Order,
|
||||||
@@ -22,15 +21,12 @@ import {
|
|||||||
ZeroExConfig,
|
ZeroExConfig,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from './types';
|
} from './types';
|
||||||
import {AbiDecoder} from './utils/abi_decoder';
|
import { AbiDecoder } from './utils/abi_decoder';
|
||||||
import {assert} from './utils/assert';
|
import { assert } from './utils/assert';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {decorators} from './utils/decorators';
|
import { decorators } from './utils/decorators';
|
||||||
import {signatureUtils} from './utils/signature_utils';
|
import { signatureUtils } from './utils/signature_utils';
|
||||||
import {utils} from './utils/utils';
|
import { utils } from './utils/utils';
|
||||||
|
|
||||||
// Customize our BigNumber instances
|
|
||||||
bigNumberConfigs.configure();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality
|
* The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality
|
||||||
@@ -161,7 +157,7 @@ export class ZeroEx {
|
|||||||
* @return The resulting orderHash from hashing the supplied order.
|
* @return The resulting orderHash from hashing the supplied order.
|
||||||
*/
|
*/
|
||||||
@decorators.syncZeroExErrorHandler
|
@decorators.syncZeroExErrorHandler
|
||||||
public static getOrderHashHex(order: Order|SignedOrder): string {
|
public static getOrderHashHex(order: Order | SignedOrder): string {
|
||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
const orderHashHex = utils.getOrderHashHex(order);
|
const orderHashHex = utils.getOrderHashHex(order);
|
||||||
return orderHashHex;
|
return orderHashHex;
|
||||||
@@ -188,27 +184,27 @@ export class ZeroEx {
|
|||||||
config.networkId,
|
config.networkId,
|
||||||
config.tokenTransferProxyContractAddress,
|
config.tokenTransferProxyContractAddress,
|
||||||
);
|
);
|
||||||
this.token = new TokenWrapper(
|
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
|
||||||
this._web3Wrapper,
|
|
||||||
config.networkId,
|
|
||||||
this._abiDecoder,
|
|
||||||
this.proxy,
|
|
||||||
);
|
|
||||||
this.exchange = new ExchangeWrapper(
|
this.exchange = new ExchangeWrapper(
|
||||||
this._web3Wrapper,
|
this._web3Wrapper,
|
||||||
config.networkId,
|
config.networkId,
|
||||||
this._abiDecoder,
|
this._abiDecoder,
|
||||||
this.token,
|
this.token,
|
||||||
config.exchangeContractAddress,
|
config.exchangeContractAddress,
|
||||||
|
config.zrxContractAddress,
|
||||||
);
|
);
|
||||||
this.tokenRegistry = new TokenRegistryWrapper(
|
this.tokenRegistry = new TokenRegistryWrapper(
|
||||||
this._web3Wrapper, config.networkId, config.tokenRegistryContractAddress,
|
this._web3Wrapper,
|
||||||
);
|
config.networkId,
|
||||||
this.etherToken = new EtherTokenWrapper(
|
config.tokenRegistryContractAddress,
|
||||||
this._web3Wrapper, config.networkId, this._abiDecoder, this.token,
|
|
||||||
);
|
);
|
||||||
|
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
|
||||||
this.orderStateWatcher = new OrderStateWatcher(
|
this.orderStateWatcher = new OrderStateWatcher(
|
||||||
this._web3Wrapper, this._abiDecoder, this.token, this.exchange, config.orderWatcherConfig,
|
this._web3Wrapper,
|
||||||
|
this._abiDecoder,
|
||||||
|
this.token,
|
||||||
|
this.exchange,
|
||||||
|
config.orderWatcherConfig,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -218,12 +214,17 @@ export class ZeroEx {
|
|||||||
* @param networkId The id of the network your provider is connected to
|
* @param networkId The id of the network your provider is connected to
|
||||||
*/
|
*/
|
||||||
public setProvider(provider: Web3Provider, networkId: number): void {
|
public setProvider(provider: Web3Provider, networkId: number): void {
|
||||||
this._web3Wrapper.setProvider(provider, networkId);
|
this._web3Wrapper.setProvider(provider);
|
||||||
(this.exchange as any)._invalidateContractInstances();
|
(this.exchange as any)._invalidateContractInstances();
|
||||||
|
(this.exchange as any)._setNetworkId(networkId);
|
||||||
(this.tokenRegistry as any)._invalidateContractInstance();
|
(this.tokenRegistry as any)._invalidateContractInstance();
|
||||||
|
(this.tokenRegistry as any)._setNetworkId(networkId);
|
||||||
(this.token as any)._invalidateContractInstances();
|
(this.token as any)._invalidateContractInstances();
|
||||||
|
(this.token as any)._setNetworkId(networkId);
|
||||||
(this.proxy as any)._invalidateContractInstance();
|
(this.proxy as any)._invalidateContractInstance();
|
||||||
|
(this.proxy as any)._setNetworkId(networkId);
|
||||||
(this.etherToken as any)._invalidateContractInstance();
|
(this.etherToken as any)._invalidateContractInstance();
|
||||||
|
(this.etherToken as any)._setNetworkId(networkId);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get user Ethereum addresses available through the supplied web3 provider available for sending transactions.
|
* Get user Ethereum addresses available through the supplied web3 provider available for sending transactions.
|
||||||
@@ -291,35 +292,46 @@ export class ZeroEx {
|
|||||||
* @return Transaction receipt with decoded log args.
|
* @return Transaction receipt with decoded log args.
|
||||||
*/
|
*/
|
||||||
public async awaitTransactionMinedAsync(
|
public async awaitTransactionMinedAsync(
|
||||||
txHash: string, pollingIntervalMs = 1000, timeoutMs?: number): Promise<TransactionReceiptWithDecodedLogs> {
|
txHash: string,
|
||||||
|
pollingIntervalMs = 1000,
|
||||||
|
timeoutMs?: number,
|
||||||
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
let timeoutExceeded = false;
|
let timeoutExceeded = false;
|
||||||
if (timeoutMs) {
|
if (timeoutMs) {
|
||||||
setTimeout(() => timeoutExceeded = true, timeoutMs);
|
setTimeout(() => (timeoutExceeded = true), timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txReceiptPromise = new Promise(
|
const txReceiptPromise = new Promise(
|
||||||
(resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => {
|
(resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => {
|
||||||
const intervalId = intervalUtils.setAsyncExcludingInterval(async () => {
|
const intervalId = intervalUtils.setAsyncExcludingInterval(
|
||||||
if (timeoutExceeded) {
|
async () => {
|
||||||
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
if (timeoutExceeded) {
|
||||||
return reject(ZeroExError.TransactionMiningTimeout);
|
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
||||||
}
|
return reject(ZeroExError.TransactionMiningTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash);
|
const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash);
|
||||||
if (!_.isNull(transactionReceipt)) {
|
if (!_.isNull(transactionReceipt)) {
|
||||||
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
||||||
const logsWithDecodedArgs = _.map(
|
const logsWithDecodedArgs = _.map(
|
||||||
transactionReceipt.logs,
|
transactionReceipt.logs,
|
||||||
this._abiDecoder.tryToDecodeLogOrNoop.bind(this._abiDecoder),
|
this._abiDecoder.tryToDecodeLogOrNoop.bind(this._abiDecoder),
|
||||||
);
|
);
|
||||||
const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = {
|
const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = {
|
||||||
...transactionReceipt,
|
...transactionReceipt,
|
||||||
logs: logsWithDecodedArgs,
|
logs: logsWithDecodedArgs,
|
||||||
};
|
};
|
||||||
resolve(transactionReceiptWithDecodedLogArgs);
|
resolve(transactionReceiptWithDecodedLogArgs);
|
||||||
}
|
}
|
||||||
}, pollingIntervalMs);
|
},
|
||||||
});
|
pollingIntervalMs,
|
||||||
|
(err: Error) => {
|
||||||
|
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
||||||
|
reject(err);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return txReceiptPromise;
|
return txReceiptPromise;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import * as TokenArtifact from './artifacts/Token.json';
|
|||||||
import * as TokenRegistryArtifact from './artifacts/TokenRegistry.json';
|
import * as TokenRegistryArtifact from './artifacts/TokenRegistry.json';
|
||||||
import * as TokenTransferProxyArtifact from './artifacts/TokenTransferProxy.json';
|
import * as TokenTransferProxyArtifact from './artifacts/TokenTransferProxy.json';
|
||||||
import * as ZRXArtifact from './artifacts/ZRX.json';
|
import * as ZRXArtifact from './artifacts/ZRX.json';
|
||||||
import {Artifact} from './types';
|
import { Artifact } from './types';
|
||||||
|
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
ZRXArtifact: ZRXArtifact as any as Artifact,
|
ZRXArtifact: (ZRXArtifact as any) as Artifact,
|
||||||
DummyTokenArtifact: DummyTokenArtifact as any as Artifact,
|
DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
|
||||||
TokenArtifact: TokenArtifact as any as Artifact,
|
TokenArtifact: (TokenArtifact as any) as Artifact,
|
||||||
ExchangeArtifact: ExchangeArtifact as any as Artifact,
|
ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
|
||||||
EtherTokenArtifact: EtherTokenArtifact as any as Artifact,
|
EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
|
||||||
TokenRegistryArtifact: TokenRegistryArtifact as any as Artifact,
|
TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
|
||||||
TokenTransferProxyArtifact: TokenTransferProxyArtifact as any as Artifact,
|
TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"contract_name": "DummyToken",
|
"contract_name": "DummyToken",
|
||||||
"abi":
|
"abi": [
|
||||||
[
|
|
||||||
{
|
{
|
||||||
"constant": false,
|
"constant": false,
|
||||||
"inputs": [
|
"inputs": [
|
||||||
|
|||||||
@@ -1,284 +1,284 @@
|
|||||||
{
|
{
|
||||||
"contract_name": "EtherToken",
|
"contract_name": "EtherToken",
|
||||||
"abi": [
|
"abi": [
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "name",
|
|
||||||
"outputs": [
|
|
||||||
{
|
{
|
||||||
"name": "",
|
"constant": true,
|
||||||
"type": "string"
|
"inputs": [],
|
||||||
}
|
"name": "name",
|
||||||
],
|
"outputs": [
|
||||||
"payable": false,
|
{
|
||||||
"type": "function"
|
"name": "",
|
||||||
},
|
"type": "string"
|
||||||
{
|
}
|
||||||
"constant": false,
|
],
|
||||||
"inputs": [
|
"payable": false,
|
||||||
{
|
"type": "function"
|
||||||
"name": "_spender",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_value",
|
"constant": false,
|
||||||
"type": "uint256"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "_spender",
|
||||||
"name": "approve",
|
"type": "address"
|
||||||
"outputs": [
|
},
|
||||||
{
|
{
|
||||||
"name": "",
|
"name": "_value",
|
||||||
"type": "bool"
|
"type": "uint256"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"payable": false,
|
"name": "approve",
|
||||||
"type": "function"
|
"outputs": [
|
||||||
},
|
{
|
||||||
{
|
"name": "",
|
||||||
"constant": true,
|
"type": "bool"
|
||||||
"inputs": [],
|
}
|
||||||
"name": "totalSupply",
|
],
|
||||||
"outputs": [
|
"payable": false,
|
||||||
{
|
"type": "function"
|
||||||
"name": "",
|
|
||||||
"type": "uint256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"payable": false,
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_from",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_to",
|
"constant": true,
|
||||||
"type": "address"
|
"inputs": [],
|
||||||
|
"name": "totalSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_value",
|
"constant": false,
|
||||||
"type": "uint256"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "_from",
|
||||||
"name": "transferFrom",
|
"type": "address"
|
||||||
"outputs": [
|
},
|
||||||
{
|
{
|
||||||
"name": "",
|
"name": "_to",
|
||||||
"type": "bool"
|
"type": "address"
|
||||||
}
|
},
|
||||||
],
|
{
|
||||||
"payable": false,
|
"name": "_value",
|
||||||
"type": "function"
|
"type": "uint256"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"constant": false,
|
"name": "transferFrom",
|
||||||
"inputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "amount",
|
"name": "",
|
||||||
"type": "uint256"
|
"type": "bool"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "withdraw",
|
"payable": false,
|
||||||
"outputs": [],
|
"type": "function"
|
||||||
"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",
|
"constant": false,
|
||||||
"type": "uint256"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "amount",
|
||||||
"name": "transfer",
|
"type": "uint256"
|
||||||
"outputs": [
|
}
|
||||||
{
|
],
|
||||||
"name": "",
|
"name": "withdraw",
|
||||||
"type": "bool"
|
"outputs": [],
|
||||||
}
|
"payable": false,
|
||||||
],
|
"type": "function"
|
||||||
"payable": false,
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [],
|
|
||||||
"name": "deposit",
|
|
||||||
"outputs": [],
|
|
||||||
"payable": true,
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"constant": true,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"name": "_owner",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_spender",
|
"constant": true,
|
||||||
"type": "address"
|
"inputs": [],
|
||||||
}
|
"name": "decimals",
|
||||||
],
|
"outputs": [
|
||||||
"name": "allowance",
|
{
|
||||||
"outputs": [
|
"name": "",
|
||||||
{
|
"type": "uint8"
|
||||||
"name": "",
|
}
|
||||||
"type": "uint256"
|
],
|
||||||
}
|
"payable": false,
|
||||||
],
|
"type": "function"
|
||||||
"payable": false,
|
|
||||||
"type": "function"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"payable": true,
|
|
||||||
"type": "fallback"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"indexed": true,
|
|
||||||
"name": "_from",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"indexed": true,
|
"constant": true,
|
||||||
"name": "_to",
|
"inputs": [
|
||||||
"type": "address"
|
{
|
||||||
|
"name": "_owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "balanceOf",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"indexed": false,
|
"constant": true,
|
||||||
"name": "_value",
|
"inputs": [],
|
||||||
"type": "uint256"
|
"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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "Transfer",
|
"networks": {
|
||||||
"type": "event"
|
"1": {
|
||||||
},
|
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
||||||
{
|
|
||||||
"anonymous": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"indexed": true,
|
|
||||||
"name": "_owner",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
"3": {
|
||||||
"indexed": true,
|
"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
|
||||||
"name": "_spender",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
"42": {
|
||||||
"indexed": false,
|
"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
|
||||||
"name": "_value",
|
},
|
||||||
"type": "uint256"
|
"50": {
|
||||||
|
"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"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"
|
|
||||||
},
|
|
||||||
"42": {
|
|
||||||
"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
|
|
||||||
},
|
|
||||||
"50": {
|
|
||||||
"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,172 +1,172 @@
|
|||||||
{
|
{
|
||||||
"contract_name": "Token",
|
"contract_name": "Token",
|
||||||
"abi": [
|
"abi": [
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
{
|
||||||
"name": "_spender",
|
"constant": false,
|
||||||
"type": "address"
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "_spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "approve",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "success",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_value",
|
"constant": true,
|
||||||
"type": "uint256"
|
"inputs": [],
|
||||||
}
|
"name": "totalSupply",
|
||||||
],
|
"outputs": [
|
||||||
"name": "approve",
|
{
|
||||||
"outputs": [
|
"name": "supply",
|
||||||
{
|
"type": "uint256"
|
||||||
"name": "success",
|
}
|
||||||
"type": "bool"
|
],
|
||||||
}
|
"payable": false,
|
||||||
],
|
"type": "function"
|
||||||
"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",
|
"constant": false,
|
||||||
"type": "address"
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "_from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "_value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferFrom",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "success",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_value",
|
"constant": true,
|
||||||
"type": "uint256"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "_owner",
|
||||||
"name": "transferFrom",
|
"type": "address"
|
||||||
"outputs": [
|
}
|
||||||
{
|
],
|
||||||
"name": "success",
|
"name": "balanceOf",
|
||||||
"type": "bool"
|
"outputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "balance",
|
||||||
"payable": false,
|
"type": "uint256"
|
||||||
"type": "function"
|
}
|
||||||
},
|
],
|
||||||
{
|
"payable": false,
|
||||||
"constant": true,
|
"type": "function"
|
||||||
"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",
|
"constant": false,
|
||||||
"type": "uint256"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "_to",
|
||||||
"name": "transfer",
|
"type": "address"
|
||||||
"outputs": [
|
},
|
||||||
{
|
{
|
||||||
"name": "success",
|
"name": "_value",
|
||||||
"type": "bool"
|
"type": "uint256"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"payable": false,
|
"name": "transfer",
|
||||||
"type": "function"
|
"outputs": [
|
||||||
},
|
{
|
||||||
{
|
"name": "success",
|
||||||
"constant": true,
|
"type": "bool"
|
||||||
"inputs": [
|
}
|
||||||
{
|
],
|
||||||
"name": "_owner",
|
"payable": false,
|
||||||
"type": "address"
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "_spender",
|
"constant": true,
|
||||||
"type": "address"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "_owner",
|
||||||
"name": "allowance",
|
"type": "address"
|
||||||
"outputs": [
|
},
|
||||||
{
|
{
|
||||||
"name": "remaining",
|
"name": "_spender",
|
||||||
"type": "uint256"
|
"type": "address"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"payable": false,
|
"name": "allowance",
|
||||||
"type": "function"
|
"outputs": [
|
||||||
},
|
{
|
||||||
{
|
"name": "remaining",
|
||||||
"anonymous": false,
|
"type": "uint256"
|
||||||
"inputs": [
|
}
|
||||||
{
|
],
|
||||||
"indexed": true,
|
"payable": false,
|
||||||
"name": "_from",
|
"type": "function"
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"indexed": true,
|
"anonymous": false,
|
||||||
"name": "_to",
|
"inputs": [
|
||||||
"type": "address"
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"name": "_from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"name": "_to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"name": "_value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Transfer",
|
||||||
|
"type": "event"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"indexed": false,
|
"anonymous": false,
|
||||||
"name": "_value",
|
"inputs": [
|
||||||
"type": "uint256"
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"name": "_owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"name": "_spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"name": "_value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Approval",
|
||||||
|
"type": "event"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,184 +1,184 @@
|
|||||||
{
|
{
|
||||||
"contract_name": "TokenTransferProxy",
|
"contract_name": "TokenTransferProxy",
|
||||||
"abi": [
|
"abi": [
|
||||||
{
|
|
||||||
"constant": false,
|
|
||||||
"inputs": [
|
|
||||||
{
|
{
|
||||||
"name": "token",
|
"constant": false,
|
||||||
"type": "address"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "from",
|
"constant": false,
|
||||||
"type": "address"
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "target",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "addAuthorizedAddress",
|
||||||
|
"outputs": [],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "to",
|
"constant": true,
|
||||||
"type": "address"
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "authorities",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "value",
|
"constant": false,
|
||||||
"type": "uint256"
|
"inputs": [
|
||||||
}
|
{
|
||||||
],
|
"name": "target",
|
||||||
"name": "transferFrom",
|
"type": "address"
|
||||||
"outputs": [
|
}
|
||||||
{
|
],
|
||||||
"name": "",
|
"name": "removeAuthorizedAddress",
|
||||||
"type": "bool"
|
"outputs": [],
|
||||||
}
|
"payable": false,
|
||||||
],
|
"type": "function"
|
||||||
"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,
|
"constant": true,
|
||||||
"name": "caller",
|
"inputs": [],
|
||||||
"type": "address"
|
"name": "owner",
|
||||||
}
|
"outputs": [
|
||||||
],
|
{
|
||||||
"name": "LogAuthorizedAddressAdded",
|
"name": "",
|
||||||
"type": "event"
|
"type": "address"
|
||||||
},
|
}
|
||||||
{
|
],
|
||||||
"anonymous": false,
|
"payable": false,
|
||||||
"inputs": [
|
"type": "function"
|
||||||
{
|
|
||||||
"indexed": true,
|
|
||||||
"name": "target",
|
|
||||||
"type": "address"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"indexed": true,
|
"constant": true,
|
||||||
"name": "caller",
|
"inputs": [
|
||||||
"type": "address"
|
{
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"42": {
|
||||||
|
"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
|
||||||
|
},
|
||||||
|
"50": {
|
||||||
|
"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"name": "LogAuthorizedAddressRemoved",
|
|
||||||
"type": "event"
|
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"networks": {
|
|
||||||
"1": {
|
|
||||||
"address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
|
|
||||||
},
|
|
||||||
"42": {
|
|
||||||
"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
|
|
||||||
},
|
|
||||||
"50": {
|
|
||||||
"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"contract_name": "ZRX",
|
"contract_name": "ZRX",
|
||||||
"networks": {
|
"networks": {
|
||||||
"1": {
|
"1": {
|
||||||
"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
|
"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
|
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
|
||||||
},
|
},
|
||||||
"42": {
|
"42": {
|
||||||
"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
|
"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
|
||||||
},
|
},
|
||||||
"50": {
|
"50": {
|
||||||
"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
|
"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {intervalUtils} from '@0xproject/utils';
|
import { intervalUtils } from '@0xproject/utils';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import {Block, BlockAndLogStreamer} from 'ethereumjs-blockstream';
|
import { Block, BlockAndLogStreamer } from 'ethereumjs-blockstream';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
@@ -17,11 +17,13 @@ import {
|
|||||||
RawLog,
|
RawLog,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {AbiDecoder} from '../utils/abi_decoder';
|
import { AbiDecoder } from '../utils/abi_decoder';
|
||||||
import {constants} from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import {filterUtils} from '../utils/filter_utils';
|
import { filterUtils } from '../utils/filter_utils';
|
||||||
|
|
||||||
const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {[contractName: string]: ZeroExError} = {
|
const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
|
||||||
|
[contractName: string]: ZeroExError;
|
||||||
|
} = {
|
||||||
ZRX: ZeroExError.ZRXContractDoesNotExist,
|
ZRX: ZeroExError.ZRXContractDoesNotExist,
|
||||||
EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
|
EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
|
||||||
Token: ZeroExError.TokenContractDoesNotExist,
|
Token: ZeroExError.TokenContractDoesNotExist,
|
||||||
@@ -34,12 +36,14 @@ export class ContractWrapper {
|
|||||||
protected _web3Wrapper: Web3Wrapper;
|
protected _web3Wrapper: Web3Wrapper;
|
||||||
private _networkId: number;
|
private _networkId: number;
|
||||||
private _abiDecoder?: AbiDecoder;
|
private _abiDecoder?: AbiDecoder;
|
||||||
private _blockAndLogStreamerIfExists: BlockAndLogStreamer|undefined;
|
private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
|
||||||
private _blockAndLogStreamInterval: NodeJS.Timer;
|
private _blockAndLogStreamInterval: NodeJS.Timer;
|
||||||
private _filters: {[filterToken: string]: Web3.FilterObject};
|
private _filters: { [filterToken: string]: Web3.FilterObject };
|
||||||
private _filterCallbacks: {[filterToken: string]: EventCallback<ContractEventArgs>};
|
private _filterCallbacks: {
|
||||||
private _onLogAddedSubscriptionToken: string|undefined;
|
[filterToken: string]: EventCallback<ContractEventArgs>;
|
||||||
private _onLogRemovedSubscriptionToken: string|undefined;
|
};
|
||||||
|
private _onLogAddedSubscriptionToken: string | undefined;
|
||||||
|
private _onLogRemovedSubscriptionToken: string | undefined;
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
|
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
|
||||||
this._web3Wrapper = web3Wrapper;
|
this._web3Wrapper = web3Wrapper;
|
||||||
this._networkId = networkId;
|
this._networkId = networkId;
|
||||||
@@ -71,27 +75,36 @@ export class ContractWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected _subscribe<ArgsType extends ContractEventArgs>(
|
protected _subscribe<ArgsType extends ContractEventArgs>(
|
||||||
address: string, eventName: ContractEvents, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi,
|
address: string,
|
||||||
callback: EventCallback<ArgsType>): string {
|
eventName: ContractEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
abi: Web3.ContractAbi,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
|
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
|
||||||
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||||
this._startBlockAndLogStream();
|
this._startBlockAndLogStream();
|
||||||
}
|
}
|
||||||
const filterToken = filterUtils.generateUUID();
|
const filterToken = filterUtils.generateUUID();
|
||||||
this._filters[filterToken] = filter;
|
this._filters[filterToken] = filter;
|
||||||
this._filterCallbacks[filterToken] = callback;
|
this._filterCallbacks[filterToken] = callback as EventCallback<ContractEventArgs>;
|
||||||
return filterToken;
|
return filterToken;
|
||||||
}
|
}
|
||||||
protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
|
protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
|
||||||
address: string, eventName: ContractEvents, blockRange: BlockRange,
|
address: string,
|
||||||
indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
eventName: ContractEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
abi: Web3.ContractAbi,
|
||||||
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
|
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
|
||||||
const logs = await this._web3Wrapper.getLogsAsync(filter);
|
const logs = await this._web3Wrapper.getLogsAsync(filter);
|
||||||
const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
|
const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
|
||||||
return logsWithDecodedArguments;
|
return logsWithDecodedArguments;
|
||||||
}
|
}
|
||||||
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
||||||
log: Web3.LogEntry): LogWithDecodedArgs<ArgsType>|RawLog {
|
log: Web3.LogEntry,
|
||||||
|
): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||||
if (_.isUndefined(this._abiDecoder)) {
|
if (_.isUndefined(this._abiDecoder)) {
|
||||||
throw new Error(InternalZeroExError.NoAbiDecoder);
|
throw new Error(InternalZeroExError.NoAbiDecoder);
|
||||||
}
|
}
|
||||||
@@ -99,7 +112,8 @@ export class ContractWrapper {
|
|||||||
return logWithDecodedArgs;
|
return logWithDecodedArgs;
|
||||||
}
|
}
|
||||||
protected async _instantiateContractIfExistsAsync(
|
protected async _instantiateContractIfExistsAsync(
|
||||||
artifact: Artifact, addressIfExists?: string,
|
artifact: Artifact,
|
||||||
|
addressIfExists?: string,
|
||||||
): Promise<Web3.ContractInstance> {
|
): Promise<Web3.ContractInstance> {
|
||||||
let contractAddress: string;
|
let contractAddress: string;
|
||||||
if (_.isUndefined(addressIfExists)) {
|
if (_.isUndefined(addressIfExists)) {
|
||||||
@@ -114,9 +128,7 @@ export class ContractWrapper {
|
|||||||
if (!doesContractExist) {
|
if (!doesContractExist) {
|
||||||
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
||||||
}
|
}
|
||||||
const contractInstance = this._web3Wrapper.getContractInstance(
|
const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
|
||||||
artifact.abi, contractAddress,
|
|
||||||
);
|
|
||||||
return contractInstance;
|
return contractInstance;
|
||||||
}
|
}
|
||||||
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
||||||
@@ -153,7 +165,9 @@ export class ContractWrapper {
|
|||||||
const catchAllLogFilter = {};
|
const catchAllLogFilter = {};
|
||||||
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
|
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
|
||||||
this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
|
this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._reconcileBlockAsync.bind(this), constants.DEFAULT_BLOCK_POLLING_INTERVAL,
|
this._reconcileBlockAsync.bind(this),
|
||||||
|
constants.DEFAULT_BLOCK_POLLING_INTERVAL,
|
||||||
|
this._onReconcileBlockError.bind(this),
|
||||||
);
|
);
|
||||||
let isRemoved = false;
|
let isRemoved = false;
|
||||||
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
|
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
|
||||||
@@ -164,6 +178,15 @@ export class ContractWrapper {
|
|||||||
this._onLogStateChanged.bind(this, isRemoved),
|
this._onLogStateChanged.bind(this, isRemoved),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
private _onReconcileBlockError(err: Error): void {
|
||||||
|
const filterTokens = _.keys(this._filterCallbacks);
|
||||||
|
_.each(filterTokens, filterToken => {
|
||||||
|
this._unsubscribe(filterToken, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private _setNetworkId(networkId: number): void {
|
||||||
|
this._networkId = networkId;
|
||||||
|
}
|
||||||
private _stopBlockAndLogStream(): void {
|
private _stopBlockAndLogStream(): void {
|
||||||
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||||
throw new Error(ZeroExError.SubscriptionNotFound);
|
throw new Error(ZeroExError.SubscriptionNotFound);
|
||||||
@@ -174,18 +197,11 @@ export class ContractWrapper {
|
|||||||
delete this._blockAndLogStreamerIfExists;
|
delete this._blockAndLogStreamerIfExists;
|
||||||
}
|
}
|
||||||
private async _reconcileBlockAsync(): Promise<void> {
|
private async _reconcileBlockAsync(): Promise<void> {
|
||||||
try {
|
const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest);
|
||||||
const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest);
|
// We need to coerce to Block type cause Web3.Block includes types for mempool blocks
|
||||||
// We need to coerce to Block type cause Web3.Block includes types for mempool blocks
|
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||||
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
|
||||||
// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
|
await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
|
||||||
await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlock as any as Block);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
const filterTokens = _.keys(this._filterCallbacks);
|
|
||||||
_.each(filterTokens, filterToken => {
|
|
||||||
this._unsubscribe(filterToken, err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {schemas} from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {artifacts} from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import {
|
import {
|
||||||
BlockRange,
|
BlockRange,
|
||||||
EtherTokenContractEventArgs,
|
EtherTokenContractEventArgs,
|
||||||
@@ -14,19 +14,21 @@ import {
|
|||||||
TransactionOpts,
|
TransactionOpts,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {AbiDecoder} from '../utils/abi_decoder';
|
import { AbiDecoder } from '../utils/abi_decoder';
|
||||||
import {assert} from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
|
|
||||||
import {ContractWrapper} from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import {EtherTokenContract} from './generated/ether_token';
|
import { EtherTokenContract } from './generated/ether_token';
|
||||||
import {TokenWrapper} from './token_wrapper';
|
import { TokenWrapper } from './token_wrapper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes all the functionality related to interacting with a wrapped Ether ERC20 token contract.
|
* 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.
|
* The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
|
||||||
*/
|
*/
|
||||||
export class EtherTokenWrapper extends ContractWrapper {
|
export class EtherTokenWrapper extends ContractWrapper {
|
||||||
private _etherTokenContractsByAddress: {[address: string]: EtherTokenContract} = {};
|
private _etherTokenContractsByAddress: {
|
||||||
|
[address: string]: EtherTokenContract;
|
||||||
|
} = {};
|
||||||
private _tokenWrapper: TokenWrapper;
|
private _tokenWrapper: TokenWrapper;
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
|
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
|
||||||
super(web3Wrapper, networkId, abiDecoder);
|
super(web3Wrapper, networkId, abiDecoder);
|
||||||
@@ -43,7 +45,10 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async depositAsync(
|
public async depositAsync(
|
||||||
etherTokenAddress: string, amountInWei: BigNumber, depositor: string, txOpts: TransactionOpts = {},
|
etherTokenAddress: string,
|
||||||
|
amountInWei: BigNumber,
|
||||||
|
depositor: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
||||||
@@ -70,7 +75,10 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async withdrawAsync(
|
public async withdrawAsync(
|
||||||
etherTokenAddress: string, amountInWei: BigNumber, withdrawer: string, txOpts: TransactionOpts = {},
|
etherTokenAddress: string,
|
||||||
|
amountInWei: BigNumber,
|
||||||
|
withdrawer: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
||||||
@@ -96,14 +104,21 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Array of logs that match the parameters
|
* @return Array of logs that match the parameters
|
||||||
*/
|
*/
|
||||||
public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
|
public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
|
||||||
etherTokenAddress: string, eventName: EtherTokenEvents, blockRange: BlockRange,
|
etherTokenAddress: string,
|
||||||
indexFilterValues: IndexedFilterValues): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
eventName: EtherTokenEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues, artifacts.EtherTokenArtifact.abi,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.EtherTokenArtifact.abi,
|
||||||
);
|
);
|
||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
@@ -117,14 +132,21 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Subscription token used later to unsubscribe
|
* @return Subscription token used later to unsubscribe
|
||||||
*/
|
*/
|
||||||
public subscribe<ArgsType extends EtherTokenContractEventArgs>(
|
public subscribe<ArgsType extends EtherTokenContractEventArgs>(
|
||||||
etherTokenAddress: string, eventName: EtherTokenEvents, indexFilterValues: IndexedFilterValues,
|
etherTokenAddress: string,
|
||||||
callback: EventCallback<ArgsType>): string {
|
eventName: EtherTokenEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
etherTokenAddress, eventName, indexFilterValues, artifacts.EtherTokenArtifact.abi, callback,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.EtherTokenArtifact.abi,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
return subscriptionToken;
|
return subscriptionToken;
|
||||||
}
|
}
|
||||||
@@ -151,7 +173,8 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
return etherTokenContract;
|
return etherTokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.EtherTokenArtifact, etherTokenAddress,
|
artifacts.EtherTokenArtifact,
|
||||||
|
etherTokenAddress,
|
||||||
);
|
);
|
||||||
const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
etherTokenContract = contractInstance;
|
etherTokenContract = contractInstance;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {schemas} from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {artifacts} from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import {
|
import {
|
||||||
BlockParamLiteral,
|
BlockParamLiteral,
|
||||||
BlockRange,
|
BlockRange,
|
||||||
@@ -28,16 +28,16 @@ import {
|
|||||||
SignedOrder,
|
SignedOrder,
|
||||||
ValidateOrderFillableOpts,
|
ValidateOrderFillableOpts,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {AbiDecoder} from '../utils/abi_decoder';
|
import { AbiDecoder } from '../utils/abi_decoder';
|
||||||
import {assert} from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
import {decorators} from '../utils/decorators';
|
import { decorators } from '../utils/decorators';
|
||||||
import {ExchangeTransferSimulator} from '../utils/exchange_transfer_simulator';
|
import { ExchangeTransferSimulator } from '../utils/exchange_transfer_simulator';
|
||||||
import {OrderValidationUtils} from '../utils/order_validation_utils';
|
import { OrderValidationUtils } from '../utils/order_validation_utils';
|
||||||
import {utils} from '../utils/utils';
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
import {ContractWrapper} from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import {ExchangeContract} from './generated/exchange';
|
import { ExchangeContract } from './generated/exchange';
|
||||||
import {TokenWrapper} from './token_wrapper';
|
import { TokenWrapper } from './token_wrapper';
|
||||||
|
|
||||||
const SHOULD_VALIDATE_BY_DEFAULT = true;
|
const SHOULD_VALIDATE_BY_DEFAULT = true;
|
||||||
|
|
||||||
@@ -81,12 +81,19 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
];
|
];
|
||||||
return [orderAddresses, orderValues];
|
return [orderAddresses, orderValues];
|
||||||
}
|
}
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder,
|
constructor(
|
||||||
tokenWrapper: TokenWrapper, contractAddressIfExists?: string) {
|
web3Wrapper: Web3Wrapper,
|
||||||
|
networkId: number,
|
||||||
|
abiDecoder: AbiDecoder,
|
||||||
|
tokenWrapper: TokenWrapper,
|
||||||
|
contractAddressIfExists?: string,
|
||||||
|
zrxContractAddressIfExists?: string,
|
||||||
|
) {
|
||||||
super(web3Wrapper, networkId, abiDecoder);
|
super(web3Wrapper, networkId, abiDecoder);
|
||||||
this._tokenWrapper = tokenWrapper;
|
this._tokenWrapper = tokenWrapper;
|
||||||
this._orderValidationUtils = new OrderValidationUtils(this);
|
this._orderValidationUtils = new OrderValidationUtils(this);
|
||||||
this._contractAddressIfExists = contractAddressIfExists;
|
this._contractAddressIfExists = contractAddressIfExists;
|
||||||
|
this._zrxContractAddressIfExists = zrxContractAddressIfExists;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns the unavailable takerAmount of an order. Unavailable amount is defined as the total
|
* Returns the unavailable takerAmount of an order. Unavailable amount is defined as the total
|
||||||
@@ -97,14 +104,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
* @return The amount of the order (in taker tokens) that has either been filled or cancelled.
|
* @return The amount of the order (in taker tokens) that has either been filled or cancelled.
|
||||||
*/
|
*/
|
||||||
public async getUnavailableTakerAmountAsync(orderHash: string,
|
public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
|
||||||
methodOpts?: MethodOpts): Promise<BigNumber> {
|
|
||||||
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
|
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
|
||||||
|
|
||||||
const exchangeContract = await this._getExchangeContractAsync();
|
const exchangeContract = await this._getExchangeContractAsync();
|
||||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
||||||
let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
||||||
orderHash, defaultBlock,
|
orderHash,
|
||||||
|
defaultBlock,
|
||||||
);
|
);
|
||||||
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
unavailableTakerTokenAmount = new BigNumber(unavailableTakerTokenAmount);
|
unavailableTakerTokenAmount = new BigNumber(unavailableTakerTokenAmount);
|
||||||
@@ -163,24 +170,32 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
public async fillOrderAsync(
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
signedOrder: SignedOrder,
|
||||||
takerAddress: string,
|
fillTakerTokenAmount: BigNumber,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
|
takerAddress: string,
|
||||||
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
||||||
@@ -219,30 +234,44 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async fillOrdersUpToAsync(signedOrders: SignedOrder[], fillTakerTokenAmount: BigNumber,
|
public async fillOrdersUpToAsync(
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
signedOrders: SignedOrder[],
|
||||||
takerAddress: string,
|
fillTakerTokenAmount: BigNumber,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
|
takerAddress: string,
|
||||||
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
|
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
|
||||||
const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress);
|
const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress);
|
||||||
assert.hasAtMostOneUniqueValue(takerTokenAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed);
|
takerTokenAddresses,
|
||||||
|
ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed,
|
||||||
|
);
|
||||||
const exchangeContractAddresses = _.map(signedOrders, signedOrder => signedOrder.exchangeContractAddress);
|
const exchangeContractAddresses = _.map(signedOrders, signedOrder => signedOrder.exchangeContractAddress);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
|
let filledTakerTokenAmount = new BigNumber(0);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
for (const signedOrder of signedOrders) {
|
for (const signedOrder of signedOrders) {
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
const singleFilledTakerTokenAmount = await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount.minus(filledTakerTokenAmount),
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
|
filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,29 +329,36 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async batchFillOrdersAsync(orderFillRequests: OrderFillRequest[],
|
public async batchFillOrdersAsync(
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
orderFillRequests: OrderFillRequest[],
|
||||||
takerAddress: string,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
takerAddress: string,
|
||||||
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderFillRequests,
|
orderFillRequests,
|
||||||
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
for (const orderFillRequest of orderFillRequests) {
|
for (const orderFillRequest of orderFillRequests) {
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount,
|
exchangeTradeEmulator,
|
||||||
takerAddress, zrxTokenAddress,
|
orderFillRequest.signedOrder,
|
||||||
|
orderFillRequest.takerTokenFillAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,23 +409,31 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
public async fillOrKillOrderAsync(
|
||||||
takerAddress: string,
|
signedOrder: SignedOrder,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
||||||
@@ -418,33 +462,39 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async batchFillOrKillAsync(orderFillRequests: OrderFillRequest[],
|
public async batchFillOrKillAsync(
|
||||||
takerAddress: string,
|
orderFillRequests: OrderFillRequest[],
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
takerAddress: string,
|
||||||
assert.doesConformToSchema('orderFillRequests', orderFillRequests,
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
schemas.orderFillRequestsSchema);
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderFillRequests,
|
orderFillRequests,
|
||||||
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
if (_.isEmpty(orderFillRequests)) {
|
if (_.isEmpty(orderFillRequests)) {
|
||||||
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
}
|
}
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
for (const orderFillRequest of orderFillRequests) {
|
for (const orderFillRequest of orderFillRequests) {
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount,
|
exchangeTradeEmulator,
|
||||||
takerAddress, zrxTokenAddress,
|
orderFillRequest.signedOrder,
|
||||||
|
orderFillRequest.takerTokenFillAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,8 +510,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
||||||
const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] =
|
const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>(
|
||||||
_.unzip<any>(orderAddressesValuesAndTakerTokenFillAmounts);
|
orderAddressesValuesAndTakerTokenFillAmounts,
|
||||||
|
);
|
||||||
const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@@ -486,23 +537,28 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async cancelOrderAsync(order: Order|SignedOrder,
|
public async cancelOrderAsync(
|
||||||
cancelTakerTokenAmount: BigNumber,
|
order: Order | SignedOrder,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
cancelTakerTokenAmount: BigNumber,
|
||||||
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const orderHash = utils.getOrderHashHex(order);
|
const orderHash = utils.getOrderHashHex(order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
||||||
order, cancelTakerTokenAmount, unavailableTakerTokenAmount);
|
order,
|
||||||
|
cancelTakerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
||||||
@@ -527,33 +583,40 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async batchCancelOrdersAsync(orderCancellationRequests: OrderCancellationRequest[],
|
public async batchCancelOrdersAsync(
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderCancellationRequests: OrderCancellationRequest[],
|
||||||
assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests,
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
schemas.orderCancellationRequestsSchema);
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema(
|
||||||
|
'orderCancellationRequests',
|
||||||
|
orderCancellationRequests,
|
||||||
|
schemas.orderCancellationRequestsSchema,
|
||||||
|
);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderCancellationRequests,
|
orderCancellationRequests,
|
||||||
orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress,
|
orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker);
|
const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker);
|
||||||
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
||||||
const maker = makers[0];
|
const maker = makers[0];
|
||||||
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
for (const orderCancellationRequest of orderCancellationRequests) {
|
for (const orderCancellationRequest of orderCancellationRequests) {
|
||||||
const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
|
const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
||||||
orderCancellationRequest.order, orderCancellationRequest.takerTokenCancelAmount,
|
orderCancellationRequest.order,
|
||||||
|
orderCancellationRequest.takerTokenCancelAmount,
|
||||||
unavailableTakerTokenAmount,
|
unavailableTakerTokenAmount,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (_.isEmpty(orderCancellationRequests)) {
|
if (_.isEmpty(orderCancellationRequests)) {
|
||||||
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
@@ -566,8 +629,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
||||||
const [orderAddresses, orderValues, cancelTakerTokenAmounts] =
|
const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>(
|
||||||
_.unzip<any>(orderAddressesValuesAndTakerTokenCancelAmounts);
|
orderAddressesValuesAndTakerTokenCancelAmounts,
|
||||||
|
);
|
||||||
const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@@ -589,14 +653,20 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Subscription token used later to unsubscribe
|
* @return Subscription token used later to unsubscribe
|
||||||
*/
|
*/
|
||||||
public subscribe<ArgsType extends ExchangeContractEventArgs>(
|
public subscribe<ArgsType extends ExchangeContractEventArgs>(
|
||||||
eventName: ExchangeEvents, indexFilterValues: IndexedFilterValues,
|
eventName: ExchangeEvents,
|
||||||
callback: EventCallback<ArgsType>): string {
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const exchangeContractAddress = this.getContractAddress();
|
const exchangeContractAddress = this.getContractAddress();
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
exchangeContractAddress, eventName, indexFilterValues, artifacts.ExchangeArtifact.abi, callback,
|
exchangeContractAddress,
|
||||||
|
eventName,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.ExchangeArtifact.abi,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
return subscriptionToken;
|
return subscriptionToken;
|
||||||
}
|
}
|
||||||
@@ -622,14 +692,20 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Array of logs that match the parameters
|
* @return Array of logs that match the parameters
|
||||||
*/
|
*/
|
||||||
public async getLogsAsync<ArgsType extends ExchangeContractEventArgs>(
|
public async getLogsAsync<ArgsType extends ExchangeContractEventArgs>(
|
||||||
eventName: ExchangeEvents, blockRange: BlockRange, indexFilterValues: IndexedFilterValues,
|
eventName: ExchangeEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const exchangeContractAddress = this.getContractAddress();
|
const exchangeContractAddress = this.getContractAddress();
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
exchangeContractAddress, eventName, blockRange, indexFilterValues, artifacts.ExchangeArtifact.abi,
|
exchangeContractAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.ExchangeArtifact.abi,
|
||||||
);
|
);
|
||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
@@ -652,14 +728,18 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* to validate for.
|
* to validate for.
|
||||||
*/
|
*/
|
||||||
public async validateOrderFillableOrThrowAsync(
|
public async validateOrderFillableOrThrowAsync(
|
||||||
signedOrder: SignedOrder, opts?: ValidateOrderFillableOpts,
|
signedOrder: SignedOrder,
|
||||||
|
opts?: ValidateOrderFillableOpts,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
|
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateOrderFillableOrThrowAsync(
|
await this._orderValidationUtils.validateOrderFillableOrThrowAsync(
|
||||||
exchangeTradeEmulator, signedOrder, zrxTokenAddress, expectedFillTakerTokenAmount,
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
zrxTokenAddress,
|
||||||
|
expectedFillTakerTokenAmount,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -670,16 +750,23 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param takerAddress The user Ethereum address who would like to fill this order.
|
* @param takerAddress The user Ethereum address who would like to fill this order.
|
||||||
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
||||||
*/
|
*/
|
||||||
public async validateFillOrderThrowIfInvalidAsync(signedOrder: SignedOrder,
|
public async validateFillOrderThrowIfInvalidAsync(
|
||||||
fillTakerTokenAmount: BigNumber,
|
signedOrder: SignedOrder,
|
||||||
takerAddress: string): Promise<void> {
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if cancelling a given order will succeed and throws an informative error if it won't.
|
* Checks if cancelling a given order will succeed and throws an informative error if it won't.
|
||||||
@@ -688,13 +775,18 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel.
|
* @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel.
|
||||||
*/
|
*/
|
||||||
public async validateCancelOrderThrowIfInvalidAsync(
|
public async validateCancelOrderThrowIfInvalidAsync(
|
||||||
order: Order, cancelTakerTokenAmount: BigNumber): Promise<void> {
|
order: Order,
|
||||||
|
cancelTakerTokenAmount: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
|
assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
|
||||||
const orderHash = utils.getOrderHashHex(order);
|
const orderHash = utils.getOrderHashHex(order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
||||||
order, cancelTakerTokenAmount, unavailableTakerTokenAmount);
|
order,
|
||||||
|
cancelTakerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if calling fillOrKill on a given order will succeed and throws an informative error if it won't.
|
* Checks if calling fillOrKill on a given order will succeed and throws an informative error if it won't.
|
||||||
@@ -704,16 +796,23 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param takerAddress The user Ethereum address who would like to fill this order.
|
* @param takerAddress The user Ethereum address who would like to fill this order.
|
||||||
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
||||||
*/
|
*/
|
||||||
public async validateFillOrKillOrderThrowIfInvalidAsync(signedOrder: SignedOrder,
|
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
fillTakerTokenAmount: BigNumber,
|
signedOrder: SignedOrder,
|
||||||
takerAddress: string): Promise<void> {
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if rounding error will be > 0.1% when computing makerTokenAmount by doing:
|
* Checks if rounding error will be > 0.1% when computing makerTokenAmount by doing:
|
||||||
@@ -724,15 +823,19 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param takerTokenAmount The order size on the taker side
|
* @param takerTokenAmount The order size on the taker side
|
||||||
* @param makerTokenAmount The order size on the maker side
|
* @param makerTokenAmount The order size on the maker side
|
||||||
*/
|
*/
|
||||||
public async isRoundingErrorAsync(fillTakerTokenAmount: BigNumber,
|
public async isRoundingErrorAsync(
|
||||||
takerTokenAmount: BigNumber,
|
fillTakerTokenAmount: BigNumber,
|
||||||
makerTokenAmount: BigNumber): Promise<boolean> {
|
takerTokenAmount: BigNumber,
|
||||||
|
makerTokenAmount: BigNumber,
|
||||||
|
): Promise<boolean> {
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isValidBaseUnitAmount('takerTokenAmount', takerTokenAmount);
|
assert.isValidBaseUnitAmount('takerTokenAmount', takerTokenAmount);
|
||||||
assert.isValidBaseUnitAmount('makerTokenAmount', makerTokenAmount);
|
assert.isValidBaseUnitAmount('makerTokenAmount', makerTokenAmount);
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const isRoundingError = await exchangeInstance.isRoundingError.callAsync(
|
const isRoundingError = await exchangeInstance.isRoundingError.callAsync(
|
||||||
fillTakerTokenAmount, takerTokenAmount, makerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
|
takerTokenAmount,
|
||||||
|
makerTokenAmount,
|
||||||
);
|
);
|
||||||
return isRoundingError;
|
return isRoundingError;
|
||||||
}
|
}
|
||||||
@@ -740,10 +843,10 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* Checks if logs contain LogError, which is emmited by Exchange contract on transaction failure.
|
* Checks if logs contain LogError, which is emmited by Exchange contract on transaction failure.
|
||||||
* @param logs Transaction logs as returned by `zeroEx.awaitTransactionMinedAsync`
|
* @param logs Transaction logs as returned by `zeroEx.awaitTransactionMinedAsync`
|
||||||
*/
|
*/
|
||||||
public throwLogErrorsAsErrors(logs: Array<LogWithDecodedArgs<DecodedLogArgs>|Web3.LogEntry>): void {
|
public throwLogErrorsAsErrors(logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>): void {
|
||||||
const errLog = _.find(logs, {
|
const errLog = _.find(logs, {
|
||||||
event: ExchangeEvents.LogError,
|
event: ExchangeEvents.LogError,
|
||||||
}) as LogWithDecodedArgs<LogErrorContractEventArgs>|undefined;
|
}) as LogWithDecodedArgs<LogErrorContractEventArgs> | undefined;
|
||||||
if (!_.isUndefined(errLog)) {
|
if (!_.isUndefined(errLog)) {
|
||||||
const logArgs = errLog.args;
|
const logArgs = errLog.args;
|
||||||
const errCode = logArgs.errorId.toNumber();
|
const errCode = logArgs.errorId.toNumber();
|
||||||
@@ -756,17 +859,18 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Address of ZRX token
|
* @return Address of ZRX token
|
||||||
*/
|
*/
|
||||||
public getZRXTokenAddress(): string {
|
public getZRXTokenAddress(): string {
|
||||||
const contractAddress = this._getContractAddress(
|
const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
|
||||||
artifacts.ZRXArtifact, this._zrxContractAddressIfExists,
|
|
||||||
);
|
|
||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
private _invalidateContractInstances(): void {
|
private _invalidateContractInstances(): void {
|
||||||
this.unsubscribeAll();
|
this.unsubscribeAll();
|
||||||
delete this._exchangeContractIfExists;
|
delete this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
private async _isValidSignatureUsingContractCallAsync(dataHex: string, ecSignature: ECSignature,
|
private async _isValidSignatureUsingContractCallAsync(
|
||||||
signerAddressHex: string): Promise<boolean> {
|
dataHex: string,
|
||||||
|
ecSignature: ECSignature,
|
||||||
|
signerAddressHex: string,
|
||||||
|
): Promise<boolean> {
|
||||||
assert.isHexString('dataHex', dataHex);
|
assert.isHexString('dataHex', dataHex);
|
||||||
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
|
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
|
||||||
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
|
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
|
||||||
@@ -782,7 +886,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
);
|
);
|
||||||
return isValidSignature;
|
return isValidSignature;
|
||||||
}
|
}
|
||||||
private async _getOrderHashHexUsingContractCallAsync(order: Order|SignedOrder): Promise<string> {
|
private async _getOrderHashHexUsingContractCallAsync(order: Order | SignedOrder): Promise<string> {
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
||||||
const orderHashHex = await exchangeInstance.getOrderHash.callAsync(orderAddresses, orderValues);
|
const orderHashHex = await exchangeInstance.getOrderHash.callAsync(orderAddresses, orderValues);
|
||||||
@@ -793,7 +897,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
return this._exchangeContractIfExists;
|
return this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.ExchangeArtifact, this._contractAddressIfExists,
|
artifacts.ExchangeArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
this._exchangeContractIfExists = contractInstance;
|
this._exchangeContractIfExists = contractInstance;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {artifacts} from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import {Token, TokenMetadata} from '../types';
|
import { Token, TokenMetadata } from '../types';
|
||||||
import {assert} from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
import {constants} from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
|
|
||||||
import {ContractWrapper} from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import {TokenRegistryContract} from './generated/token_registry';
|
import { TokenRegistryContract } from './generated/token_registry';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes all the functionality related to interacting with the 0x Token Registry smart contract.
|
* This class includes all the functionality related to interacting with the 0x Token Registry smart contract.
|
||||||
@@ -15,7 +15,7 @@ import {TokenRegistryContract} from './generated/token_registry';
|
|||||||
export class TokenRegistryWrapper extends ContractWrapper {
|
export class TokenRegistryWrapper extends ContractWrapper {
|
||||||
private _tokenRegistryContractIfExists?: TokenRegistryContract;
|
private _tokenRegistryContractIfExists?: TokenRegistryContract;
|
||||||
private _contractAddressIfExists?: string;
|
private _contractAddressIfExists?: string;
|
||||||
private static _createTokenFromMetadata(metadata: TokenMetadata): Token|undefined {
|
private static _createTokenFromMetadata(metadata: TokenMetadata): Token | undefined {
|
||||||
if (metadata[0] === constants.NULL_ADDRESS) {
|
if (metadata[0] === constants.NULL_ADDRESS) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -37,9 +37,8 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
public async getTokensAsync(): Promise<Token[]> {
|
public async getTokensAsync(): Promise<Token[]> {
|
||||||
const addresses = await this.getTokenAddressesAsync();
|
const addresses = await this.getTokenAddressesAsync();
|
||||||
const tokenPromises: Array<Promise<Token|undefined>> = _.map(
|
const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (address: string) =>
|
||||||
addresses,
|
this.getTokenIfExistsAsync(address),
|
||||||
async (address: string) => this.getTokenIfExistsAsync(address),
|
|
||||||
);
|
);
|
||||||
const tokens = await Promise.all(tokenPromises);
|
const tokens = await Promise.all(tokenPromises);
|
||||||
return tokens as Token[];
|
return tokens as Token[];
|
||||||
@@ -57,7 +56,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
* Retrieves a token by address currently listed in the Token Registry smart contract
|
* Retrieves a token by address currently listed in the Token Registry smart contract
|
||||||
* @return An object that conforms to the Token interface or undefined if token not found.
|
* @return An object that conforms to the Token interface or undefined if token not found.
|
||||||
*/
|
*/
|
||||||
public async getTokenIfExistsAsync(address: string): Promise<Token|undefined> {
|
public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> {
|
||||||
assert.isETHAddressHex('address', address);
|
assert.isETHAddressHex('address', address);
|
||||||
|
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
@@ -65,7 +64,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string|undefined> {
|
public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string | undefined> {
|
||||||
assert.isString('symbol', symbol);
|
assert.isString('symbol', symbol);
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const addressIfExists = await tokenRegistryContract.getTokenAddressBySymbol.callAsync(symbol);
|
const addressIfExists = await tokenRegistryContract.getTokenAddressBySymbol.callAsync(symbol);
|
||||||
@@ -74,7 +73,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
return addressIfExists;
|
return addressIfExists;
|
||||||
}
|
}
|
||||||
public async getTokenAddressByNameIfExistsAsync(name: string): Promise<string|undefined> {
|
public async getTokenAddressByNameIfExistsAsync(name: string): Promise<string | undefined> {
|
||||||
assert.isString('name', name);
|
assert.isString('name', name);
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const addressIfExists = await tokenRegistryContract.getTokenAddressByName.callAsync(name);
|
const addressIfExists = await tokenRegistryContract.getTokenAddressByName.callAsync(name);
|
||||||
@@ -83,14 +82,14 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
return addressIfExists;
|
return addressIfExists;
|
||||||
}
|
}
|
||||||
public async getTokenBySymbolIfExistsAsync(symbol: string): Promise<Token|undefined> {
|
public async getTokenBySymbolIfExistsAsync(symbol: string): Promise<Token | undefined> {
|
||||||
assert.isString('symbol', symbol);
|
assert.isString('symbol', symbol);
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
|
const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol);
|
||||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
public async getTokenByNameIfExistsAsync(name: string): Promise<Token|undefined> {
|
public async getTokenByNameIfExistsAsync(name: string): Promise<Token | undefined> {
|
||||||
assert.isString('name', name);
|
assert.isString('name', name);
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
|
const metadata = await tokenRegistryContract.getTokenByName.callAsync(name);
|
||||||
@@ -104,7 +103,8 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
public getContractAddress(): string {
|
public getContractAddress(): string {
|
||||||
const contractAddress = this._getContractAddress(
|
const contractAddress = this._getContractAddress(
|
||||||
artifacts.TokenRegistryArtifact, this._contractAddressIfExists,
|
artifacts.TokenRegistryArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
@@ -116,10 +116,12 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
return this._tokenRegistryContractIfExists;
|
return this._tokenRegistryContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenRegistryArtifact, this._contractAddressIfExists,
|
artifacts.TokenRegistryArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenRegistryContract(
|
const contractInstance = new TokenRegistryContract(
|
||||||
web3ContractInstance, this._web3Wrapper.getContractDefaults(),
|
web3ContractInstance,
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
);
|
);
|
||||||
this._tokenRegistryContractIfExists = contractInstance;
|
this._tokenRegistryContractIfExists = contractInstance;
|
||||||
return this._tokenRegistryContractIfExists;
|
return this._tokenRegistryContractIfExists;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {artifacts} from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
|
|
||||||
import {ContractWrapper} from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import {TokenTransferProxyContract} from './generated/token_transfer_proxy';
|
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes the functionality related to interacting with the TokenTransferProxy contract.
|
* This class includes the functionality related to interacting with the TokenTransferProxy contract.
|
||||||
@@ -42,7 +42,8 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
public getContractAddress(): string {
|
public getContractAddress(): string {
|
||||||
const contractAddress = this._getContractAddress(
|
const contractAddress = this._getContractAddress(
|
||||||
artifacts.TokenTransferProxyArtifact, this._contractAddressIfExists,
|
artifacts.TokenTransferProxyArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
@@ -54,10 +55,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
return this._tokenTransferProxyContractIfExists;
|
return this._tokenTransferProxyContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenTransferProxyArtifact, this._contractAddressIfExists,
|
artifacts.TokenTransferProxyArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenTransferProxyContract(
|
const contractInstance = new TokenTransferProxyContract(
|
||||||
web3ContractInstance, this._web3Wrapper.getContractDefaults(),
|
web3ContractInstance,
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
);
|
);
|
||||||
this._tokenTransferProxyContractIfExists = contractInstance;
|
this._tokenTransferProxyContractIfExists = contractInstance;
|
||||||
return this._tokenTransferProxyContractIfExists;
|
return this._tokenTransferProxyContractIfExists;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {schemas} from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {artifacts} from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import {
|
import {
|
||||||
BlockRange,
|
BlockRange,
|
||||||
EventCallback,
|
EventCallback,
|
||||||
@@ -15,13 +15,13 @@ import {
|
|||||||
TransactionOpts,
|
TransactionOpts,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {AbiDecoder} from '../utils/abi_decoder';
|
import { AbiDecoder } from '../utils/abi_decoder';
|
||||||
import {assert} from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
import {constants} from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
|
|
||||||
import {ContractWrapper} from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import {TokenContract} from './generated/token';
|
import { TokenContract } from './generated/token';
|
||||||
import {TokenTransferProxyWrapper} from './token_transfer_proxy_wrapper';
|
import { TokenTransferProxyWrapper } from './token_transfer_proxy_wrapper';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class includes all the functionality related to interacting with ERC20 token contracts.
|
* This class includes all the functionality related to interacting with ERC20 token contracts.
|
||||||
@@ -30,10 +30,14 @@ import {TokenTransferProxyWrapper} from './token_transfer_proxy_wrapper';
|
|||||||
*/
|
*/
|
||||||
export class TokenWrapper extends ContractWrapper {
|
export class TokenWrapper extends ContractWrapper {
|
||||||
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
||||||
private _tokenContractsByAddress: {[address: string]: TokenContract};
|
private _tokenContractsByAddress: { [address: string]: TokenContract };
|
||||||
private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
|
private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder,
|
constructor(
|
||||||
tokenTransferProxyWrapper: TokenTransferProxyWrapper) {
|
web3Wrapper: Web3Wrapper,
|
||||||
|
networkId: number,
|
||||||
|
abiDecoder: AbiDecoder,
|
||||||
|
tokenTransferProxyWrapper: TokenTransferProxyWrapper,
|
||||||
|
) {
|
||||||
super(web3Wrapper, networkId, abiDecoder);
|
super(web3Wrapper, networkId, abiDecoder);
|
||||||
this._tokenContractsByAddress = {};
|
this._tokenContractsByAddress = {};
|
||||||
this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
|
this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
|
||||||
@@ -45,8 +49,11 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
* @return The owner's ERC20 token balance in base units.
|
* @return The owner's ERC20 token balance in base units.
|
||||||
*/
|
*/
|
||||||
public async getBalanceAsync(tokenAddress: string, ownerAddress: string,
|
public async getBalanceAsync(
|
||||||
methodOpts?: MethodOpts): Promise<BigNumber> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
methodOpts?: MethodOpts,
|
||||||
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
|
||||||
@@ -68,8 +75,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string,
|
public async setAllowanceAsync(
|
||||||
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
spenderAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
||||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
@@ -95,10 +107,18 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setUnlimitedAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async setUnlimitedAllowanceAsync(
|
||||||
spenderAddress: string, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
spenderAddress: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, spenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts,
|
tokenAddress,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
|
txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -110,8 +130,12 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param spenderAddress The hex encoded user Ethereum address who can spend the allowance you are fetching.
|
* @param spenderAddress The hex encoded user Ethereum address who can spend the allowance you are fetching.
|
||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
*/
|
*/
|
||||||
public async getAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async getAllowanceAsync(
|
||||||
spenderAddress: string, methodOpts?: MethodOpts): Promise<BigNumber> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
spenderAddress: string,
|
||||||
|
methodOpts?: MethodOpts,
|
||||||
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
|
||||||
@@ -128,8 +152,11 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param ownerAddress The hex encoded user Ethereum address whose proxy contract allowance we are retrieving.
|
* @param ownerAddress The hex encoded user Ethereum address whose proxy contract allowance we are retrieving.
|
||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
*/
|
*/
|
||||||
public async getProxyAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async getProxyAllowanceAsync(
|
||||||
methodOpts?: MethodOpts): Promise<BigNumber> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
methodOpts?: MethodOpts,
|
||||||
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
|
||||||
@@ -147,15 +174,23 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setProxyAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async setProxyAllowanceAsync(
|
||||||
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits, txOpts,
|
tokenAddress,
|
||||||
|
ownerAddress,
|
||||||
|
proxyAddress,
|
||||||
|
amountInBaseUnits,
|
||||||
|
txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -171,10 +206,15 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setUnlimitedProxyAllowanceAsync(
|
public async setUnlimitedProxyAllowanceAsync(
|
||||||
tokenAddress: string, ownerAddress: string, txOpts: TransactionOpts = {},
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const txHash = await this.setProxyAllowanceAsync(
|
const txHash = await this.setProxyAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts,
|
tokenAddress,
|
||||||
|
ownerAddress,
|
||||||
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
|
txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@@ -187,8 +227,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async transferAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
public async transferAsync(
|
||||||
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
fromAddress: string,
|
||||||
|
toAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
@@ -222,9 +267,14 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async transferFromAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
public async transferFromAsync(
|
||||||
senderAddress: string, amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}):
|
tokenAddress: string,
|
||||||
Promise<string> {
|
fromAddress: string,
|
||||||
|
toAddress: string,
|
||||||
|
senderAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
assert.isETHAddressHex('fromAddress', fromAddress);
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
@@ -244,7 +294,9 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
||||||
fromAddress, toAddress, amountInBaseUnits,
|
fromAddress,
|
||||||
|
toAddress,
|
||||||
|
amountInBaseUnits,
|
||||||
{
|
{
|
||||||
from: senderAddress,
|
from: senderAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
@@ -263,14 +315,21 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @return Subscription token used later to unsubscribe
|
* @return Subscription token used later to unsubscribe
|
||||||
*/
|
*/
|
||||||
public subscribe<ArgsType extends TokenContractEventArgs>(
|
public subscribe<ArgsType extends TokenContractEventArgs>(
|
||||||
tokenAddress: string, eventName: TokenEvents, indexFilterValues: IndexedFilterValues,
|
tokenAddress: string,
|
||||||
callback: EventCallback<ArgsType>): string {
|
eventName: TokenEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
tokenAddress, eventName, indexFilterValues, artifacts.TokenArtifact.abi, callback,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.TokenArtifact.abi,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
return subscriptionToken;
|
return subscriptionToken;
|
||||||
}
|
}
|
||||||
@@ -297,14 +356,21 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @return Array of logs that match the parameters
|
* @return Array of logs that match the parameters
|
||||||
*/
|
*/
|
||||||
public async getLogsAsync<ArgsType extends TokenContractEventArgs>(
|
public async getLogsAsync<ArgsType extends TokenContractEventArgs>(
|
||||||
tokenAddress: string, eventName: TokenEvents, blockRange: BlockRange,
|
tokenAddress: string,
|
||||||
indexFilterValues: IndexedFilterValues): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
eventName: TokenEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
tokenAddress, eventName, blockRange, indexFilterValues, artifacts.TokenArtifact.abi,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.TokenArtifact.abi,
|
||||||
);
|
);
|
||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
@@ -318,11 +384,10 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
return tokenContract;
|
return tokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenArtifact, tokenAddress,
|
artifacts.TokenArtifact,
|
||||||
);
|
tokenAddress,
|
||||||
const contractInstance = new TokenContract(
|
|
||||||
web3ContractInstance, this._web3Wrapper.getContractDefaults(),
|
|
||||||
);
|
);
|
||||||
|
const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
tokenContract = contractInstance;
|
tokenContract = contractInstance;
|
||||||
this._tokenContractsByAddress[tokenAddress] = tokenContract;
|
this._tokenContractsByAddress[tokenAddress] = tokenContract;
|
||||||
return tokenContract;
|
return tokenContract;
|
||||||
|
|||||||
17
packages/0x.js/src/globals.d.ts
vendored
17
packages/0x.js/src/globals.d.ts
vendored
@@ -1,5 +1,3 @@
|
|||||||
/// <reference types='chai-typescript-typings' />
|
|
||||||
/// <reference types='chai-as-promised-typescript-typings' />
|
|
||||||
declare module 'web3_beta';
|
declare module 'web3_beta';
|
||||||
declare module 'chai-bignumber';
|
declare module 'chai-bignumber';
|
||||||
declare module 'dirty-chai';
|
declare module 'dirty-chai';
|
||||||
@@ -27,18 +25,6 @@ declare module '*.json' {
|
|||||||
/* tslint:enable */
|
/* tslint:enable */
|
||||||
}
|
}
|
||||||
|
|
||||||
// find-version declarations
|
|
||||||
declare function findVersions(version: string): string[];
|
|
||||||
declare module 'find-versions' {
|
|
||||||
export = findVersions;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare-version declarations
|
|
||||||
declare function compareVersions(firstVersion: string, secondVersion: string): number;
|
|
||||||
declare module 'compare-versions' {
|
|
||||||
export = compareVersions;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'ethereumjs-abi' {
|
declare module 'ethereumjs-abi' {
|
||||||
const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
|
const soliditySHA3: (argTypes: string[], args: any[]) => Buffer;
|
||||||
}
|
}
|
||||||
@@ -57,8 +43,7 @@ declare module 'truffle-hdwallet-provider' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// abi-decoder declarations
|
// abi-decoder declarations
|
||||||
interface DecodedLogArg {
|
interface DecodedLogArg {}
|
||||||
}
|
|
||||||
interface DecodedLog {
|
interface DecodedLog {
|
||||||
name: string;
|
name: string;
|
||||||
events: DecodedLogArg[];
|
events: DecodedLogArg[];
|
||||||
|
|||||||
6
packages/0x.js/src/globalsAugment.d.ts
vendored
6
packages/0x.js/src/globalsAugment.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
|
||||||
// HACK: This module overrides the Chai namespace so that we can use BigNumber types inside.
|
// HACK: This module overrides the Chai namespace so that we can use BigNumber types inside.
|
||||||
// Source: https://github.com/Microsoft/TypeScript/issues/7352#issuecomment-191547232
|
// Source: https://github.com/Microsoft/TypeScript/issues/7352#issuecomment-191547232
|
||||||
@@ -9,7 +9,7 @@ declare global {
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
namespace Chai {
|
namespace Chai {
|
||||||
interface NumberComparer {
|
interface NumberComparer {
|
||||||
(value: number|BigNumber, message?: string): Assertion;
|
(value: number | BigNumber, message?: string): Assertion;
|
||||||
}
|
}
|
||||||
interface NumericComparison {
|
interface NumericComparison {
|
||||||
greaterThan: NumberComparer;
|
greaterThan: NumberComparer;
|
||||||
@@ -18,6 +18,6 @@ declare global {
|
|||||||
/* tslint:enable */
|
/* tslint:enable */
|
||||||
interface DecodedLogArg {
|
interface DecodedLogArg {
|
||||||
name: string;
|
name: string;
|
||||||
value: string|BigNumber;
|
value: string | BigNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export {ZeroEx} from './0x';
|
export { ZeroEx } from './0x';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Order,
|
Order,
|
||||||
@@ -47,6 +47,4 @@ export {
|
|||||||
OrderState,
|
OrderState,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export {
|
export { TransactionReceipt } from '@0xproject/types';
|
||||||
TransactionReceipt,
|
|
||||||
} from '@0xproject/types';
|
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import {intervalUtils} from '@0xproject/utils';
|
import { intervalUtils } from '@0xproject/utils';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {
|
import { BlockParamLiteral, EventWatcherCallback, ZeroExError } from '../types';
|
||||||
BlockParamLiteral,
|
import { assert } from '../utils/assert';
|
||||||
EventWatcherCallback,
|
|
||||||
ZeroExError,
|
|
||||||
} from '../types';
|
|
||||||
import {assert} from '../utils/assert';
|
|
||||||
|
|
||||||
const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
|
const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
|
||||||
|
|
||||||
@@ -26,11 +22,11 @@ export class EventWatcher {
|
|||||||
private _pollingIntervalMs: number;
|
private _pollingIntervalMs: number;
|
||||||
private _intervalIdIfExists?: NodeJS.Timer;
|
private _intervalIdIfExists?: NodeJS.Timer;
|
||||||
private _lastEvents: Web3.LogEntry[] = [];
|
private _lastEvents: Web3.LogEntry[] = [];
|
||||||
constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined|number) {
|
constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
|
||||||
this._web3Wrapper = web3Wrapper;
|
this._web3Wrapper = web3Wrapper;
|
||||||
this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ?
|
this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs)
|
||||||
DEFAULT_EVENT_POLLING_INTERVAL_MS :
|
? DEFAULT_EVENT_POLLING_INTERVAL_MS
|
||||||
pollingIntervalIfExistsMs;
|
: pollingIntervalIfExistsMs;
|
||||||
}
|
}
|
||||||
public subscribe(callback: EventWatcherCallback): void {
|
public subscribe(callback: EventWatcherCallback): void {
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
@@ -38,7 +34,12 @@ export class EventWatcher {
|
|||||||
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
||||||
}
|
}
|
||||||
this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._pollForBlockchainEventsAsync.bind(this, callback), this._pollingIntervalMs,
|
this._pollForBlockchainEventsAsync.bind(this, callback),
|
||||||
|
this._pollingIntervalMs,
|
||||||
|
(err: Error) => {
|
||||||
|
this.unsubscribe();
|
||||||
|
callback(err);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public unsubscribe(): void {
|
public unsubscribe(): void {
|
||||||
@@ -50,6 +51,10 @@ export class EventWatcher {
|
|||||||
}
|
}
|
||||||
private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> {
|
private async _pollForBlockchainEventsAsync(callback: EventWatcherCallback): Promise<void> {
|
||||||
const pendingEvents = await this._getEventsAsync();
|
const pendingEvents = await this._getEventsAsync();
|
||||||
|
if (_.isUndefined(pendingEvents)) {
|
||||||
|
// HACK: This should never happen, but happens frequently on CI due to a ganache bug
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (pendingEvents.length === 0) {
|
if (pendingEvents.length === 0) {
|
||||||
// HACK: Sometimes when node rebuilds the pending block we get back the empty result.
|
// HACK: Sometimes when node rebuilds the pending block we get back the empty result.
|
||||||
// We don't want to emit a lot of removal events and bring them back after a couple of miliseconds,
|
// We don't want to emit a lot of removal events and bring them back after a couple of miliseconds,
|
||||||
@@ -71,7 +76,9 @@ export class EventWatcher {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
private async _emitDifferencesAsync(
|
private async _emitDifferencesAsync(
|
||||||
logs: Web3.LogEntry[], logEventState: LogEventState, callback: EventWatcherCallback,
|
logs: Web3.LogEntry[],
|
||||||
|
logEventState: LogEventState,
|
||||||
|
callback: EventWatcherCallback,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
for (const log of logs) {
|
for (const log of logs) {
|
||||||
const logEvent = {
|
const logEvent = {
|
||||||
@@ -79,7 +86,7 @@ export class EventWatcher {
|
|||||||
...log,
|
...log,
|
||||||
};
|
};
|
||||||
if (!_.isUndefined(this._intervalIdIfExists)) {
|
if (!_.isUndefined(this._intervalIdIfExists)) {
|
||||||
callback(logEvent);
|
callback(null, logEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import {intervalUtils} from '@0xproject/utils';
|
import { BigNumber, intervalUtils } from '@0xproject/utils';
|
||||||
import {BigNumber} from 'bignumber.js';
|
import { RBTree } from 'bintrees';
|
||||||
import {RBTree} from 'bintrees';
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {ZeroExError} from '../types';
|
import { ZeroExError } from '../types';
|
||||||
import {utils} from '../utils/utils';
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
const DEFAULT_EXPIRATION_MARGIN_MS = 0;
|
const DEFAULT_EXPIRATION_MARGIN_MS = 0;
|
||||||
const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50;
|
const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50;
|
||||||
@@ -15,16 +14,14 @@ const DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS = 50;
|
|||||||
*/
|
*/
|
||||||
export class ExpirationWatcher {
|
export class ExpirationWatcher {
|
||||||
private _orderHashByExpirationRBTree: RBTree<string>;
|
private _orderHashByExpirationRBTree: RBTree<string>;
|
||||||
private _expiration: {[orderHash: string]: BigNumber} = {};
|
private _expiration: { [orderHash: string]: BigNumber } = {};
|
||||||
private _orderExpirationCheckingIntervalMs: number;
|
private _orderExpirationCheckingIntervalMs: number;
|
||||||
private _expirationMarginMs: number;
|
private _expirationMarginMs: number;
|
||||||
private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
|
private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
|
||||||
constructor(expirationMarginIfExistsMs?: number,
|
constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) {
|
||||||
orderExpirationCheckingIntervalIfExistsMs?: number) {
|
this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS;
|
||||||
this._expirationMarginMs = expirationMarginIfExistsMs ||
|
this._orderExpirationCheckingIntervalMs =
|
||||||
DEFAULT_EXPIRATION_MARGIN_MS;
|
expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
|
||||||
this._orderExpirationCheckingIntervalMs = expirationMarginIfExistsMs ||
|
|
||||||
DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
|
|
||||||
const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
|
const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
|
||||||
const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
|
const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
|
||||||
this._orderHashByExpirationRBTree = new RBTree(comparator);
|
this._orderHashByExpirationRBTree = new RBTree(comparator);
|
||||||
@@ -33,15 +30,17 @@ export class ExpirationWatcher {
|
|||||||
if (!_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
|
if (!_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
|
||||||
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
||||||
}
|
}
|
||||||
this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setInterval(
|
||||||
this._pruneExpiredOrders.bind(this, callback), this._orderExpirationCheckingIntervalMs,
|
this._pruneExpiredOrders.bind(this, callback),
|
||||||
|
this._orderExpirationCheckingIntervalMs,
|
||||||
|
_.noop, // _pruneExpiredOrders never throws
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public unsubscribe(): void {
|
public unsubscribe(): void {
|
||||||
if (_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
|
if (_.isUndefined(this._orderExpirationCheckingIntervalIdIfExists)) {
|
||||||
throw new Error(ZeroExError.SubscriptionNotFound);
|
throw new Error(ZeroExError.SubscriptionNotFound);
|
||||||
}
|
}
|
||||||
intervalUtils.clearAsyncExcludingInterval(this._orderExpirationCheckingIntervalIdIfExists);
|
intervalUtils.clearInterval(this._orderExpirationCheckingIntervalIdIfExists);
|
||||||
delete this._orderExpirationCheckingIntervalIdIfExists;
|
delete this._orderExpirationCheckingIntervalIdIfExists;
|
||||||
}
|
}
|
||||||
public addOrder(orderHash: string, expirationUnixTimestampMs: BigNumber): void {
|
public addOrder(orderHash: string, expirationUnixTimestampMs: BigNumber): void {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {schemas} from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import {intervalUtils} from '@0xproject/utils';
|
import { intervalUtils } from '@0xproject/utils';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {ZeroEx} from '../0x';
|
import { ZeroEx } from '../0x';
|
||||||
import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper';
|
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
|
||||||
import {TokenWrapper} from '../contract_wrappers/token_wrapper';
|
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||||
import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store';
|
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
|
||||||
import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store';
|
import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store';
|
||||||
import {
|
import {
|
||||||
ApprovalContractEventArgs,
|
ApprovalContractEventArgs,
|
||||||
BlockParamLiteral,
|
BlockParamLiteral,
|
||||||
@@ -29,13 +29,13 @@ import {
|
|||||||
WithdrawalContractEventArgs,
|
WithdrawalContractEventArgs,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import {AbiDecoder} from '../utils/abi_decoder';
|
import { AbiDecoder } from '../utils/abi_decoder';
|
||||||
import {assert} from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
import {OrderStateUtils} from '../utils/order_state_utils';
|
import { OrderStateUtils } from '../utils/order_state_utils';
|
||||||
import {utils} from '../utils/utils';
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
import {EventWatcher} from './event_watcher';
|
import { EventWatcher } from './event_watcher';
|
||||||
import {ExpirationWatcher} from './expiration_watcher';
|
import { ExpirationWatcher } from './expiration_watcher';
|
||||||
|
|
||||||
interface DependentOrderHashes {
|
interface DependentOrderHashes {
|
||||||
[makerAddress: string]: {
|
[makerAddress: string]: {
|
||||||
@@ -74,7 +74,10 @@ export class OrderStateWatcher {
|
|||||||
private _cleanupJobInterval: number;
|
private _cleanupJobInterval: number;
|
||||||
private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
|
private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
|
||||||
constructor(
|
constructor(
|
||||||
web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper,
|
web3Wrapper: Web3Wrapper,
|
||||||
|
abiDecoder: AbiDecoder,
|
||||||
|
token: TokenWrapper,
|
||||||
|
exchange: ExchangeWrapper,
|
||||||
config?: OrderStateWatcherConfig,
|
config?: OrderStateWatcherConfig,
|
||||||
) {
|
) {
|
||||||
this._abiDecoder = abiDecoder;
|
this._abiDecoder = abiDecoder;
|
||||||
@@ -82,24 +85,26 @@ export class OrderStateWatcher {
|
|||||||
const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
|
const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
|
||||||
this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
|
this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
|
||||||
this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
token, BlockParamLiteral.Pending,
|
token,
|
||||||
|
BlockParamLiteral.Pending,
|
||||||
);
|
);
|
||||||
this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
|
this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
|
||||||
this._orderStateUtils = new OrderStateUtils(
|
this._orderStateUtils = new OrderStateUtils(
|
||||||
this._balanceAndProxyAllowanceLazyStore, this._orderFilledCancelledLazyStore,
|
this._balanceAndProxyAllowanceLazyStore,
|
||||||
|
this._orderFilledCancelledLazyStore,
|
||||||
);
|
);
|
||||||
const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config) ?
|
const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config)
|
||||||
undefined :
|
? undefined
|
||||||
config.orderExpirationCheckingIntervalMs;
|
: config.orderExpirationCheckingIntervalMs;
|
||||||
const expirationMarginIfExistsMs = _.isUndefined(config) ?
|
const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs;
|
||||||
undefined :
|
|
||||||
config.expirationMarginMs;
|
|
||||||
this._expirationWatcher = new ExpirationWatcher(
|
this._expirationWatcher = new ExpirationWatcher(
|
||||||
expirationMarginIfExistsMs, orderExpirationCheckingIntervalMsIfExists,
|
expirationMarginIfExistsMs,
|
||||||
|
orderExpirationCheckingIntervalMsIfExists,
|
||||||
);
|
);
|
||||||
this._cleanupJobInterval = _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs) ?
|
this._cleanupJobInterval =
|
||||||
DEFAULT_CLEANUP_JOB_INTERVAL_MS :
|
_.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs)
|
||||||
config.cleanupJobIntervalMs;
|
? DEFAULT_CLEANUP_JOB_INTERVAL_MS
|
||||||
|
: config.cleanupJobIntervalMs;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Add an order to the orderStateWatcher. Before the order is added, it's
|
* Add an order to the orderStateWatcher. Before the order is added, it's
|
||||||
@@ -148,7 +153,12 @@ export class OrderStateWatcher {
|
|||||||
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
||||||
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
||||||
this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._cleanupAsync.bind(this), this._cleanupJobInterval,
|
this._cleanupAsync.bind(this),
|
||||||
|
this._cleanupJobInterval,
|
||||||
|
(err: Error) => {
|
||||||
|
this.unsubscribe();
|
||||||
|
callback(err);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -201,11 +211,19 @@ export class OrderStateWatcher {
|
|||||||
if (!_.isUndefined(this._orderByOrderHash[orderHash])) {
|
if (!_.isUndefined(this._orderByOrderHash[orderHash])) {
|
||||||
this.removeOrder(orderHash);
|
this.removeOrder(orderHash);
|
||||||
if (!_.isUndefined(this._callbackIfExists)) {
|
if (!_.isUndefined(this._callbackIfExists)) {
|
||||||
this._callbackIfExists(orderState);
|
this._callbackIfExists(null, orderState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async _onEventWatcherCallbackAsync(log: LogEvent): Promise<void> {
|
private async _onEventWatcherCallbackAsync(err: Error | null, logIfExists?: LogEvent): Promise<void> {
|
||||||
|
if (!_.isNull(err)) {
|
||||||
|
if (!_.isUndefined(this._callbackIfExists)) {
|
||||||
|
this._callbackIfExists(err);
|
||||||
|
this.unsubscribe();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const log = logIfExists as LogEvent; // At this moment we are sure that no error occured and log is defined.
|
||||||
const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
|
const maybeDecodedLog = this._abiDecoder.tryToDecodeLogOrNoop(log);
|
||||||
const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event);
|
const isLogDecoded = !_.isUndefined((maybeDecodedLog as LogWithDecodedArgs<any>).event);
|
||||||
if (!isLogDecoded) {
|
if (!isLogDecoded) {
|
||||||
@@ -215,23 +233,23 @@ export class OrderStateWatcher {
|
|||||||
let makerToken: string;
|
let makerToken: string;
|
||||||
let makerAddress: string;
|
let makerAddress: string;
|
||||||
switch (decodedLog.event) {
|
switch (decodedLog.event) {
|
||||||
case TokenEvents.Approval:
|
case TokenEvents.Approval: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as ApprovalContractEventArgs;
|
const args = decodedLog.args as ApprovalContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._owner;
|
makerAddress = args._owner;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TokenEvents.Transfer:
|
case TokenEvents.Transfer: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as TransferContractEventArgs;
|
const args = decodedLog.args as TransferContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from);
|
||||||
@@ -239,45 +257,48 @@ export class OrderStateWatcher {
|
|||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._from;
|
makerAddress = args._from;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EtherTokenEvents.Deposit:
|
case EtherTokenEvents.Deposit: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as DepositContractEventArgs;
|
const args = decodedLog.args as DepositContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._owner;
|
makerAddress = args._owner;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EtherTokenEvents.Withdrawal:
|
case EtherTokenEvents.Withdrawal: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as WithdrawalContractEventArgs;
|
const args = decodedLog.args as WithdrawalContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._owner;
|
makerAddress = args._owner;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ExchangeEvents.LogFill:
|
case ExchangeEvents.LogFill: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as LogFillContractEventArgs;
|
const args = decodedLog.args as LogFillContractEventArgs;
|
||||||
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash);
|
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash);
|
||||||
@@ -289,8 +310,7 @@ export class OrderStateWatcher {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ExchangeEvents.LogCancel:
|
case ExchangeEvents.LogCancel: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as LogCancelContractEventArgs;
|
const args = decodedLog.args as LogCancelContractEventArgs;
|
||||||
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash);
|
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash);
|
||||||
@@ -324,7 +344,7 @@ export class OrderStateWatcher {
|
|||||||
} else {
|
} else {
|
||||||
this._orderStateByOrderHashCache[orderHash] = orderState;
|
this._orderStateByOrderHashCache[orderHash] = orderState;
|
||||||
}
|
}
|
||||||
this._callbackIfExists(orderState);
|
this._callbackIfExists(null, orderState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private _addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string): void {
|
private _addToDependentOrderHashes(signedOrder: SignedOrder, orderHash: string): void {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {BigNumber} from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
|
||||||
import {SignedOrder} from '../types';
|
import { SignedOrder } from '../types';
|
||||||
|
|
||||||
export class RemainingFillableCalculator {
|
export class RemainingFillableCalculator {
|
||||||
private _signedOrder: SignedOrder;
|
private _signedOrder: SignedOrder;
|
||||||
@@ -10,18 +10,21 @@ export class RemainingFillableCalculator {
|
|||||||
private _transferrableMakerFeeTokenAmount: BigNumber;
|
private _transferrableMakerFeeTokenAmount: BigNumber;
|
||||||
private _remainingMakerTokenAmount: BigNumber;
|
private _remainingMakerTokenAmount: BigNumber;
|
||||||
private _remainingMakerFeeAmount: BigNumber;
|
private _remainingMakerFeeAmount: BigNumber;
|
||||||
constructor(signedOrder: SignedOrder,
|
constructor(
|
||||||
isMakerTokenZRX: boolean,
|
signedOrder: SignedOrder,
|
||||||
transferrableMakerTokenAmount: BigNumber,
|
isMakerTokenZRX: boolean,
|
||||||
transferrableMakerFeeTokenAmount: BigNumber,
|
transferrableMakerTokenAmount: BigNumber,
|
||||||
remainingMakerTokenAmount: BigNumber) {
|
transferrableMakerFeeTokenAmount: BigNumber,
|
||||||
|
remainingMakerTokenAmount: BigNumber,
|
||||||
|
) {
|
||||||
this._signedOrder = signedOrder;
|
this._signedOrder = signedOrder;
|
||||||
this._isMakerTokenZRX = isMakerTokenZRX;
|
this._isMakerTokenZRX = isMakerTokenZRX;
|
||||||
this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
|
this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
|
||||||
this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
|
this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
|
||||||
this._remainingMakerTokenAmount = remainingMakerTokenAmount;
|
this._remainingMakerTokenAmount = remainingMakerTokenAmount;
|
||||||
this._remainingMakerFeeAmount = remainingMakerTokenAmount.times(signedOrder.makerFee)
|
this._remainingMakerFeeAmount = remainingMakerTokenAmount
|
||||||
.dividedToIntegerBy(signedOrder.makerTokenAmount);
|
.times(signedOrder.makerFee)
|
||||||
|
.dividedToIntegerBy(signedOrder.makerTokenAmount);
|
||||||
}
|
}
|
||||||
public computeRemainingMakerFillable(): BigNumber {
|
public computeRemainingMakerFillable(): BigNumber {
|
||||||
if (this._hasSufficientFundsForFeeAndTransferAmount()) {
|
if (this._hasSufficientFundsForFeeAndTransferAmount()) {
|
||||||
@@ -33,20 +36,24 @@ export class RemainingFillableCalculator {
|
|||||||
return this._calculatePartiallyFillableMakerTokenAmount();
|
return this._calculatePartiallyFillableMakerTokenAmount();
|
||||||
}
|
}
|
||||||
public computeRemainingTakerFillable(): BigNumber {
|
public computeRemainingTakerFillable(): BigNumber {
|
||||||
return this.computeRemainingMakerFillable().times(this._signedOrder.takerTokenAmount)
|
return this.computeRemainingMakerFillable()
|
||||||
.dividedToIntegerBy(this._signedOrder.makerTokenAmount);
|
.times(this._signedOrder.takerTokenAmount)
|
||||||
|
.dividedToIntegerBy(this._signedOrder.makerTokenAmount);
|
||||||
}
|
}
|
||||||
private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
|
private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
|
||||||
if (this._isMakerTokenZRX) {
|
if (this._isMakerTokenZRX) {
|
||||||
const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
|
const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
|
||||||
const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
||||||
totalZRXTransferAmountRequired);
|
totalZRXTransferAmountRequired,
|
||||||
|
);
|
||||||
return hasSufficientFunds;
|
return hasSufficientFunds;
|
||||||
} else {
|
} else {
|
||||||
const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
||||||
this._remainingMakerTokenAmount);
|
this._remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
|
const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
|
||||||
this._remainingMakerFeeAmount);
|
this._remainingMakerFeeAmount,
|
||||||
|
);
|
||||||
const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
|
const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
|
||||||
return hasSufficientFunds;
|
return hasSufficientFunds;
|
||||||
}
|
}
|
||||||
@@ -57,8 +64,10 @@ export class RemainingFillableCalculator {
|
|||||||
// The number of times the maker can fill the order, if each fill only required the transfer of a single
|
// The number of times the maker can fill the order, if each fill only required the transfer of a single
|
||||||
// baseUnit of fee tokens.
|
// baseUnit of fee tokens.
|
||||||
// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
|
// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
|
||||||
const fillableTimesInFeeTokenBaseUnits = BigNumber.min(this._transferrableMakerFeeTokenAmount,
|
const fillableTimesInFeeTokenBaseUnits = BigNumber.min(
|
||||||
this._remainingMakerFeeAmount);
|
this._transferrableMakerFeeTokenAmount,
|
||||||
|
this._remainingMakerFeeAmount,
|
||||||
|
);
|
||||||
// The number of times the Maker can fill the order, given the Maker Token Balance
|
// The number of times the Maker can fill the order, given the Maker Token Balance
|
||||||
// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
|
// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
|
||||||
let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
|
let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
|
||||||
@@ -68,20 +77,20 @@ export class RemainingFillableCalculator {
|
|||||||
const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
|
const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
|
||||||
// The purchasing power here is less as the tokens are taken from the same Pool
|
// The purchasing power here is less as the tokens are taken from the same Pool
|
||||||
// For every one number of fills, we have to take an extra ZRX out of the pool
|
// For every one number of fills, we have to take an extra ZRX out of the pool
|
||||||
fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(
|
fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
|
||||||
orderToFeeRatio.plus(new BigNumber(1)));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
|
// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
|
||||||
// This can result in a RoundingError being thrown by the Exchange Contract.
|
// This can result in a RoundingError being thrown by the Exchange Contract.
|
||||||
const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
|
const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
|
||||||
.times(this._signedOrder.makerTokenAmount)
|
.times(this._signedOrder.makerTokenAmount)
|
||||||
.dividedToIntegerBy(this._signedOrder.makerFee);
|
.dividedToIntegerBy(this._signedOrder.makerFee);
|
||||||
const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
|
const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
|
||||||
.times(this._signedOrder.makerTokenAmount)
|
.times(this._signedOrder.makerTokenAmount)
|
||||||
.dividedToIntegerBy(this._signedOrder.makerFee);
|
.dividedToIntegerBy(this._signedOrder.makerFee);
|
||||||
const partiallyFillableAmount = BigNumber.min(partiallyFillableMakerTokenAmount,
|
const partiallyFillableAmount = BigNumber.min(
|
||||||
partiallyFillableFeeTokenAmount);
|
partiallyFillableMakerTokenAmount,
|
||||||
|
partiallyFillableFeeTokenAmount,
|
||||||
|
);
|
||||||
return partiallyFillableAmount;
|
return partiallyFillableAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ export const zeroExConfigSchema = {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
},
|
},
|
||||||
gasPrice: {$ref: '/Number'},
|
gasPrice: { $ref: '/Number' },
|
||||||
exchangeContractAddress: {$ref: '/Address'},
|
exchangeContractAddress: { $ref: '/Address' },
|
||||||
tokenRegistryContractAddress: {$ref: '/Address'},
|
tokenRegistryContractAddress: { $ref: '/Address' },
|
||||||
orderWatcherConfig: {
|
orderWatcherConfig: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {BigNumber} from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {TokenWrapper} from '../contract_wrappers/token_wrapper';
|
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||||
import {BlockParamLiteral} from '../types';
|
import { BlockParamLiteral } from '../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy on read store for balances/proxyAllowances of tokens/accounts
|
* Copy on read store for balances/proxyAllowances of tokens/accounts
|
||||||
@@ -52,8 +52,10 @@ export class BalanceAndProxyAllowanceLazyStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
||||||
if (_.isUndefined(this._proxyAllowance[tokenAddress]) ||
|
if (
|
||||||
_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])) {
|
_.isUndefined(this._proxyAllowance[tokenAddress]) ||
|
||||||
|
_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
|
||||||
|
) {
|
||||||
const methodOpts = {
|
const methodOpts = {
|
||||||
defaultBlock: this._defaultBlock,
|
defaultBlock: this._defaultBlock,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {BigNumber} from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper';
|
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
|
||||||
import {BlockParamLiteral} from '../types';
|
import { BlockParamLiteral } from '../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy on read store for filled/cancelled taker amounts
|
* Copy on read store for filled/cancelled taker amounts
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {TransactionReceipt} from '@0xproject/types';
|
import { TransactionReceipt } from '@0xproject/types';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
export enum ZeroExError {
|
export enum ZeroExError {
|
||||||
@@ -42,8 +42,7 @@ export interface ECSignature {
|
|||||||
|
|
||||||
export type OrderAddresses = [string, string, string, string, string];
|
export type OrderAddresses = [string, string, string, string, string];
|
||||||
|
|
||||||
export type OrderValues = [BigNumber, BigNumber, BigNumber,
|
export type OrderValues = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber];
|
||||||
BigNumber, BigNumber, BigNumber];
|
|
||||||
|
|
||||||
export type LogEvent = Web3.LogEntryEvent;
|
export type LogEvent = Web3.LogEntryEvent;
|
||||||
export interface DecodedLogEvent<ArgsType> {
|
export interface DecodedLogEvent<ArgsType> {
|
||||||
@@ -51,8 +50,8 @@ export interface DecodedLogEvent<ArgsType> {
|
|||||||
log: LogWithDecodedArgs<ArgsType>;
|
log: LogWithDecodedArgs<ArgsType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EventCallback<ArgsType> = (err: null|Error, log?: DecodedLogEvent<ArgsType>) => void;
|
export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void;
|
||||||
export type EventWatcherCallback = (log: LogEvent) => void;
|
export type EventWatcherCallback = (err: null | Error, log?: LogEvent) => void;
|
||||||
|
|
||||||
export enum SolidityTypes {
|
export enum SolidityTypes {
|
||||||
Address = 'address',
|
Address = 'address',
|
||||||
@@ -136,7 +135,10 @@ export interface LogErrorContractEventArgs {
|
|||||||
errorId: BigNumber;
|
errorId: BigNumber;
|
||||||
orderHash: string;
|
orderHash: string;
|
||||||
}
|
}
|
||||||
export type ExchangeContractEventArgs = LogFillContractEventArgs|LogCancelContractEventArgs|LogErrorContractEventArgs;
|
export type ExchangeContractEventArgs =
|
||||||
|
| LogFillContractEventArgs
|
||||||
|
| LogCancelContractEventArgs
|
||||||
|
| LogErrorContractEventArgs;
|
||||||
export interface TransferContractEventArgs {
|
export interface TransferContractEventArgs {
|
||||||
_from: string;
|
_from: string;
|
||||||
_to: string;
|
_to: string;
|
||||||
@@ -155,10 +157,13 @@ export interface WithdrawalContractEventArgs {
|
|||||||
_owner: string;
|
_owner: string;
|
||||||
_value: BigNumber;
|
_value: BigNumber;
|
||||||
}
|
}
|
||||||
export type TokenContractEventArgs = TransferContractEventArgs|ApprovalContractEventArgs;
|
export type TokenContractEventArgs = TransferContractEventArgs | ApprovalContractEventArgs;
|
||||||
export type EtherTokenContractEventArgs = TokenContractEventArgs|DepositContractEventArgs|WithdrawalContractEventArgs;
|
export type EtherTokenContractEventArgs =
|
||||||
export type ContractEventArgs = ExchangeContractEventArgs|TokenContractEventArgs|EtherTokenContractEventArgs;
|
| TokenContractEventArgs
|
||||||
export type ContractEventArg = string|BigNumber;
|
| DepositContractEventArgs
|
||||||
|
| WithdrawalContractEventArgs;
|
||||||
|
export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
|
||||||
|
export type ContractEventArg = string | BigNumber;
|
||||||
|
|
||||||
export interface Order {
|
export interface Order {
|
||||||
maker: string;
|
maker: string;
|
||||||
@@ -211,14 +216,14 @@ export enum TokenEvents {
|
|||||||
Approval = 'Approval',
|
Approval = 'Approval',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum EtherTokenEvents {
|
export enum EtherTokenEvents {
|
||||||
Transfer = 'Transfer',
|
Transfer = 'Transfer',
|
||||||
Approval = 'Approval',
|
Approval = 'Approval',
|
||||||
Deposit = 'Deposit',
|
Deposit = 'Deposit',
|
||||||
Withdrawal = 'Withdrawal',
|
Withdrawal = 'Withdrawal',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ContractEvents = TokenEvents|ExchangeEvents|EtherTokenEvents;
|
export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents;
|
||||||
|
|
||||||
export interface IndexedFilterValues {
|
export interface IndexedFilterValues {
|
||||||
[index: string]: ContractEventArg;
|
[index: string]: ContractEventArg;
|
||||||
@@ -232,7 +237,7 @@ export enum BlockParamLiteral {
|
|||||||
Pending = 'pending',
|
Pending = 'pending',
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BlockParam = BlockParamLiteral|number;
|
export type BlockParam = BlockParamLiteral | number;
|
||||||
|
|
||||||
export interface BlockRange {
|
export interface BlockRange {
|
||||||
fromBlock: BlockParam;
|
fromBlock: BlockParam;
|
||||||
@@ -242,7 +247,7 @@ export interface BlockRange {
|
|||||||
export type DoneCallback = (err?: Error) => void;
|
export type DoneCallback = (err?: Error) => void;
|
||||||
|
|
||||||
export interface OrderCancellationRequest {
|
export interface OrderCancellationRequest {
|
||||||
order: Order|SignedOrder;
|
order: Order | SignedOrder;
|
||||||
takerTokenCancelAmount: BigNumber;
|
takerTokenCancelAmount: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,6 +290,7 @@ export interface OrderStateWatcherConfig {
|
|||||||
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 42-kovan, 50-testrpc)
|
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 42-kovan, 50-testrpc)
|
||||||
* gasPrice: Gas price to use with every transaction
|
* gasPrice: Gas price to use with every transaction
|
||||||
* exchangeContractAddress: The address of an exchange contract to use
|
* exchangeContractAddress: The address of an exchange contract to use
|
||||||
|
* zrxContractAddress: The address of the ZRX contract to use
|
||||||
* tokenRegistryContractAddress: The address of a token registry contract to use
|
* tokenRegistryContractAddress: The address of a token registry contract to use
|
||||||
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
|
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
|
||||||
* orderWatcherConfig: All the configs related to the orderWatcher
|
* orderWatcherConfig: All the configs related to the orderWatcher
|
||||||
@@ -293,6 +299,7 @@ export interface ZeroExConfig {
|
|||||||
networkId: number;
|
networkId: number;
|
||||||
gasPrice?: BigNumber;
|
gasPrice?: BigNumber;
|
||||||
exchangeContractAddress?: string;
|
exchangeContractAddress?: string;
|
||||||
|
zrxContractAddress?: string;
|
||||||
tokenRegistryContractAddress?: string;
|
tokenRegistryContractAddress?: string;
|
||||||
tokenTransferProxyContractAddress?: string;
|
tokenTransferProxyContractAddress?: string;
|
||||||
orderWatcherConfig?: OrderStateWatcherConfig;
|
orderWatcherConfig?: OrderStateWatcherConfig;
|
||||||
@@ -312,10 +319,10 @@ export interface DecodedLogArgs {
|
|||||||
export interface LogWithDecodedArgs<ArgsType> extends Web3.DecodedLogEntry<ArgsType> {}
|
export interface LogWithDecodedArgs<ArgsType> extends Web3.DecodedLogEntry<ArgsType> {}
|
||||||
|
|
||||||
export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt {
|
export interface TransactionReceiptWithDecodedLogs extends TransactionReceipt {
|
||||||
logs: Array<LogWithDecodedArgs<DecodedLogArgs>|Web3.LogEntry>;
|
logs: Array<LogWithDecodedArgs<DecodedLogArgs> | Web3.LogEntry>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ArtifactContractName = 'ZRX'|'TokenTransferProxy'|'TokenRegistry'|'Token'|'Exchange'|'EtherToken';
|
export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken';
|
||||||
|
|
||||||
export interface Artifact {
|
export interface Artifact {
|
||||||
contract_name: ArtifactContractName;
|
contract_name: ArtifactContractName;
|
||||||
@@ -399,7 +406,7 @@ export interface OrderStateInvalid {
|
|||||||
error: ExchangeContractErrs;
|
error: ExchangeContractErrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OrderState = OrderStateValid|OrderStateInvalid;
|
export type OrderState = OrderStateValid | OrderStateInvalid;
|
||||||
|
|
||||||
export type OnOrderStateChangeCallback = (orderState: OrderState) => void;
|
export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void;
|
||||||
// tslint:disable:max-file-line-count
|
// tslint:disable:max-file-line-count
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
import * as SolidityCoder from 'web3/lib/solidity/coder';
|
import * as SolidityCoder from 'web3/lib/solidity/coder';
|
||||||
|
|
||||||
import {AbiType, ContractEventArgs, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes} from '../types';
|
import { AbiType, ContractEventArgs, DecodedLogArgs, LogWithDecodedArgs, RawLog, SolidityTypes } from '../types';
|
||||||
|
|
||||||
export class AbiDecoder {
|
export class AbiDecoder {
|
||||||
private _savedABIs: Web3.AbiDefinition[] = [];
|
private _savedABIs: Web3.AbiDefinition[] = [];
|
||||||
private _methodIds: {[signatureHash: string]: Web3.EventAbi} = {};
|
private _methodIds: { [signatureHash: string]: Web3.EventAbi } = {};
|
||||||
private static _padZeros(address: string) {
|
private static _padZeros(address: string) {
|
||||||
let formatted = address;
|
let formatted = address;
|
||||||
if (_.startsWith(formatted, '0x')) {
|
if (_.startsWith(formatted, '0x')) {
|
||||||
@@ -22,7 +22,8 @@ export class AbiDecoder {
|
|||||||
}
|
}
|
||||||
// This method can only decode logs from the 0x & ERC20 smart contracts
|
// This method can only decode logs from the 0x & ERC20 smart contracts
|
||||||
public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
||||||
log: Web3.LogEntry): LogWithDecodedArgs<ArgsType>|RawLog {
|
log: Web3.LogEntry,
|
||||||
|
): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||||
const methodId = log.topics[0];
|
const methodId = log.topics[0];
|
||||||
const event = this._methodIds[methodId];
|
const event = this._methodIds[methodId];
|
||||||
if (_.isUndefined(event)) {
|
if (_.isUndefined(event)) {
|
||||||
@@ -42,9 +43,11 @@ export class AbiDecoder {
|
|||||||
let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++];
|
let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++];
|
||||||
if (param.type === SolidityTypes.Address) {
|
if (param.type === SolidityTypes.Address) {
|
||||||
value = AbiDecoder._padZeros(new BigNumber(value).toString(16));
|
value = AbiDecoder._padZeros(new BigNumber(value).toString(16));
|
||||||
} else if (param.type === SolidityTypes.Uint256 ||
|
} else if (
|
||||||
param.type === SolidityTypes.Uint8 ||
|
param.type === SolidityTypes.Uint256 ||
|
||||||
param.type === SolidityTypes.Uint) {
|
param.type === SolidityTypes.Uint8 ||
|
||||||
|
param.type === SolidityTypes.Uint
|
||||||
|
) {
|
||||||
value = new BigNumber(value);
|
value = new BigNumber(value);
|
||||||
}
|
}
|
||||||
decodedParams[param.name] = value;
|
decodedParams[param.name] = value;
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import {assert as sharedAssert} from '@0xproject/assert';
|
import { assert as sharedAssert } from '@0xproject/assert';
|
||||||
// We need those two unused imports because they're actually used by sharedAssert which gets injected here
|
// We need those two unused imports because they're actually used by sharedAssert which gets injected here
|
||||||
// tslint:disable-next-line:no-unused-variable
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import {Schema} from '@0xproject/json-schemas';
|
import { Schema } from '@0xproject/json-schemas';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
|
||||||
// tslint:disable-next-line:no-unused-variable
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import * as BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {ECSignature} from '../types';
|
import { ECSignature } from '../types';
|
||||||
import {signatureUtils} from '../utils/signature_utils';
|
import { signatureUtils } from '../utils/signature_utils';
|
||||||
|
|
||||||
export const assert = {
|
export const assert = {
|
||||||
...sharedAssert,
|
...sharedAssert,
|
||||||
@@ -16,11 +16,15 @@ export const assert = {
|
|||||||
const isValidSignature = signatureUtils.isValidSignature(orderHash, ecSignature, signerAddress);
|
const isValidSignature = signatureUtils.isValidSignature(orderHash, ecSignature, signerAddress);
|
||||||
this.assert(isValidSignature, `Expected order with hash '${orderHash}' to have a valid signature`);
|
this.assert(isValidSignature, `Expected order with hash '${orderHash}' to have a valid signature`);
|
||||||
},
|
},
|
||||||
async isSenderAddressAsync(variableName: string, senderAddressHex: string,
|
async isSenderAddressAsync(
|
||||||
web3Wrapper: Web3Wrapper): Promise<void> {
|
variableName: string,
|
||||||
|
senderAddressHex: string,
|
||||||
|
web3Wrapper: Web3Wrapper,
|
||||||
|
): Promise<void> {
|
||||||
sharedAssert.isETHAddressHex(variableName, senderAddressHex);
|
sharedAssert.isETHAddressHex(variableName, senderAddressHex);
|
||||||
const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
|
const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
|
||||||
sharedAssert.assert(isSenderAddressAvailable,
|
sharedAssert.assert(
|
||||||
|
isSenderAddressAvailable,
|
||||||
`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
|
`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
|
||||||
export const constants = {
|
export const constants = {
|
||||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {AsyncMethod, SyncMethod, ZeroExError} from '../types';
|
import { AsyncMethod, SyncMethod, ZeroExError } from '../types';
|
||||||
|
|
||||||
import {constants} from './constants';
|
import { constants } from './constants';
|
||||||
|
|
||||||
type ErrorTransformer = (err: Error) => Error;
|
type ErrorTransformer = (err: Error) => Error;
|
||||||
|
|
||||||
@@ -18,8 +18,8 @@ const contractCallErrorTransformer = (error: Error) => {
|
|||||||
|
|
||||||
const schemaErrorTransformer = (error: Error) => {
|
const schemaErrorTransformer = (error: Error) => {
|
||||||
if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
|
if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
|
||||||
// tslint:disable-next-line:max-line-length
|
const errMsg =
|
||||||
const errMsg = 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
||||||
return new Error(errMsg);
|
return new Error(errMsg);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
@@ -30,14 +30,16 @@ const schemaErrorTransformer = (error: Error) => {
|
|||||||
*/
|
*/
|
||||||
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||||
const asyncErrorHandlingDecorator = (
|
const asyncErrorHandlingDecorator = (
|
||||||
target: object, key: string|symbol, descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
target: object,
|
||||||
|
key: string | symbol,
|
||||||
|
descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
||||||
) => {
|
) => {
|
||||||
const originalMethod = (descriptor.value as AsyncMethod);
|
const originalMethod = descriptor.value as AsyncMethod;
|
||||||
|
|
||||||
// Do not use arrow syntax here. Use a function expression in
|
// Do not use arrow syntax here. Use a function expression in
|
||||||
// order to use the correct value of `this` in this method
|
// order to use the correct value of `this` in this method
|
||||||
// tslint:disable-next-line:only-arrow-functions
|
// tslint:disable-next-line:only-arrow-functions
|
||||||
descriptor.value = async function(...args: any[]) {
|
descriptor.value = async function(...args: any[]) {
|
||||||
try {
|
try {
|
||||||
const result = await originalMethod.apply(this, args);
|
const result = await originalMethod.apply(this, args);
|
||||||
return result;
|
return result;
|
||||||
@@ -55,9 +57,11 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
|||||||
|
|
||||||
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||||
const syncErrorHandlingDecorator = (
|
const syncErrorHandlingDecorator = (
|
||||||
target: object, key: string|symbol, descriptor: TypedPropertyDescriptor<SyncMethod>,
|
target: object,
|
||||||
|
key: string | symbol,
|
||||||
|
descriptor: TypedPropertyDescriptor<SyncMethod>,
|
||||||
) => {
|
) => {
|
||||||
const originalMethod = (descriptor.value as SyncMethod);
|
const originalMethod = descriptor.value as SyncMethod;
|
||||||
|
|
||||||
// Do not use arrow syntax here. Use a function expression in
|
// Do not use arrow syntax here. Use a function expression in
|
||||||
// order to use the correct value of `this` in this method
|
// order to use the correct value of `this` in this method
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {TokenWrapper} from '../contract_wrappers/token_wrapper';
|
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
|
||||||
import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store';
|
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
|
||||||
import {BlockParamLiteral, ExchangeContractErrs, TradeSide, TransferType} from '../types';
|
import { BlockParamLiteral, ExchangeContractErrs, TradeSide, TransferType } from '../types';
|
||||||
|
|
||||||
enum FailureReason {
|
enum FailureReason {
|
||||||
Balance = 'balance',
|
Balance = 'balance',
|
||||||
@@ -36,8 +36,11 @@ const ERR_MSG_MAPPING = {
|
|||||||
export class ExchangeTransferSimulator {
|
export class ExchangeTransferSimulator {
|
||||||
private _store: BalanceAndProxyAllowanceLazyStore;
|
private _store: BalanceAndProxyAllowanceLazyStore;
|
||||||
private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
|
private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
|
||||||
private static _throwValidationError(failureReason: FailureReason, tradeSide: TradeSide,
|
private static _throwValidationError(
|
||||||
transferType: TransferType): never {
|
failureReason: FailureReason,
|
||||||
|
tradeSide: TradeSide,
|
||||||
|
transferType: TransferType,
|
||||||
|
): never {
|
||||||
const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
|
const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
|
||||||
throw new Error(errMsg);
|
throw new Error(errMsg);
|
||||||
}
|
}
|
||||||
@@ -54,9 +57,14 @@ export class ExchangeTransferSimulator {
|
|||||||
* @param tradeSide Is Maker/Taker transferring
|
* @param tradeSide Is Maker/Taker transferring
|
||||||
* @param transferType Is it a fee payment or a value transfer
|
* @param transferType Is it a fee payment or a value transfer
|
||||||
*/
|
*/
|
||||||
public async transferFromAsync(tokenAddress: string, from: string, to: string,
|
public async transferFromAsync(
|
||||||
amountInBaseUnits: BigNumber, tradeSide: TradeSide,
|
tokenAddress: string,
|
||||||
transferType: TransferType): Promise<void> {
|
from: string,
|
||||||
|
to: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
tradeSide: TradeSide,
|
||||||
|
transferType: TransferType,
|
||||||
|
): Promise<void> {
|
||||||
const balance = await this._store.getBalanceAsync(tokenAddress, from);
|
const balance = await this._store.getBalanceAsync(tokenAddress, from);
|
||||||
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
|
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
|
||||||
if (proxyAllowance.lessThan(amountInBaseUnits)) {
|
if (proxyAllowance.lessThan(amountInBaseUnits)) {
|
||||||
@@ -69,20 +77,29 @@ export class ExchangeTransferSimulator {
|
|||||||
await this._decreaseBalanceAsync(tokenAddress, from, amountInBaseUnits);
|
await this._decreaseBalanceAsync(tokenAddress, from, amountInBaseUnits);
|
||||||
await this._increaseBalanceAsync(tokenAddress, to, amountInBaseUnits);
|
await this._increaseBalanceAsync(tokenAddress, to, amountInBaseUnits);
|
||||||
}
|
}
|
||||||
private async _decreaseProxyAllowanceAsync(tokenAddress: string, userAddress: string,
|
private async _decreaseProxyAllowanceAsync(
|
||||||
amountInBaseUnits: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
userAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, userAddress);
|
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, userAddress);
|
||||||
if (!proxyAllowance.eq(this._UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
|
if (!proxyAllowance.eq(this._UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
|
||||||
this._store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits));
|
this._store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async _increaseBalanceAsync(tokenAddress: string, userAddress: string,
|
private async _increaseBalanceAsync(
|
||||||
amountInBaseUnits: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
userAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
||||||
this._store.setBalance(tokenAddress, userAddress, balance.plus(amountInBaseUnits));
|
this._store.setBalance(tokenAddress, userAddress, balance.plus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
private async _decreaseBalanceAsync(tokenAddress: string, userAddress: string,
|
private async _decreaseBalanceAsync(
|
||||||
amountInBaseUnits: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
userAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
||||||
this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
|
this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import * as _ from 'lodash';
|
|||||||
import * as uuid from 'uuid/v4';
|
import * as uuid from 'uuid/v4';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {BlockRange, ContractEvents, IndexedFilterValues} from '../types';
|
import { BlockRange, ContractEvents, IndexedFilterValues } from '../types';
|
||||||
|
|
||||||
const TOPIC_LENGTH = 32;
|
const TOPIC_LENGTH = 32;
|
||||||
|
|
||||||
@@ -12,10 +12,14 @@ export const filterUtils = {
|
|||||||
generateUUID(): string {
|
generateUUID(): string {
|
||||||
return uuid();
|
return uuid();
|
||||||
},
|
},
|
||||||
getFilter(address: string, eventName: ContractEvents,
|
getFilter(
|
||||||
indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi,
|
address: string,
|
||||||
blockRange?: BlockRange): Web3.FilterObject {
|
eventName: ContractEvents,
|
||||||
const eventAbi = _.find(abi, {name: eventName}) as Web3.EventAbi;
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
abi: Web3.ContractAbi,
|
||||||
|
blockRange?: BlockRange,
|
||||||
|
): Web3.FilterObject {
|
||||||
|
const eventAbi = _.find(abi, { name: eventName }) as Web3.EventAbi;
|
||||||
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName);
|
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName);
|
||||||
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
||||||
const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues);
|
const topicsForIndexedArgs = filterUtils.getTopicsForIndexedArgs(eventAbi, indexFilterValues);
|
||||||
@@ -37,8 +41,8 @@ export const filterUtils = {
|
|||||||
const signature = `${eventAbi.name}(${types.join(',')})`;
|
const signature = `${eventAbi.name}(${types.join(',')})`;
|
||||||
return signature;
|
return signature;
|
||||||
},
|
},
|
||||||
getTopicsForIndexedArgs(abi: Web3.EventAbi, indexFilterValues: IndexedFilterValues): Array<string|null> {
|
getTopicsForIndexedArgs(abi: Web3.EventAbi, indexFilterValues: IndexedFilterValues): Array<string | null> {
|
||||||
const topics: Array<string|null> = [];
|
const topics: Array<string | null> = [];
|
||||||
for (const eventInput of abi.inputs) {
|
for (const eventInput of abi.inputs) {
|
||||||
if (!eventInput.indexed) {
|
if (!eventInput.indexed) {
|
||||||
continue;
|
continue;
|
||||||
@@ -65,12 +69,12 @@ export const filterUtils = {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
matchesTopics(logTopics: string[], filterTopics: Array<string[]|string|null>): boolean {
|
matchesTopics(logTopics: string[], filterTopics: Array<string[] | string | null>): boolean {
|
||||||
const matchesTopic = _.zipWith(logTopics, filterTopics, filterUtils.matchesTopic.bind(filterUtils));
|
const matchesTopic = _.zipWith(logTopics, filterTopics, filterUtils.matchesTopic.bind(filterUtils));
|
||||||
const matchesTopics = _.every(matchesTopic);
|
const matchesTopics = _.every(matchesTopic);
|
||||||
return matchesTopics;
|
return matchesTopics;
|
||||||
},
|
},
|
||||||
matchesTopic(logTopic: string, filterTopic: string[]|string|null): boolean {
|
matchesTopic(logTopic: string, filterTopic: string[] | string | null): boolean {
|
||||||
if (_.isArray(filterTopic)) {
|
if (_.isArray(filterTopic)) {
|
||||||
return _.includes(filterTopic, logTopic);
|
return _.includes(filterTopic, logTopic);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {ZeroEx} from '../0x';
|
import { ZeroEx } from '../0x';
|
||||||
import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper';
|
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
|
||||||
import {RemainingFillableCalculator} from '../order_watcher/remaining_fillable_calculator';
|
import { RemainingFillableCalculator } from '../order_watcher/remaining_fillable_calculator';
|
||||||
import {BalanceAndProxyAllowanceLazyStore} from '../stores/balance_proxy_allowance_lazy_store';
|
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
|
||||||
import {OrderFilledCancelledLazyStore} from '../stores/order_filled_cancelled_lazy_store';
|
import { OrderFilledCancelledLazyStore } from '../stores/order_filled_cancelled_lazy_store';
|
||||||
import {
|
import {
|
||||||
ExchangeContractErrs,
|
ExchangeContractErrs,
|
||||||
OrderRelevantState,
|
OrderRelevantState,
|
||||||
@@ -44,15 +44,20 @@ export class OrderStateUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
|
const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
|
||||||
.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
|
.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
|
||||||
.dividedBy(signedOrder.makerTokenAmount);
|
.dividedBy(signedOrder.makerTokenAmount);
|
||||||
if (orderRelevantState.remainingFillableTakerTokenAmount
|
if (
|
||||||
.lessThan(minFillableTakerTokenAmountWithinNoRoundingErrorRange)) {
|
orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
|
||||||
|
minFillableTakerTokenAmountWithinNoRoundingErrorRange,
|
||||||
|
)
|
||||||
|
) {
|
||||||
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constructor(balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
|
constructor(
|
||||||
orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore) {
|
balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
|
||||||
|
orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore,
|
||||||
|
) {
|
||||||
this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
|
this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
|
||||||
this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
|
this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
|
||||||
}
|
}
|
||||||
@@ -85,16 +90,20 @@ export class OrderStateUtils {
|
|||||||
const zrxTokenAddress = exchange.getZRXTokenAddress();
|
const zrxTokenAddress = exchange.getZRXTokenAddress();
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
const makerBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
const makerBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker,
|
signedOrder.makerTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const makerProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
const makerProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker,
|
signedOrder.makerTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const makerFeeBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
const makerFeeBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
||||||
zrxTokenAddress, signedOrder.maker,
|
zrxTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const makerFeeProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
const makerFeeProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
||||||
zrxTokenAddress, signedOrder.maker,
|
zrxTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const filledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getFilledTakerAmountAsync(orderHash);
|
const filledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getFilledTakerAmountAsync(orderHash);
|
||||||
const cancelledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getCancelledTakerAmountAsync(
|
const cancelledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getCancelledTakerAmountAsync(
|
||||||
@@ -104,17 +113,20 @@ export class OrderStateUtils {
|
|||||||
const totalMakerTokenAmount = signedOrder.makerTokenAmount;
|
const totalMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
const totalTakerTokenAmount = signedOrder.takerTokenAmount;
|
const totalTakerTokenAmount = signedOrder.takerTokenAmount;
|
||||||
const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount);
|
const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||||
const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount)
|
const remainingMakerTokenAmount = remainingTakerTokenAmount
|
||||||
.dividedToIntegerBy(totalTakerTokenAmount);
|
.times(totalMakerTokenAmount)
|
||||||
|
.dividedToIntegerBy(totalTakerTokenAmount);
|
||||||
const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
|
const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
|
||||||
const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
|
const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
|
||||||
|
|
||||||
const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
|
const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
|
||||||
const remainingFillableCalculator = new RemainingFillableCalculator(signedOrder,
|
const remainingFillableCalculator = new RemainingFillableCalculator(
|
||||||
isMakerTokenZRX,
|
signedOrder,
|
||||||
transferrableMakerTokenAmount,
|
isMakerTokenZRX,
|
||||||
transferrableFeeTokenAmount,
|
transferrableMakerTokenAmount,
|
||||||
remainingMakerTokenAmount);
|
transferrableFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
|
const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
|
||||||
const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
|
const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
|
||||||
const orderRelevantState = {
|
const orderRelevantState = {
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {ZeroEx} from '../0x';
|
import { ZeroEx } from '../0x';
|
||||||
import {ExchangeWrapper} from '../contract_wrappers/exchange_wrapper';
|
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
|
||||||
import {ExchangeContractErrs, Order, SignedOrder, TradeSide, TransferType, ZeroExError} from '../types';
|
import { ExchangeContractErrs, Order, SignedOrder, TradeSide, TransferType, ZeroExError } from '../types';
|
||||||
import {constants} from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import {utils} from '../utils/utils';
|
import { utils } from '../utils/utils';
|
||||||
|
|
||||||
import {ExchangeTransferSimulator} from './exchange_transfer_simulator';
|
import { ExchangeTransferSimulator } from './exchange_transfer_simulator';
|
||||||
|
|
||||||
export class OrderValidationUtils {
|
export class OrderValidationUtils {
|
||||||
private _exchangeWrapper: ExchangeWrapper;
|
private _exchangeWrapper: ExchangeWrapper;
|
||||||
public static validateCancelOrderThrowIfInvalid(
|
public static validateCancelOrderThrowIfInvalid(
|
||||||
order: Order, cancelTakerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber,
|
order: Order,
|
||||||
|
cancelTakerTokenAmount: BigNumber,
|
||||||
|
unavailableTakerTokenAmount: BigNumber,
|
||||||
): void {
|
): void {
|
||||||
if (cancelTakerTokenAmount.eq(0)) {
|
if (cancelTakerTokenAmount.eq(0)) {
|
||||||
throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
|
throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
@@ -26,8 +28,11 @@ export class OrderValidationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
fillTakerTokenAmount: BigNumber, senderAddress: string, zrxTokenAddress: string,
|
signedOrder: SignedOrder,
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
senderAddress: string,
|
||||||
|
zrxTokenAddress: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
|
const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
@@ -35,12 +40,20 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerTokenAmount,
|
signedOrder.makerTokenAmount,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker, senderAddress, fillMakerTokenAmount,
|
signedOrder.makerTokenAddress,
|
||||||
TradeSide.Maker, TransferType.Trade,
|
signedOrder.maker,
|
||||||
|
senderAddress,
|
||||||
|
fillMakerTokenAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
signedOrder.takerTokenAddress, senderAddress, signedOrder.maker, fillTakerTokenAmount,
|
signedOrder.takerTokenAddress,
|
||||||
TradeSide.Taker, TransferType.Trade,
|
senderAddress,
|
||||||
|
signedOrder.maker,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
@@ -48,7 +61,11 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerFee,
|
signedOrder.makerFee,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount, TradeSide.Maker,
|
zrxTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
|
signedOrder.feeRecipient,
|
||||||
|
makerFeeAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
TransferType.Fee,
|
TransferType.Fee,
|
||||||
);
|
);
|
||||||
const takerFeeAmount = OrderValidationUtils._getPartialAmount(
|
const takerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||||
@@ -57,12 +74,17 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.takerFee,
|
signedOrder.takerFee,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
zrxTokenAddress, senderAddress, signedOrder.feeRecipient, takerFeeAmount, TradeSide.Taker,
|
zrxTokenAddress,
|
||||||
|
senderAddress,
|
||||||
|
signedOrder.feeRecipient,
|
||||||
|
takerFeeAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
TransferType.Fee,
|
TransferType.Fee,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
private static _validateRemainingFillAmountNotZeroOrThrow(
|
private static _validateRemainingFillAmountNotZeroOrThrow(
|
||||||
takerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber,
|
takerTokenAmount: BigNumber,
|
||||||
|
unavailableTakerTokenAmount: BigNumber,
|
||||||
) {
|
) {
|
||||||
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
|
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
|
||||||
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||||
@@ -74,24 +96,27 @@ export class OrderValidationUtils {
|
|||||||
throw new Error(ExchangeContractErrs.OrderFillExpired);
|
throw new Error(ExchangeContractErrs.OrderFillExpired);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber,
|
private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
|
||||||
target: BigNumber): BigNumber {
|
|
||||||
const fillMakerTokenAmount = numerator
|
const fillMakerTokenAmount = numerator
|
||||||
.mul(target)
|
.mul(target)
|
||||||
.div(denominator)
|
.div(denominator)
|
||||||
.round(0);
|
.round(0);
|
||||||
return fillMakerTokenAmount;
|
return fillMakerTokenAmount;
|
||||||
}
|
}
|
||||||
constructor(exchangeWrapper: ExchangeWrapper) {
|
constructor(exchangeWrapper: ExchangeWrapper) {
|
||||||
this._exchangeWrapper = exchangeWrapper;
|
this._exchangeWrapper = exchangeWrapper;
|
||||||
}
|
}
|
||||||
public async validateOrderFillableOrThrowAsync(
|
public async validateOrderFillableOrThrowAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, zrxTokenAddress: string,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
expectedFillTakerTokenAmount?: BigNumber): Promise<void> {
|
signedOrder: SignedOrder,
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
expectedFillTakerTokenAmount?: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const orderHash = utils.getOrderHashHex(signedOrder);
|
const orderHash = utils.getOrderHashHex(signedOrder);
|
||||||
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
||||||
signedOrder.takerTokenAmount, unavailableTakerTokenAmount,
|
signedOrder.takerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
);
|
);
|
||||||
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
||||||
let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||||
@@ -104,8 +129,12 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerTokenAmount,
|
signedOrder.makerTokenAmount,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker, signedOrder.taker, fillMakerTokenAmount,
|
signedOrder.makerTokenAddress,
|
||||||
TradeSide.Maker, TransferType.Trade,
|
signedOrder.maker,
|
||||||
|
signedOrder.taker,
|
||||||
|
fillMakerTokenAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
@@ -113,14 +142,21 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerFee,
|
signedOrder.makerFee,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount,
|
zrxTokenAddress,
|
||||||
TradeSide.Maker, TransferType.Fee,
|
signedOrder.maker,
|
||||||
|
signedOrder.feeRecipient,
|
||||||
|
makerFeeAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Fee,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async validateFillOrderThrowIfInvalidAsync(
|
public async validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
fillTakerTokenAmount: BigNumber, takerAddress: string,
|
signedOrder: SignedOrder,
|
||||||
zrxTokenAddress: string): Promise<BigNumber> {
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
): Promise<BigNumber> {
|
||||||
if (fillTakerTokenAmount.eq(0)) {
|
if (fillTakerTokenAmount.eq(0)) {
|
||||||
throw new Error(ExchangeContractErrs.OrderFillAmountZero);
|
throw new Error(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
}
|
}
|
||||||
@@ -130,22 +166,29 @@ export class OrderValidationUtils {
|
|||||||
}
|
}
|
||||||
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
||||||
signedOrder.takerTokenAmount, unavailableTakerTokenAmount,
|
signedOrder.takerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
);
|
);
|
||||||
if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
|
if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
|
||||||
throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
||||||
}
|
}
|
||||||
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
||||||
const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||||
const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount) ?
|
const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
|
||||||
remainingTakerTokenAmount :
|
? remainingTakerTokenAmount
|
||||||
fillTakerTokenAmount;
|
: fillTakerTokenAmount;
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, filledTakerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
filledTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
|
|
||||||
const wouldRoundingErrorOccur = await this._exchangeWrapper.isRoundingErrorAsync(
|
const wouldRoundingErrorOccur = await this._exchangeWrapper.isRoundingErrorAsync(
|
||||||
filledTakerTokenAmount, signedOrder.takerTokenAmount, signedOrder.makerTokenAmount,
|
filledTakerTokenAmount,
|
||||||
|
signedOrder.takerTokenAmount,
|
||||||
|
signedOrder.makerTokenAmount,
|
||||||
);
|
);
|
||||||
if (wouldRoundingErrorOccur) {
|
if (wouldRoundingErrorOccur) {
|
||||||
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
@@ -153,10 +196,18 @@ export class OrderValidationUtils {
|
|||||||
return filledTakerTokenAmount;
|
return filledTakerTokenAmount;
|
||||||
}
|
}
|
||||||
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
fillTakerTokenAmount: BigNumber, takerAddress: string, zrxTokenAddress: string): Promise<void> {
|
signedOrder: SignedOrder,
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
): Promise<void> {
|
||||||
const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
|
const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
if (filledTakerTokenAmount !== fillTakerTokenAmount) {
|
if (filledTakerTokenAmount !== fillTakerTokenAmount) {
|
||||||
throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
|
||||||
import {ECSignature} from '../types';
|
import { ECSignature } from '../types';
|
||||||
|
|
||||||
export const signatureUtils = {
|
export const signatureUtils = {
|
||||||
isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
|
isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
|
||||||
@@ -11,7 +11,8 @@ export const signatureUtils = {
|
|||||||
msgHashBuff,
|
msgHashBuff,
|
||||||
signature.v,
|
signature.v,
|
||||||
ethUtil.toBuffer(signature.r),
|
ethUtil.toBuffer(signature.r),
|
||||||
ethUtil.toBuffer(signature.s));
|
ethUtil.toBuffer(signature.s),
|
||||||
|
);
|
||||||
const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
|
const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
|
||||||
return retrievedAddress === signerAddress;
|
return retrievedAddress === signerAddress;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -34,7 +35,7 @@ export const signatureUtils = {
|
|||||||
return ecSignature;
|
return ecSignature;
|
||||||
},
|
},
|
||||||
parseSignatureHexAsRSV(signatureHex: string): ECSignature {
|
parseSignatureHexAsRSV(signatureHex: string): ECSignature {
|
||||||
const {v, r, s} = ethUtil.fromRpcSig(signatureHex);
|
const { v, r, s } = ethUtil.fromRpcSig(signatureHex);
|
||||||
const ecSignature: ECSignature = {
|
const ecSignature: ECSignature = {
|
||||||
v,
|
v,
|
||||||
r: ethUtil.bufferToHex(r),
|
r: ethUtil.bufferToHex(r),
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import BN = require('bn.js');
|
import BN = require('bn.js');
|
||||||
import * as ethABI from 'ethereumjs-abi';
|
import * as ethABI from 'ethereumjs-abi';
|
||||||
import * as ethUtil from 'ethereumjs-util';
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {Order, SignedOrder, SolidityTypes} from '../types';
|
import { Order, SignedOrder, SolidityTypes } from '../types';
|
||||||
|
|
||||||
export const utils = {
|
export const utils = {
|
||||||
/**
|
/**
|
||||||
@@ -29,20 +29,35 @@ export const utils = {
|
|||||||
spawnSwitchErr(name: string, value: any): Error {
|
spawnSwitchErr(name: string, value: any): Error {
|
||||||
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
|
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
|
||||||
},
|
},
|
||||||
getOrderHashHex(order: Order|SignedOrder): string {
|
getOrderHashHex(order: Order | SignedOrder): string {
|
||||||
const orderParts = [
|
const orderParts = [
|
||||||
{value: order.exchangeContractAddress, type: SolidityTypes.Address},
|
{ value: order.exchangeContractAddress, type: SolidityTypes.Address },
|
||||||
{value: order.maker, type: SolidityTypes.Address},
|
{ value: order.maker, type: SolidityTypes.Address },
|
||||||
{value: order.taker, type: SolidityTypes.Address},
|
{ value: order.taker, type: SolidityTypes.Address },
|
||||||
{value: order.makerTokenAddress, type: SolidityTypes.Address},
|
{ value: order.makerTokenAddress, type: SolidityTypes.Address },
|
||||||
{value: order.takerTokenAddress, type: SolidityTypes.Address},
|
{ value: order.takerTokenAddress, type: SolidityTypes.Address },
|
||||||
{value: order.feeRecipient, type: SolidityTypes.Address},
|
{ value: order.feeRecipient, type: SolidityTypes.Address },
|
||||||
{value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.Uint256},
|
{
|
||||||
{value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.Uint256},
|
value: utils.bigNumberToBN(order.makerTokenAmount),
|
||||||
{value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.Uint256},
|
type: SolidityTypes.Uint256,
|
||||||
{value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.Uint256},
|
},
|
||||||
{value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.Uint256},
|
{
|
||||||
{value: utils.bigNumberToBN(order.salt), type: SolidityTypes.Uint256},
|
value: utils.bigNumberToBN(order.takerTokenAmount),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: utils.bigNumberToBN(order.makerFee),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: utils.bigNumberToBN(order.takerFee),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: utils.bigNumberToBN(order.expirationUnixTimestampSec),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{ value: utils.bigNumberToBN(order.salt), type: SolidityTypes.Uint256 },
|
||||||
];
|
];
|
||||||
const types = _.map(orderParts, o => o.type);
|
const types = _.map(orderParts, o => o.type);
|
||||||
const values = _.map(orderParts, o => o.value);
|
const values = _.map(orderParts, o => o.value);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
|
|
||||||
import {ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx} from '../src';
|
import { ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx } from '../src';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {TokenUtils} from './utils/token_utils';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
|
const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
@@ -41,11 +41,11 @@ describe('ZeroEx library', () => {
|
|||||||
|
|
||||||
// Check that all nested web3 wrapper instances return the updated provider
|
// Check that all nested web3 wrapper instances return the updated provider
|
||||||
const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
|
const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
|
||||||
expect((nestedWeb3WrapperProvider).zeroExTestId).to.be.a('number');
|
expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||||
const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
|
const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
|
||||||
expect((exchangeWeb3WrapperProvider).zeroExTestId).to.be.a('number');
|
expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||||
const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
|
const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
|
||||||
expect((tokenRegistryWeb3WrapperProvider).zeroExTestId).to.be.a('number');
|
expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isValidSignature', () => {
|
describe('#isValidSignature', () => {
|
||||||
@@ -58,22 +58,25 @@ describe('ZeroEx library', () => {
|
|||||||
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
|
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
|
||||||
};
|
};
|
||||||
const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
|
const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
|
||||||
it('should return false if the data doesn\'t pertain to the signature & address', async () => {
|
it("should return false if the data doesn't pertain to the signature & address", async () => {
|
||||||
expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
|
expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
|
||||||
return expect(
|
return expect(
|
||||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
|
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
|
||||||
).to.become(false);
|
).to.become(false);
|
||||||
});
|
});
|
||||||
it('should return false if the address doesn\'t pertain to the signature & data', async () => {
|
it("should return false if the address doesn't pertain to the signature & data", async () => {
|
||||||
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
|
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
|
||||||
expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
|
expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
|
||||||
return expect(
|
return expect(
|
||||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature,
|
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
|
||||||
validUnrelatedAddress),
|
dataHex,
|
||||||
|
signature,
|
||||||
|
validUnrelatedAddress,
|
||||||
|
),
|
||||||
).to.become(false);
|
).to.become(false);
|
||||||
});
|
});
|
||||||
it('should return false if the signature doesn\'t pertain to the dataHex & address', async () => {
|
it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
|
||||||
const wrongSignature = _.assign({}, signature, {v: 28});
|
const wrongSignature = _.assign({}, signature, { v: 28 });
|
||||||
expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
|
expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
|
||||||
return expect(
|
return expect(
|
||||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
|
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
|
||||||
@@ -117,8 +120,9 @@ describe('ZeroEx library', () => {
|
|||||||
it('should throw if invalid baseUnit amount supplied as argument', () => {
|
it('should throw if invalid baseUnit amount supplied as argument', () => {
|
||||||
const invalidBaseUnitAmount = new BigNumber(1000000000.4);
|
const invalidBaseUnitAmount = new BigNumber(1000000000.4);
|
||||||
const decimals = 6;
|
const decimals = 6;
|
||||||
expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals))
|
expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
|
||||||
.to.throw('amount should be in baseUnits (no decimals), found value: 1000000000.4');
|
'amount should be in baseUnits (no decimals), found value: 1000000000.4',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('Should return the expected unit amount for the decimals passed in', () => {
|
it('Should return the expected unit amount for the decimals passed in', () => {
|
||||||
const baseUnitAmount = new BigNumber(1000000000);
|
const baseUnitAmount = new BigNumber(1000000000);
|
||||||
@@ -139,8 +143,9 @@ describe('ZeroEx library', () => {
|
|||||||
it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
|
it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
|
||||||
const unitAmount = new BigNumber(0.823091);
|
const unitAmount = new BigNumber(0.823091);
|
||||||
const decimals = 5;
|
const decimals = 5;
|
||||||
expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals))
|
expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
|
||||||
.to.throw('Invalid unit amount: 0.823091 - Too many decimal places');
|
'Invalid unit amount: 0.823091 - Too many decimal places',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#getOrderHashHex', () => {
|
describe('#getOrderHashHex', () => {
|
||||||
@@ -167,10 +172,10 @@ describe('ZeroEx library', () => {
|
|||||||
it('throws a readable error message if taker format is invalid', async () => {
|
it('throws a readable error message if taker format is invalid', async () => {
|
||||||
const orderWithInvalidtakerFormat = {
|
const orderWithInvalidtakerFormat = {
|
||||||
...order,
|
...order,
|
||||||
taker: null as any as string,
|
taker: (null as any) as string,
|
||||||
};
|
};
|
||||||
// tslint:disable-next-line:max-line-length
|
const expectedErrorMessage =
|
||||||
const expectedErrorMessage = 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
||||||
expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
|
expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -198,16 +203,15 @@ describe('ZeroEx library', () => {
|
|||||||
});
|
});
|
||||||
it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
|
it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
|
||||||
const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
|
const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
|
||||||
// tslint:disable-next-line: max-line-length
|
const signature =
|
||||||
const signature = '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
|
'0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
|
||||||
const expectedECSignature = {
|
const expectedECSignature = {
|
||||||
v: 27,
|
v: 27,
|
||||||
r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
|
r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
|
||||||
s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
|
s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
|
||||||
};
|
};
|
||||||
stubs = [
|
stubs = [
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync')
|
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
|
||||||
.returns(Promise.resolve(signature)),
|
|
||||||
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -216,16 +220,15 @@ describe('ZeroEx library', () => {
|
|||||||
});
|
});
|
||||||
it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
|
it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
|
||||||
const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
|
const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
|
||||||
// tslint:disable-next-line: max-line-length
|
const signature =
|
||||||
const signature = '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
|
'0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
|
||||||
const expectedECSignature = {
|
const expectedECSignature = {
|
||||||
v: 27,
|
v: 27,
|
||||||
r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
|
r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
|
||||||
s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
|
s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
|
||||||
};
|
};
|
||||||
stubs = [
|
stubs = [
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync')
|
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
|
||||||
.returns(Promise.resolve(signature)),
|
|
||||||
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -271,8 +274,9 @@ describe('ZeroEx library', () => {
|
|||||||
networkId: constants.TESTRPC_NETWORK_ID,
|
networkId: constants.TESTRPC_NETWORK_ID,
|
||||||
};
|
};
|
||||||
const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
|
const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
|
||||||
expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress())
|
expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
|
||||||
.to.be.equal(ZeroEx.NULL_ADDRESS);
|
ZeroEx.NULL_ADDRESS,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import HDWalletProvider = require('truffle-hdwallet-provider');
|
import HDWalletProvider = require('truffle-hdwallet-provider');
|
||||||
|
|
||||||
import {ZeroEx} from '../src';
|
import { ZeroEx } from '../src';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import {ZeroEx} from '../src';
|
import { ZeroEx } from '../src';
|
||||||
import {assert} from '../src/utils/assert';
|
import { assert } from '../src/utils/assert';
|
||||||
|
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
|
||||||
@@ -19,22 +19,25 @@ describe('Assertion library', () => {
|
|||||||
it('throws when address is invalid', async () => {
|
it('throws when address is invalid', async () => {
|
||||||
const address = '0xdeadbeef';
|
const address = '0xdeadbeef';
|
||||||
const varName = 'address';
|
const varName = 'address';
|
||||||
return expect(assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper))
|
return expect(
|
||||||
.to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
|
assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
|
||||||
|
).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
|
||||||
});
|
});
|
||||||
it('throws when address is unavailable', async () => {
|
it('throws when address is unavailable', async () => {
|
||||||
const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
|
const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
|
||||||
const varName = 'address';
|
const varName = 'address';
|
||||||
return expect(assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper))
|
return expect(
|
||||||
.to.be.rejectedWith(
|
assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
|
||||||
`Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
|
).to.be.rejectedWith(
|
||||||
);
|
`Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('doesn\'t throw if address is available', async () => {
|
it("doesn't throw if address is available", async () => {
|
||||||
const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
|
const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
|
||||||
const varName = 'address';
|
const varName = 'address';
|
||||||
return expect(assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper))
|
return expect(
|
||||||
.to.become(undefined);
|
assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
|
||||||
|
).to.become(undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
@@ -17,13 +17,14 @@ import {
|
|||||||
ZeroEx,
|
ZeroEx,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../src';
|
} from '../src';
|
||||||
import {artifacts} from '../src/artifacts';
|
import { artifacts } from '../src/artifacts';
|
||||||
import {DoneCallback} from '../src/types';
|
import { DoneCallback } from '../src/types';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {TokenUtils} from './utils/token_utils';
|
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -153,118 +154,137 @@ describe('EtherTokenWrapper', () => {
|
|||||||
// Source: https://github.com/mochajs/mocha/issues/2407
|
// Source: https://github.com/mochajs/mocha/issues/2407
|
||||||
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
|
const callback = reportNodeCallbackErrors(done)(
|
||||||
expect(err).to.be.null();
|
(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
|
||||||
expect(logEvent).to.not.be.undefined();
|
expect(logEvent).to.not.be.undefined();
|
||||||
expect(logEvent.isRemoved).to.be.false();
|
expect(logEvent.isRemoved).to.be.false();
|
||||||
expect(logEvent.log.logIndex).to.be.equal(0);
|
expect(logEvent.log.logIndex).to.be.equal(0);
|
||||||
expect(logEvent.log.transactionIndex).to.be.equal(0);
|
expect(logEvent.log.transactionIndex).to.be.equal(0);
|
||||||
expect(logEvent.log.blockNumber).to.be.a('number');
|
expect(logEvent.log.blockNumber).to.be.a('number');
|
||||||
const args = logEvent.log.args;
|
const args = logEvent.log.args;
|
||||||
expect(args._from).to.be.equal(addressWithETH);
|
expect(args._from).to.be.equal(addressWithETH);
|
||||||
expect(args._to).to.be.equal(addressWithoutFunds);
|
expect(args._to).to.be.equal(addressWithoutFunds);
|
||||||
expect(args._value).to.be.bignumber.equal(transferAmount);
|
expect(args._value).to.be.bignumber.equal(transferAmount);
|
||||||
done();
|
},
|
||||||
};
|
);
|
||||||
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callback = reportNodeCallbackErrors(done)(
|
||||||
expect(err).to.be.null();
|
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
expect(logEvent).to.not.be.undefined();
|
expect(logEvent).to.not.be.undefined();
|
||||||
expect(logEvent.isRemoved).to.be.false();
|
expect(logEvent.isRemoved).to.be.false();
|
||||||
const args = logEvent.log.args;
|
const args = logEvent.log.args;
|
||||||
expect(args._owner).to.be.equal(addressWithETH);
|
expect(args._owner).to.be.equal(addressWithETH);
|
||||||
expect(args._spender).to.be.equal(addressWithoutFunds);
|
expect(args._spender).to.be.equal(addressWithoutFunds);
|
||||||
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
||||||
done();
|
},
|
||||||
};
|
);
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
|
||||||
etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(
|
await zeroEx.token.setAllowanceAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, allowanceAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
allowanceAmount,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
|
it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
|
const callback = reportNodeCallbackErrors(done)(
|
||||||
expect(err).to.be.null();
|
(logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
|
||||||
expect(logEvent).to.not.be.undefined();
|
expect(logEvent).to.not.be.undefined();
|
||||||
expect(logEvent.isRemoved).to.be.false();
|
expect(logEvent.isRemoved).to.be.false();
|
||||||
const args = logEvent.log.args;
|
const args = logEvent.log.args;
|
||||||
expect(args._owner).to.be.equal(addressWithETH);
|
expect(args._owner).to.be.equal(addressWithETH);
|
||||||
expect(args._value).to.be.bignumber.equal(depositAmount);
|
expect(args._value).to.be.bignumber.equal(depositAmount);
|
||||||
done();
|
},
|
||||||
};
|
|
||||||
zeroEx.etherToken.subscribe(
|
|
||||||
etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
|
|
||||||
await zeroEx.etherToken.depositAsync(
|
|
||||||
etherTokenAddress, depositAmount, addressWithETH,
|
|
||||||
);
|
);
|
||||||
|
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
|
||||||
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
|
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
|
const callback = reportNodeCallbackErrors(done)(
|
||||||
expect(err).to.be.null();
|
(logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
|
||||||
expect(logEvent).to.not.be.undefined();
|
expect(logEvent).to.not.be.undefined();
|
||||||
expect(logEvent.isRemoved).to.be.false();
|
expect(logEvent.isRemoved).to.be.false();
|
||||||
const args = logEvent.log.args;
|
const args = logEvent.log.args;
|
||||||
expect(args._owner).to.be.equal(addressWithETH);
|
expect(args._owner).to.be.equal(addressWithETH);
|
||||||
expect(args._value).to.be.bignumber.equal(depositAmount);
|
expect(args._value).to.be.bignumber.equal(depositAmount);
|
||||||
done();
|
},
|
||||||
};
|
|
||||||
await zeroEx.etherToken.depositAsync(
|
|
||||||
etherTokenAddress, depositAmount, addressWithETH,
|
|
||||||
);
|
);
|
||||||
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Withdrawal, indexFilterValues, callback);
|
etherTokenAddress,
|
||||||
await zeroEx.etherToken.withdrawAsync(
|
EtherTokenEvents.Withdrawal,
|
||||||
etherTokenAddress, withdrawalAmount, addressWithETH,
|
indexFilterValues,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
|
await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
};
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
zeroEx.etherToken.subscribe(
|
},
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
|
|
||||||
);
|
);
|
||||||
const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
zeroEx.etherToken.subscribe(
|
||||||
done();
|
etherTokenAddress,
|
||||||
};
|
EtherTokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
|
);
|
||||||
|
const callbackToBeCalled = reportNodeCallbackErrors(done)();
|
||||||
const newProvider = web3Factory.getRpcProvider();
|
const newProvider = web3Factory.getRpcProvider();
|
||||||
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
||||||
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackToBeCalled,
|
etherTokenAddress,
|
||||||
|
EtherTokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackToBeCalled,
|
||||||
);
|
);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
};
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
|
},
|
||||||
|
);
|
||||||
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||||
const subscriptionToken = zeroEx.etherToken.subscribe(
|
const subscriptionToken = zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
|
etherTokenAddress,
|
||||||
|
EtherTokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
|
);
|
||||||
zeroEx.etherToken.unsubscribe(subscriptionToken);
|
zeroEx.etherToken.unsubscribe(subscriptionToken);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
@@ -291,7 +311,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const eventName = EtherTokenEvents.Approval;
|
const eventName = EtherTokenEvents.Approval;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@@ -305,7 +328,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const eventName = EtherTokenEvents.Deposit;
|
const eventName = EtherTokenEvents.Deposit;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
|
const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@@ -319,7 +345,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const differentEventName = EtherTokenEvents.Transfer;
|
const differentEventName = EtherTokenEvents.Transfer;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync(
|
const logs = await zeroEx.etherToken.getLogsAsync(
|
||||||
etherTokenAddress, differentEventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
differentEventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(0);
|
expect(logs).to.have.length(0);
|
||||||
});
|
});
|
||||||
@@ -333,7 +362,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
_owner: addressWithETH,
|
_owner: addressWithETH,
|
||||||
};
|
};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {
|
import { LogEvent } from '../src';
|
||||||
LogEvent,
|
import { EventWatcher } from '../src/order_watcher/event_watcher';
|
||||||
} from '../src';
|
import { DoneCallback } from '../src/types';
|
||||||
import {EventWatcher} from '../src/order_watcher/event_watcher';
|
|
||||||
import {DoneCallback} from '../src/types';
|
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
|
||||||
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -38,7 +37,7 @@ describe('EventWatcher', () => {
|
|||||||
blockNumber: null,
|
blockNumber: null,
|
||||||
data: '',
|
data: '',
|
||||||
logIndex: null,
|
logIndex: null,
|
||||||
topics: [ '0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567' ],
|
topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
|
||||||
transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
|
transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
|
||||||
transactionIndex: 0,
|
transactionIndex: 0,
|
||||||
};
|
};
|
||||||
@@ -48,7 +47,7 @@ describe('EventWatcher', () => {
|
|||||||
blockNumber: null,
|
blockNumber: null,
|
||||||
data: '',
|
data: '',
|
||||||
logIndex: null,
|
logIndex: null,
|
||||||
topics: [ '0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567' ],
|
topics: ['0xf341246adaac6f497bc2a656f546ab9e182111d630394f0c57c710a59a2cb567'],
|
||||||
transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
|
transactionHash: '0x01ef3c048b18d9b09ea195b4ed94cf8dd5f3d857a1905ff886b152cfb1166f25',
|
||||||
transactionIndex: 0,
|
transactionIndex: 0,
|
||||||
};
|
};
|
||||||
@@ -79,13 +78,14 @@ describe('EventWatcher', () => {
|
|||||||
const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
|
const getLogsStub = Sinon.stub(web3Wrapper, 'getLogsAsync');
|
||||||
getLogsStub.onCall(0).returns(logs);
|
getLogsStub.onCall(0).returns(logs);
|
||||||
stubs.push(getLogsStub);
|
stubs.push(getLogsStub);
|
||||||
const callback = (event: LogEvent) => {
|
const expectedToBeCalledOnce = false;
|
||||||
|
const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
|
||||||
const expectedLogEvent = expectedLogEvents.shift();
|
const expectedLogEvent = expectedLogEvents.shift();
|
||||||
expect(event).to.be.deep.equal(expectedLogEvent);
|
expect(event).to.be.deep.equal(expectedLogEvent);
|
||||||
if (_.isEmpty(expectedLogEvents)) {
|
if (_.isEmpty(expectedLogEvents)) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
eventWatcher.subscribe(callback);
|
eventWatcher.subscribe(callback);
|
||||||
});
|
});
|
||||||
it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
|
it('correctly computes the difference and emits only changes', (done: DoneCallback) => {
|
||||||
@@ -113,13 +113,14 @@ describe('EventWatcher', () => {
|
|||||||
getLogsStub.onCall(0).returns(initialLogs);
|
getLogsStub.onCall(0).returns(initialLogs);
|
||||||
getLogsStub.onCall(1).returns(changedLogs);
|
getLogsStub.onCall(1).returns(changedLogs);
|
||||||
stubs.push(getLogsStub);
|
stubs.push(getLogsStub);
|
||||||
const callback = (event: LogEvent) => {
|
const expectedToBeCalledOnce = false;
|
||||||
|
const callback = reportNodeCallbackErrors(done, expectedToBeCalledOnce)((event: LogEvent) => {
|
||||||
const expectedLogEvent = expectedLogEvents.shift();
|
const expectedLogEvent = expectedLogEvents.shift();
|
||||||
expect(event).to.be.deep.equal(expectedLogEvent);
|
expect(event).to.be.deep.equal(expectedLogEvent);
|
||||||
if (_.isEmpty(expectedLogEvents)) {
|
if (_.isEmpty(expectedLogEvents)) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
eventWatcher.subscribe(callback);
|
eventWatcher.subscribe(callback);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
|
|
||||||
import {ExchangeContractErrs, Token, ZeroEx} from '../src';
|
import { ExchangeContractErrs, Token, ZeroEx } from '../src';
|
||||||
import {BlockParamLiteral, TradeSide, TransferType} from '../src/types';
|
import { BlockParamLiteral, TradeSide, TransferType } from '../src/types';
|
||||||
import {ExchangeTransferSimulator} from '../src/utils/exchange_transfer_simulator';
|
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -45,17 +45,31 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
|
exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
|
||||||
});
|
});
|
||||||
it('throws if the user doesn\'t have enough allowance', async () => {
|
it("throws if the user doesn't have enough allowance", async () => {
|
||||||
return expect(exchangeTransferSimulator.transferFromAsync(
|
return expect(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
|
exchangeTransferSimulator.transferFromAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
|
||||||
});
|
});
|
||||||
it('throws if the user doesn\'t have enough balance', async () => {
|
it("throws if the user doesn't have enough balance", async () => {
|
||||||
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
return expect(exchangeTransferSimulator.transferFromAsync(
|
return expect(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Maker, TransferType.Trade,
|
exchangeTransferSimulator.transferFromAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
|
||||||
});
|
});
|
||||||
it('updates balances and proxyAllowance after transfer', async () => {
|
it('updates balances and proxyAllowance after transfer', async () => {
|
||||||
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
||||||
@@ -63,7 +77,12 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
await exchangeTransferSimulator.transferFromAsync(
|
await exchangeTransferSimulator.transferFromAsync(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const store = (exchangeTransferSimulator as any)._store;
|
const store = (exchangeTransferSimulator as any)._store;
|
||||||
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
||||||
@@ -73,13 +92,18 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
|
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
|
||||||
expect(senderProxyAllowance).to.be.bignumber.equal(0);
|
expect(senderProxyAllowance).to.be.bignumber.equal(0);
|
||||||
});
|
});
|
||||||
it('doesn\'t update proxyAllowance after transfer if unlimited', async () => {
|
it("doesn't update proxyAllowance after transfer if unlimited", async () => {
|
||||||
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
|
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
await exchangeTransferSimulator.transferFromAsync(
|
await exchangeTransferSimulator.transferFromAsync(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const store = (exchangeTransferSimulator as any)._store;
|
const store = (exchangeTransferSimulator as any)._store;
|
||||||
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,23 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {ZeroEx} from '../src/0x';
|
import { ZeroEx } from '../src/0x';
|
||||||
import {ExpirationWatcher} from '../src/order_watcher/expiration_watcher';
|
import { ExpirationWatcher } from '../src/order_watcher/expiration_watcher';
|
||||||
import {DoneCallback, Token} from '../src/types';
|
import { DoneCallback, Token } from '../src/types';
|
||||||
import {constants} from '../src/utils/constants';
|
import { constants } from '../src/utils/constants';
|
||||||
import {utils} from '../src/utils/utils';
|
import { utils } from '../src/utils/utils';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants as testConstants} from './utils/constants';
|
import { constants as testConstants } from './utils/constants';
|
||||||
import {FillScenarios} from './utils/fill_scenarios';
|
import { FillScenarios } from './utils/fill_scenarios';
|
||||||
import {reportCallbackErrors} from './utils/report_callback_errors';
|
import { reportNoErrorCallbackErrors } from './utils/report_callback_errors';
|
||||||
import {TokenUtils} from './utils/token_utils';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -62,7 +62,7 @@ describe('ExpirationWatcher', () => {
|
|||||||
});
|
});
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await blockchainLifecycle.startAsync();
|
await blockchainLifecycle.startAsync();
|
||||||
const sinonTimerConfig = {shouldAdvanceTime: true} as any;
|
const sinonTimerConfig = { shouldAdvanceTime: true } as any;
|
||||||
// This constructor has incorrect types
|
// This constructor has incorrect types
|
||||||
timer = Sinon.useFakeTimers(sinonTimerConfig);
|
timer = Sinon.useFakeTimers(sinonTimerConfig);
|
||||||
currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
|
currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
|
||||||
@@ -78,31 +78,38 @@ describe('ExpirationWatcher', () => {
|
|||||||
const orderLifetimeSec = 60;
|
const orderLifetimeSec = 60;
|
||||||
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
expirationUnixTimestampSec,
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
|
expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
|
||||||
const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
|
const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => {
|
||||||
expect(hash).to.be.equal(orderHash);
|
expect(hash).to.be.equal(orderHash);
|
||||||
expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
|
expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
expirationWatcher.subscribe(callbackAsync);
|
expirationWatcher.subscribe(callbackAsync);
|
||||||
timer.tick(orderLifetimeSec * 1000);
|
timer.tick(orderLifetimeSec * 1000);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('doesn\'t emit events before order expires', (done: DoneCallback) => {
|
it("doesn't emit events before order expires", (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const orderLifetimeSec = 60;
|
const orderLifetimeSec = 60;
|
||||||
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
expirationUnixTimestampSec,
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
|
expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
|
||||||
const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
|
const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => {
|
||||||
done(new Error('Emitted expiration went before the order actually expired'));
|
done(new Error('Emitted expiration went before the order actually expired'));
|
||||||
});
|
});
|
||||||
expirationWatcher.subscribe(callbackAsync);
|
expirationWatcher.subscribe(callbackAsync);
|
||||||
@@ -118,11 +125,19 @@ describe('ExpirationWatcher', () => {
|
|||||||
const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
|
const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
|
||||||
const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
|
const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
|
||||||
const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
order1ExpirationUnixTimestampSec,
|
order1ExpirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
order2ExpirationUnixTimestampSec,
|
order2ExpirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
|
const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
|
||||||
@@ -130,7 +145,8 @@ describe('ExpirationWatcher', () => {
|
|||||||
expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
|
expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000));
|
||||||
expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
|
expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000));
|
||||||
const expirationOrder = [orderHash1, orderHash2];
|
const expirationOrder = [orderHash1, orderHash2];
|
||||||
const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
|
const expectToBeCalledOnce = false;
|
||||||
|
const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => {
|
||||||
const orderHash = expirationOrder.shift();
|
const orderHash = expirationOrder.shift();
|
||||||
expect(hash).to.be.equal(orderHash);
|
expect(hash).to.be.equal(orderHash);
|
||||||
if (_.isEmpty(expirationOrder)) {
|
if (_.isEmpty(expirationOrder)) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
@@ -15,14 +15,14 @@ import {
|
|||||||
ZeroEx,
|
ZeroEx,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../src';
|
} from '../src';
|
||||||
import {DoneCallback} from '../src/types';
|
import { DoneCallback } from '../src/types';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {FillScenarios} from './utils/fill_scenarios';
|
import { FillScenarios } from './utils/fill_scenarios';
|
||||||
import {reportCallbackErrors} from './utils/report_callback_errors';
|
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
|
||||||
import {TokenUtils} from './utils/token_utils';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
const TIMEOUT_MS = 150;
|
const TIMEOUT_MS = 150;
|
||||||
|
|
||||||
@@ -71,7 +71,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
describe('#removeOrder', async () => {
|
describe('#removeOrder', async () => {
|
||||||
it('should successfully remove existing order', async () => {
|
it('should successfully remove existing order', async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@@ -89,10 +93,18 @@ describe('OrderStateWatcher', () => {
|
|||||||
});
|
});
|
||||||
it('should no-op when removing a non-existing order', async () => {
|
it('should no-op when removing a non-existing order', async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
const nonExistentOrderHash = `0x${orderHash.substr(2).split('').reverse().join('')}`;
|
const nonExistentOrderHash = `0x${orderHash
|
||||||
|
.substr(2)
|
||||||
|
.split('')
|
||||||
|
.reverse()
|
||||||
|
.join('')}`;
|
||||||
zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
|
zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -102,8 +114,7 @@ describe('OrderStateWatcher', () => {
|
|||||||
});
|
});
|
||||||
it('should fail when trying to subscribe twice', async () => {
|
it('should fail when trying to subscribe twice', async () => {
|
||||||
zeroEx.orderStateWatcher.subscribe(_.noop);
|
zeroEx.orderStateWatcher.subscribe(_.noop);
|
||||||
expect(() => zeroEx.orderStateWatcher.subscribe(_.noop))
|
expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
|
||||||
.to.throw(ZeroExError.SubscriptionAlreadyPresent);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('tests with cleanup', async () => {
|
describe('tests with cleanup', async () => {
|
||||||
@@ -115,16 +126,19 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.false();
|
expect(orderState.isValid).to.be.false();
|
||||||
const invalidOrderState = orderState as OrderStateInvalid;
|
const invalidOrderState = orderState as OrderStateInvalid;
|
||||||
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
||||||
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
|
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
|
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
|
||||||
@@ -133,10 +147,14 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
|
it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
throw new Error('OrderState callback fired for irrelevant order');
|
throw new Error('OrderState callback fired for irrelevant order');
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
@@ -152,16 +170,19 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.false();
|
expect(orderState.isValid).to.be.false();
|
||||||
const invalidOrderState = orderState as OrderStateInvalid;
|
const invalidOrderState = orderState as OrderStateInvalid;
|
||||||
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
||||||
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
|
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
const anyRecipient = taker;
|
const anyRecipient = taker;
|
||||||
@@ -172,30 +193,40 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.false();
|
expect(orderState.isValid).to.be.false();
|
||||||
const invalidOrderState = orderState as OrderStateInvalid;
|
const invalidOrderState = orderState as OrderStateInvalid;
|
||||||
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
||||||
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
|
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, taker,
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
taker,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
|
it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
||||||
@@ -203,7 +234,7 @@ describe('OrderStateWatcher', () => {
|
|||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.true();
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
||||||
@@ -211,16 +242,20 @@ describe('OrderStateWatcher', () => {
|
|||||||
const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
|
const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
|
||||||
const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
|
const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingFillable);
|
remainingFillable,
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingFillable);
|
remainingFillable,
|
||||||
|
);
|
||||||
expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
|
expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker,
|
signedOrder,
|
||||||
|
fillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
taker,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@@ -229,11 +264,16 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
|
||||||
const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
|
const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
taker);
|
takerToken.address,
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
makerFee,
|
||||||
done();
|
takerFee,
|
||||||
});
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
taker,
|
||||||
|
);
|
||||||
|
const callback = reportNodeCallbackErrors(done)();
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
|
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
|
||||||
@@ -245,47 +285,60 @@ describe('OrderStateWatcher', () => {
|
|||||||
const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
|
const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
|
||||||
const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
|
const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
|
||||||
signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, makerFillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
makerFillableAmount,
|
||||||
takerFillableAmount,
|
takerFillableAmount,
|
||||||
);
|
);
|
||||||
const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.true();
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals));
|
ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals));
|
ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
|
||||||
done();
|
);
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker,
|
signedOrder,
|
||||||
|
fillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
taker,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
|
it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
changedMakerApprovalAmount);
|
changedMakerApprovalAmount,
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
changedMakerApprovalAmount);
|
changedMakerApprovalAmount,
|
||||||
done();
|
);
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
|
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount);
|
||||||
@@ -294,7 +347,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
|
it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
||||||
@@ -303,19 +360,19 @@ describe('OrderStateWatcher', () => {
|
|||||||
const transferAmount = makerBalance.sub(remainingAmount);
|
const transferAmount = makerBalance.sub(remainingAmount);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.true();
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingAmount);
|
remainingAmount,
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingAmount);
|
remainingAmount,
|
||||||
done();
|
);
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
|
||||||
makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
|
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
|
it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
|
||||||
@@ -324,20 +381,27 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
||||||
const feeRecipient = taker;
|
const feeRecipient = taker;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker,
|
makerToken.address,
|
||||||
taker, fillableAmount, feeRecipient);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
|
);
|
||||||
|
|
||||||
const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
|
const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
|
||||||
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
|
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.true();
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingTokenAmount);
|
remainingTokenAmount,
|
||||||
done();
|
);
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount);
|
||||||
@@ -349,8 +413,15 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
||||||
const feeRecipient = taker;
|
const feeRecipient = taker;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker,
|
makerToken.address,
|
||||||
taker, fillableAmount, feeRecipient);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
|
);
|
||||||
|
|
||||||
const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
||||||
|
|
||||||
@@ -358,17 +429,21 @@ describe('OrderStateWatcher', () => {
|
|||||||
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
|
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingFeeAmount);
|
remainingFeeAmount,
|
||||||
done();
|
);
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
|
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferTokenAmount);
|
makerToken.address,
|
||||||
|
maker,
|
||||||
|
ZeroEx.NULL_ADDRESS,
|
||||||
|
transferTokenAmount,
|
||||||
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
|
it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
|
||||||
@@ -377,38 +452,51 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
const feeRecipient = taker;
|
const feeRecipient = taker;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker,
|
makerToken.address,
|
||||||
taker, fillableAmount, feeRecipient);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
|
);
|
||||||
|
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
fillableAmount);
|
fillableAmount,
|
||||||
done();
|
);
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(
|
await zeroEx.token.setProxyAllowanceAsync(
|
||||||
makerToken.address, maker, ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals));
|
makerToken.address,
|
||||||
|
maker,
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
|
||||||
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.false();
|
expect(orderState.isValid).to.be.false();
|
||||||
const invalidOrderState = orderState as OrderStateInvalid;
|
const invalidOrderState = orderState as OrderStateInvalid;
|
||||||
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
||||||
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
|
|
||||||
@@ -419,41 +507,48 @@ describe('OrderStateWatcher', () => {
|
|||||||
(async () => {
|
(async () => {
|
||||||
const remainingFillableAmountInBaseUnits = new BigNumber(100);
|
const remainingFillableAmountInBaseUnits = new BigNumber(100);
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.false();
|
expect(orderState.isValid).to.be.false();
|
||||||
const invalidOrderState = orderState as OrderStateInvalid;
|
const invalidOrderState = orderState as OrderStateInvalid;
|
||||||
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
expect(invalidOrderState.orderHash).to.be.equal(orderHash);
|
||||||
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
|
expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.exchange.cancelOrderAsync(
|
await zeroEx.exchange.cancelOrderAsync(
|
||||||
signedOrder, fillableAmount.minus(remainingFillableAmountInBaseUnits),
|
signedOrder,
|
||||||
|
fillableAmount.minus(remainingFillableAmountInBaseUnits),
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
|
it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const cancelAmountInBaseUnits = new BigNumber(2);
|
const cancelAmountInBaseUnits = new BigNumber(2);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportNodeCallbackErrors(done)((orderState: OrderState) => {
|
||||||
expect(orderState.isValid).to.be.true();
|
expect(orderState.isValid).to.be.true();
|
||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
|
expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits);
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {ExchangeContractErrs, SignedOrder, Token, ZeroEx, ZeroExError} from '../src';
|
import { ExchangeContractErrs, SignedOrder, Token, ZeroEx, ZeroExError } from '../src';
|
||||||
import {BlockParamLiteral, TradeSide, TransferType} from '../src/types';
|
import { BlockParamLiteral, TradeSide, TransferType } from '../src/types';
|
||||||
import {ExchangeTransferSimulator} from '../src/utils/exchange_transfer_simulator';
|
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
|
||||||
import {OrderValidationUtils} from '../src/utils/order_validation_utils';
|
import { OrderValidationUtils } from '../src/utils/order_validation_utils';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {FillScenarios} from './utils/fill_scenarios';
|
import { FillScenarios } from './utils/fill_scenarios';
|
||||||
import {TokenUtils} from './utils/token_utils';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -62,108 +62,152 @@ describe('OrderValidation', () => {
|
|||||||
describe('validateOrderFillableOrThrowAsync', () => {
|
describe('validateOrderFillableOrThrowAsync', () => {
|
||||||
it('should succeed if the order is fillable', async () => {
|
it('should succeed if the order is fillable', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
);
|
takerTokenAddress,
|
||||||
await zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
makerAddress,
|
||||||
signedOrder,
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||||
});
|
});
|
||||||
it('should succeed if the order is asymmetric and fillable', async () => {
|
it('should succeed if the order is asymmetric and fillable', async () => {
|
||||||
const makerFillableAmount = fillableAmount;
|
const makerFillableAmount = fillableAmount;
|
||||||
const takerFillableAmount = fillableAmount.minus(4);
|
const takerFillableAmount = fillableAmount.minus(4);
|
||||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
makerFillableAmount, takerFillableAmount,
|
takerTokenAddress,
|
||||||
);
|
makerAddress,
|
||||||
await zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
takerAddress,
|
||||||
signedOrder,
|
makerFillableAmount,
|
||||||
|
takerFillableAmount,
|
||||||
);
|
);
|
||||||
|
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||||
});
|
});
|
||||||
it('should throw when the order is fully filled or cancelled', async () => {
|
it('should throw when the order is fully filled or cancelled', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
|
||||||
signedOrder,
|
ExchangeContractErrs.OrderRemainingFillAmountZero,
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when order is expired', async () => {
|
it('should throw when order is expired', async () => {
|
||||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, expirationInPast,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
expirationInPast,
|
||||||
|
);
|
||||||
|
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
|
||||||
|
ExchangeContractErrs.OrderFillExpired,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
|
||||||
signedOrder,
|
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('validateFillOrderAndThrowIfInvalidAsync', () => {
|
describe('validateFillOrderAndThrowIfInvalidAsync', () => {
|
||||||
it('should throw when the fill amount is zero', async () => {
|
it('should throw when the fill amount is zero', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const zeroFillAmount = new BigNumber(0);
|
const zeroFillAmount = new BigNumber(0);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, zeroFillAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should throw when the signature is invalid', async () => {
|
it('should throw when the signature is invalid', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
// 27 <--> 28
|
// 27 <--> 28
|
||||||
signedOrder.ecSignature.v = (28 - signedOrder.ecSignature.v) + 27;
|
signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillableAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ZeroExError.InvalidSignature);
|
).to.be.rejectedWith(ZeroExError.InvalidSignature);
|
||||||
});
|
});
|
||||||
it('should throw when the order is fully filled or cancelled', async () => {
|
it('should throw when the order is fully filled or cancelled', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillableAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should throw when sender is not a taker', async () => {
|
it('should throw when sender is not a taker', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const nonTakerAddress = userAddresses[6];
|
const nonTakerAddress = userAddresses[6];
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillTakerAmount, nonTakerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
||||||
});
|
});
|
||||||
it('should throw when order is expired', async () => {
|
it('should throw when order is expired', async () => {
|
||||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, expirationInPast,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
expirationInPast,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillTakerAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
||||||
});
|
});
|
||||||
it('should throw when there a rounding error would have occurred', async () => {
|
it('should throw when there a rounding error would have occurred', async () => {
|
||||||
const makerAmount = new BigNumber(3);
|
const makerAmount = new BigNumber(3);
|
||||||
const takerAmount = new BigNumber(5);
|
const takerAmount = new BigNumber(5);
|
||||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
makerAmount, takerAmount,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerAmount,
|
||||||
|
takerAmount,
|
||||||
);
|
);
|
||||||
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
|
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillTakerAmountThatCausesRoundingError, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
|
signedOrder,
|
||||||
|
fillTakerAmountThatCausesRoundingError,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
|
describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
|
||||||
it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
|
it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const tooLargeFillAmount = new BigNumber(7);
|
const tooLargeFillAmount = new BigNumber(7);
|
||||||
const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
|
const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
|
||||||
@@ -172,9 +216,13 @@ describe('OrderValidation', () => {
|
|||||||
await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
|
await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
|
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
|
||||||
|
|
||||||
return expect(zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, tooLargeFillAmount, takerAddress,
|
zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
signedOrder,
|
||||||
|
tooLargeFillAmount,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
|
describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
|
||||||
@@ -186,27 +234,38 @@ describe('OrderValidation', () => {
|
|||||||
makerTokenAddress = makerToken.address;
|
makerTokenAddress = makerToken.address;
|
||||||
takerTokenAddress = takerToken.address;
|
takerTokenAddress = takerToken.address;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when cancel amount is zero', async () => {
|
it('should throw when cancel amount is zero', async () => {
|
||||||
const zeroCancelAmount = new BigNumber(0);
|
const zeroCancelAmount = new BigNumber(0);
|
||||||
return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
it('should throw when order is expired', async () => {
|
it('should throw when order is expired', async () => {
|
||||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||||
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, expirationInPast,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
expirationInPast,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
|
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
|
||||||
});
|
});
|
||||||
it('should throw when order is already cancelled or filled', async () => {
|
it('should throw when order is already cancelled or filled', async () => {
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
|
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
|
describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
|
||||||
@@ -224,82 +283,159 @@ describe('OrderValidation', () => {
|
|||||||
const makerFee = new BigNumber(2);
|
const makerFee = new BigNumber(2);
|
||||||
const takerFee = new BigNumber(2);
|
const takerFee = new BigNumber(2);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
makerTokenAddress,
|
||||||
makerAddress, takerAddress, fillableAmount, feeRecipient,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
);
|
);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(0).calledWith(
|
transferFromAsync
|
||||||
makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
|
.getCall(0)
|
||||||
TradeSide.Maker, TransferType.Trade,
|
.calledWith(
|
||||||
),
|
makerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(1).calledWith(
|
transferFromAsync
|
||||||
takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
|
.getCall(1)
|
||||||
TradeSide.Taker, TransferType.Trade,
|
.calledWith(
|
||||||
),
|
takerTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(2).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
|
.getCall(2)
|
||||||
TradeSide.Maker, TransferType.Fee,
|
.calledWith(
|
||||||
),
|
zrxTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(makerFee),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Fee,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(3).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
|
.getCall(3)
|
||||||
TradeSide.Taker, TransferType.Fee,
|
.calledWith(
|
||||||
),
|
zrxTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(takerFee),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Fee,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
});
|
});
|
||||||
it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
|
it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
|
||||||
const makerFee = new BigNumber(2);
|
const makerFee = new BigNumber(2);
|
||||||
const takerFee = new BigNumber(2);
|
const takerFee = new BigNumber(2);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
makerTokenAddress,
|
||||||
makerAddress, ZeroEx.NULL_ADDRESS, fillableAmount, feeRecipient,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
ZeroEx.NULL_ADDRESS,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
);
|
);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(0).calledWith(
|
transferFromAsync
|
||||||
makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
|
.getCall(0)
|
||||||
TradeSide.Maker, TransferType.Trade,
|
.calledWith(
|
||||||
),
|
makerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(1).calledWith(
|
transferFromAsync
|
||||||
takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
|
.getCall(1)
|
||||||
TradeSide.Taker, TransferType.Trade,
|
.calledWith(
|
||||||
),
|
takerTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(2).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
|
.getCall(2)
|
||||||
TradeSide.Maker, TransferType.Fee,
|
.calledWith(
|
||||||
),
|
zrxTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(makerFee),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Fee,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(3).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
|
.getCall(3)
|
||||||
TradeSide.Taker, TransferType.Fee,
|
.calledWith(
|
||||||
),
|
zrxTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(takerFee),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Fee,
|
||||||
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
});
|
});
|
||||||
it('should correctly round the fillMakerTokenAmount', async () => {
|
it('should correctly round the fillMakerTokenAmount', async () => {
|
||||||
const makerTokenAmount = new BigNumber(3);
|
const makerTokenAmount = new BigNumber(3);
|
||||||
const takerTokenAmount = new BigNumber(1);
|
const takerTokenAmount = new BigNumber(1);
|
||||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, makerTokenAmount, takerTokenAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerTokenAmount,
|
||||||
|
takerTokenAmount,
|
||||||
);
|
);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, takerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
takerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||||
const makerFillAmount = transferFromAsync.getCall(0).args[3];
|
const makerFillAmount = transferFromAsync.getCall(0).args[3];
|
||||||
@@ -309,12 +445,22 @@ describe('OrderValidation', () => {
|
|||||||
const makerFee = new BigNumber(2);
|
const makerFee = new BigNumber(2);
|
||||||
const takerFee = new BigNumber(4);
|
const takerFee = new BigNumber(4);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, ZeroEx.NULL_ADDRESS,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
ZeroEx.NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
const fillTakerTokenAmount = fillableAmount.div(2).round(0);
|
const fillTakerTokenAmount = fillableAmount.div(2).round(0);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
const makerPartialFee = makerFee.div(2);
|
const makerPartialFee = makerFee.div(2);
|
||||||
const takerPartialFee = takerFee.div(2);
|
const takerPartialFee = takerFee.div(2);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import {ZeroEx} from '../src/0x';
|
import { ZeroEx } from '../src/0x';
|
||||||
import {RemainingFillableCalculator} from '../src/order_watcher/remaining_fillable_calculator';
|
import { RemainingFillableCalculator } from '../src/order_watcher/remaining_fillable_calculator';
|
||||||
import {ECSignature, SignedOrder} from '../src/types';
|
import { ECSignature, SignedOrder } from '../src/types';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -26,29 +26,34 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
const decimals: number = 4;
|
const decimals: number = 4;
|
||||||
const zero: BigNumber = new BigNumber(0);
|
const zero: BigNumber = new BigNumber(0);
|
||||||
const zeroAddress = '0x0';
|
const zeroAddress = '0x0';
|
||||||
const signature: ECSignature = {v: 27, r: '', s: ''};
|
const signature: ECSignature = { v: 27, r: '', s: '' };
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
[makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
|
||||||
|
];
|
||||||
[transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
|
[transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
function buildSignedOrder(): SignedOrder {
|
function buildSignedOrder(): SignedOrder {
|
||||||
return { ecSignature: signature,
|
return {
|
||||||
exchangeContractAddress: zeroAddress,
|
ecSignature: signature,
|
||||||
feeRecipient: zeroAddress,
|
exchangeContractAddress: zeroAddress,
|
||||||
maker: zeroAddress,
|
feeRecipient: zeroAddress,
|
||||||
taker: zeroAddress,
|
maker: zeroAddress,
|
||||||
makerFee: makerFeeAmount,
|
taker: zeroAddress,
|
||||||
takerFee: zero,
|
makerFee: makerFeeAmount,
|
||||||
makerTokenAmount: makerAmount,
|
takerFee: zero,
|
||||||
takerTokenAmount: takerAmount,
|
makerTokenAmount: makerAmount,
|
||||||
makerTokenAddress: makerToken,
|
takerTokenAmount: takerAmount,
|
||||||
takerTokenAddress: takerToken,
|
makerTokenAddress: makerToken,
|
||||||
salt: zero,
|
takerTokenAddress: takerToken,
|
||||||
expirationUnixTimestampSec: zero };
|
salt: zero,
|
||||||
|
expirationUnixTimestampSec: zero,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
describe('Maker token is NOT ZRX', () => {
|
describe('Maker token is NOT ZRX', () => {
|
||||||
before(async () => {
|
before(async () => {
|
||||||
@@ -57,23 +62,38 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
it('calculates the correct amount when unfilled and funds available', () => {
|
it('calculates the correct amount when unfilled and funds available', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when partially filled and funds available', () => {
|
it('calculates the correct amount when partially filled and funds available', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
transferrableMakerFeeTokenAmount = zero;
|
transferrableMakerFeeTokenAmount = zero;
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
||||||
@@ -81,41 +101,58 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
|
||||||
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
|
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
||||||
});
|
});
|
||||||
describe('Order to Fee Ratio is < 1', () => {
|
describe('Order to Fee Ratio is < 1', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
[makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when funds unavailable', () => {
|
it('calculates the correct amount when funds unavailable', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount,
|
signedOrder,
|
||||||
remainingMakerTokenAmount);
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Ratio is not evenly divisble', () => {
|
describe('Ratio is not evenly divisble', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
[makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when funds unavailable', () => {
|
it('calculates the correct amount when funds unavailable', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount,
|
signedOrder,
|
||||||
remainingMakerTokenAmount);
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
||||||
expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
|
expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
|
||||||
expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
|
expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
|
||||||
@@ -134,15 +171,25 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
|
transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
|
||||||
transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
|
transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when partially filled and funds available', () => {
|
it('calculates the correct amount when partially filled and funds available', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
||||||
@@ -150,8 +197,13 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
transferrableMakerTokenAmount = zero;
|
transferrableMakerTokenAmount = zero;
|
||||||
transferrableMakerFeeTokenAmount = zero;
|
transferrableMakerFeeTokenAmount = zero;
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
||||||
@@ -163,8 +215,13 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
|
|
||||||
const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
|
const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
|
||||||
const expectedFillableAmount = new BigNumber(450980);
|
const expectedFillableAmount = new BigNumber(450980);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
||||||
const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
|
const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
|
||||||
const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
|
const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
|
||||||
|
|||||||
@@ -1,27 +1,19 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {
|
import { ApprovalContractEventArgs, DecodedLogEvent, Token, TokenEvents, ZeroEx } from '../src';
|
||||||
ApprovalContractEventArgs,
|
import { DoneCallback } from '../src/types';
|
||||||
DecodedLogEvent,
|
|
||||||
Token,
|
|
||||||
TokenEvents,
|
|
||||||
ZeroEx,
|
|
||||||
} from '../src';
|
|
||||||
import {DoneCallback} from '../src/types';
|
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {reportCallbackErrors} from './utils/report_callback_errors';
|
import { assertNodeCallbackError } from './utils/report_callback_errors';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
|
||||||
const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
|
const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL);
|
||||||
|
|
||||||
describe('SubscriptionTest', () => {
|
describe('SubscriptionTest', () => {
|
||||||
@@ -65,50 +57,26 @@ describe('SubscriptionTest', () => {
|
|||||||
it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
|
it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const errMsg = 'Error fetching block';
|
const errMsg = 'Error fetching block';
|
||||||
const callback = reportCallbackErrors(done)(
|
const callback = assertNodeCallbackError(done, errMsg);
|
||||||
(err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
|
||||||
expect(err.message).to.be.equal(errMsg);
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
expect(logEvent).to.be.undefined();
|
|
||||||
done();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
stubs = [
|
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
|
|
||||||
.throws(new Error(errMsg)),
|
|
||||||
];
|
|
||||||
zeroEx.token.subscribe(
|
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
|
it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const errMsg = 'Error fetching logs';
|
const errMsg = 'Error fetching logs';
|
||||||
const callback = reportCallbackErrors(done)(
|
const callback = assertNodeCallbackError(done, errMsg);
|
||||||
(err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
|
||||||
expect(err.message).to.be.equal(errMsg);
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
expect(logEvent).to.be.undefined();
|
|
||||||
done();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
stubs = [
|
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync')
|
|
||||||
.throws(new Error(errMsg)),
|
|
||||||
];
|
|
||||||
zeroEx.token.subscribe(
|
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
|
||||||
stubs = [
|
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
|
|
||||||
.throws(new Error('JSON RPC error')),
|
|
||||||
];
|
|
||||||
zeroEx.token.unsubscribeAll();
|
zeroEx.token.unsubscribeAll();
|
||||||
done();
|
done();
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import {schemas, SchemaValidator} from '@0xproject/json-schemas';
|
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import {Token, ZeroEx} from '../src';
|
import { Token, ZeroEx } from '../src';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -19,10 +19,10 @@ const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
|
|||||||
describe('TokenRegistryWrapper', () => {
|
describe('TokenRegistryWrapper', () => {
|
||||||
let zeroEx: ZeroEx;
|
let zeroEx: ZeroEx;
|
||||||
let tokens: Token[];
|
let tokens: Token[];
|
||||||
const tokenAddressBySymbol: {[symbol: string]: string} = {};
|
const tokenAddressBySymbol: { [symbol: string]: string } = {};
|
||||||
const tokenAddressByName: {[symbol: string]: string} = {};
|
const tokenAddressByName: { [symbol: string]: string } = {};
|
||||||
const tokenBySymbol: {[symbol: string]: Token} = {};
|
const tokenBySymbol: { [symbol: string]: Token } = {};
|
||||||
const tokenByName: {[symbol: string]: Token} = {};
|
const tokenByName: { [symbol: string]: Token } = {};
|
||||||
const registeredSymbol = 'ZRX';
|
const registeredSymbol = 'ZRX';
|
||||||
const registeredName = '0x Protocol Token';
|
const registeredName = '0x Protocol Token';
|
||||||
const unregisteredSymbol = 'MAL';
|
const unregisteredSymbol = 'MAL';
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
|
|
||||||
import {ZeroEx} from '../src';
|
import { ZeroEx } from '../src';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {BlockchainLifecycle} from '@0xproject/dev-utils';
|
import { BlockchainLifecycle } from '@0xproject/dev-utils';
|
||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
@@ -16,12 +16,13 @@ import {
|
|||||||
ZeroEx,
|
ZeroEx,
|
||||||
ZeroExError,
|
ZeroExError,
|
||||||
} from '../src';
|
} from '../src';
|
||||||
import {DoneCallback} from '../src/types';
|
import { DoneCallback } from '../src/types';
|
||||||
|
|
||||||
import {chaiSetup} from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
import {constants} from './utils/constants';
|
import { constants } from './utils/constants';
|
||||||
import {TokenUtils} from './utils/token_utils';
|
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
|
||||||
import {web3Factory} from './utils/web3_factory';
|
import { TokenUtils } from './utils/token_utils';
|
||||||
|
import { web3Factory } from './utils/web3_factory';
|
||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
@@ -74,17 +75,17 @@ describe('TokenWrapper', () => {
|
|||||||
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
|
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
|
||||||
const fromAddress = addressWithoutFunds;
|
const fromAddress = addressWithoutFunds;
|
||||||
const toAddress = coinbase;
|
const toAddress = coinbase;
|
||||||
return expect(zeroEx.token.transferAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, transferAmount,
|
zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
});
|
});
|
||||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
const toAddress = coinbase;
|
const toAddress = coinbase;
|
||||||
return expect(zeroEx.token.transferAsync(
|
return expect(
|
||||||
nonExistentTokenAddress, fromAddress, toAddress, transferAmount,
|
zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#transferFromAsync', () => {
|
describe('#transferFromAsync', () => {
|
||||||
@@ -103,24 +104,22 @@ describe('TokenWrapper', () => {
|
|||||||
const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
|
const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
|
||||||
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
|
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
|
||||||
|
|
||||||
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress,
|
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
|
||||||
toAddress);
|
|
||||||
expect(fromAddressAllowance).to.be.bignumber.equal(0);
|
expect(fromAddressAllowance).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, senderAddress, transferAmount,
|
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
||||||
});
|
});
|
||||||
it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress',
|
it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
|
||||||
async () => {
|
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
const transferAmount = new BigNumber(42);
|
const transferAmount = new BigNumber(42);
|
||||||
|
|
||||||
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
|
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
|
||||||
|
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, senderAddress, transferAmount,
|
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
||||||
});
|
});
|
||||||
it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
|
it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
|
||||||
const fromAddress = addressWithoutFunds;
|
const fromAddress = addressWithoutFunds;
|
||||||
@@ -130,13 +129,16 @@ describe('TokenWrapper', () => {
|
|||||||
expect(fromAddressBalance).to.be.bignumber.equal(0);
|
expect(fromAddressBalance).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
||||||
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress,
|
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
|
||||||
senderAddress);
|
token.address,
|
||||||
|
fromAddress,
|
||||||
|
senderAddress,
|
||||||
|
);
|
||||||
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
|
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
|
||||||
|
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, senderAddress, transferAmount,
|
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
});
|
});
|
||||||
it('should successfully transfer tokens', async () => {
|
it('should successfully transfer tokens', async () => {
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
@@ -147,17 +149,22 @@ describe('TokenWrapper', () => {
|
|||||||
const transferAmount = new BigNumber(42);
|
const transferAmount = new BigNumber(42);
|
||||||
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
||||||
|
|
||||||
await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress,
|
await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
|
||||||
transferAmount);
|
|
||||||
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
|
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
|
||||||
return expect(postBalance).to.be.bignumber.equal(transferAmount);
|
return expect(postBalance).to.be.bignumber.equal(transferAmount);
|
||||||
});
|
});
|
||||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
nonExistentTokenAddress, fromAddress, toAddress, senderAddress, new BigNumber(42),
|
zeroEx.token.transferFromAsync(
|
||||||
)).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
nonExistentTokenAddress,
|
||||||
|
fromAddress,
|
||||||
|
toAddress,
|
||||||
|
senderAddress,
|
||||||
|
new BigNumber(42),
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#getBalanceAsync', () => {
|
describe('#getBalanceAsync', () => {
|
||||||
@@ -172,8 +179,9 @@ describe('TokenWrapper', () => {
|
|||||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress))
|
return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
ZeroExError.TokenContractDoesNotExist,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should return a balance of 0 for a non-existent owner address', async () => {
|
it('should return a balance of 0 for a non-existent owner address', async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
@@ -191,22 +199,25 @@ describe('TokenWrapper', () => {
|
|||||||
zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
|
zeroExWithoutAccounts = new ZeroEx(web3WithoutAccounts.currentProvider, config);
|
||||||
});
|
});
|
||||||
it('should return balance even when called with Web3 provider instance without addresses', async () => {
|
it('should return balance even when called with Web3 provider instance without addresses', async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
|
const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
|
||||||
const expectedBalance = new BigNumber('1000000000000000000000000000');
|
const expectedBalance = new BigNumber('1000000000000000000000000000');
|
||||||
return expect(balance).to.be.bignumber.equal(expectedBalance);
|
return expect(balance).to.be.bignumber.equal(expectedBalance);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#setAllowanceAsync', () => {
|
describe('#setAllowanceAsync', () => {
|
||||||
it('should set the spender\'s allowance', async () => {
|
it("should set the spender's allowance", async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
const spenderAddress = addressWithoutFunds;
|
const spenderAddress = addressWithoutFunds;
|
||||||
|
|
||||||
const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress,
|
const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
|
||||||
spenderAddress);
|
token.address,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
|
);
|
||||||
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
|
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
|
||||||
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
|
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
|
||||||
|
|
||||||
@@ -219,7 +230,7 @@ describe('TokenWrapper', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#setUnlimitedAllowanceAsync', () => {
|
describe('#setUnlimitedAllowanceAsync', () => {
|
||||||
it('should set the unlimited spender\'s allowance', async () => {
|
it("should set the unlimited spender's allowance", async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
const spenderAddress = addressWithoutFunds;
|
const spenderAddress = addressWithoutFunds;
|
||||||
@@ -241,10 +252,18 @@ describe('TokenWrapper', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await zeroEx.token.transferFromAsync(
|
await zeroEx.token.transferFromAsync(
|
||||||
zrx.address, coinbase, userWithNormalAllowance, userWithNormalAllowance, transferAmount,
|
zrx.address,
|
||||||
|
coinbase,
|
||||||
|
userWithNormalAllowance,
|
||||||
|
userWithNormalAllowance,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
await zeroEx.token.transferFromAsync(
|
await zeroEx.token.transferFromAsync(
|
||||||
zrx.address, coinbase, userWithUnlimitedAllowance, userWithUnlimitedAllowance, transferAmount,
|
zrx.address,
|
||||||
|
coinbase,
|
||||||
|
userWithUnlimitedAllowance,
|
||||||
|
userWithUnlimitedAllowance,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
|
const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
|
||||||
@@ -300,7 +319,9 @@ describe('TokenWrapper', () => {
|
|||||||
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
|
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
|
||||||
|
|
||||||
const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
|
const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
|
||||||
token.address, ownerAddress, spenderAddress,
|
token.address,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
);
|
);
|
||||||
const expectedAllowance = amountInBaseUnits;
|
const expectedAllowance = amountInBaseUnits;
|
||||||
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
|
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
|
||||||
@@ -366,65 +387,66 @@ describe('TokenWrapper', () => {
|
|||||||
// Source: https://github.com/mochajs/mocha/issues/2407
|
// Source: https://github.com/mochajs/mocha/issues/2407
|
||||||
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
|
const callback = reportNodeCallbackErrors(done)(
|
||||||
expect(logEvent).to.not.be.undefined();
|
(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
|
||||||
expect(logEvent.isRemoved).to.be.false();
|
expect(logEvent.isRemoved).to.be.false();
|
||||||
expect(logEvent.log.logIndex).to.be.equal(0);
|
expect(logEvent.log.logIndex).to.be.equal(0);
|
||||||
expect(logEvent.log.transactionIndex).to.be.equal(0);
|
expect(logEvent.log.transactionIndex).to.be.equal(0);
|
||||||
expect(logEvent.log.blockNumber).to.be.a('number');
|
expect(logEvent.log.blockNumber).to.be.a('number');
|
||||||
const args = logEvent.log.args;
|
const args = logEvent.log.args;
|
||||||
expect(args._from).to.be.equal(coinbase);
|
expect(args._from).to.be.equal(coinbase);
|
||||||
expect(args._to).to.be.equal(addressWithoutFunds);
|
expect(args._to).to.be.equal(addressWithoutFunds);
|
||||||
expect(args._value).to.be.bignumber.equal(transferAmount);
|
expect(args._value).to.be.bignumber.equal(transferAmount);
|
||||||
done();
|
},
|
||||||
};
|
);
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callback = reportNodeCallbackErrors(done)(
|
||||||
expect(logEvent).to.not.be.undefined();
|
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
expect(logEvent.isRemoved).to.be.false();
|
expect(logEvent).to.not.be.undefined();
|
||||||
const args = logEvent.log.args;
|
expect(logEvent.isRemoved).to.be.false();
|
||||||
expect(args._owner).to.be.equal(coinbase);
|
const args = logEvent.log.args;
|
||||||
expect(args._spender).to.be.equal(addressWithoutFunds);
|
expect(args._owner).to.be.equal(coinbase);
|
||||||
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
expect(args._spender).to.be.equal(addressWithoutFunds);
|
||||||
done();
|
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
||||||
};
|
},
|
||||||
zeroEx.token.subscribe(
|
);
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
|
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
};
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
zeroEx.token.subscribe(
|
},
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
|
|
||||||
);
|
);
|
||||||
const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
|
||||||
done();
|
const callbackToBeCalled = reportNodeCallbackErrors(done)();
|
||||||
};
|
|
||||||
const newProvider = web3Factory.getRpcProvider();
|
const newProvider = web3Factory.getRpcProvider();
|
||||||
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled,
|
|
||||||
);
|
|
||||||
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
};
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
|
},
|
||||||
|
);
|
||||||
const subscriptionToken = zeroEx.token.subscribe(
|
const subscriptionToken = zeroEx.token.subscribe(
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
|
tokenAddress,
|
||||||
|
TokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
|
);
|
||||||
zeroEx.token.unsubscribe(subscriptionToken);
|
zeroEx.token.unsubscribe(subscriptionToken);
|
||||||
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||||
done();
|
done();
|
||||||
@@ -450,7 +472,10 @@ describe('TokenWrapper', () => {
|
|||||||
const eventName = TokenEvents.Approval;
|
const eventName = TokenEvents.Approval;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
tokenAddress, eventName, blockRange, indexFilterValues,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@@ -465,7 +490,10 @@ describe('TokenWrapper', () => {
|
|||||||
const differentEventName = TokenEvents.Transfer;
|
const differentEventName = TokenEvents.Transfer;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.token.getLogsAsync(
|
const logs = await zeroEx.token.getLogsAsync(
|
||||||
tokenAddress, differentEventName, blockRange, indexFilterValues,
|
tokenAddress,
|
||||||
|
differentEventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(0);
|
expect(logs).to.have.length(0);
|
||||||
});
|
});
|
||||||
@@ -479,7 +507,10 @@ describe('TokenWrapper', () => {
|
|||||||
_owner: coinbase,
|
_owner: coinbase,
|
||||||
};
|
};
|
||||||
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
tokenAddress, eventName, blockRange, indexFilterValues,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@@ -487,3 +518,4 @@ describe('TokenWrapper', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// tslint:disable:max-file-line-count
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export const constants = {
|
export const constants = {
|
||||||
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
|
||||||
RPC_URL: 'http://localhost:8545/',
|
RPC_URL: 'http://localhost:8545',
|
||||||
ROPSTEN_NETWORK_ID: 3,
|
ROPSTEN_NETWORK_ID: 3,
|
||||||
KOVAN_NETWORK_ID: 42,
|
KOVAN_NETWORK_ID: 42,
|
||||||
TESTRPC_NETWORK_ID: 50,
|
TESTRPC_NETWORK_ID: 50,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
||||||
|
|
||||||
import {SignedOrder, Token, ZeroEx} from '../../src';
|
import { SignedOrder, Token, ZeroEx } from '../../src';
|
||||||
import {artifacts} from '../../src/artifacts';
|
import { artifacts } from '../../src/artifacts';
|
||||||
import {DummyTokenContract} from '../../src/contract_wrappers/generated/dummy_token';
|
import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token';
|
||||||
import {orderFactory} from '../utils/order_factory';
|
import { orderFactory } from '../utils/order_factory';
|
||||||
|
|
||||||
import {constants} from './constants';
|
import { constants } from './constants';
|
||||||
|
|
||||||
const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
|
const INITIAL_COINBASE_TOKEN_SUPPLY_IN_UNITS = new BigNumber(100);
|
||||||
|
|
||||||
@@ -17,8 +17,13 @@ export class FillScenarios {
|
|||||||
private _coinbase: string;
|
private _coinbase: string;
|
||||||
private _zrxTokenAddress: string;
|
private _zrxTokenAddress: string;
|
||||||
private _exchangeContractAddress: string;
|
private _exchangeContractAddress: string;
|
||||||
constructor(zeroEx: ZeroEx, userAddresses: string[],
|
constructor(
|
||||||
tokens: Token[], zrxTokenAddress: string, exchangeContractAddress: string) {
|
zeroEx: ZeroEx,
|
||||||
|
userAddresses: string[],
|
||||||
|
tokens: Token[],
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
exchangeContractAddress: string,
|
||||||
|
) {
|
||||||
this._zeroEx = zeroEx;
|
this._zeroEx = zeroEx;
|
||||||
this._userAddresses = userAddresses;
|
this._userAddresses = userAddresses;
|
||||||
this._tokens = tokens;
|
this._tokens = tokens;
|
||||||
@@ -31,7 +36,8 @@ export class FillScenarios {
|
|||||||
for (const token of this._tokens) {
|
for (const token of this._tokens) {
|
||||||
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
|
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
|
||||||
const contractInstance = web3Wrapper.getContractInstance(
|
const contractInstance = web3Wrapper.getContractInstance(
|
||||||
artifacts.DummyTokenArtifact.abi, token.address,
|
artifacts.DummyTokenArtifact.abi,
|
||||||
|
token.address,
|
||||||
);
|
);
|
||||||
const defaults = {};
|
const defaults = {};
|
||||||
const dummyToken = new DummyTokenContract(contractInstance, defaults);
|
const dummyToken = new DummyTokenContract(contractInstance, defaults);
|
||||||
@@ -43,61 +49,110 @@ export class FillScenarios {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async createFillableSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
public async createFillableSignedOrderAsync(
|
||||||
makerAddress: string, takerAddress: string,
|
makerTokenAddress: string,
|
||||||
fillableAmount: BigNumber,
|
takerTokenAddress: string,
|
||||||
expirationUnixTimestampSec?: BigNumber):
|
makerAddress: string,
|
||||||
Promise<SignedOrder> {
|
takerAddress: string,
|
||||||
|
fillableAmount: BigNumber,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
return this.createAsymmetricFillableSignedOrderAsync(
|
return this.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, fillableAmount, expirationUnixTimestampSec,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
fillableAmount,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async createFillableSignedOrderWithFeesAsync(
|
public async createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress: string, takerTokenAddress: string,
|
makerTokenAddress: string,
|
||||||
makerFee: BigNumber, takerFee: BigNumber,
|
takerTokenAddress: string,
|
||||||
makerAddress: string, takerAddress: string,
|
makerFee: BigNumber,
|
||||||
|
takerFee: BigNumber,
|
||||||
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
fillableAmount: BigNumber,
|
fillableAmount: BigNumber,
|
||||||
feeRecepient: string, expirationUnixTimestampSec?: BigNumber,
|
feeRecepient: string,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
): Promise<SignedOrder> {
|
): Promise<SignedOrder> {
|
||||||
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, fillableAmount, feeRecepient, expirationUnixTimestampSec,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecepient,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async createAsymmetricFillableSignedOrderAsync(
|
public async createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress: string, takerTokenAddress: string, makerAddress: string, takerAddress: string,
|
makerTokenAddress: string,
|
||||||
makerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
|
takerTokenAddress: string,
|
||||||
expirationUnixTimestampSec?: BigNumber): Promise<SignedOrder> {
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
|
makerFillableAmount: BigNumber,
|
||||||
|
takerFillableAmount: BigNumber,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
const makerFee = new BigNumber(0);
|
const makerFee = new BigNumber(0);
|
||||||
const takerFee = new BigNumber(0);
|
const takerFee = new BigNumber(0);
|
||||||
const feeRecepient = constants.NULL_ADDRESS;
|
const feeRecepient = constants.NULL_ADDRESS;
|
||||||
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
makerFillableAmount, takerFillableAmount, feeRecepient, expirationUnixTimestampSec,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerFillableAmount,
|
||||||
|
takerFillableAmount,
|
||||||
|
feeRecepient,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async createPartiallyFilledSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
public async createPartiallyFilledSignedOrderAsync(
|
||||||
takerAddress: string, fillableAmount: BigNumber,
|
makerTokenAddress: string,
|
||||||
partialFillAmount: BigNumber) {
|
takerTokenAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
|
fillableAmount: BigNumber,
|
||||||
|
partialFillAmount: BigNumber,
|
||||||
|
) {
|
||||||
const [makerAddress] = this._userAddresses;
|
const [makerAddress] = this._userAddresses;
|
||||||
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, fillableAmount,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = false;
|
const shouldThrowOnInsufficientBalanceOrAllowance = false;
|
||||||
await this._zeroEx.exchange.fillOrderAsync(
|
await this._zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, partialFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
signedOrder,
|
||||||
|
partialFillAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
return signedOrder;
|
return signedOrder;
|
||||||
}
|
}
|
||||||
private async _createAsymmetricFillableSignedOrderWithFeesAsync(
|
private async _createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress: string, takerTokenAddress: string,
|
makerTokenAddress: string,
|
||||||
makerFee: BigNumber, takerFee: BigNumber,
|
takerTokenAddress: string,
|
||||||
makerAddress: string, takerAddress: string,
|
makerFee: BigNumber,
|
||||||
makerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
|
takerFee: BigNumber,
|
||||||
feeRecepient: string, expirationUnixTimestampSec?: BigNumber): Promise<SignedOrder> {
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
|
makerFillableAmount: BigNumber,
|
||||||
|
takerFillableAmount: BigNumber,
|
||||||
|
feeRecepient: string,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
|
this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
|
||||||
this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
|
this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
|
||||||
@@ -107,14 +162,27 @@ export class FillScenarios {
|
|||||||
this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
|
this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const signedOrder = await orderFactory.createSignedOrderAsync(this._zeroEx,
|
const signedOrder = await orderFactory.createSignedOrderAsync(
|
||||||
makerAddress, takerAddress, makerFee, takerFee,
|
this._zeroEx,
|
||||||
makerFillableAmount, makerTokenAddress, takerFillableAmount, takerTokenAddress,
|
makerAddress,
|
||||||
this._exchangeContractAddress, feeRecepient, expirationUnixTimestampSec);
|
takerAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerFillableAmount,
|
||||||
|
makerTokenAddress,
|
||||||
|
takerFillableAmount,
|
||||||
|
takerTokenAddress,
|
||||||
|
this._exchangeContractAddress,
|
||||||
|
feeRecepient,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
|
);
|
||||||
return signedOrder;
|
return signedOrder;
|
||||||
}
|
}
|
||||||
private async _increaseBalanceAndAllowanceAsync(
|
private async _increaseBalanceAndAllowanceAsync(
|
||||||
tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
address: string,
|
||||||
|
amount: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
|
if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
|
||||||
return; // noop
|
return; // noop
|
||||||
}
|
}
|
||||||
@@ -123,16 +191,12 @@ export class FillScenarios {
|
|||||||
this._increaseAllowanceAsync(tokenAddress, address, amount),
|
this._increaseAllowanceAsync(tokenAddress, address, amount),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
private async _increaseBalanceAsync(
|
private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
||||||
tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
|
||||||
await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
|
await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
|
||||||
}
|
}
|
||||||
private async _increaseAllowanceAsync(
|
private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
||||||
tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
|
||||||
const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
|
const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
|
||||||
const newMakerAllowance = oldMakerAllowance.plus(amount);
|
const newMakerAllowance = oldMakerAllowance.plus(amount);
|
||||||
await this._zeroEx.token.setProxyAllowanceAsync(
|
await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
|
||||||
tokenAddress, address, newMakerAllowance,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import BigNumber from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {SignedOrder, ZeroEx} from '../../src';
|
import { SignedOrder, ZeroEx } from '../../src';
|
||||||
|
|
||||||
export const orderFactory = {
|
export const orderFactory = {
|
||||||
async createSignedOrderAsync(
|
async createSignedOrderAsync(
|
||||||
@@ -16,11 +16,12 @@ export const orderFactory = {
|
|||||||
takerTokenAddress: string,
|
takerTokenAddress: string,
|
||||||
exchangeContractAddress: string,
|
exchangeContractAddress: string,
|
||||||
feeRecipient: string,
|
feeRecipient: string,
|
||||||
expirationUnixTimestampSecIfExists?: BigNumber): Promise<SignedOrder> {
|
expirationUnixTimestampSecIfExists?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
|
const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
|
||||||
const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists) ?
|
const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
|
||||||
defaultExpirationUnixTimestampSec :
|
? defaultExpirationUnixTimestampSec
|
||||||
expirationUnixTimestampSecIfExists;
|
: expirationUnixTimestampSecIfExists;
|
||||||
const order = {
|
const order = {
|
||||||
maker,
|
maker,
|
||||||
taker,
|
taker,
|
||||||
@@ -37,7 +38,7 @@ export const orderFactory = {
|
|||||||
};
|
};
|
||||||
const orderHash = ZeroEx.getOrderHashHex(order);
|
const orderHash = ZeroEx.getOrderHashHex(order);
|
||||||
const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker);
|
const ecSignature = await zeroEx.signOrderHashAsync(orderHash, maker);
|
||||||
const signedOrder: SignedOrder = _.assign(order, {ecSignature});
|
const signedOrder: SignedOrder = _.assign(order, { ecSignature });
|
||||||
return signedOrder;
|
return signedOrder;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
import {DoneCallback} from '../../src/types';
|
import * as chai from 'chai';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
export const reportCallbackErrors = (done: DoneCallback) => {
|
import { DoneCallback } from '../../src/types';
|
||||||
return (f: (...args: any[]) => void) => {
|
|
||||||
const wrapped = async (...args: any[]) => {
|
const expect = chai.expect;
|
||||||
|
|
||||||
|
export const reportNoErrorCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
|
||||||
|
return <T>(f?: (value: T) => void) => {
|
||||||
|
const wrapped = (value: T) => {
|
||||||
|
if (_.isUndefined(f)) {
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
f(...args);
|
f(value);
|
||||||
|
if (expectToBeCalledOnce) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
done(err);
|
done(err);
|
||||||
}
|
}
|
||||||
@@ -12,3 +24,43 @@ export const reportCallbackErrors = (done: DoneCallback) => {
|
|||||||
return wrapped;
|
return wrapped;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const reportNodeCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
|
||||||
|
return <T>(f?: (value: T) => void) => {
|
||||||
|
const wrapped = (error: Error | null, value: T | undefined) => {
|
||||||
|
if (!_.isNull(error)) {
|
||||||
|
done(error);
|
||||||
|
} else {
|
||||||
|
if (_.isUndefined(f)) {
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f(value as T);
|
||||||
|
if (expectToBeCalledOnce) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return wrapped;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const assertNodeCallbackError = (done: DoneCallback, errMsg: string) => {
|
||||||
|
const wrapped = <T>(error: Error | null, value: T | undefined) => {
|
||||||
|
if (_.isNull(error)) {
|
||||||
|
done(new Error('Expected callback to receive an error'));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
expect(error.message).to.be.equal(errMsg);
|
||||||
|
done();
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return wrapped;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {JSONRPCPayload} from '../../../src/types';
|
import { JSONRPCPayload } from '../../../src/types';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class implements the web3-provider-engine subprovider interface and returns
|
* This class implements the web3-provider-engine subprovider interface and returns
|
||||||
@@ -8,7 +8,7 @@ import {JSONRPCPayload} from '../../../src/types';
|
|||||||
export class EmptyWalletSubprovider {
|
export class EmptyWalletSubprovider {
|
||||||
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
||||||
// tslint:disable-next-line:prefer-function-over-method
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
|
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
|
||||||
switch (payload.method) {
|
switch (payload.method) {
|
||||||
case 'eth_accounts':
|
case 'eth_accounts':
|
||||||
end(null, []);
|
end(null, []);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {JSONRPCPayload} from '../../../src/types';
|
import { JSONRPCPayload } from '../../../src/types';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class implements the web3-provider-engine subprovider interface and returns
|
* This class implements the web3-provider-engine subprovider interface and returns
|
||||||
@@ -15,7 +15,7 @@ export class FakeGasEstimateSubprovider {
|
|||||||
}
|
}
|
||||||
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
// This method needs to be here to satisfy the interface but linter wants it to be static.
|
||||||
// tslint:disable-next-line:prefer-function-over-method
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) {
|
public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error | null, result: any) => void) {
|
||||||
switch (payload.method) {
|
switch (payload.method) {
|
||||||
case 'eth_estimateGas':
|
case 'eth_estimateGas':
|
||||||
end(null, this._constantGasAmount);
|
end(null, this._constantGasAmount);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {InternalZeroExError, Token} from '../../src/types';
|
import { InternalZeroExError, Token } from '../../src/types';
|
||||||
|
|
||||||
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
|
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
|
||||||
const WETH_TOKEN_SYMBOL = 'WETH';
|
const WETH_TOKEN_SYMBOL = 'WETH';
|
||||||
@@ -11,14 +11,14 @@ export class TokenUtils {
|
|||||||
this._tokens = tokens;
|
this._tokens = tokens;
|
||||||
}
|
}
|
||||||
public getProtocolTokenOrThrow(): Token {
|
public getProtocolTokenOrThrow(): Token {
|
||||||
const zrxToken = _.find(this._tokens, {symbol: PROTOCOL_TOKEN_SYMBOL});
|
const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
|
||||||
if (_.isUndefined(zrxToken)) {
|
if (_.isUndefined(zrxToken)) {
|
||||||
throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
|
throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
|
||||||
}
|
}
|
||||||
return zrxToken;
|
return zrxToken;
|
||||||
}
|
}
|
||||||
public getWethTokenOrThrow(): Token {
|
public getWethTokenOrThrow(): Token {
|
||||||
const wethToken = _.find(this._tokens, {symbol: WETH_TOKEN_SYMBOL});
|
const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
|
||||||
if (_.isUndefined(wethToken)) {
|
if (_.isUndefined(wethToken)) {
|
||||||
throw new Error(InternalZeroExError.WethNotInTokenRegistry);
|
throw new Error(InternalZeroExError.WethNotInTokenRegistry);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
import ProviderEngine = require('web3-provider-engine');
|
import ProviderEngine = require('web3-provider-engine');
|
||||||
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
||||||
|
|
||||||
import {EmptyWalletSubprovider} from './subproviders/empty_wallet_subprovider';
|
import { EmptyWalletSubprovider } from './subproviders/empty_wallet_subprovider';
|
||||||
import {FakeGasEstimateSubprovider} from './subproviders/fake_gas_estimate_subprovider';
|
import { FakeGasEstimateSubprovider } from './subproviders/fake_gas_estimate_subprovider';
|
||||||
|
|
||||||
import {constants} from './constants';
|
import { constants } from './constants';
|
||||||
|
|
||||||
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
|
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
|
||||||
// because they are using the wrong XHR package.
|
// because they are using the wrong XHR package.
|
||||||
@@ -31,9 +31,11 @@ export const web3Factory = {
|
|||||||
provider.addProvider(new EmptyWalletSubprovider());
|
provider.addProvider(new EmptyWalletSubprovider());
|
||||||
}
|
}
|
||||||
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
|
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
|
||||||
provider.addProvider(new RpcSubprovider({
|
provider.addProvider(
|
||||||
rpcUrl: constants.RPC_URL,
|
new RpcSubprovider({
|
||||||
}));
|
rpcUrl: constants.RPC_URL,
|
||||||
|
}),
|
||||||
|
);
|
||||||
provider.start();
|
provider.start();
|
||||||
return provider;
|
return provider;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"extends": "../../tsconfig",
|
||||||
"module": "commonjs",
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"outDir": "lib",
|
||||||
"lib": [ "es2015", "dom" ],
|
"noImplicitThis": false
|
||||||
"outDir": "lib",
|
},
|
||||||
"sourceMap": true,
|
"include": [
|
||||||
"declaration": true,
|
"./src/**/*",
|
||||||
"noImplicitAny": true,
|
"./test/**/*",
|
||||||
"experimentalDecorators": true,
|
"../../node_modules/types-bn/index.d.ts",
|
||||||
"strictNullChecks": true
|
"../../node_modules/types-ethereumjs-util/index.d.ts",
|
||||||
},
|
"../../node_modules/web3-typescript-typings/index.d.ts",
|
||||||
"include": [
|
"../../node_modules/chai-typescript-typings/index.d.ts",
|
||||||
"./src/**/*",
|
"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
|
||||||
"./test/**/*",
|
]
|
||||||
"../../node_modules/types-bn/index.d.ts",
|
|
||||||
"../../node_modules/types-ethereumjs-util/index.d.ts",
|
|
||||||
"../../node_modules/web3-typescript-typings/index.d.ts",
|
|
||||||
"../../node_modules/chai-typescript-typings/index.d.ts",
|
|
||||||
"../../node_modules/chai-as-promised-typescript-typings/index.d.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": ["@0xproject/tslint-config"]
|
||||||
"@0xproject/tslint-config"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ const path = require('path');
|
|||||||
const production = process.env.NODE_ENV === 'production';
|
const production = process.env.NODE_ENV === 'production';
|
||||||
|
|
||||||
let entry = {
|
let entry = {
|
||||||
'index': './src/index.ts',
|
index: './src/index.ts',
|
||||||
};
|
};
|
||||||
if (production) {
|
if (production) {
|
||||||
entry = _.assign({}, entry, {'index.min': './src/index.ts'});
|
entry = _.assign({}, entry, { 'index.min': './src/index.ts' });
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
vx.x.x
|
## v0.1.0 - _January 11, 2018_
|
||||||
------------------------
|
|
||||||
|
* Fixed array typings with union types (#295)
|
||||||
|
* Add event ABIs to context data passed to templates (#302)
|
||||||
|
* Add constructor ABIs to context data passed to templates (#304)
|
||||||
|
|||||||
@@ -8,8 +8,11 @@ For an example of the generated [wrapper files](https://github.com/0xProject/0x.
|
|||||||
[Here](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files.
|
[Here](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
`yarn add -g @0xproject/abi-gen`
|
`yarn add -g @0xproject/abi-gen`
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
abi-gen
|
abi-gen
|
||||||
Options:
|
Options:
|
||||||
@@ -19,8 +22,10 @@ Options:
|
|||||||
--templates Folder where to search for templates [string] [required]
|
--templates Folder where to search for templates [string] [required]
|
||||||
--output Folder where to put the output files [string] [required]
|
--output Folder where to put the output files [string] [required]
|
||||||
```
|
```
|
||||||
|
|
||||||
## ABI files
|
## ABI files
|
||||||
You're required to pass a [glob](https://en.wikipedia.org/wiki/Glob_(programming)) template where your abi files are located.
|
|
||||||
|
You're required to pass a [glob](<https://en.wikipedia.org/wiki/Glob_(programming)>) template where your abi files are located.
|
||||||
TL;DR - here is the example from 0x.js.
|
TL;DR - here is the example from 0x.js.
|
||||||
|
|
||||||
`--abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry).json`
|
`--abiGlob 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry).json`
|
||||||
@@ -28,12 +33,18 @@ TL;DR - here is the example from 0x.js.
|
|||||||
We could've just used `--abiGlob 'src/artifacts/*.json` but we wanted to exclude some of the abi files.
|
We could've just used `--abiGlob 'src/artifacts/*.json` but we wanted to exclude some of the abi files.
|
||||||
|
|
||||||
The abi file should be either a [Truffle](http://truffleframework.com/) contract artifact (a JSON object with an abi key) or a JSON abi array.
|
The abi file should be either a [Truffle](http://truffleframework.com/) contract artifact (a JSON object with an abi key) or a JSON abi array.
|
||||||
|
|
||||||
## How to write custom templates?
|
## How to write custom templates?
|
||||||
|
|
||||||
The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) and start adjusting them for your needs.
|
The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x.js/tree/development/packages/0x.js/contract_templates) and start adjusting them for your needs.
|
||||||
We use [handlebars](http://handlebarsjs.com/) template engine under the hood.
|
We use [handlebars](http://handlebarsjs.com/) template engine under the hood.
|
||||||
You need to have a master template called `contract.mustache`. it will be used to generate each contract wrapper. Although - you don't need and probably shouldn't write all your logic in a single template file. You can write [partial templates](http://handlebarsjs.com/partials.html) and as long as they are within a partials folder - they will be registered and available.
|
You need to have a master template called `contract.mustache`. it will be used to generate each contract wrapper. Although - you don't need and probably shouldn't write all your logic in a single template file. You can write [partial templates](http://handlebarsjs.com/partials.html) and as long as they are within a partials folder - they will be registered and available.
|
||||||
|
|
||||||
## Which data/context do I get in my templates?
|
## Which data/context do I get in my templates?
|
||||||
|
|
||||||
For now you don't get much on top of methods abi, some useful helpers and a contract name because it was enough for our use-case, but if you need something else - create a PR.
|
For now you don't get much on top of methods abi, some useful helpers and a contract name because it was enough for our use-case, but if you need something else - create a PR.
|
||||||
See the [type definition](https://github.com/0xProject/0x.js/tree/development/packages/abi-gen/src/types.ts) of what we pass to the render method.
|
See the [type definition](https://github.com/0xProject/0x.js/tree/development/packages/abi-gen/src/types.ts) of what we pass to the render method.
|
||||||
|
|
||||||
## Output files
|
## Output files
|
||||||
|
|
||||||
Output files will be generated within an output folder with names converted to camel case and taken from abi file names. If you already have some files in that folder they will be overwritten.
|
Output files will be generated within an output folder with names converted to camel case and taken from abi file names. If you already have some files in that folder they will be overwritten.
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/abi-gen",
|
"name": "@0xproject/abi-gen",
|
||||||
"version": "0.0.4",
|
"version": "0.1.2",
|
||||||
"description": "Generate contract wrappers from ABI and handlebars templates",
|
"description": "Generate contract wrappers from ABI and handlebars templates",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "tslint --project . 'src/**/*.ts'",
|
"lint": "tslint --project . 'src/**/*.ts'",
|
||||||
"clean": "shx rm -rf lib",
|
"clean": "shx rm -rf lib",
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"abi-gen": "lib/index.js"
|
"abi-gen": "lib/index.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js.git"
|
"url": "https://github.com/0xProject/0x.js.git"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/0xProject/0x.js/issues"
|
"url": "https://github.com/0xProject/0x.js/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
|
"homepage": "https://github.com/0xProject/0x.js/packages/abi-gen/README.md",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bignumber.js": "~4.1.0",
|
"@0xproject/utils": "^0.2.0",
|
||||||
"chalk": "^2.3.0",
|
"chalk": "^2.3.0",
|
||||||
"glob": "^7.1.2",
|
"glob": "^7.1.2",
|
||||||
"handlebars": "^4.0.11",
|
"handlebars": "^4.0.11",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"to-snake-case": "^1.0.0",
|
"to-snake-case": "^1.0.0",
|
||||||
"web3": "^0.20.0",
|
"web3": "^0.20.0",
|
||||||
"yargs": "^10.0.3"
|
"yargs": "^10.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.4.0",
|
"@0xproject/tslint-config": "^0.4.2",
|
||||||
"@types/glob": "^5.0.33",
|
"@types/glob": "^5.0.33",
|
||||||
"@types/handlebars": "^4.0.36",
|
"@types/handlebars": "^4.0.36",
|
||||||
"@types/mkdirp": "^0.5.1",
|
"@types/mkdirp": "^0.5.1",
|
||||||
"@types/node": "^8.0.53",
|
"@types/node": "^8.0.53",
|
||||||
"@types/yargs": "^10.0.0",
|
"@types/yargs": "^10.0.0",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"typescript": "~2.6.1",
|
"typescript": "~2.6.1",
|
||||||
"web3-typescript-typings": "^0.7.2"
|
"web3-typescript-typings": "^0.9.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ const packageJSON = require('../package.json');
|
|||||||
|
|
||||||
const subPackageName = packageJSON.name;
|
const subPackageName = packageJSON.name;
|
||||||
|
|
||||||
postpublish_utils.getLatestTagAndVersionAsync(subPackageName)
|
postpublish_utils
|
||||||
|
.getLatestTagAndVersionAsync(subPackageName)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
const releaseName = postpublish_utils.getReleaseName(subPackageName, result.version);
|
const releaseName = postpublish_utils.getReleaseName(subPackageName, result.version);
|
||||||
const assets = [];
|
const assets = [];
|
||||||
return postpublish_utils.publishReleaseNotes(result.tag, releaseName, assets);
|
return postpublish_utils.publishReleaseNotes(result.tag, releaseName, assets);
|
||||||
})
|
})
|
||||||
.catch (function(err) {
|
.catch(function(err) {
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {sync as globSync} from 'glob';
|
import { sync as globSync } from 'glob';
|
||||||
import * as Handlebars from 'handlebars';
|
import * as Handlebars from 'handlebars';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as mkdirp from 'mkdirp';
|
import * as mkdirp from 'mkdirp';
|
||||||
@@ -11,10 +11,12 @@ import * as yargs from 'yargs';
|
|||||||
import toSnakeCase = require('to-snake-case');
|
import toSnakeCase = require('to-snake-case');
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {ContextData, ParamKind} from './types';
|
import { ContextData, ParamKind } from './types';
|
||||||
import {utils} from './utils';
|
import { utils } from './utils';
|
||||||
|
|
||||||
|
const ABI_TYPE_CONSTRUCTOR = 'constructor';
|
||||||
const ABI_TYPE_METHOD = 'function';
|
const ABI_TYPE_METHOD = 'function';
|
||||||
|
const ABI_TYPE_EVENT = 'event';
|
||||||
const MAIN_TEMPLATE_NAME = 'contract.mustache';
|
const MAIN_TEMPLATE_NAME = 'contract.mustache';
|
||||||
|
|
||||||
const args = yargs
|
const args = yargs
|
||||||
@@ -32,8 +34,7 @@ const args = yargs
|
|||||||
describe: 'Folder where to put the output files',
|
describe: 'Folder where to put the output files',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
demand: true,
|
demand: true,
|
||||||
})
|
}).argv;
|
||||||
.argv;
|
|
||||||
|
|
||||||
function writeOutputFile(name: string, renderedTsCode: string): void {
|
function writeOutputFile(name: string, renderedTsCode: string): void {
|
||||||
const fileName = toSnakeCase(name);
|
const fileName = toSnakeCase(name);
|
||||||
@@ -66,14 +67,20 @@ for (const abiFileName of abiFileNames) {
|
|||||||
const namedContent = utils.getNamedContent(abiFileName);
|
const namedContent = utils.getNamedContent(abiFileName);
|
||||||
utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
|
utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
|
||||||
const parsedContent = JSON.parse(namedContent.content);
|
const parsedContent = JSON.parse(namedContent.content);
|
||||||
const ABI = _.isArray(parsedContent) ?
|
const ABI = _.isArray(parsedContent)
|
||||||
parsedContent : // ABI file
|
? parsedContent // ABI file
|
||||||
parsedContent.abi; // Truffle contracts file
|
: parsedContent.abi; // Truffle contracts file
|
||||||
if (_.isUndefined(ABI)) {
|
if (_.isUndefined(ABI)) {
|
||||||
utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
|
utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
|
||||||
utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
|
utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ctor = ABI.find((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as Web3.ConstructorAbi;
|
||||||
|
if (_.isUndefined(ctor)) {
|
||||||
|
ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
|
||||||
|
}
|
||||||
|
|
||||||
const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[];
|
const methodAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_METHOD) as Web3.MethodAbi[];
|
||||||
const methodsData = _.map(methodAbis, methodAbi => {
|
const methodsData = _.map(methodAbis, methodAbi => {
|
||||||
_.map(methodAbi.inputs, input => {
|
_.map(methodAbi.inputs, input => {
|
||||||
@@ -89,9 +96,14 @@ for (const abiFileName of abiFileNames) {
|
|||||||
};
|
};
|
||||||
return methodData;
|
return methodData;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const eventAbis = ABI.filter((abi: Web3.AbiDefinition) => abi.type === ABI_TYPE_EVENT) as Web3.EventAbi[];
|
||||||
|
|
||||||
const contextData = {
|
const contextData = {
|
||||||
contractName: namedContent.name,
|
contractName: namedContent.name,
|
||||||
|
ctor,
|
||||||
methods: methodsData,
|
methods: methodsData,
|
||||||
|
events: eventAbis,
|
||||||
};
|
};
|
||||||
const renderedTsCode = template(contextData);
|
const renderedTsCode = template(contextData);
|
||||||
writeOutputFile(namedContent.name, renderedTsCode);
|
writeOutputFile(namedContent.name, renderedTsCode);
|
||||||
|
|||||||
@@ -5,6 +5,13 @@ export enum ParamKind {
|
|||||||
Output = 'output',
|
Output = 'output',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum AbiType {
|
||||||
|
Function = 'function',
|
||||||
|
Constructor = 'constructor',
|
||||||
|
Event = 'event',
|
||||||
|
Fallback = 'fallback',
|
||||||
|
}
|
||||||
|
|
||||||
export interface Method extends Web3.MethodAbi {
|
export interface Method extends Web3.MethodAbi {
|
||||||
singleReturnValue: boolean;
|
singleReturnValue: boolean;
|
||||||
}
|
}
|
||||||
@@ -12,4 +19,5 @@ export interface Method extends Web3.MethodAbi {
|
|||||||
export interface ContextData {
|
export interface ContextData {
|
||||||
contractName: string;
|
contractName: string;
|
||||||
methods: Method[];
|
methods: Method[];
|
||||||
|
events: Web3.EventAbi[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {ParamKind} from './types';
|
import { AbiType, ParamKind } from './types';
|
||||||
|
|
||||||
export const utils = {
|
export const utils = {
|
||||||
solTypeToTsType(paramKind: ParamKind, solType: string): string {
|
solTypeToTsType(paramKind: ParamKind, solType: string): string {
|
||||||
@@ -10,23 +11,28 @@ export const utils = {
|
|||||||
if (solType.match(trailingArrayRegex)) {
|
if (solType.match(trailingArrayRegex)) {
|
||||||
const arrayItemSolType = solType.replace(trailingArrayRegex, '');
|
const arrayItemSolType = solType.replace(trailingArrayRegex, '');
|
||||||
const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
|
const arrayItemTsType = utils.solTypeToTsType(paramKind, arrayItemSolType);
|
||||||
const arrayTsType = `${arrayItemTsType}[]`;
|
const arrayTsType = utils.isUnionType(arrayItemTsType)
|
||||||
|
? `Array<${arrayItemTsType}>`
|
||||||
|
: `${arrayItemTsType}[]`;
|
||||||
return arrayTsType;
|
return arrayTsType;
|
||||||
} else {
|
} else {
|
||||||
const solTypeRegexToTsType = [
|
const solTypeRegexToTsType = [
|
||||||
{regex: '^string$', tsType: 'string'},
|
{ regex: '^string$', tsType: 'string' },
|
||||||
{regex: '^address$', tsType: 'string'},
|
{ regex: '^address$', tsType: 'string' },
|
||||||
{regex: '^bool$', tsType: 'boolean'},
|
{ regex: '^bool$', tsType: 'boolean' },
|
||||||
{regex: '^u?int\\d*$', tsType: 'BigNumber'},
|
{ regex: '^u?int\\d*$', tsType: 'BigNumber' },
|
||||||
{regex: '^bytes\\d*$', tsType: 'string'},
|
{ regex: '^bytes\\d*$', tsType: 'string' },
|
||||||
];
|
];
|
||||||
if (paramKind === ParamKind.Input) {
|
if (paramKind === ParamKind.Input) {
|
||||||
// web3 allows to pass those an non-bignumbers and that's nice
|
// web3 allows to pass those an non-bignumbers and that's nice
|
||||||
// but it always returns stuff as BigNumbers
|
// but it always returns stuff as BigNumbers
|
||||||
solTypeRegexToTsType.unshift({regex: '^u?int(8|16|32)?$', tsType: 'number|BigNumber'});
|
solTypeRegexToTsType.unshift({
|
||||||
|
regex: '^u?int(8|16|32)?$',
|
||||||
|
tsType: 'number|BigNumber',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
for (const regexAndTxType of solTypeRegexToTsType) {
|
for (const regexAndTxType of solTypeRegexToTsType) {
|
||||||
const {regex, tsType} = regexAndTxType;
|
const { regex, tsType } = regexAndTxType;
|
||||||
if (solType.match(regex)) {
|
if (solType.match(regex)) {
|
||||||
return tsType;
|
return tsType;
|
||||||
}
|
}
|
||||||
@@ -34,6 +40,9 @@ export const utils = {
|
|||||||
throw new Error(`Unknown Solidity type found: ${solType}`);
|
throw new Error(`Unknown Solidity type found: ${solType}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isUnionType(tsType: string): boolean {
|
||||||
|
return tsType === 'number|BigNumber';
|
||||||
|
},
|
||||||
log(...args: any[]): void {
|
log(...args: any[]): void {
|
||||||
console.log(...args); // tslint:disable-line:no-console
|
console.log(...args); // tslint:disable-line:no-console
|
||||||
},
|
},
|
||||||
@@ -41,7 +50,7 @@ export const utils = {
|
|||||||
const name = path.parse(filename).name;
|
const name = path.parse(filename).name;
|
||||||
return name;
|
return name;
|
||||||
},
|
},
|
||||||
getNamedContent(filename: string): {name: string; content: string} {
|
getNamedContent(filename: string): { name: string; content: string } {
|
||||||
const name = utils.getPartialNameFromFileName(filename);
|
const name = utils.getPartialNameFromFileName(filename);
|
||||||
try {
|
try {
|
||||||
const content = fs.readFileSync(filename).toString();
|
const content = fs.readFileSync(filename).toString();
|
||||||
@@ -53,4 +62,12 @@ export const utils = {
|
|||||||
throw new Error(`Failed to read ${filename}: ${err}`);
|
throw new Error(`Failed to read ${filename}: ${err}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getEmptyConstructor(): Web3.ConstructorAbi {
|
||||||
|
return {
|
||||||
|
type: AbiType.Constructor,
|
||||||
|
stateMutability: 'nonpayable',
|
||||||
|
payable: false,
|
||||||
|
inputs: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"extends": "../../tsconfig",
|
||||||
"module": "commonjs",
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"outDir": "lib"
|
||||||
"lib": ["es2015", "dom"],
|
},
|
||||||
"outDir": "lib",
|
"include": ["./src/**/*", "./test/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
|
||||||
"sourceMap": true,
|
|
||||||
"declaration": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"strictNullChecks": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"./src/**/*",
|
|
||||||
"./test/**/*",
|
|
||||||
"../../node_modules/web3-typescript-typings/index.d.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": ["@0xproject/tslint-config"]
|
||||||
"@0xproject/tslint-config"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
v0.0.4 - _Nov. 14, 2017_
|
## v0.0.4 - _Nov. 14, 2017_
|
||||||
------------------------
|
|
||||||
* Re-publish Assert previously published under NPM package @0xproject/0x-assert
|
* Re-publish Assert previously published under NPM package @0xproject/0x-assert
|
||||||
* Added assertion isValidBaseUnitAmount which checks both that the value is a valid bigNumber and that it does not contain decimals.
|
* Added assertion isValidBaseUnitAmount which checks both that the value is a valid bigNumber and that it does not contain decimals.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
@0xproject/assert
|
## @0xproject/assert
|
||||||
------
|
|
||||||
|
|
||||||
Standard type and schema assertions to be used across all 0x projects and packages
|
Standard type and schema assertions to be used across all 0x projects and packages
|
||||||
|
|
||||||
@@ -12,7 +11,7 @@ yarn add @0xproject/assert
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import {assert} from '@0xproject/assert';
|
import { assert } from '@0xproject/assert';
|
||||||
|
|
||||||
assert.isValidBaseUnitAmount('baseUnitAmount', baseUnitAmount);
|
assert.isValidBaseUnitAmount('baseUnitAmount', baseUnitAmount);
|
||||||
```
|
```
|
||||||
@@ -26,11 +25,13 @@ Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting
|
|||||||
### Install Dependencies
|
### Install Dependencies
|
||||||
|
|
||||||
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
|
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn config set workspaces-experimental true
|
yarn config set workspaces-experimental true
|
||||||
```
|
```
|
||||||
|
|
||||||
Then install dependencies
|
Then install dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
yarn install
|
yarn install
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,46 +1,45 @@
|
|||||||
{
|
{
|
||||||
"name": "@0xproject/assert",
|
"name": "@0xproject/assert",
|
||||||
"version": "0.0.9",
|
"version": "0.0.11",
|
||||||
"description": "Provides a standard way of performing type and schema validation across 0x projects",
|
"description": "Provides a standard way of performing type and schema validation across 0x projects",
|
||||||
"main": "lib/src/index.js",
|
"main": "lib/src/index.js",
|
||||||
"types": "lib/src/index.d.ts",
|
"types": "lib/src/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"clean": "shx rm -rf _bundles lib test_temp",
|
"clean": "shx rm -rf _bundles lib test_temp",
|
||||||
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
|
||||||
"run_mocha": "mocha lib/test/**/*_test.js",
|
"run_mocha": "mocha lib/test/**/*_test.js",
|
||||||
"prepublishOnly": "run-p build",
|
"prepublishOnly": "run-p build",
|
||||||
"test": "run-s clean build run_mocha",
|
"test": "run-s clean build run_mocha",
|
||||||
"test:circleci": "yarn test"
|
"test:circleci": "yarn test"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/0xProject/0x.js.git"
|
"url": "https://github.com/0xProject/0x.js.git"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/0xProject/0x.js/issues"
|
"url": "https://github.com/0xProject/0x.js/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
|
"homepage": "https://github.com/0xProject/0x.js/packages/assert/README.md",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0xproject/tslint-config": "^0.4.0",
|
"@0xproject/tslint-config": "^0.4.2",
|
||||||
"@types/lodash": "^4.14.86",
|
"@types/lodash": "^4.14.86",
|
||||||
"@types/mocha": "^2.2.42",
|
"@types/mocha": "^2.2.42",
|
||||||
"@types/valid-url": "^1.0.2",
|
"@types/valid-url": "^1.0.2",
|
||||||
"chai": "^4.0.1",
|
"chai": "^4.0.1",
|
||||||
"chai-typescript-typings": "^0.0.1",
|
"chai-typescript-typings": "^0.0.2",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"mocha": "^4.0.1",
|
"mocha": "^4.0.1",
|
||||||
"npm-run-all": "^4.1.2",
|
"npm-run-all": "^4.1.2",
|
||||||
"shx": "^0.2.2",
|
"shx": "^0.2.2",
|
||||||
"tslint": "5.8.0",
|
"tslint": "5.8.0",
|
||||||
"typescript": "~2.6.1"
|
"typescript": "~2.6.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0xproject/json-schemas": "^0.7.1",
|
"@0xproject/json-schemas": "^0.7.3",
|
||||||
"@0xproject/utils": "^0.1.2",
|
"@0xproject/utils": "^0.2.0",
|
||||||
"bignumber.js": "~4.1.0",
|
"lodash": "^4.17.4",
|
||||||
"lodash": "^4.17.4",
|
"valid-url": "^1.0.9"
|
||||||
"valid-url": "^1.0.9"
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ const packageJSON = require('../package.json');
|
|||||||
|
|
||||||
const subPackageName = packageJSON.name;
|
const subPackageName = packageJSON.name;
|
||||||
|
|
||||||
postpublish_utils.getLatestTagAndVersionAsync(subPackageName)
|
postpublish_utils
|
||||||
|
.getLatestTagAndVersionAsync(subPackageName)
|
||||||
.then(function(result) {
|
.then(function(result) {
|
||||||
const releaseName = postpublish_utils.getReleaseName(subPackageName, result.version);
|
const releaseName = postpublish_utils.getReleaseName(subPackageName, result.version);
|
||||||
const assets = [];
|
const assets = [];
|
||||||
return postpublish_utils.publishReleaseNotes(result.tag, releaseName, assets);
|
return postpublish_utils.publishReleaseNotes(result.tag, releaseName, assets);
|
||||||
})
|
})
|
||||||
.catch (function(err) {
|
.catch(function(err) {
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import {
|
import { Schema, SchemaValidator } from '@0xproject/json-schemas';
|
||||||
Schema,
|
import { addressUtils, BigNumber } from '@0xproject/utils';
|
||||||
SchemaValidator,
|
|
||||||
} from '@0xproject/json-schemas';
|
|
||||||
import {addressUtils} from '@0xproject/utils';
|
|
||||||
import BigNumber from 'bignumber.js';
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as validUrl from 'valid-url';
|
import * as validUrl from 'valid-url';
|
||||||
|
|
||||||
@@ -16,14 +12,14 @@ export const assert = {
|
|||||||
},
|
},
|
||||||
isValidBaseUnitAmount(variableName: string, value: BigNumber) {
|
isValidBaseUnitAmount(variableName: string, value: BigNumber) {
|
||||||
assert.isBigNumber(variableName, value);
|
assert.isBigNumber(variableName, value);
|
||||||
|
const isNegative = value.lessThan(0);
|
||||||
|
this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
|
||||||
const hasDecimals = value.decimalPlaces() !== 0;
|
const hasDecimals = value.decimalPlaces() !== 0;
|
||||||
this.assert(
|
this.assert(
|
||||||
!hasDecimals, `${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
|
!hasDecimals,
|
||||||
|
`${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
isUndefined(value: any, variableName?: string): void {
|
|
||||||
this.assert(_.isUndefined(value), this.typeAssertionMessage(variableName, 'undefined', value));
|
|
||||||
},
|
|
||||||
isString(variableName: string, value: string): void {
|
isString(variableName: string, value: string): void {
|
||||||
this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
|
this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
|
||||||
},
|
},
|
||||||
@@ -31,8 +27,10 @@ export const assert = {
|
|||||||
this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value));
|
this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value));
|
||||||
},
|
},
|
||||||
isHexString(variableName: string, value: string): void {
|
isHexString(variableName: string, value: string): void {
|
||||||
this.assert(_.isString(value) && HEX_REGEX.test(value),
|
this.assert(
|
||||||
this.typeAssertionMessage(variableName, 'HexString', value));
|
_.isString(value) && HEX_REGEX.test(value),
|
||||||
|
this.typeAssertionMessage(variableName, 'HexString', value),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
isETHAddressHex(variableName: string, value: string): void {
|
isETHAddressHex(variableName: string, value: string): void {
|
||||||
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
|
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
|
||||||
@@ -41,8 +39,11 @@ export const assert = {
|
|||||||
`Checksummed addresses are not supported. Convert ${variableName} to lower case before passing`,
|
`Checksummed addresses are not supported. Convert ${variableName} to lower case before passing`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
doesBelongToStringEnum(variableName: string, value: string,
|
doesBelongToStringEnum(
|
||||||
stringEnum: any /* There is no base type for every string enum */): void {
|
variableName: string,
|
||||||
|
value: string,
|
||||||
|
stringEnum: any /* There is no base type for every string enum */,
|
||||||
|
): void {
|
||||||
const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]);
|
const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]);
|
||||||
const enumValues = _.keys(stringEnum);
|
const enumValues = _.keys(stringEnum);
|
||||||
const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`);
|
const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`);
|
||||||
@@ -62,7 +63,7 @@ export const assert = {
|
|||||||
this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value));
|
this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value));
|
||||||
},
|
},
|
||||||
isWeb3Provider(variableName: string, value: any): void {
|
isWeb3Provider(variableName: string, value: any): void {
|
||||||
const isWeb3Provider = _.isFunction((value).send) || _.isFunction((value).sendAsync);
|
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
|
||||||
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
|
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
|
||||||
},
|
},
|
||||||
doesConformToSchema(variableName: string, value: any, schema: Schema): void {
|
doesConformToSchema(variableName: string, value: any, schema: Schema): void {
|
||||||
@@ -75,11 +76,11 @@ Validation errors: ${validationResult.errors.join(', ')}`;
|
|||||||
this.assert(!hasValidationErrors, msg);
|
this.assert(!hasValidationErrors, msg);
|
||||||
},
|
},
|
||||||
isHttpUrl(variableName: string, value: any): void {
|
isHttpUrl(variableName: string, value: any): void {
|
||||||
const isValidUrl = validUrl.isWebUri(value);
|
const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
|
||||||
this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
|
this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'http url', value));
|
||||||
},
|
},
|
||||||
isUri(variableName: string, value: any): void {
|
isUri(variableName: string, value: any): void {
|
||||||
const isValidUri = validUrl.isUri(value);
|
const isValidUri = !_.isUndefined(validUrl.isUri(value));
|
||||||
this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
|
this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
|
||||||
},
|
},
|
||||||
assert(condition: boolean, message: string): void {
|
assert(condition: boolean, message: string): void {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {schemas} from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import {BigNumber} from 'bignumber.js';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import * as dirtyChai from 'dirty-chai';
|
import * as dirtyChai from 'dirty-chai';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import {assert} from '../src/index';
|
import { assert } from '../src/index';
|
||||||
|
|
||||||
chai.config.includeStack = true;
|
chai.config.includeStack = true;
|
||||||
chai.use(dirtyChai);
|
chai.use(dirtyChai);
|
||||||
@@ -14,75 +14,45 @@ describe('Assertions', () => {
|
|||||||
const variableName = 'variable';
|
const variableName = 'variable';
|
||||||
describe('#isBigNumber', () => {
|
describe('#isBigNumber', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [new BigNumber(23), new BigNumber('45')];
|
||||||
new BigNumber(23),
|
|
||||||
new BigNumber('45'),
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = ['test', 42, false, { random: 'test' }, undefined];
|
||||||
'test',
|
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isUndefined', () => {
|
describe('#isValidBaseUnitAmount', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [new BigNumber(23), new BigNumber('45000000')];
|
||||||
undefined,
|
validInputs.forEach(input =>
|
||||||
];
|
expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.not.throw(),
|
||||||
validInputs.forEach(input => expect(assert.isUndefined.bind(assert, input, variableName)).to.not.throw());
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [0, undefined, new BigNumber(3.145), 3.145, new BigNumber(-400)];
|
||||||
'test',
|
invalidInputs.forEach(input =>
|
||||||
42,
|
expect(assert.isValidBaseUnitAmount.bind(assert, variableName, input)).to.throw(),
|
||||||
false,
|
);
|
||||||
{random: 'test'},
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isUndefined.bind(assert, input, variableName)).to.throw());
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isString', () => {
|
describe('#isString', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = ['hello', 'goodbye'];
|
||||||
'hello',
|
|
||||||
'goodbye',
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isFunction', () => {
|
describe('#isFunction', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [BigNumber, assert.isString];
|
||||||
BigNumber,
|
|
||||||
assert.isString.bind(this),
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -98,7 +68,7 @@ describe('Assertions', () => {
|
|||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
42,
|
42,
|
||||||
false,
|
false,
|
||||||
{random: 'test'},
|
{ random: 'test' },
|
||||||
undefined,
|
undefined,
|
||||||
new BigNumber(45),
|
new BigNumber(45),
|
||||||
'0x61a3ed31B43c8780e905a260a35faYfEc527be7516aa11c0256729b5b351bc33',
|
'0x61a3ed31B43c8780e905a260a35faYfEc527be7516aa11c0256729b5b351bc33',
|
||||||
@@ -121,15 +91,13 @@ describe('Assertions', () => {
|
|||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
42,
|
42,
|
||||||
false,
|
false,
|
||||||
{random: 'test'},
|
{ random: 'test' },
|
||||||
undefined,
|
undefined,
|
||||||
new BigNumber(45),
|
new BigNumber(45),
|
||||||
'0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
|
'0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
|
||||||
'0x6FFFd0ae3f7d88c9b4925323f54c6e4',
|
'0x6FFFd0ae3f7d88c9b4925323f54c6e4',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input => expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw());
|
||||||
expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#doesBelongToStringEnum', () => {
|
describe('#doesBelongToStringEnum', () => {
|
||||||
@@ -138,22 +106,13 @@ describe('Assertions', () => {
|
|||||||
Test2 = 'Test2',
|
Test2 = 'Test2',
|
||||||
}
|
}
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [TestEnums.Test1, TestEnums.Test2];
|
||||||
TestEnums.Test1,
|
|
||||||
TestEnums.Test2,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input =>
|
||||||
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
|
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input =>
|
||||||
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
|
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
|
||||||
);
|
);
|
||||||
@@ -162,19 +121,13 @@ describe('Assertions', () => {
|
|||||||
describe('#hasAtMostOneUniqueValue', () => {
|
describe('#hasAtMostOneUniqueValue', () => {
|
||||||
const errorMsg = 'more than one unique value';
|
const errorMsg = 'more than one unique value';
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [['hello'], ['goodbye', 'goodbye', 'goodbye']];
|
||||||
['hello'],
|
|
||||||
['goodbye', 'goodbye', 'goodbye'],
|
|
||||||
];
|
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input =>
|
||||||
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
|
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [['hello', 'goodbye'], ['goodbye', 42, false, false]];
|
||||||
['hello', 'goodbye'],
|
|
||||||
['goodbye', 42, false, false],
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input =>
|
||||||
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
|
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
|
||||||
);
|
);
|
||||||
@@ -182,61 +135,34 @@ describe('Assertions', () => {
|
|||||||
});
|
});
|
||||||
describe('#isNumber', () => {
|
describe('#isNumber', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [42, 0, 21e42];
|
||||||
42,
|
|
||||||
0,
|
|
||||||
21e+42,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isBoolean', () => {
|
describe('#isBoolean', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [true, false];
|
||||||
true,
|
|
||||||
false,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isWeb3Provider', () => {
|
describe('#isWeb3Provider', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [{ send: () => 45 }, { sendAsync: () => 45 }];
|
||||||
{send: () => 45},
|
|
||||||
{sendAsync: () => 45},
|
|
||||||
];
|
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input =>
|
||||||
expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
|
expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
invalidInputs.forEach(input => expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw());
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
|
||||||
expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#doesConformToSchema', () => {
|
describe('#doesConformToSchema', () => {
|
||||||
@@ -251,12 +177,7 @@ describe('Assertions', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input =>
|
||||||
expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
|
expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
|
||||||
);
|
);
|
||||||
@@ -270,14 +191,12 @@ describe('Assertions', () => {
|
|||||||
'https://api.radarrelay.com/0x/v0/',
|
'https://api.radarrelay.com/0x/v0/',
|
||||||
'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
|
'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
|
||||||
];
|
];
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
|
||||||
expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
42,
|
42,
|
||||||
{random: 'test'},
|
{ random: 'test' },
|
||||||
undefined,
|
undefined,
|
||||||
new BigNumber(45),
|
new BigNumber(45),
|
||||||
'ws://www.api.example-relayer.net',
|
'ws://www.api.example-relayer.net',
|
||||||
@@ -286,9 +205,7 @@ describe('Assertions', () => {
|
|||||||
'user:password@api.example-relayer.net',
|
'user:password@api.example-relayer.net',
|
||||||
'//api.example-relayer.net',
|
'//api.example-relayer.net',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
|
||||||
expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isUri', () => {
|
describe('#isUri', () => {
|
||||||
@@ -302,23 +219,19 @@ describe('Assertions', () => {
|
|||||||
'wss://www.api.example-relayer.net',
|
'wss://www.api.example-relayer.net',
|
||||||
'user:password@api.example-relayer.net',
|
'user:password@api.example-relayer.net',
|
||||||
];
|
];
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.not.throw());
|
||||||
expect(assert.isUri.bind(assert, variableName, input)).to.not.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
42,
|
42,
|
||||||
{random: 'test'},
|
{ random: 'test' },
|
||||||
undefined,
|
undefined,
|
||||||
new BigNumber(45),
|
new BigNumber(45),
|
||||||
'www.google.com',
|
'www.google.com',
|
||||||
'api.example-relayer.net',
|
'api.example-relayer.net',
|
||||||
'//api.example-relayer.net',
|
'//api.example-relayer.net',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.throw());
|
||||||
expect(assert.isUri.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#assert', () => {
|
describe('#assert', () => {
|
||||||
@@ -332,8 +245,9 @@ describe('Assertions', () => {
|
|||||||
});
|
});
|
||||||
describe('#typeAssertionMessage', () => {
|
describe('#typeAssertionMessage', () => {
|
||||||
it('should render correct message', () => {
|
it('should render correct message', () => {
|
||||||
expect(assert.typeAssertionMessage('variable', 'string', 'number'))
|
expect(assert.typeAssertionMessage('variable', 'string', 'number')).to.equal(
|
||||||
.to.equal(`Expected variable to be of type string, encountered: number`);
|
`Expected variable to be of type string, encountered: number`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,18 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"extends": "../../tsconfig",
|
||||||
"module": "commonjs",
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"outDir": "lib"
|
||||||
"lib": [ "es2017", "dom"],
|
},
|
||||||
"outDir": "lib",
|
"include": ["./src/**/*", "./test/**/*", "../../node_modules/chai-typescript-typings/index.d.ts"]
|
||||||
"sourceMap": true,
|
|
||||||
"declaration": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"strictNullChecks": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"./src/**/*",
|
|
||||||
"./test/**/*",
|
|
||||||
"../../node_modules/chai-typescript-typings/index.d.ts",
|
|
||||||
"../../node_modules/web3-typescript-typings/index.d.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": [
|
"extends": ["@0xproject/tslint-config"]
|
||||||
"@0xproject/tslint-config"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.x.x - _TBD, 2018_
|
||||||
43
packages/chai-as-promised-typescript-typings/README.md
Normal file
43
packages/chai-as-promised-typescript-typings/README.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
## chai-as-promised-typescript-typings
|
||||||
|
|
||||||
|
Fork of type definitions for chai-as-promised that includes changes made by dirty-chai
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn add -D chai-as-promised-typescript-typings
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add the following line within an `include` section of your `tsconfig.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
"./node_modules/chai-as-promised-typescript-typings/index.d.ts"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
We strongly encourage that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
|
||||||
|
|
||||||
|
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
|
||||||
|
|
||||||
|
### Install Dependencies
|
||||||
|
|
||||||
|
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn config set workspaces-experimental true
|
||||||
|
```
|
||||||
|
|
||||||
|
Then install dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lint
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn lint
|
||||||
|
```
|
||||||
268
packages/chai-as-promised-typescript-typings/index.d.ts
vendored
Normal file
268
packages/chai-as-promised-typescript-typings/index.d.ts
vendored
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
// Type definitions for chai-as-promised
|
||||||
|
// Project: https://github.com/domenic/chai-as-promised/
|
||||||
|
// Definitions by: jt000 <https://github.com/jt000>, Yuki Kokubun <https://github.com/Kuniwak>
|
||||||
|
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||||
|
|
||||||
|
declare module 'chai-as-promised' {
|
||||||
|
function chaiAsPromised(chai: any, utils: any): void;
|
||||||
|
namespace chaiAsPromised {
|
||||||
|
|
||||||
|
}
|
||||||
|
export = chaiAsPromised;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable:no-namespace ban-types member-ordering
|
||||||
|
declare namespace Chai {
|
||||||
|
// For BDD API
|
||||||
|
interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
|
||||||
|
eventually: PromisedAssertion;
|
||||||
|
fulfilled: PromisedAssertion;
|
||||||
|
become(expected: any): PromisedAssertion;
|
||||||
|
rejected(): PromisedAssertion;
|
||||||
|
rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
|
||||||
|
notify(fn: Function): PromisedAssertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eventually does not have .then(), but PromisedAssertion have.
|
||||||
|
interface Eventually extends PromisedLanguageChains, PromisedNumericComparison, PromisedTypeComparison {
|
||||||
|
// From chai-as-promised
|
||||||
|
become(expected: PromiseLike<any>): PromisedAssertion;
|
||||||
|
fulfilled: PromisedAssertion;
|
||||||
|
rejected: () => PromisedAssertion;
|
||||||
|
rejectedWith(expected: any, message?: string | RegExp): PromisedAssertion;
|
||||||
|
notify(fn: Function): PromisedAssertion;
|
||||||
|
|
||||||
|
// From chai
|
||||||
|
not: PromisedAssertion;
|
||||||
|
deep: PromisedDeep;
|
||||||
|
all: PromisedKeyFilter;
|
||||||
|
a: PromisedTypeComparison;
|
||||||
|
an: PromisedTypeComparison;
|
||||||
|
include: PromisedInclude;
|
||||||
|
contain: PromisedInclude;
|
||||||
|
ok: PromisedAssertion;
|
||||||
|
true: () => PromisedAssertion;
|
||||||
|
false: () => PromisedAssertion;
|
||||||
|
null: PromisedAssertion;
|
||||||
|
undefined: PromisedAssertion;
|
||||||
|
exist: PromisedAssertion;
|
||||||
|
empty: PromisedAssertion;
|
||||||
|
arguments: PromisedAssertion;
|
||||||
|
Arguments: PromisedAssertion;
|
||||||
|
equal: PromisedEqual;
|
||||||
|
equals: PromisedEqual;
|
||||||
|
eq: PromisedEqual;
|
||||||
|
eql: PromisedEqual;
|
||||||
|
eqls: PromisedEqual;
|
||||||
|
property: PromisedProperty;
|
||||||
|
ownProperty: PromisedOwnProperty;
|
||||||
|
haveOwnProperty: PromisedOwnProperty;
|
||||||
|
length: PromisedLength;
|
||||||
|
lengthOf: PromisedLength;
|
||||||
|
match(regexp: RegExp | string, message?: string): PromisedAssertion;
|
||||||
|
string(string: string, message?: string): PromisedAssertion;
|
||||||
|
keys: PromisedKeys;
|
||||||
|
key(string: string): PromisedAssertion;
|
||||||
|
throw: PromisedThrow;
|
||||||
|
throws: PromisedThrow;
|
||||||
|
Throw: PromisedThrow;
|
||||||
|
respondTo(method: string, message?: string): PromisedAssertion;
|
||||||
|
itself: PromisedAssertion;
|
||||||
|
satisfy(matcher: Function, message?: string): PromisedAssertion;
|
||||||
|
closeTo(expected: number, delta: number, message?: string): PromisedAssertion;
|
||||||
|
members: PromisedMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PromisedAssertion extends Eventually, PromiseLike<any> {}
|
||||||
|
|
||||||
|
interface PromisedLanguageChains {
|
||||||
|
eventually: Eventually;
|
||||||
|
|
||||||
|
// From chai
|
||||||
|
to: PromisedAssertion;
|
||||||
|
be: PromisedAssertion;
|
||||||
|
been: PromisedAssertion;
|
||||||
|
is: PromisedAssertion;
|
||||||
|
that: PromisedAssertion;
|
||||||
|
which: PromisedAssertion;
|
||||||
|
and: PromisedAssertion;
|
||||||
|
has: PromisedAssertion;
|
||||||
|
have: PromisedAssertion;
|
||||||
|
with: PromisedAssertion;
|
||||||
|
at: PromisedAssertion;
|
||||||
|
of: PromisedAssertion;
|
||||||
|
same: PromisedAssertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PromisedNumericComparison {
|
||||||
|
above: PromisedNumberComparer;
|
||||||
|
gt: PromisedNumberComparer;
|
||||||
|
greaterThan: PromisedNumberComparer;
|
||||||
|
least: PromisedNumberComparer;
|
||||||
|
gte: PromisedNumberComparer;
|
||||||
|
below: PromisedNumberComparer;
|
||||||
|
lt: PromisedNumberComparer;
|
||||||
|
lessThan: PromisedNumberComparer;
|
||||||
|
most: PromisedNumberComparer;
|
||||||
|
lte: PromisedNumberComparer;
|
||||||
|
within(start: number, finish: number, message?: string): PromisedAssertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PromisedNumberComparer = (value: number, message?: string) => PromisedAssertion;
|
||||||
|
|
||||||
|
interface PromisedTypeComparison {
|
||||||
|
(type: string, message?: string): PromisedAssertion;
|
||||||
|
instanceof: PromisedInstanceOf;
|
||||||
|
instanceOf: PromisedInstanceOf;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PromisedInstanceOf = (constructor: Object, message?: string) => PromisedAssertion;
|
||||||
|
|
||||||
|
interface PromisedDeep {
|
||||||
|
equal: PromisedEqual;
|
||||||
|
include: PromisedInclude;
|
||||||
|
property: PromisedProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PromisedKeyFilter {
|
||||||
|
keys: PromisedKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PromisedEqual = (value: any, message?: string) => PromisedAssertion;
|
||||||
|
|
||||||
|
type PromisedProperty = (name: string, value?: any, message?: string) => PromisedAssertion;
|
||||||
|
|
||||||
|
type PromisedOwnProperty = (name: string, message?: string) => PromisedAssertion;
|
||||||
|
|
||||||
|
interface PromisedLength extends PromisedLanguageChains, PromisedNumericComparison {
|
||||||
|
(length: number, message?: string): PromisedAssertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PromisedInclude {
|
||||||
|
(value: Object | string | number, message?: string): PromisedAssertion;
|
||||||
|
keys: PromisedKeys;
|
||||||
|
members: PromisedMembers;
|
||||||
|
all: PromisedKeyFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PromisedKeys {
|
||||||
|
(...keys: string[]): PromisedAssertion;
|
||||||
|
(keys: any[]): PromisedAssertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PromisedThrow {
|
||||||
|
(): PromisedAssertion;
|
||||||
|
(expected: string | RegExp, message?: string): PromisedAssertion;
|
||||||
|
(constructor: Error | Function, expected?: string | RegExp, message?: string): PromisedAssertion;
|
||||||
|
}
|
||||||
|
|
||||||
|
type PromisedMembers = (set: any[], message?: string) => PromisedAssertion;
|
||||||
|
|
||||||
|
// For Assert API
|
||||||
|
interface Assert {
|
||||||
|
eventually: PromisedAssert;
|
||||||
|
isFulfilled(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
|
||||||
|
becomes(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
|
||||||
|
doesNotBecome(promise: PromiseLike<any>, expected: any, message?: string): PromiseLike<void>;
|
||||||
|
isRejected(promise: PromiseLike<any>, message?: string): PromiseLike<void>;
|
||||||
|
isRejected(promise: PromiseLike<any>, expected: any | RegExp, message?: string): PromiseLike<void>;
|
||||||
|
notify(fn: Function): PromiseLike<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PromisedAssert {
|
||||||
|
fail(actual?: any, expected?: any, msg?: string, operator?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
ok(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
notOk(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
equal(act: any, exp: any, msg?: string): PromiseLike<void>;
|
||||||
|
notEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
strictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
|
||||||
|
notStrictEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
deepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
|
||||||
|
notDeepEqual(act: any, exp: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isTrue(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isFalse(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isNull(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotNull(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isUndefined(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isDefined(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isFunction(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotFunction(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isObject(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotObject(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isArray(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotArray(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isString(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotString(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isNumber(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotNumber(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
isBoolean(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
isNotBoolean(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
typeOf(val: any, type: string, msg?: string): PromiseLike<void>;
|
||||||
|
notTypeOf(val: any, type: string, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
instanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
|
||||||
|
notInstanceOf(val: any, type: Function, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
include(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
notInclude(exp: string | any[], inc: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
match(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
|
||||||
|
notMatch(exp: any, re: RegExp, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
property(obj: Object, prop: string, msg?: string): PromiseLike<void>;
|
||||||
|
notProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
|
||||||
|
deepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
|
||||||
|
notDeepProperty(obj: Object, prop: string, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
propertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
|
||||||
|
propertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
|
||||||
|
deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
lengthOf(exp: any, len: number, msg?: string): PromiseLike<void>;
|
||||||
|
// alias frenzy
|
||||||
|
throw(fn: Function, msg?: string): PromiseLike<void>;
|
||||||
|
throw(fn: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
|
||||||
|
throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
|
||||||
|
throws(fn: Function, msg?: string): PromiseLike<void>;
|
||||||
|
throws(fn: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
throws(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
|
||||||
|
throws(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
|
||||||
|
Throw(fn: Function, msg?: string): PromiseLike<void>;
|
||||||
|
Throw(fn: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
Throw(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
|
||||||
|
Throw(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
|
||||||
|
doesNotThrow(fn: Function, msg?: string): PromiseLike<void>;
|
||||||
|
doesNotThrow(fn: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
doesNotThrow(fn: Function, errType: Function, msg?: string): PromiseLike<void>;
|
||||||
|
doesNotThrow(fn: Function, errType: Function, regExp: RegExp): PromiseLike<void>;
|
||||||
|
|
||||||
|
operator(val: any, operator: string, val2: any, msg?: string): PromiseLike<void>;
|
||||||
|
closeTo(act: number, exp: number, delta: number, msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
sameMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
|
||||||
|
includeMembers(set1: any[], set2: any[], msg?: string): PromiseLike<void>;
|
||||||
|
|
||||||
|
ifError(val: any, msg?: string): PromiseLike<void>;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
packages/chai-as-promised-typescript-typings/package.json
Normal file
21
packages/chai-as-promised-typescript-typings/package.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "chai-as-promised-typescript-typings",
|
||||||
|
"version": "0.0.4",
|
||||||
|
"description": "Typescript type definitions for chai-as-promised",
|
||||||
|
"main": "index.d.ts",
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/0xProject/0x.js.git"
|
||||||
|
},
|
||||||
|
"author": "Fabio Berger",
|
||||||
|
"contributors": ["Leonid Logvinov <logvinov.leon@gmail.com>"],
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/0xProject/0x.js/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/0xProject/0x.js/packages/chai-as-promised-typescript-typings#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"chai-typescript-typings": "^0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
const postpublish_utils = require('../../../scripts/postpublish_utils');
|
||||||
|
const packageJSON = require('../package.json');
|
||||||
|
|
||||||
|
const subPackageName = packageJSON.name;
|
||||||
|
|
||||||
|
postpublish_utils
|
||||||
|
.getLatestTagAndVersionAsync(subPackageName)
|
||||||
|
.then(function(result) {
|
||||||
|
const releaseName = postpublish_utils.getReleaseName(subPackageName, result.version);
|
||||||
|
const assets = [];
|
||||||
|
return postpublish_utils.publishReleaseNotes(result.tag, releaseName, assets);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
3
packages/chai-as-promised-typescript-typings/tslint.json
Normal file
3
packages/chai-as-promised-typescript-typings/tslint.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": ["tslint-config-0xproject"]
|
||||||
|
}
|
||||||
3
packages/chai-typescript-typings/CHANGELOG.md
Normal file
3
packages/chai-typescript-typings/CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v0.x.x - _TBD, 2018_
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user