aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contract-wrappers
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contract-wrappers')
-rw-r--r--packages/contract-wrappers/package.json6
-rw-r--r--packages/contract-wrappers/src/artifacts.ts18
-rw-r--r--packages/contract-wrappers/src/artifacts/DummyERC20Token.json (renamed from packages/contract-wrappers/src/compact_artifacts/DummyERC20Token.json)0
-rw-r--r--packages/contract-wrappers/src/artifacts/DummyERC721Token.json (renamed from packages/contract-wrappers/src/compact_artifacts/DummyERC721Token.json)0
-rw-r--r--packages/contract-wrappers/src/artifacts/ERC20Proxy.json210
-rw-r--r--packages/contract-wrappers/src/artifacts/ERC20Token.json (renamed from packages/contract-wrappers/src/compact_artifacts/ERC20Token.json)0
-rw-r--r--packages/contract-wrappers/src/artifacts/ERC721Proxy.json210
-rw-r--r--packages/contract-wrappers/src/artifacts/ERC721Token.json (renamed from packages/contract-wrappers/src/compact_artifacts/ERC721Token.json)0
-rw-r--r--packages/contract-wrappers/src/artifacts/Exchange.json (renamed from packages/contract-wrappers/src/compact_artifacts/Exchange.json)337
-rw-r--r--packages/contract-wrappers/src/artifacts/WETH9.json (renamed from packages/contract-wrappers/src/compact_artifacts/WETH9.json)0
-rw-r--r--packages/contract-wrappers/src/artifacts/ZRXToken.json (renamed from packages/contract-wrappers/src/compact_artifacts/ZRXToken.json)0
-rw-r--r--packages/contract-wrappers/src/compact_artifacts/ERC20Proxy.json43
-rw-r--r--packages/contract-wrappers/src/compact_artifacts/ERC721Proxy.json43
-rw-r--r--packages/contract-wrappers/src/contract_wrappers.ts40
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts9
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts9
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts65
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts9
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts86
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts9
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts961
-rw-r--r--packages/contract-wrappers/src/index.ts11
-rw-r--r--packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts1
-rw-r--r--packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts1
-rw-r--r--packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts8
-rw-r--r--packages/contract-wrappers/src/types.ts18
-rw-r--r--packages/contract-wrappers/test/erc721_wrapper_test.ts2
-rw-r--r--packages/contract-wrappers/test/exchange_wrapper_test.ts1334
-rw-r--r--packages/contract-wrappers/test/utils/token_utils.ts6
29 files changed, 2131 insertions, 1305 deletions
diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json
index 075cd2fe1..8c65c8cca 100644
--- a/packages/contract-wrappers/package.json
+++ b/packages/contract-wrappers/package.json
@@ -13,15 +13,15 @@
"scripts": {
"watch_without_deps": "yarn pre_build && tsc -w",
"build": "yarn pre_build && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
- "pre_build": "run-s generate_contract_wrappers update_compact_artifacts",
- "generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|DummyERC20Token|DummyERC721Token|ZRXToken|ERC20Token|ERC721Token|WETH9|ERC20Proxy|ERC721Proxy).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers",
+ "pre_build": "run-s generate_contract_wrappers update_artifacts",
+ "generate_contract_wrappers": "abi-gen --abis 'src/artifacts/@(Exchange|DummyERC20Token|DummyERC721Token|ZRXToken|ERC20Token|ERC721Token|WETH9|ERC20Proxy|ERC721Proxy).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers",
"lint": "tslint --project . --exclude **/src/contract_wrappers/**/* --exclude **/lib/**/*",
"test:circleci": "run-s test:coverage",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s build test",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
- "update_compact_artifacts": "copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts",
+ "update_artifacts": "copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts",
"clean": "shx rm -rf _bundles lib test_temp scripts test/artifacts src/contract_wrappers/generated",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
diff --git a/packages/contract-wrappers/src/artifacts.ts b/packages/contract-wrappers/src/artifacts.ts
index e5daa73be..742d0e1b2 100644
--- a/packages/contract-wrappers/src/artifacts.ts
+++ b/packages/contract-wrappers/src/artifacts.ts
@@ -1,14 +1,14 @@
import { ContractArtifact } from '@0xproject/sol-compiler';
-import * as DummyERC20Token from './compact_artifacts/DummyERC20Token.json';
-import * as DummyERC721Token from './compact_artifacts/DummyERC721Token.json';
-import * as ERC20Proxy from './compact_artifacts/ERC20Proxy.json';
-import * as ERC20Token from './compact_artifacts/ERC20Token.json';
-import * as ERC721Proxy from './compact_artifacts/ERC721Proxy.json';
-import * as ERC721Token from './compact_artifacts/ERC721Token.json';
-import * as Exchange from './compact_artifacts/Exchange.json';
-import * as EtherToken from './compact_artifacts/WETH9.json';
-import * as ZRXToken from './compact_artifacts/ZRXToken.json';
+import * as DummyERC20Token from './artifacts/DummyERC20Token.json';
+import * as DummyERC721Token from './artifacts/DummyERC721Token.json';
+import * as ERC20Proxy from './artifacts/ERC20Proxy.json';
+import * as ERC20Token from './artifacts/ERC20Token.json';
+import * as ERC721Proxy from './artifacts/ERC721Proxy.json';
+import * as ERC721Token from './artifacts/ERC721Token.json';
+import * as Exchange from './artifacts/Exchange.json';
+import * as EtherToken from './artifacts/WETH9.json';
+import * as ZRXToken from './artifacts/ZRXToken.json';
export const artifacts = {
ZRXToken: (ZRXToken as any) as ContractArtifact,
diff --git a/packages/contract-wrappers/src/compact_artifacts/DummyERC20Token.json b/packages/contract-wrappers/src/artifacts/DummyERC20Token.json
index 0fe22d7f9..0fe22d7f9 100644
--- a/packages/contract-wrappers/src/compact_artifacts/DummyERC20Token.json
+++ b/packages/contract-wrappers/src/artifacts/DummyERC20Token.json
diff --git a/packages/contract-wrappers/src/compact_artifacts/DummyERC721Token.json b/packages/contract-wrappers/src/artifacts/DummyERC721Token.json
index 4a75b9aaf..4a75b9aaf 100644
--- a/packages/contract-wrappers/src/compact_artifacts/DummyERC721Token.json
+++ b/packages/contract-wrappers/src/artifacts/DummyERC721Token.json
diff --git a/packages/contract-wrappers/src/artifacts/ERC20Proxy.json b/packages/contract-wrappers/src/artifacts/ERC20Proxy.json
new file mode 100644
index 000000000..82a08e23d
--- /dev/null
+++ b/packages/contract-wrappers/src/artifacts/ERC20Proxy.json
@@ -0,0 +1,210 @@
+{
+ "contractName": "ERC20Proxy",
+ "compilerOutput": {
+ "abi": [
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "addAuthorizedAddress",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "authorities",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "removeAuthorizedAddress",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "name": "index",
+ "type": "uint256"
+ }
+ ],
+ "name": "removeAuthorizedAddressAtIndex",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "assetData",
+ "type": "bytes"
+ },
+ {
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getProxyId",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "authorized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getAuthorizedAddresses",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "caller",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedAddressAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "caller",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedAddressRemoved",
+ "type": "event"
+ }
+ ]
+ },
+ "networks": {
+ "50": { "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48" }
+ }
+}
diff --git a/packages/contract-wrappers/src/compact_artifacts/ERC20Token.json b/packages/contract-wrappers/src/artifacts/ERC20Token.json
index 46f18b4e5..46f18b4e5 100644
--- a/packages/contract-wrappers/src/compact_artifacts/ERC20Token.json
+++ b/packages/contract-wrappers/src/artifacts/ERC20Token.json
diff --git a/packages/contract-wrappers/src/artifacts/ERC721Proxy.json b/packages/contract-wrappers/src/artifacts/ERC721Proxy.json
new file mode 100644
index 000000000..a31f5b858
--- /dev/null
+++ b/packages/contract-wrappers/src/artifacts/ERC721Proxy.json
@@ -0,0 +1,210 @@
+{
+ "contractName": "ERC20Proxy",
+ "compilerOutput": {
+ "abi": [
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "addAuthorizedAddress",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "authorities",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "removeAuthorizedAddress",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "name": "index",
+ "type": "uint256"
+ }
+ ],
+ "name": "removeAuthorizedAddressAtIndex",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "assetData",
+ "type": "bytes"
+ },
+ {
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getProxyId",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes4"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "authorized",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "getAuthorizedAddresses",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "caller",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedAddressAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "name": "caller",
+ "type": "address"
+ }
+ ],
+ "name": "AuthorizedAddressRemoved",
+ "type": "event"
+ }
+ ]
+ },
+ "networks": {
+ "50": { "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401" }
+ }
+}
diff --git a/packages/contract-wrappers/src/compact_artifacts/ERC721Token.json b/packages/contract-wrappers/src/artifacts/ERC721Token.json
index d3208e197..d3208e197 100644
--- a/packages/contract-wrappers/src/compact_artifacts/ERC721Token.json
+++ b/packages/contract-wrappers/src/artifacts/ERC721Token.json
diff --git a/packages/contract-wrappers/src/compact_artifacts/Exchange.json b/packages/contract-wrappers/src/artifacts/Exchange.json
index 5ba9017c3..7d0bac63a 100644
--- a/packages/contract-wrappers/src/compact_artifacts/Exchange.json
+++ b/packages/contract-wrappers/src/artifacts/Exchange.json
@@ -4,6 +4,20 @@
"abi": [
{
"constant": true,
+ "inputs": [],
+ "name": "EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [
{
"name": "",
@@ -88,7 +102,30 @@
}
],
"name": "batchFillOrders",
- "outputs": [],
+ "outputs": [
+ {
+ "components": [
+ {
+ "name": "makerAssetFilledAmount",
+ "type": "uint256"
+ },
+ {
+ "name": "takerAssetFilledAmount",
+ "type": "uint256"
+ },
+ {
+ "name": "makerFeePaid",
+ "type": "uint256"
+ },
+ {
+ "name": "takerFeePaid",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalFillResults",
+ "type": "tuple"
+ }
+ ],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
@@ -113,20 +150,6 @@
"type": "function"
},
{
- "constant": true,
- "inputs": [],
- "name": "zrxAssetData",
- "outputs": [
- {
- "name": "",
- "type": "bytes"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
"constant": false,
"inputs": [
{
@@ -134,7 +157,7 @@
"type": "bytes32"
},
{
- "name": "signer",
+ "name": "signerAddress",
"type": "address"
},
{
@@ -149,25 +172,6 @@
"type": "function"
},
{
- "constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint8"
- }
- ],
- "name": "assetProxies",
- "outputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
"constant": false,
"inputs": [
{
@@ -444,6 +448,25 @@
"type": "function"
},
{
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "bytes4"
+ }
+ ],
+ "name": "assetProxies",
+ "outputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"constant": false,
"inputs": [
{
@@ -574,7 +597,30 @@
}
],
"name": "batchFillOrKillOrders",
- "outputs": [],
+ "outputs": [
+ {
+ "components": [
+ {
+ "name": "makerAssetFilledAmount",
+ "type": "uint256"
+ },
+ {
+ "name": "takerAssetFilledAmount",
+ "type": "uint256"
+ },
+ {
+ "name": "makerFeePaid",
+ "type": "uint256"
+ },
+ {
+ "name": "takerFeePaid",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalFillResults",
+ "type": "tuple"
+ }
+ ],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
@@ -583,7 +629,7 @@
"constant": false,
"inputs": [
{
- "name": "salt",
+ "name": "targetOrderEpoch",
"type": "uint256"
}
],
@@ -660,31 +706,51 @@
}
],
"name": "batchFillOrdersNoThrow",
- "outputs": [],
+ "outputs": [
+ {
+ "components": [
+ {
+ "name": "makerAssetFilledAmount",
+ "type": "uint256"
+ },
+ {
+ "name": "takerAssetFilledAmount",
+ "type": "uint256"
+ },
+ {
+ "name": "makerFeePaid",
+ "type": "uint256"
+ },
+ {
+ "name": "takerFeePaid",
+ "type": "uint256"
+ }
+ ],
+ "name": "totalFillResults",
+ "type": "tuple"
+ }
+ ],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
- "constant": false,
+ "constant": true,
"inputs": [
{
"name": "assetProxyId",
- "type": "uint8"
- },
- {
- "name": "newAssetProxy",
- "type": "address"
- },
+ "type": "bytes4"
+ }
+ ],
+ "name": "getAssetProxy",
+ "outputs": [
{
- "name": "oldAssetProxy",
+ "name": "",
"type": "address"
}
],
- "name": "registerAssetProxy",
- "outputs": [],
"payable": false,
- "stateMutability": "nonpayable",
+ "stateMutability": "view",
"type": "function"
},
{
@@ -802,29 +868,10 @@
"type": "function"
},
{
- "constant": true,
- "inputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "makerEpoch",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
"constant": false,
"inputs": [
{
- "name": "validator",
+ "name": "validatorAddress",
"type": "address"
},
{
@@ -980,6 +1027,28 @@
"type": "function"
},
{
+ "constant": false,
+ "inputs": [
+ {
+ "name": "assetProxyId",
+ "type": "bytes4"
+ },
+ {
+ "name": "newAssetProxy",
+ "type": "address"
+ },
+ {
+ "name": "oldAssetProxy",
+ "type": "address"
+ }
+ ],
+ "name": "registerAssetProxy",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"constant": true,
"inputs": [],
"name": "owner",
@@ -997,15 +1066,23 @@
"constant": true,
"inputs": [
{
- "name": "assetProxyId",
- "type": "uint8"
+ "name": "hash",
+ "type": "bytes32"
+ },
+ {
+ "name": "signerAddress",
+ "type": "address"
+ },
+ {
+ "name": "signature",
+ "type": "bytes"
}
],
- "name": "getAssetProxy",
+ "name": "isValidSignature",
"outputs": [
{
- "name": "",
- "type": "address"
+ "name": "isValid",
+ "type": "bool"
}
],
"payable": false,
@@ -1210,7 +1287,7 @@
"type": "uint256"
},
{
- "name": "signer",
+ "name": "signerAddress",
"type": "address"
},
{
@@ -1376,6 +1453,43 @@
"type": "function"
},
{
+ "constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ },
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "orderEpoch",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "ZRX_ASSET_DATA",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"constant": false,
"inputs": [
{
@@ -1471,6 +1585,20 @@
"type": "function"
},
{
+ "constant": true,
+ "inputs": [],
+ "name": "EIP712_DOMAIN_HASH",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"constant": false,
"inputs": [
{
@@ -1622,22 +1750,22 @@
"anonymous": false,
"inputs": [
{
- "indexed": false,
- "name": "id",
- "type": "uint8"
+ "indexed": true,
+ "name": "signerAddress",
+ "type": "address"
},
{
- "indexed": false,
- "name": "newAssetProxy",
+ "indexed": true,
+ "name": "validatorAddress",
"type": "address"
},
{
"indexed": false,
- "name": "oldAssetProxy",
- "type": "address"
+ "name": "approved",
+ "type": "bool"
}
],
- "name": "AssetProxySet",
+ "name": "SignatureValidatorApproval",
"type": "event"
},
{
@@ -1649,13 +1777,18 @@
"type": "address"
},
{
+ "indexed": true,
+ "name": "feeRecipientAddress",
+ "type": "address"
+ },
+ {
"indexed": false,
"name": "takerAddress",
"type": "address"
},
{
- "indexed": true,
- "name": "feeRecipientAddress",
+ "indexed": false,
+ "name": "senderAddress",
"type": "address"
},
{
@@ -1711,6 +1844,11 @@
"type": "address"
},
{
+ "indexed": false,
+ "name": "senderAddress",
+ "type": "address"
+ },
+ {
"indexed": true,
"name": "orderHash",
"type": "bytes32"
@@ -1738,13 +1876,40 @@
"type": "address"
},
{
+ "indexed": true,
+ "name": "senderAddress",
+ "type": "address"
+ },
+ {
"indexed": false,
- "name": "makerEpoch",
+ "name": "orderEpoch",
"type": "uint256"
}
],
"name": "CancelUpTo",
"type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "name": "id",
+ "type": "bytes4"
+ },
+ {
+ "indexed": false,
+ "name": "newAssetProxy",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "name": "oldAssetProxy",
+ "type": "address"
+ }
+ ],
+ "name": "AssetProxySet",
+ "type": "event"
}
]
},
diff --git a/packages/contract-wrappers/src/compact_artifacts/WETH9.json b/packages/contract-wrappers/src/artifacts/WETH9.json
index ba2c6372c..ba2c6372c 100644
--- a/packages/contract-wrappers/src/compact_artifacts/WETH9.json
+++ b/packages/contract-wrappers/src/artifacts/WETH9.json
diff --git a/packages/contract-wrappers/src/compact_artifacts/ZRXToken.json b/packages/contract-wrappers/src/artifacts/ZRXToken.json
index bb574be7c..bb574be7c 100644
--- a/packages/contract-wrappers/src/compact_artifacts/ZRXToken.json
+++ b/packages/contract-wrappers/src/artifacts/ZRXToken.json
diff --git a/packages/contract-wrappers/src/compact_artifacts/ERC20Proxy.json b/packages/contract-wrappers/src/compact_artifacts/ERC20Proxy.json
deleted file mode 100644
index 430a8af68..000000000
--- a/packages/contract-wrappers/src/compact_artifacts/ERC20Proxy.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "contractName": "ERC20Proxy",
- "compilerOutput": {
- "abi": [
- {
- "constant": true,
- "inputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "authorized",
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "getAuthorizedAddresses",
- "outputs": [
- {
- "name": "",
- "type": "address[]"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- }
- ]
- },
- "networks": {
- "50": { "address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48" }
- }
-}
diff --git a/packages/contract-wrappers/src/compact_artifacts/ERC721Proxy.json b/packages/contract-wrappers/src/compact_artifacts/ERC721Proxy.json
deleted file mode 100644
index 8924ede96..000000000
--- a/packages/contract-wrappers/src/compact_artifacts/ERC721Proxy.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
- "contractName": "ERC20Proxy",
- "compilerOutput": {
- "abi": [
- {
- "constant": true,
- "inputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "authorized",
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
- "constant": true,
- "inputs": [],
- "name": "getAuthorizedAddresses",
- "outputs": [
- {
- "name": "",
- "type": "address[]"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- }
- ]
- },
- "networks": {
- "50": { "address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401" }
- }
-}
diff --git a/packages/contract-wrappers/src/contract_wrappers.ts b/packages/contract-wrappers/src/contract_wrappers.ts
index 72c953421..8010242c5 100644
--- a/packages/contract-wrappers/src/contract_wrappers.ts
+++ b/packages/contract-wrappers/src/contract_wrappers.ts
@@ -2,12 +2,15 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider } from 'ethereum-types';
import * as _ from 'lodash';
+import { constants } from './utils/constants';
+
import { artifacts } from './artifacts';
import { ERC20ProxyWrapper } from './contract_wrappers/erc20_proxy_wrapper';
import { ERC20TokenWrapper } from './contract_wrappers/erc20_token_wrapper';
import { ERC721ProxyWrapper } from './contract_wrappers/erc721_proxy_wrapper';
import { ERC721TokenWrapper } from './contract_wrappers/erc721_token_wrapper';
import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
+import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema';
import { contractWrappersPrivateNetworkConfigSchema } from './schemas/contract_wrappers_private_network_config_schema';
import { contractWrappersPublicNetworkConfigSchema } from './schemas/contract_wrappers_public_network_config_schema';
@@ -18,6 +21,10 @@ import { assert } from './utils/assert';
*/
export class ContractWrappers {
/**
+ * An instance of the ExchangeWrapper class containing methods for interacting with the 0x Exchange smart contract.
+ */
+ public exchange: ExchangeWrapper;
+ /**
* An instance of the ERC20TokenWrapper class containing methods for interacting with any ERC20 token smart contract.
*/
public erc20Token: ERC20TokenWrapper;
@@ -63,15 +70,40 @@ export class ContractWrappers {
_.forEach(abiArrays, abi => {
this._web3Wrapper.abiDecoder.addABI(abi);
});
+ const blockPollingIntervalMs = _.isUndefined(config.blockPollingIntervalMs)
+ ? constants.DEFAULT_BLOCK_POLLING_INTERVAL
+ : config.blockPollingIntervalMs;
this.erc20Proxy = new ERC20ProxyWrapper(this._web3Wrapper, config.networkId, config.erc20ProxyContractAddress);
this.erc721Proxy = new ERC721ProxyWrapper(
this._web3Wrapper,
config.networkId,
config.erc721ProxyContractAddress,
);
- this.erc20Token = new ERC20TokenWrapper(this._web3Wrapper, config.networkId, this.erc20Proxy);
- this.erc721Token = new ERC721TokenWrapper(this._web3Wrapper, config.networkId, this.erc721Proxy);
- this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this.erc20Token);
+ this.erc20Token = new ERC20TokenWrapper(
+ this._web3Wrapper,
+ config.networkId,
+ this.erc20Proxy,
+ blockPollingIntervalMs,
+ );
+ this.erc721Token = new ERC721TokenWrapper(
+ this._web3Wrapper,
+ config.networkId,
+ this.erc721Proxy,
+ blockPollingIntervalMs,
+ );
+ this.etherToken = new EtherTokenWrapper(
+ this._web3Wrapper,
+ config.networkId,
+ this.erc20Token,
+ blockPollingIntervalMs,
+ );
+ this.exchange = new ExchangeWrapper(
+ this._web3Wrapper,
+ config.networkId,
+ config.exchangeContractAddress,
+ config.zrxContractAddress,
+ blockPollingIntervalMs,
+ );
}
/**
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
@@ -81,6 +113,8 @@ export class ContractWrappers {
*/
public setProvider(provider: Provider, networkId: number): void {
this._web3Wrapper.setProvider(provider);
+ (this.exchange as any)._invalidateContractInstances();
+ (this.exchange as any)._setNetworkId(networkId);
(this.erc20Token as any)._invalidateContractInstances();
(this.erc20Token as any)._setNetworkId(networkId);
(this.erc20Proxy as any)._invalidateContractInstance();
diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
index 7895a42ee..b8ca4d29b 100644
--- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
@@ -12,7 +12,6 @@ import {
ContractWrappersError,
EventCallback,
IndexedFilterValues,
- InternalContractWrappersError,
} from '../types';
import { constants } from '../utils/constants';
import { filterUtils } from '../utils/filter_utils';
@@ -34,6 +33,7 @@ export abstract class ContractWrapper {
protected _web3Wrapper: Web3Wrapper;
protected _networkId: number;
private _blockAndLogStreamerIfExists: BlockAndLogStreamer<Block, Log> | undefined;
+ private _blockPollingIntervalMs: number;
private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer;
private _filters: { [filterToken: string]: FilterObject };
private _filterCallbacks: {
@@ -41,9 +41,12 @@ export abstract class ContractWrapper {
};
private _onLogAddedSubscriptionToken: string | undefined;
private _onLogRemovedSubscriptionToken: string | undefined;
- constructor(web3Wrapper: Web3Wrapper, networkId: number) {
+ constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) {
this._web3Wrapper = web3Wrapper;
this._networkId = networkId;
+ this._blockPollingIntervalMs = _.isUndefined(blockPollingIntervalMs)
+ ? constants.DEFAULT_BLOCK_POLLING_INTERVAL
+ : blockPollingIntervalMs;
this._filters = {};
this._filterCallbacks = {};
this._blockAndLogStreamerIfExists = undefined;
@@ -161,7 +164,7 @@ export abstract class ContractWrapper {
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval(
this._reconcileBlockAsync.bind(this),
- constants.DEFAULT_BLOCK_POLLING_INTERVAL,
+ this._blockPollingIntervalMs,
this._onReconcileBlockError.bind(this),
);
let isRemoved = false;
diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts
index 839248754..883d7c4d6 100644
--- a/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/erc20_proxy_wrapper.ts
@@ -20,6 +20,15 @@ export class ERC20ProxyWrapper extends ContractWrapper {
this._contractAddressIfExists = contractAddressIfExists;
}
/**
+ * Get the 4 bytes ID of this asset proxy
+ * @return Proxy id
+ */
+ public async getProxyIdAsync(): Promise<string> {
+ const ERC20ProxyContractInstance = await this._getERC20ProxyContractAsync();
+ const proxyId = await ERC20ProxyContractInstance.getProxyId.callAsync();
+ return proxyId;
+ }
+ /**
* Check if the Exchange contract address is authorized by the ERC20Proxy contract.
* @param exchangeContractAddress The hex encoded address of the Exchange contract to call.
* @return Whether the exchangeContractAddress is authorized.
diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts
index f393e4ed1..29c63564e 100644
--- a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts
@@ -34,8 +34,13 @@ export class ERC20TokenWrapper extends ContractWrapper {
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
private _tokenContractsByAddress: { [address: string]: ERC20TokenContract };
private _erc20ProxyWrapper: ERC20ProxyWrapper;
- constructor(web3Wrapper: Web3Wrapper, networkId: number, erc20ProxyWrapper: ERC20ProxyWrapper) {
- super(web3Wrapper, networkId);
+ constructor(
+ web3Wrapper: Web3Wrapper,
+ networkId: number,
+ erc20ProxyWrapper: ERC20ProxyWrapper,
+ blockPollingIntervalMs?: number,
+ ) {
+ super(web3Wrapper, networkId, blockPollingIntervalMs);
this._tokenContractsByAddress = {};
this._erc20ProxyWrapper = erc20ProxyWrapper;
}
@@ -49,20 +54,18 @@ export class ERC20TokenWrapper extends ContractWrapper {
public async getBalanceAsync(
tokenAddress: string,
ownerAddress: string,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<BigNumber> {
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedOwnerAddress = ownerAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
+
const txData = {};
- let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, defaultBlock);
+ let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, methodOpts.defaultBlock);
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
balance = new BigNumber(balance);
return balance;
@@ -85,16 +88,14 @@ export class ERC20TokenWrapper extends ContractWrapper {
amountInBaseUnits: BigNumber,
txOpts: TransactionOpts = {},
): Promise<string> {
- assert.isETHAddressHex('spenderAddress', spenderAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
- if (!_.isUndefined(txOpts)) {
- assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
- }
+ assert.isETHAddressHex('spenderAddress', spenderAddress);
+ assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+ assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
- const normalizedSpenderAddress = spenderAddress.toLowerCase();
const normalizedOwnerAddress = ownerAddress.toLowerCase();
- assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+ const normalizedSpenderAddress = spenderAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
const txHash = await tokenContract.approve.sendTransactionAsync(
@@ -147,26 +148,24 @@ export class ERC20TokenWrapper extends ContractWrapper {
tokenAddress: string,
ownerAddress: string,
spenderAddress: string,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<BigNumber> {
- assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('spenderAddress', spenderAddress);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedOwnerAddress = ownerAddress.toLowerCase();
const normalizedSpenderAddress = spenderAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
+
const txData = {};
let allowanceInBaseUnits = await tokenContract.allowance.callAsync(
normalizedOwnerAddress,
normalizedSpenderAddress,
txData,
- defaultBlock,
+ methodOpts.defaultBlock,
);
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
@@ -181,7 +180,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
public async getProxyAllowanceAsync(
tokenAddress: string,
ownerAddress: string,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<BigNumber> {
const proxyAddress = this._erc20ProxyWrapper.getContractAddress();
const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts);
@@ -254,15 +253,13 @@ export class ERC20TokenWrapper extends ContractWrapper {
txOpts: TransactionOpts = {},
): Promise<string> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
- assert.isETHAddressHex('toAddress', toAddress);
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
- if (!_.isUndefined(txOpts)) {
- assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
- }
+ assert.isETHAddressHex('toAddress', toAddress);
+ assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+ assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedFromAddress = fromAddress.toLowerCase();
const normalizedToAddress = toAddress.toLowerCase();
- assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
@@ -304,18 +301,16 @@ export class ERC20TokenWrapper extends ContractWrapper {
amountInBaseUnits: BigNumber,
txOpts: TransactionOpts = {},
): Promise<string> {
- assert.isETHAddressHex('toAddress', toAddress);
- assert.isETHAddressHex('fromAddress', fromAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ assert.isETHAddressHex('fromAddress', fromAddress);
+ assert.isETHAddressHex('toAddress', toAddress);
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
- if (!_.isUndefined(txOpts)) {
- assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
- }
+ assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
+ assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
const normalizedToAddress = toAddress.toLowerCase();
const normalizedFromAddress = fromAddress.toLowerCase();
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedSenderAddress = senderAddress.toLowerCase();
- assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
@@ -361,10 +356,10 @@ export class ERC20TokenWrapper extends ContractWrapper {
callback: EventCallback<ArgsType>,
): string {
assert.isETHAddressHex('tokenAddress', tokenAddress);
- const normalizedTokenAddress = tokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
assert.isFunction('callback', callback);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
const subscriptionToken = this._subscribe<ArgsType>(
normalizedTokenAddress,
eventName,
@@ -404,10 +399,10 @@ export class ERC20TokenWrapper extends ContractWrapper {
indexFilterValues: IndexedFilterValues,
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
- const normalizedTokenAddress = tokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents);
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
const logs = await this._getLogsAsync<ArgsType>(
normalizedTokenAddress,
eventName,
diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts
index fba995395..648c150df 100644
--- a/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/erc721_proxy_wrapper.ts
@@ -20,6 +20,15 @@ export class ERC721ProxyWrapper extends ContractWrapper {
this._contractAddressIfExists = contractAddressIfExists;
}
/**
+ * Get the 4 bytes ID of this asset proxy
+ * @return Proxy id
+ */
+ public async getProxyIdAsync(): Promise<string> {
+ const ERC721ProxyContractInstance = await this._getERC721ProxyContractAsync();
+ const proxyId = await ERC721ProxyContractInstance.getProxyId.callAsync();
+ return proxyId;
+ }
+ /**
* Check if the Exchange contract address is authorized by the ERC721Proxy contract.
* @param exchangeContractAddress The hex encoded address of the Exchange contract to call.
* @return Whether the exchangeContractAddress is authorized.
diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts
index 415415fd7..b7e5519c4 100644
--- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts
@@ -33,8 +33,13 @@ export class ERC721TokenWrapper extends ContractWrapper {
public abi: ContractAbi = artifacts.ERC721Token.compilerOutput.abi;
private _tokenContractsByAddress: { [address: string]: ERC721TokenContract };
private _erc721ProxyWrapper: ERC721ProxyWrapper;
- constructor(web3Wrapper: Web3Wrapper, networkId: number, erc721ProxyWrapper: ERC721ProxyWrapper) {
- super(web3Wrapper, networkId);
+ constructor(
+ web3Wrapper: Web3Wrapper,
+ networkId: number,
+ erc721ProxyWrapper: ERC721ProxyWrapper,
+ blockPollingIntervalMs?: number,
+ ) {
+ super(web3Wrapper, networkId, blockPollingIntervalMs);
this._tokenContractsByAddress = {};
this._erc721ProxyWrapper = erc721ProxyWrapper;
}
@@ -49,20 +54,18 @@ export class ERC721TokenWrapper extends ContractWrapper {
public async getTokenCountAsync(
tokenAddress: string,
ownerAddress: string,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<BigNumber> {
- assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
+ assert.isETHAddressHex('ownerAddress', ownerAddress);
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedOwnerAddress = ownerAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
+
const txData = {};
- let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, defaultBlock);
+ let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, txData, methodOpts.defaultBlock);
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
balance = new BigNumber(balance);
return balance;
@@ -75,19 +78,21 @@ export class ERC721TokenWrapper extends ContractWrapper {
* @param methodOpts Optional arguments this method accepts.
* @return The address of the owner of the NFT
*/
- public async getOwnerOfAsync(tokenAddress: string, tokenId: BigNumber, methodOpts?: MethodOpts): Promise<string> {
+ public async getOwnerOfAsync(
+ tokenAddress: string,
+ tokenId: BigNumber,
+ methodOpts: MethodOpts = {},
+ ): Promise<string> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isBigNumber('tokenId', tokenId);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
+
const txData = {};
try {
- const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId, txData, defaultBlock);
+ const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId, txData, methodOpts.defaultBlock);
return tokenOwner;
} catch (err) {
throw new Error(ContractWrappersError.ERC721OwnerNotFound);
@@ -105,26 +110,24 @@ export class ERC721TokenWrapper extends ContractWrapper {
tokenAddress: string,
ownerAddress: string,
operatorAddress: string,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<boolean> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isETHAddressHex('ownerAddress', ownerAddress);
assert.isETHAddressHex('operatorAddress', operatorAddress);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedOwnerAddress = ownerAddress.toLowerCase();
const normalizedOperatorAddress = operatorAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
+
const txData = {};
const isApprovedForAll = await tokenContract.isApprovedForAll.callAsync(
normalizedOwnerAddress,
normalizedOperatorAddress,
txData,
- defaultBlock,
+ methodOpts.defaultBlock,
);
return isApprovedForAll;
}
@@ -138,19 +141,12 @@ export class ERC721TokenWrapper extends ContractWrapper {
public async isProxyApprovedForAllAsync(
tokenAddress: string,
ownerAddress: string,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<boolean> {
- assert.isETHAddressHex('tokenAddress', tokenAddress);
- assert.isETHAddressHex('ownerAddress', ownerAddress);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
- const normalizedTokenAddress = tokenAddress.toLowerCase();
- const normalizedOwnerAddress = ownerAddress.toLowerCase();
const proxyAddress = this._erc721ProxyWrapper.getContractAddress();
const isProxyApprovedForAll = await this.isApprovedForAllAsync(
- normalizedTokenAddress,
- normalizedOwnerAddress,
+ tokenAddress,
+ ownerAddress,
proxyAddress,
methodOpts,
);
@@ -167,19 +163,17 @@ export class ERC721TokenWrapper extends ContractWrapper {
public async getApprovedIfExistsAsync(
tokenAddress: string,
tokenId: BigNumber,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<string | undefined> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isBigNumber('tokenId', tokenId);
- if (!_.isUndefined(methodOpts)) {
- assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
- }
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
- const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
+
const txData = {};
- const approvedAddress = await tokenContract.getApproved.callAsync(tokenId, txData, defaultBlock);
+ const approvedAddress = await tokenContract.getApproved.callAsync(tokenId, txData, methodOpts.defaultBlock);
if (approvedAddress === constants.NULL_ADDRESS) {
return undefined;
}
@@ -196,7 +190,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
public async isProxyApprovedAsync(
tokenAddress: string,
tokenId: BigNumber,
- methodOpts?: MethodOpts,
+ methodOpts: MethodOpts = {},
): Promise<boolean> {
const proxyAddress = this._erc721ProxyWrapper.getContractAddress();
const approvedAddress = await this.getApprovedIfExistsAsync(tokenAddress, tokenId, methodOpts);
@@ -225,9 +219,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
assert.isETHAddressHex('operatorAddress', operatorAddress);
assert.isBoolean('isApproved', isApproved);
- if (!_.isUndefined(txOpts)) {
- assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
- }
+ assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedOwnerAddress = ownerAddress.toLowerCase();
const normalizedOperatorAddress = operatorAddress.toLowerCase();
@@ -286,9 +278,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isETHAddressHex('approvedAddress', approvedAddress);
assert.isBigNumber('tokenId', tokenId);
- if (!_.isUndefined(txOpts)) {
- assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
- }
+ assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedApprovedAddress = approvedAddress.toLowerCase();
@@ -346,9 +336,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isETHAddressHex('receiverAddress', receiverAddress);
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
- if (!_.isUndefined(txOpts)) {
- assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
- }
+ assert.doesConformToSchema('txOpts', txOpts, txOptsSchema);
const normalizedTokenAddress = tokenAddress.toLowerCase();
const normalizedReceiverAddress = receiverAddress.toLowerCase();
const normalizedSenderAddress = senderAddress.toLowerCase();
@@ -393,10 +381,10 @@ export class ERC721TokenWrapper extends ContractWrapper {
callback: EventCallback<ArgsType>,
): string {
assert.isETHAddressHex('tokenAddress', tokenAddress);
- const normalizedTokenAddress = tokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
assert.isFunction('callback', callback);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
const subscriptionToken = this._subscribe<ArgsType>(
normalizedTokenAddress,
eventName,
@@ -436,10 +424,10 @@ export class ERC721TokenWrapper extends ContractWrapper {
indexFilterValues: IndexedFilterValues,
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
assert.isETHAddressHex('tokenAddress', tokenAddress);
- const normalizedTokenAddress = tokenAddress.toLowerCase();
assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents);
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+ const normalizedTokenAddress = tokenAddress.toLowerCase();
const logs = await this._getLogsAsync<ArgsType>(
normalizedTokenAddress,
eventName,
diff --git a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts
index 97872c247..01440a5e1 100644
--- a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts
@@ -24,8 +24,13 @@ export class EtherTokenWrapper extends ContractWrapper {
[address: string]: WETH9Contract;
} = {};
private _erc20TokenWrapper: ERC20TokenWrapper;
- constructor(web3Wrapper: Web3Wrapper, networkId: number, erc20TokenWrapper: ERC20TokenWrapper) {
- super(web3Wrapper, networkId);
+ constructor(
+ web3Wrapper: Web3Wrapper,
+ networkId: number,
+ erc20TokenWrapper: ERC20TokenWrapper,
+ blockPollingIntervalMs?: number,
+ ) {
+ super(web3Wrapper, networkId, blockPollingIntervalMs);
this._erc20TokenWrapper = erc20TokenWrapper;
}
/**
diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
new file mode 100644
index 000000000..0e8664cc9
--- /dev/null
+++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
@@ -0,0 +1,961 @@
+import { schemas } from '@0xproject/json-schemas';
+import { Order, SignedOrder } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import { ContractAbi, LogWithDecodedArgs } from 'ethereum-types';
+import * as _ from 'lodash';
+
+import { artifacts } from '../artifacts';
+import { methodOptsSchema } from '../schemas/method_opts_schema';
+import { orderTxOptsSchema } from '../schemas/order_tx_opts_schema';
+import { txOptsSchema } from '../schemas/tx_opts_schema';
+import { BlockRange, EventCallback, IndexedFilterValues, MethodOpts, OrderInfo, OrderTransactionOpts } from '../types';
+import { assert } from '../utils/assert';
+import { decorators } from '../utils/decorators';
+
+import { ContractWrapper } from './contract_wrapper';
+import { ExchangeContract, ExchangeEventArgs, ExchangeEvents } from './generated/exchange';
+
+/**
+ * This class includes all the functionality related to calling methods, sending transactions and subscribing to
+ * events of the 0x V2 Exchange smart contract.
+ */
+export class ExchangeWrapper extends ContractWrapper {
+ public abi: ContractAbi = artifacts.Exchange.compilerOutput.abi;
+ private _exchangeContractIfExists?: ExchangeContract;
+ private _contractAddressIfExists?: string;
+ private _zrxContractAddressIfExists?: string;
+ constructor(
+ web3Wrapper: Web3Wrapper,
+ networkId: number,
+ contractAddressIfExists?: string,
+ zrxContractAddressIfExists?: string,
+ blockPollingIntervalMs?: number,
+ ) {
+ super(web3Wrapper, networkId, blockPollingIntervalMs);
+ this._contractAddressIfExists = contractAddressIfExists;
+ this._zrxContractAddressIfExists = zrxContractAddressIfExists;
+ }
+ /**
+ * Retrieve the address of an asset proxy by signature.
+ * @param proxySignature The 4 bytes signature of an asset proxy
+ * @param methodOpts Optional arguments this method accepts.
+ * @return The address of an asset proxy for a given signature
+ */
+ public async getAssetProxyBySignatureAsync(proxySignature: string, methodOpts: MethodOpts = {}): Promise<string> {
+ assert.isHexString('proxySignature', proxySignature);
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ const exchangeContract = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const assetProxy = await exchangeContract.getAssetProxy.callAsync(
+ proxySignature,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return assetProxy;
+ }
+ /**
+ * Retrieve the takerAssetAmount of an order that has already been filled.
+ * @param orderHash The hex encoded orderHash for which you would like to retrieve the filled takerAssetAmount.
+ * @param methodOpts Optional arguments this method accepts.
+ * @return The amount of the order (in taker asset base units) that has already been filled.
+ */
+ public async getFilledTakerAssetAmountAsync(orderHash: string, methodOpts: MethodOpts = {}): Promise<BigNumber> {
+ assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ const exchangeContract = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const filledTakerAssetAmountInBaseUnits = await exchangeContract.filled.callAsync(
+ orderHash,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return filledTakerAssetAmountInBaseUnits;
+ }
+ /**
+ * Retrieve the exchange contract version
+ * @param methodOpts Optional arguments this method accepts.
+ * @return Version
+ */
+ public async getVersionAsync(methodOpts: MethodOpts = {}): Promise<string> {
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ const exchangeContract = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const version = await exchangeContract.VERSION.callAsync(txData, methodOpts.defaultBlock);
+ return version;
+ }
+ /**
+ * Retrieve the set order epoch for a given makerAddress & senderAddress pair.
+ * Orders can be bulk cancelled by setting the order epoch to a value lower then the salt value of orders one wishes to cancel.
+ * @param makerAddress Maker address
+ * @param senderAddress Sender address
+ * @param methodOpts Optional arguments this method accepts.
+ * @return Order epoch. Defaults to 0.
+ */
+ public async getOrderEpochAsync(
+ makerAddress: string,
+ senderAddress: string,
+ methodOpts: MethodOpts = {},
+ ): Promise<BigNumber> {
+ assert.isETHAddressHex('makerAddress', makerAddress);
+ assert.isETHAddressHex('senderAddress', senderAddress);
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ const exchangeContract = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const orderEpoch = await exchangeContract.orderEpoch.callAsync(
+ makerAddress,
+ senderAddress,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return orderEpoch;
+ }
+ /**
+ * Check if an order has been cancelled. Order cancellations are binary
+ * @param orderHash The hex encoded orderHash for which you would like to retrieve the cancelled takerAmount.
+ * @param methodOpts Optional arguments this method accepts.
+ * @return Whether the order has been cancelled.
+ */
+ public async isCancelledAsync(orderHash: string, methodOpts: MethodOpts = {}): Promise<boolean> {
+ assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ const exchangeContract = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const isCancelled = await exchangeContract.cancelled.callAsync(orderHash, txData, methodOpts.defaultBlock);
+ return isCancelled;
+ }
+ /**
+ * Fills a signed order with an amount denominated in baseUnits of the taker asset.
+ * @param signedOrder An object that conforms to the SignedOrder interface.
+ * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
+ * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async fillOrderAsync(
+ signedOrder: SignedOrder,
+ takerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+ assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+
+ const txHash = await exchangeInstance.fillOrder.sendTransactionAsync(
+ signedOrder,
+ takerAssetFillAmount,
+ signedOrder.signature,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * No-throw version of fillOrderAsync. This version will not throw if the fill fails. This allows the caller to save gas at the expense of not knowing the reason the fill failed.
+ * @param signedOrder An object that conforms to the SignedOrder interface.
+ * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
+ * @param takerAddress The user Ethereum address who would like to fill this order.
+ * Must be available via the supplied Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async fillOrderNoThrowAsync(
+ signedOrder: SignedOrder,
+ takerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+ assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+
+ const txHash = await exchangeInstance.fillOrderNoThrow.sendTransactionAsync(
+ signedOrder,
+ takerAssetFillAmount,
+ signedOrder.signature,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Attempts to fill a specific amount of an order. If the entire amount specified cannot be filled,
+ * the fill order is abandoned.
+ * @param signedOrder An object that conforms to the SignedOrder interface.
+ * @param takerAssetFillAmount The amount of the order (in taker asset baseUnits) that you wish to fill.
+ * @param takerAddress The user Ethereum address who would like to fill this order. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async fillOrKillOrderAsync(
+ signedOrder: SignedOrder,
+ takerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
+ assert.isValidBaseUnitAmount('takerAssetFillAmount', takerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+
+ const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
+ signedOrder,
+ takerAssetFillAmount,
+ signedOrder.signature,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Executes a 0x transaction. Transaction messages exist for the purpose of calling methods on the Exchange contract
+ * in the context of another address (see [ZEIP18](https://github.com/0xProject/ZEIPs/issues/18)).
+ * This is especially useful for implementing filter contracts.
+ * @param salt Salt
+ * @param signerAddress Signer address
+ * @param data Transaction data
+ * @param signature Signature
+ * @param senderAddress Sender address
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async executeTransactionAsync(
+ salt: BigNumber,
+ signerAddress: string,
+ data: string,
+ signature: string,
+ senderAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.isBigNumber('salt', salt);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ assert.isHexString('data', data);
+ assert.isHexString('signature', signature);
+ await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedSenderAddress = senderAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+
+ const txHash = await exchangeInstance.executeTransaction.sendTransactionAsync(
+ salt,
+ signerAddress,
+ data,
+ signature,
+ {
+ from: normalizedSenderAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Batch version of fillOrderAsync. Executes multiple fills atomically in a single transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async batchFillOrdersAsync(
+ signedOrders: SignedOrder[],
+ takerAssetFillAmounts: BigNumber[],
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ _.forEach(takerAssetFillAmounts, takerAssetFillAmount =>
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount),
+ );
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.batchFillOrders.sendTransactionAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Synchronously executes multiple calls to fillOrder until total amount of makerAsset is bought by taker.
+ * @param signedOrders An array of signed orders to fill.
+ * @param makerAssetFillAmount Maker asset fill amount.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async marketBuyOrdersAsync(
+ signedOrders: SignedOrder[],
+ makerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.marketBuyOrders.sendTransactionAsync(
+ signedOrders,
+ makerAssetFillAmount,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Synchronously executes multiple calls to fillOrder until total amount of makerAsset is bought by taker.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmount Taker asset fill amount.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async marketSellOrdersAsync(
+ signedOrders: SignedOrder[],
+ takerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.marketSellOrders.sendTransactionAsync(
+ signedOrders,
+ takerAssetFillAmount,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * No throw version of marketBuyOrdersAsync
+ * @param signedOrders An array of signed orders to fill.
+ * @param makerAssetFillAmount Maker asset fill amount.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async marketBuyOrdersNoThrowAsync(
+ signedOrders: SignedOrder[],
+ makerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.marketBuyOrdersNoThrow.sendTransactionAsync(
+ signedOrders,
+ makerAssetFillAmount,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * No throw version of marketSellOrdersAsync
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmount Taker asset fill amount.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async marketSellOrdersNoThrowAsync(
+ signedOrders: SignedOrder[],
+ takerAssetFillAmount: BigNumber,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.marketSellOrdersNoThrow.sendTransactionAsync(
+ signedOrders,
+ takerAssetFillAmount,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * No throw version of batchFillOrdersAsync
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async batchFillOrdersNoThrowAsync(
+ signedOrders: SignedOrder[],
+ takerAssetFillAmounts: BigNumber[],
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ _.forEach(takerAssetFillAmounts, takerAssetFillAmount =>
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount),
+ );
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.batchFillOrdersNoThrow.sendTransactionAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Batch version of fillOrKillOrderAsync. Executes multiple fills atomically in a single transaction.
+ * @param signedOrders An array of signed orders to fill.
+ * @param takerAssetFillAmounts The amounts of the orders (in taker asset baseUnits) that you wish to fill.
+ * @param takerAddress The user Ethereum address who would like to fill these orders. Must be available via the supplied
+ * Provider provided at instantiation.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async batchFillOrKillOrdersAsync(
+ signedOrders: SignedOrder[],
+ takerAssetFillAmounts: BigNumber[],
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
+ _.forEach(takerAssetFillAmounts, takerAssetFillAmount =>
+ assert.isBigNumber('takerAssetFillAmount', takerAssetFillAmount),
+ );
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const signatures = _.map(signedOrders, signedOrder => signedOrder.signature);
+ const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ signatures,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Batch version of cancelOrderAsync. Executes multiple cancels atomically in a single transaction.
+ * @param orders An array of orders to cancel.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async batchCancelOrdersAsync(
+ orders: Array<Order | SignedOrder>,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('orders', orders, schemas.ordersSchema);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const makerAddresses = _.map(orders, order => order.makerAddress);
+ const makerAddress = makerAddresses[0];
+ await assert.isSenderAddressAsync('makerAddress', makerAddress, this._web3Wrapper);
+ const normalizedMakerAddress = makerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(orders, {
+ from: normalizedMakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ });
+ return txHash;
+ }
+ /**
+ * Match two complementary orders that have a profitable spread.
+ * Each order is filled at their respective price point. However, the calculations are carried out as though
+ * the orders are both being filled at the right order's price point.
+ * The profit made by the left order goes to the taker (whoever matched the two orders).
+ * @param leftSignedOrder First order to match.
+ * @param rightSignedOrder Second order to match.
+ * @param takerAddress The address that sends the transaction and gets the spread.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async matchOrdersAsync(
+ leftSignedOrder: SignedOrder,
+ rightSignedOrder: SignedOrder,
+ takerAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('leftSignedOrder', leftSignedOrder, schemas.signedOrderSchema);
+ assert.doesConformToSchema('rightSignedOrder', rightSignedOrder, schemas.signedOrderSchema);
+ await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = takerAddress.toLowerCase();
+ // TODO(logvinov): Check that:
+ // rightOrder.makerAssetData === leftOrder.takerAssetData;
+ // rightOrder.takerAssetData === leftOrder.makerAssetData;
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txHash = await exchangeInstance.matchOrders.sendTransactionAsync(
+ leftSignedOrder,
+ rightSignedOrder,
+ leftSignedOrder.signature,
+ rightSignedOrder.signature,
+ {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Approves a hash on-chain using any valid signature type.
+ * After presigning a hash, the preSign signature type will become valid for that hash and signer.
+ * @param hash Hash to pre-sign
+ * @param signerAddress Address that should have signed the given hash.
+ * @param signature Proof that the hash has been signed by signer.
+ * @param senderAddress Address that should send the transaction.
+ * @returns Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async preSignAsync(
+ hash: string,
+ signerAddress: string,
+ signature: string,
+ senderAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.isHexString('hash', hash);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ assert.isHexString('signature', signature);
+ await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedTakerAddress = senderAddress.toLowerCase();
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txHash = await exchangeInstance.preSign.sendTransactionAsync(hash, signerAddress, signature, {
+ from: normalizedTakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ });
+ return txHash;
+ }
+ /**
+ * Checks if the signature is valid.
+ * @param hash Hash to pre-sign
+ * @param signerAddress Address that should have signed the given hash.
+ * @param signature Proof that the hash has been signed by signer.
+ * @param methodOpts Optional arguments this method accepts.
+ * @returns If the signature is valid
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async isValidSignatureAsync(
+ hash: string,
+ signerAddress: string,
+ signature: string,
+ methodOpts: MethodOpts = {},
+ ): Promise<boolean> {
+ assert.isHexString('hash', hash);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ assert.isHexString('signature', signature);
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txData = {};
+ const isValidSignature = await exchangeInstance.isValidSignature.callAsync(
+ hash,
+ signerAddress,
+ signature,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return isValidSignature;
+ }
+ /**
+ * Checks if the validator is allowed by the signer.
+ * @param validatorAddress Address of a validator
+ * @param signerAddress Address of a signer
+ * @param methodOpts Optional arguments this method accepts.
+ * @returns If the validator is allowed
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async isAllowedValidatorAsync(
+ signerAddress: string,
+ validatorAddress: string,
+ methodOpts: MethodOpts = {},
+ ): Promise<boolean> {
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ assert.isETHAddressHex('validatorAddress', validatorAddress);
+ if (!_.isUndefined(methodOpts)) {
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ }
+ const normalizedSignerAddress = signerAddress.toLowerCase();
+ const normalizedValidatorAddress = validatorAddress.toLowerCase();
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txData = {};
+ const isValidSignature = await exchangeInstance.allowedValidators.callAsync(
+ normalizedSignerAddress,
+ normalizedValidatorAddress,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return isValidSignature;
+ }
+ /**
+ * Check whether the hash is pre-signed on-chain.
+ * @param hash Hash to check if pre-signed
+ * @param signerAddress Address that should have signed the given hash.
+ * @param methodOpts Optional arguments this method accepts.
+ * @returns Whether the hash is pre-signed.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async isPreSignedAsync(hash: string, signerAddress: string, methodOpts: MethodOpts = {}): Promise<boolean> {
+ assert.isHexString('hash', hash);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ if (!_.isUndefined(methodOpts)) {
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ }
+ const exchangeInstance = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const isPreSigned = await exchangeInstance.preSigned.callAsync(
+ hash,
+ signerAddress,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return isPreSigned;
+ }
+ /**
+ * Checks if transaction is already executed.
+ * @param transactionHash Transaction hash to check
+ * @param signerAddress Address that should have signed the given hash.
+ * @param methodOpts Optional arguments this method accepts.
+ * @returns If transaction is already executed.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async isTransactionExecutedAsync(transactionHash: string, methodOpts: MethodOpts = {}): Promise<boolean> {
+ assert.isHexString('transactionHash', transactionHash);
+ if (!_.isUndefined(methodOpts)) {
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ }
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txData = {};
+ const isExecuted = await exchangeInstance.transactions.callAsync(
+ transactionHash,
+ txData,
+ methodOpts.defaultBlock,
+ );
+ return isExecuted;
+ }
+ /**
+ * Get order info
+ * @param order Order
+ * @param methodOpts Optional arguments this method accepts.
+ * @returns Order info
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async getOrderInfoAsync(order: Order | SignedOrder, methodOpts: MethodOpts = {}): Promise<OrderInfo> {
+ if (!_.isUndefined(methodOpts)) {
+ assert.doesConformToSchema('methodOpts', methodOpts, methodOptsSchema);
+ }
+ const exchangeInstance = await this._getExchangeContractAsync();
+
+ const txData = {};
+ const orderInfo = await exchangeInstance.getOrderInfo.callAsync(order, txData, methodOpts.defaultBlock);
+ return orderInfo;
+ }
+ /**
+ * Cancel a given order.
+ * @param order An object that conforms to the Order or SignedOrder interface. The order you would like to cancel.
+ * @param transactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async cancelOrderAsync(
+ order: Order | SignedOrder,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.doesConformToSchema('order', order, schemas.orderSchema);
+ await assert.isSenderAddressAsync('order.maker', order.makerAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedMakerAddress = order.makerAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(order, {
+ from: normalizedMakerAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ });
+ return txHash;
+ }
+ /**
+ * Sets the signature validator approval
+ * @param validatorAddress Validator contract address.
+ * @param isApproved Boolean value to set approval to.
+ * @param senderAddress Sender address.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async setSignatureValidatorApprovalAsync(
+ validatorAddress: string,
+ isApproved: boolean,
+ senderAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.isETHAddressHex('validatorAddress', validatorAddress);
+ assert.isBoolean('isApproved', isApproved);
+ await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedSenderAddress = senderAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txHash = await exchangeInstance.setSignatureValidatorApproval.sendTransactionAsync(
+ validatorAddress,
+ isApproved,
+ {
+ from: normalizedSenderAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ },
+ );
+ return txHash;
+ }
+ /**
+ * Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch
+ * and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).
+ * @param targetOrderEpoch Target order epoch.
+ * @param senderAddress Address that should send the transaction.
+ * @param orderTransactionOpts Optional arguments this method accepts.
+ * @return Transaction hash.
+ */
+ @decorators.asyncZeroExErrorHandler
+ public async cancelOrdersUpToAsync(
+ targetOrderEpoch: BigNumber,
+ senderAddress: string,
+ orderTransactionOpts: OrderTransactionOpts = {},
+ ): Promise<string> {
+ assert.isBigNumber('targetOrderEpoch', targetOrderEpoch);
+ await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
+ assert.doesConformToSchema('orderTransactionOpts', orderTransactionOpts, orderTxOptsSchema, [txOptsSchema]);
+ const normalizedSenderAddress = senderAddress.toLowerCase();
+
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const txHash = await exchangeInstance.cancelOrdersUpTo.sendTransactionAsync(targetOrderEpoch, {
+ from: normalizedSenderAddress,
+ gas: orderTransactionOpts.gasLimit,
+ gasPrice: orderTransactionOpts.gasPrice,
+ });
+ return txHash;
+ }
+ /**
+ * Subscribe to an event type emitted by the Exchange contract.
+ * @param eventName The exchange contract event you would like to subscribe to.
+ * @param indexFilterValues An object where the keys are indexed args returned by the event and
+ * the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
+ * @param callback Callback that gets called when a log is added/removed
+ * @return Subscription token used later to unsubscribe
+ */
+ public subscribe<ArgsType extends ExchangeEventArgs>(
+ eventName: ExchangeEvents,
+ indexFilterValues: IndexedFilterValues,
+ callback: EventCallback<ArgsType>,
+ ): string {
+ assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
+ assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+ assert.isFunction('callback', callback);
+ const exchangeContractAddress = this.getContractAddress();
+ const subscriptionToken = this._subscribe<ArgsType>(
+ exchangeContractAddress,
+ eventName,
+ indexFilterValues,
+ artifacts.Exchange.compilerOutput.abi,
+ callback,
+ );
+ return subscriptionToken;
+ }
+ /**
+ * Cancel a subscription
+ * @param subscriptionToken Subscription token returned by `subscribe()`
+ */
+ public unsubscribe(subscriptionToken: string): void {
+ this._unsubscribe(subscriptionToken);
+ }
+ /**
+ * Cancels all existing subscriptions
+ */
+ public unsubscribeAll(): void {
+ super._unsubscribeAll();
+ }
+ /**
+ * Gets historical logs without creating a subscription
+ * @param eventName The exchange contract event you would like to subscribe to.
+ * @param blockRange Block range to get logs from.
+ * @param indexFilterValues An object where the keys are indexed args returned by the event and
+ * the value is the value you are interested in. E.g `{_from: aUserAddressHex}`
+ * @return Array of logs that match the parameters
+ */
+ public async getLogsAsync<ArgsType extends ExchangeEventArgs>(
+ eventName: ExchangeEvents,
+ blockRange: BlockRange,
+ indexFilterValues: IndexedFilterValues,
+ ): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
+ assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
+ assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
+ assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
+ const exchangeContractAddress = this.getContractAddress();
+ const logs = await this._getLogsAsync<ArgsType>(
+ exchangeContractAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
+ artifacts.Exchange.compilerOutput.abi,
+ );
+ return logs;
+ }
+ /**
+ * Retrieves the Ethereum address of the Exchange contract deployed on the network
+ * that the user-passed web3 provider is connected to.
+ * @returns The Ethereum address of the Exchange contract being used.
+ */
+ public getContractAddress(): string {
+ const contractAddress = this._getContractAddress(artifacts.Exchange, this._contractAddressIfExists);
+ return contractAddress;
+ }
+ /**
+ * Returns the ZRX token address used by the exchange contract.
+ * @return Address of ZRX token
+ */
+ public getZRXTokenAddress(): string {
+ const contractAddress = this._getContractAddress(artifacts.ZRXToken, this._zrxContractAddressIfExists);
+ return contractAddress;
+ }
+ /**
+ * Returns the ZRX asset data used by the exchange contract.
+ * @return ZRX asset data
+ */
+ public async getZRXAssetDataAsync(): Promise<string> {
+ const exchangeInstance = await this._getExchangeContractAsync();
+ const zrxAssetData = exchangeInstance.ZRX_ASSET_DATA.callAsync();
+ return zrxAssetData;
+ }
+ // tslint:disable:no-unused-variable
+ private _invalidateContractInstances(): void {
+ this.unsubscribeAll();
+ delete this._exchangeContractIfExists;
+ }
+ // tslint:enable:no-unused-variable
+ private async _getExchangeContractAsync(): Promise<ExchangeContract> {
+ if (!_.isUndefined(this._exchangeContractIfExists)) {
+ return this._exchangeContractIfExists;
+ }
+ const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
+ artifacts.Exchange,
+ this._contractAddressIfExists,
+ );
+ const contractInstance = new ExchangeContract(
+ abi,
+ address,
+ this._web3Wrapper.getProvider(),
+ this._web3Wrapper.getContractDefaults(),
+ );
+ this._exchangeContractIfExists = contractInstance;
+ return this._exchangeContractIfExists;
+ }
+} // tslint:disable:max-file-line-count
diff --git a/packages/contract-wrappers/src/index.ts b/packages/contract-wrappers/src/index.ts
index 200ad7676..194a933f0 100644
--- a/packages/contract-wrappers/src/index.ts
+++ b/packages/contract-wrappers/src/index.ts
@@ -19,6 +19,8 @@ export {
LogEvent,
DecodedLogEvent,
OnOrderStateChangeCallback,
+ OrderStatus,
+ OrderInfo,
} from './types';
export { Order, SignedOrder, ECSignature, OrderStateValid, OrderStateInvalid, OrderState } from '@0xproject/types';
@@ -56,3 +58,12 @@ export {
ERC721TokenTransferEventArgs,
ERC721TokenEvents,
} from './contract_wrappers/generated/erc721_token';
+
+export {
+ ExchangeCancelUpToEventArgs,
+ ExchangeAssetProxySetEventArgs,
+ ExchangeFillEventArgs,
+ ExchangeCancelEventArgs,
+ ExchangeEventArgs,
+ ExchangeEvents,
+} from './contract_wrappers/generated/exchange';
diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts
index 759078feb..4b68daf1a 100644
--- a/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts
+++ b/packages/contract-wrappers/src/schemas/contract_wrappers_private_network_config_schema.ts
@@ -10,6 +10,7 @@ export const contractWrappersPrivateNetworkConfigSchema = {
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
+ blockPollingIntervalMs: { type: 'number' },
orderWatcherConfig: {
type: 'object',
properties: {
diff --git a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts
index 304cd100b..988872376 100644
--- a/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts
+++ b/packages/contract-wrappers/src/schemas/contract_wrappers_public_network_config_schema.ts
@@ -24,6 +24,7 @@ export const contractWrappersPublicNetworkConfigSchema = {
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
+ blockPollingIntervalMs: { type: 'number' },
orderWatcherConfig: {
type: 'object',
properties: {
diff --git a/packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts b/packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts
new file mode 100644
index 000000000..31ad759d5
--- /dev/null
+++ b/packages/contract-wrappers/src/schemas/order_tx_opts_schema.ts
@@ -0,0 +1,8 @@
+export const orderTxOptsSchema = {
+ id: '/OrderTxOpts',
+ allOf: [{ $ref: '/TxOpts' }],
+ properties: {
+ shouldValidate: { type: 'boolean' },
+ },
+ type: 'object',
+};
diff --git a/packages/contract-wrappers/src/types.ts b/packages/contract-wrappers/src/types.ts
index eb0b5abfe..8d19d085f 100644
--- a/packages/contract-wrappers/src/types.ts
+++ b/packages/contract-wrappers/src/types.ts
@@ -108,6 +108,7 @@ export type SyncMethod = (...args: any[]) => any;
* erc20ProxyContractAddress: The address of the erc20 token transfer proxy contract to use
* erc721ProxyContractAddress: The address of the erc721 token transfer proxy contract to use
* orderWatcherConfig: All the configs related to the orderWatcher
+ * blockPollingIntervalMs: The interval to use for block polling in event watching methods (defaults to 1000)
*/
export interface ContractWrappersConfig {
networkId: number;
@@ -116,6 +117,7 @@ export interface ContractWrappersConfig {
zrxContractAddress?: string;
erc20ProxyContractAddress?: string;
erc721ProxyContractAddress?: string;
+ blockPollingIntervalMs?: number;
}
/**
@@ -166,3 +168,19 @@ export enum TransferType {
}
export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void;
+
+export interface OrderInfo {
+ orderStatus: number;
+ orderHash: string;
+ orderTakerAssetFilledAmount: BigNumber;
+}
+
+export enum OrderStatus {
+ INVALID,
+ INVALID_MAKER_ASSET_AMOUNT,
+ INVALID_TAKER_ASSET_AMOUNT,
+ FILLABLE,
+ EXPIRED,
+ FULLY_FILLED,
+ CANCELLED,
+}
diff --git a/packages/contract-wrappers/test/erc721_wrapper_test.ts b/packages/contract-wrappers/test/erc721_wrapper_test.ts
index e3440b9b9..96b8fcf1d 100644
--- a/packages/contract-wrappers/test/erc721_wrapper_test.ts
+++ b/packages/contract-wrappers/test/erc721_wrapper_test.ts
@@ -426,7 +426,7 @@ describe('ERC721Wrapper', () => {
);
expect(logs).to.have.length(0);
});
- it.only('should only get the logs with the correct indexed fields', async () => {
+ it('should only get the logs with the correct indexed fields', async () => {
const isApprovedForAll = true;
txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
tokenAddress,
diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts
index c945b4c70..e1e0e02f6 100644
--- a/packages/contract-wrappers/test/exchange_wrapper_test.ts
+++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts
@@ -1,57 +1,91 @@
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
import { FillScenarios } from '@0xproject/fill-scenarios';
-import { getOrderHashHex } from '@0xproject/order-utils';
-import { BlockParamLiteral, DoneCallback, OrderState } from '@0xproject/types';
+import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
+import { DoneCallback, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
-import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
+import { BlockParamLiteral } from 'ethereum-types';
import 'mocha';
import {
- BlockRange,
ContractWrappers,
DecodedLogEvent,
- ExchangeContractErrs,
+ ExchangeCancelEventArgs,
ExchangeEvents,
- LogCancelContractEventArgs,
- LogFillContractEventArgs,
- OrderCancellationRequest,
- OrderFillRequest,
- SignedOrder,
- Token,
+ ExchangeFillEventArgs,
+ OrderStatus,
} from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
-import { TokenUtils } from './utils/token_utils';
+import { tokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
-
describe('ExchangeWrapper', () => {
let contractWrappers: ContractWrappers;
- let tokenUtils: TokenUtils;
- let tokens: Token[];
let userAddresses: string[];
let zrxTokenAddress: string;
let fillScenarios: FillScenarios;
let exchangeContractAddress: string;
+ let makerTokenAddress: string;
+ let takerTokenAddress: string;
+ let coinbase: string;
+ let makerAddress: string;
+ let anotherMakerAddress: string;
+ let takerAddress: string;
+ let makerAssetData: string;
+ let takerAssetData: string;
+ let feeRecipient: string;
+ let txHash: string;
+ const fillableAmount = new BigNumber(5);
+ const takerTokenFillAmount = new BigNumber(5);
+ let signedOrder: SignedOrder;
+ let anotherSignedOrder: SignedOrder;
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
+ blockPollingIntervalMs: 0,
};
before(async () => {
+ await blockchainLifecycle.startAsync();
contractWrappers = new ContractWrappers(provider, config);
exchangeContractAddress = contractWrappers.exchange.getContractAddress();
+ const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- tokenUtils = new TokenUtils(tokens);
- zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
- fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
- await fillScenarios.initTokenBalancesAsync();
+ zrxTokenAddress = tokenUtils.getProtocolTokenAddress();
+ fillScenarios = new FillScenarios(
+ provider,
+ userAddresses,
+ zrxTokenAddress,
+ exchangeContractAddress,
+ erc20ProxyAddress,
+ );
+ [coinbase, makerAddress, takerAddress, feeRecipient, anotherMakerAddress] = userAddresses;
+ [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
+ [makerAssetData, takerAssetData] = [
+ assetProxyUtils.encodeERC20AssetData(makerTokenAddress),
+ assetProxyUtils.encodeERC20AssetData(takerTokenAddress),
+ ];
+ signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerAssetData,
+ takerAssetData,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ );
+ anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerAssetData,
+ takerAssetData,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ );
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -59,903 +93,279 @@ describe('ExchangeWrapper', () => {
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
- describe('fillOrKill order(s)', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- const takerTokenFillAmount = new BigNumber(5);
- before(async () => {
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- describe('#batchFillOrKillAsync', () => {
- it('successfully batch fillOrKill', async () => {
- const fillableAmount = new BigNumber(5);
- const partialFillTakerAmount = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ describe('fill order(s)', () => {
+ describe('#fillOrderAsync', () => {
+ it('should fill a valid order', async () => {
+ txHash = await contractWrappers.exchange.fillOrderAsync(
+ signedOrder,
+ takerTokenFillAmount,
takerAddress,
- fillableAmount,
);
- const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ });
+ });
+ describe('#fillOrderNoThrowAsync', () => {
+ it('should fill a valid order', async () => {
+ txHash = await contractWrappers.exchange.fillOrderNoThrowAsync(
+ signedOrder,
+ takerTokenFillAmount,
takerAddress,
- fillableAmount,
);
- const orderFillRequests = [
- {
- signedOrder,
- takerTokenFillAmount: partialFillTakerAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount: partialFillTakerAmount,
- },
- ];
- await contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
- });
- describe('order transaction options', () => {
- let signedOrder: SignedOrder;
- let orderFillRequests: OrderFillRequest[];
- const fillableAmount = new BigNumber(5);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- orderFillRequests = [
- {
- signedOrder,
- takerTokenFillAmount: new BigNumber(0),
- },
- ];
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
});
});
describe('#fillOrKillOrderAsync', () => {
- let signedOrder: SignedOrder;
- const fillableAmount = new BigNumber(5);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ it('should fill or kill a valid order', async () => {
+ txHash = await contractWrappers.exchange.fillOrKillOrderAsync(
+ signedOrder,
+ takerTokenFillAmount,
takerAddress,
- fillableAmount,
);
- });
- describe('successful fills', () => {
- it('should fill a valid order', async () => {
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- await contractWrappers.exchange.fillOrKillOrderAsync(
- signedOrder,
- takerTokenFillAmount,
- takerAddress,
- );
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- });
- it('should partially fill a valid order', async () => {
- const partialFillAmount = new BigNumber(3);
- await contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- });
- });
- describe('order transaction options', () => {
- const emptyFillableAmount = new BigNumber(0);
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
- });
- describe('fill order(s)', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- const fillableAmount = new BigNumber(5);
- const takerTokenFillAmount = new BigNumber(5);
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
- before(async () => {
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- describe('#fillOrderAsync', () => {
- describe('successful fills', () => {
- it('should fill a valid order', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- const txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- takerTokenFillAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- });
- it('should partially fill the valid order', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const partialFillAmount = new BigNumber(3);
- const txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- partialFillAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- });
- it('should fill the valid orders with fees', async () => {
- const makerFee = new BigNumber(1);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- feeRecipient,
- );
- const txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- takerTokenFillAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- expect(
- await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient),
- ).to.be.bignumber.equal(makerFee.plus(takerFee));
- });
- });
- describe('order transaction options', () => {
- let signedOrder: SignedOrder;
- const emptyFillTakerAmount = new BigNumber(0);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- emptyFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- emptyFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: true,
- },
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- emptyFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: false,
- },
- ),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ describe('#batchFillOrdersAsync', () => {
+ it('should fill a batch of valid orders', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount];
+ txHash = await contractWrappers.exchange.batchFillOrdersAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
- describe('negative fill amount', async () => {
- let signedOrder: SignedOrder;
- const negativeFillTakerAmount = new BigNumber(-100);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- });
- it('should not allow the exchange wrapper to fill if amount is negative', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- negativeFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejected();
- });
+ });
+ describe('#marketBuyOrdersAsync', () => {
+ it('should maker buy', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const makerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketBuyOrdersAsync(
+ signedOrders,
+ makerAssetFillAmount,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
- describe('#batchFillOrdersAsync', () => {
- let signedOrder: SignedOrder;
- let signedOrderHashHex: string;
- let anotherSignedOrder: SignedOrder;
- let anotherOrderHashHex: string;
- let orderFillBatch: OrderFillRequest[];
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ describe('#marketBuyOrdersNoThrowAsync', () => {
+ it('should no throw maker buy', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const makerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketBuyOrdersNoThrowAsync(
+ signedOrders,
+ makerAssetFillAmount,
takerAddress,
- fillableAmount,
);
- signedOrderHashHex = getOrderHashHex(signedOrder);
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ });
+ });
+ describe('#marketSellOrdersAsync', () => {
+ it('should maker sell', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketSellOrdersAsync(
+ signedOrders,
+ takerAssetFillAmount,
takerAddress,
- fillableAmount,
);
- anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
- });
- describe('successful batch fills', () => {
- beforeEach(() => {
- orderFillBatch = [
- {
- signedOrder,
- takerTokenFillAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount,
- },
- ];
- });
- it('should throw if a batch is empty', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- [],
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
- });
- it('should successfully fill multiple orders', async () => {
- const txHash = await contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount);
- expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
- describe('order transaction options', () => {
- beforeEach(async () => {
- const emptyFillTakerAmount = new BigNumber(0);
- orderFillBatch = [
- {
- signedOrder,
- takerTokenFillAmount: emptyFillTakerAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount: emptyFillTakerAmount,
- },
- ];
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: true,
- },
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: false,
- },
- ),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- });
- describe('negative batch fill amount', async () => {
- beforeEach(async () => {
- const negativeFillTakerAmount = new BigNumber(-100);
- orderFillBatch = [
- {
- signedOrder,
- takerTokenFillAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount: negativeFillTakerAmount,
- },
- ];
- });
- it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejected();
- });
+ });
+ describe('#marketSellOrdersNoThrowAsync', () => {
+ it('should no throw maker sell', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketSellOrdersNoThrowAsync(
+ signedOrders,
+ takerAssetFillAmount,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ });
+ });
+ describe('#batchFillOrdersNoThrowAsync', () => {
+ it('should fill a batch of valid orders', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount];
+ txHash = await contractWrappers.exchange.batchFillOrdersNoThrowAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ let orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ orderInfo = await contractWrappers.exchange.getOrderInfoAsync(anotherSignedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ });
+ });
+ describe('#batchFillOrKillOrdersAsync', () => {
+ it('should fill or kill a batch of valid orders', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount];
+ txHash = await contractWrappers.exchange.batchFillOrKillOrdersAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
- describe('#fillOrdersUpTo', () => {
- let signedOrder: SignedOrder;
- let signedOrderHashHex: string;
- let anotherSignedOrder: SignedOrder;
- let anotherOrderHashHex: string;
- let signedOrders: SignedOrder[];
- const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
+ describe('#matchOrdersAsync', () => {
+ it('should match two valid ordersr', async () => {
+ const matchingSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ takerAssetData,
+ makerAssetData,
makerAddress,
takerAddress,
fillableAmount,
);
- signedOrderHashHex = getOrderHashHex(signedOrder);
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ txHash = await contractWrappers.exchange.matchOrdersAsync(
+ signedOrder,
+ matchingSignedOrder,
takerAddress,
- fillableAmount,
);
- anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
- signedOrders = [signedOrder, anotherSignedOrder];
- });
- describe('successful batch fills', () => {
- it('should throw if a batch is empty', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- [],
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
- });
- it('should successfully fill up to specified amount when all orders are fully funded', async () => {
- const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(filledAmount).to.be.bignumber.equal(fillableAmount);
- const remainingFillAmount = fillableAmount.minus(1);
- expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
- });
- it('should successfully fill up to specified amount and leave the rest of the orders untouched', async () => {
- const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const zeroAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
- expect(filledAmount).to.be.bignumber.equal(fillableAmount);
- expect(zeroAmount).to.be.bignumber.equal(0);
- });
- it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
- const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
- // but won't have 10 to fully fill all orders in a batch.
- await contractWrappers.token.transferAsync(
- makerTokenAddress,
- makerAddress,
- coinbase,
- missingBalance,
- );
- const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(filledAmount).to.be.bignumber.equal(fillableAmount);
- const remainingFillAmount = fillableAmount.minus(1);
- expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
- });
- });
- describe('failed batch fills', () => {
- it("should fail validation if user doesn't have enough balance without fill up to", async () => {
- const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
- await contractWrappers.token.transferAsync(
- makerTokenAddress,
- makerAddress,
- coinbase,
- missingBalance,
- );
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
- });
- });
- describe('order transaction options', () => {
- const emptyFillUpToAmount = new BigNumber(0);
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- emptyFillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- emptyFillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: true,
- },
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- emptyFillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: false,
- },
- ),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
});
describe('cancel order(s)', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- const fillableAmount = new BigNumber(5);
- let signedOrder: SignedOrder;
- let orderHashHex: string;
- const cancelAmount = new BigNumber(3);
- beforeEach(async () => {
- [coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- orderHashHex = getOrderHashHex(signedOrder);
- });
describe('#cancelOrderAsync', () => {
- describe('successful cancels', () => {
- it('should cancel an order', async () => {
- const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex);
- expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
- });
- });
- describe('order transaction options', () => {
- const emptyCancelTakerTokenAmount = new BigNumber(0);
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
+ it('should cancel a valid order', async () => {
+ txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
describe('#batchCancelOrdersAsync', () => {
- let anotherSignedOrder: SignedOrder;
- let anotherOrderHashHex: string;
- let cancelBatch: OrderCancellationRequest[];
- beforeEach(async () => {
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
+ it('should cancel a batch of valid orders', async () => {
+ const orders = [signedOrder, anotherSignedOrder];
+ txHash = await contractWrappers.exchange.batchCancelOrdersAsync(orders);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ });
+ });
+ describe('#cancelOrdersUpTo/getOrderEpochAsync', () => {
+ it('should cancel orders up to target order epoch', async () => {
+ const targetOrderEpoch = new BigNumber(42);
+ txHash = await contractWrappers.exchange.cancelOrdersUpToAsync(targetOrderEpoch, makerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderEpoch = await contractWrappers.exchange.getOrderEpochAsync(
makerAddress,
- takerAddress,
- fillableAmount,
+ constants.NULL_ADDRESS,
);
- anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
- cancelBatch = [
- {
- order: signedOrder,
- takerTokenCancelAmount: cancelAmount,
- },
- {
- order: anotherSignedOrder,
- takerTokenCancelAmount: cancelAmount,
- },
- ];
- });
- describe('failed batch cancels', () => {
- it('should throw when orders have different makers', async () => {
- const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- takerAddress,
- takerAddress,
- fillableAmount,
- );
- return expect(
- contractWrappers.exchange.batchCancelOrdersAsync([
- cancelBatch[0],
- {
- order: signedOrderWithDifferentMaker,
- takerTokenCancelAmount: cancelAmount,
- },
- ]),
- ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
- });
- });
- describe('successful batch cancels', () => {
- it('should cancel a batch of orders', async () => {
- await contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch);
- const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex);
- const anotherCancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
- expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
- });
- });
- describe('order transaction options', () => {
- beforeEach(async () => {
- const emptyTakerTokenCancelAmount = new BigNumber(0);
- cancelBatch = [
- {
- order: signedOrder,
- takerTokenCancelAmount: emptyTakerTokenCancelAmount,
- },
- {
- order: anotherSignedOrder,
- takerTokenCancelAmount: emptyTakerTokenCancelAmount,
- },
- ];
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
- ExchangeContractErrs.OrderCancelAmountZero,
- );
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
+ expect(orderEpoch).to.be.bignumber.equal(targetOrderEpoch.plus(1));
});
});
});
- describe('tests that require partially filled order', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let takerAddress: string;
- let fillableAmount: BigNumber;
- let partialFillAmount: BigNumber;
- let signedOrder: SignedOrder;
- let orderHash: string;
- before(() => {
- takerAddress = userAddresses[1];
- tokenUtils = new TokenUtils(tokens);
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
+ describe('#getZRXAssetData', () => {
+ it('should get the asset data', async () => {
+ const ZRX_ASSET_DATA = await contractWrappers.exchange.getZRXAssetDataAsync();
+ const ASSET_DATA_HEX_LENGTH = 74;
+ expect(ZRX_ASSET_DATA).to.have.length(ASSET_DATA_HEX_LENGTH);
});
- beforeEach(async () => {
- fillableAmount = new BigNumber(5);
- partialFillAmount = new BigNumber(2);
- signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- takerAddress,
- fillableAmount,
- partialFillAmount,
+ });
+ describe('#getOrderInfoAsync', () => {
+ it('should get the order info', async () => {
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ expect(orderInfo.orderHash).to.be.equal(orderHash);
+ });
+ });
+ describe('#isValidSignature', () => {
+ it('should check if the signature is valid', async () => {
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ let isValid = await contractWrappers.exchange.isValidSignatureAsync(
+ orderHash,
+ signedOrder.makerAddress,
+ signedOrder.signature,
+ );
+ expect(isValid).to.be.true();
+ isValid = await contractWrappers.exchange.isValidSignatureAsync(
+ orderHash,
+ signedOrder.takerAddress,
+ signedOrder.signature,
);
- orderHash = getOrderHashHex(signedOrder);
+ expect(isValid).to.be.false();
});
- describe('#getUnavailableTakerAmountAsync', () => {
- it('should throw if passed an invalid orderHash', async () => {
- const invalidOrderHashHex = '0x123';
- return expect(
- contractWrappers.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex),
- ).to.be.rejected();
- });
- it('should return zero if passed a valid but non-existent orderHash', async () => {
- const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(
- NON_EXISTENT_ORDER_HASH,
- );
- expect(unavailableValueT).to.be.bignumber.equal(0);
- });
- it('should return the unavailableValueT for a valid and partially filled orderHash', async () => {
- const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(orderHash);
- expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
- });
+ });
+ describe('#isAllowedValidatorAsync', () => {
+ it('should check if the validator is alllowed', async () => {
+ const signerAddress = makerAddress;
+ const validatorAddress = constants.NULL_ADDRESS;
+ const isAllowed = await contractWrappers.exchange.isAllowedValidatorAsync(signerAddress, validatorAddress);
+ expect(isAllowed).to.be.false();
});
- describe('#getFilledTakerAmountAsync', () => {
- it('should throw if passed an invalid orderHash', async () => {
- const invalidOrderHashHex = '0x123';
- return expect(
- contractWrappers.exchange.getFilledTakerAmountAsync(invalidOrderHashHex),
- ).to.be.rejected();
- });
- it('should return zero if passed a valid but non-existent orderHash', async () => {
- const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
- expect(filledValueT).to.be.bignumber.equal(0);
- });
- it('should return the filledValueT for a valid and partially filled orderHash', async () => {
- const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(orderHash);
- expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
- });
+ });
+ describe('#setSignatureValidatorApproval', () => {
+ it('should set signature validator approval', async () => {
+ const validatorAddress = constants.NULL_ADDRESS;
+ const isApproved = true;
+ const senderAddress = makerAddress;
+ txHash = await contractWrappers.exchange.setSignatureValidatorApprovalAsync(
+ validatorAddress,
+ isApproved,
+ senderAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
- describe('#getCancelledTakerAmountAsync', () => {
- it('should throw if passed an invalid orderHash', async () => {
- const invalidOrderHashHex = '0x123';
- return expect(
- contractWrappers.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex),
- ).to.be.rejected();
- });
- it('should return zero if passed a valid but non-existent orderHash', async () => {
- const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(
- NON_EXISTENT_ORDER_HASH,
- );
- expect(cancelledValueT).to.be.bignumber.equal(0);
- });
- it('should return the cancelledValueT for a valid and partially filled orderHash', async () => {
- const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash);
- expect(cancelledValueT).to.be.bignumber.equal(0);
- });
- it('should return the cancelledValueT for a valid and cancelled orderHash', async () => {
- const cancelAmount = fillableAmount.minus(partialFillAmount);
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
- const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash);
- expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
- });
+ });
+ describe('#isTransactionExecutedAsync', () => {
+ it('should check if the transaction is executed', async () => {
+ const transactionHash = '0x0000000000000000000000000000000000000000000000000000000000000000';
+ const isExecuted = await contractWrappers.exchange.isTransactionExecutedAsync(transactionHash);
+ expect(isExecuted).to.be.false();
+ });
+ });
+ describe('#getAssetProxyBySignatureAsync', () => {
+ it('should fill or kill a valid order', async () => {
+ const erc20ProxyId = await contractWrappers.erc20Proxy.getProxyIdAsync();
+ const erc20ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc20ProxyId);
+ const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
+ expect(erc20ProxyAddressById).to.be.equal(erc20ProxyAddress);
+ const erc721ProxyId = await contractWrappers.erc721Proxy.getProxyIdAsync();
+ const erc721ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc721ProxyId);
+ const erc721ProxyAddress = contractWrappers.erc721Proxy.getContractAddress();
+ expect(erc721ProxyAddressById).to.be.equal(erc721ProxyAddress);
+ });
+ });
+ describe('#preSignAsync/isPreSignedAsync', () => {
+ it('should preSign the hash', async () => {
+ const senderAddress = takerAddress;
+ const hash = orderHashUtils.getOrderHashHex(signedOrder);
+ const signerAddress = signedOrder.makerAddress;
+ let isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress);
+ expect(isPreSigned).to.be.false();
+ txHash = await contractWrappers.exchange.preSignAsync(
+ hash,
+ signerAddress,
+ signedOrder.signature,
+ senderAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress);
+ expect(isPreSigned).to.be.true();
+ });
+ });
+ describe('#getVersionAsync', () => {
+ it('should return version the hash', async () => {
+ const version = await contractWrappers.exchange.getVersionAsync();
+ const VERSION = '2.0.1-alpha';
+ expect(version).to.be.equal(VERSION);
});
});
describe('#subscribe', () => {
const indexFilterValues = {};
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let takerAddress: string;
- let makerAddress: string;
- let fillableAmount: BigNumber;
- let signedOrder: SignedOrder;
const takerTokenFillAmountInBaseUnits = new BigNumber(1);
- const cancelTakerAmountInBaseUnits = new BigNumber(1);
- before(() => {
- [coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
beforeEach(async () => {
- fillableAmount = new BigNumber(5);
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
+ makerAssetData,
+ takerAssetData,
makerAddress,
takerAddress,
fillableAmount,
@@ -969,18 +379,17 @@ describe('ExchangeWrapper', () => {
// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
// wrap the rest of the test in an async block
// Source: https://github.com/mochajs/mocha/issues/2407
- it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
+ it('Should receive the Fill event when an order is filled', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+ (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill);
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
- shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
})().catch(done);
@@ -988,35 +397,34 @@ describe('ExchangeWrapper', () => {
it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
+ (logEvent: DecodedLogEvent<ExchangeCancelEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.Cancel);
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Cancel, indexFilterValues, callback);
+ await contractWrappers.exchange.cancelOrderAsync(signedOrder);
})().catch(done);
});
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callbackNeverToBeCalled);
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+ (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill);
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
- shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
})().catch(done);
@@ -1024,12 +432,12 @@ describe('ExchangeWrapper', () => {
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ (_logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
const subscriptionToken = contractWrappers.exchange.subscribe(
- ExchangeEvents.LogFill,
+ ExchangeEvents.Fill,
indexFilterValues,
callbackNeverToBeCalled,
);
@@ -1037,102 +445,36 @@ describe('ExchangeWrapper', () => {
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
- shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
done();
})().catch(done);
});
});
- describe('#getOrderHashHexUsingContractCallAsync', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let makerAddress: string;
- let takerAddress: string;
- const fillableAmount = new BigNumber(5);
- before(async () => {
- [, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- it("get's the same hash as the local function", async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = getOrderHashHex(signedOrder);
- const orderHashFromContract = await (contractWrappers.exchange as any)._getOrderHashHexUsingContractCallAsync(
- signedOrder,
- );
- expect(orderHash).to.equal(orderHashFromContract);
- });
- });
describe('#getZRXTokenAddressAsync', () => {
it('gets the same token as is in token registry', () => {
- const zrxAddress = contractWrappers.exchange.getZRXTokenAddress();
- const zrxToken = tokenUtils.getProtocolTokenOrThrow();
- expect(zrxAddress).to.equal(zrxToken.address);
+ const zrxAddressFromExchangeWrapper = contractWrappers.exchange.getZRXTokenAddress();
+ const zrxAddress = tokenUtils.getProtocolTokenAddress();
+ expect(zrxAddressFromExchangeWrapper).to.equal(zrxAddress);
});
});
describe('#getLogsAsync', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let makerAddress: string;
- let takerAddress: string;
- const fillableAmount = new BigNumber(5);
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
- const blockRange: BlockRange = {
+ const blockRange = {
fromBlock: 0,
toBlock: BlockParamLiteral.Latest,
};
- let txHash: string;
- before(async () => {
- [, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- it('should get logs with decoded args emitted by LogFill', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const eventName = ExchangeEvents.LogFill;
+ it('should get logs with decoded args emitted by Fill', async () => {
+ txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+ const eventName = ExchangeEvents.Fill;
const indexFilterValues = {};
const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
expect(logs).to.have.length(1);
expect(logs[0].event).to.be.equal(eventName);
});
it('should only get the logs with the correct event name', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const differentEventName = ExchangeEvents.LogCancel;
+ txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const differentEventName = ExchangeEvents.Cancel;
const indexFilterValues = {};
const logs = await contractWrappers.exchange.getLogsAsync(
differentEventName,
@@ -1142,86 +484,28 @@ describe('ExchangeWrapper', () => {
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
+ txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
- const differentMakerAddress = userAddresses[2];
- const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- differentMakerAddress,
- takerAddress,
- fillableAmount,
- );
txHash = await contractWrappers.exchange.fillOrderAsync(
anotherSignedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
+ takerTokenFillAmount,
takerAddress,
);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
- const eventName = ExchangeEvents.LogFill;
+ const eventName = ExchangeEvents.Fill;
const indexFilterValues = {
- maker: differentMakerAddress,
+ makerAddress: anotherMakerAddress,
};
- const logs = await contractWrappers.exchange.getLogsAsync<LogFillContractEventArgs>(
+ const logs = await contractWrappers.exchange.getLogsAsync<ExchangeFillEventArgs>(
eventName,
blockRange,
indexFilterValues,
);
expect(logs).to.have.length(1);
const args = logs[0].args;
- expect(args.maker).to.be.equal(differentMakerAddress);
- });
- });
- describe('#getOrderStateAsync', () => {
- let maker: string;
- let taker: string;
- let makerToken: Token;
- let takerToken: Token;
- let signedOrder: SignedOrder;
- let orderState: OrderState;
- const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), constants.ZRX_DECIMALS);
- before(async () => {
- [, maker, taker] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- [makerToken, takerToken] = tokenUtils.getDummyTokens();
- });
- it('should report orderStateValid when order is fillable', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerToken.address,
- takerToken.address,
- maker,
- taker,
- fillableAmount,
- );
- orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.be.true();
- });
- it('should report orderStateInvalid when maker allowance set to 0', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerToken.address,
- takerToken.address,
- maker,
- taker,
- fillableAmount,
- );
- await contractWrappers.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
- orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.be.false();
+ expect(args.makerAddress).to.be.equal(anotherMakerAddress);
});
});
}); // tslint:disable:max-file-line-count
diff --git a/packages/contract-wrappers/test/utils/token_utils.ts b/packages/contract-wrappers/test/utils/token_utils.ts
index 3ef83546b..06a82ff6e 100644
--- a/packages/contract-wrappers/test/utils/token_utils.ts
+++ b/packages/contract-wrappers/test/utils/token_utils.ts
@@ -10,14 +10,14 @@ import { provider, txDefaults, web3Wrapper } from './web3_wrapper';
// Those addresses come from migrations. They're deterministic so it's relatively safe to hard-code them here.
// Before we were fetching them from the TokenRegistry but now we can't as it's deprecated and removed.
const DUMMY_ERC_20_ADRESSES = [
- '0x07f96aa816c1f244cbc6ef114bb2b023ba54a2eb',
- '0x6a4a62e5a7ed13c361b176a5f62c2ee620ac0df8',
'0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f',
'0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db',
'0xf22469f31527adc53284441bae1665a7b9214dba',
+ '0x10add991de718a69dec2117cb6aa28098836511b',
+ '0x8d61158a366019ac78db4149d75fff9dda51160d',
];
-const DUMMY_ERC_721_ADRESSES = ['0x10add991de718a69dec2117cb6aa28098836511b'];
+const DUMMY_ERC_721_ADRESSES = ['0x131855dda0aaff096f6854854c55a4debf61077a'];
export const tokenUtils = {
getProtocolTokenAddress(): string {