Compare commits

...

243 Commits

Author SHA1 Message Date
Fabio Berger
8fb5c29b4b Publish
- 0x.js@0.38.4
 - @0xproject/abi-gen@0.3.2
 - @0xproject/assert@0.2.12
 - @0xproject/base-contract@0.3.4
 - @0xproject/connect@0.6.15
 - @0xproject/contract-wrappers@0.0.5
 - contracts@2.1.33
 - @0xproject/dev-utils@0.4.4
 - @0xproject/fill-scenarios@0.0.4
 - @0xproject/json-schemas@0.8.1
 - @0xproject/metacoin@0.0.8
 - @0xproject/migrations@0.0.8
 - @0xproject/monorepo-scripts@0.2.1
 - @0xproject/order-utils@0.0.7
 - @0xproject/order-watcher@0.0.6
 - @0xproject/react-docs-example@0.0.13
 - @0xproject/react-docs@0.0.14
 - @0xproject/react-shared@0.2.1
 - @0xproject/sol-compiler@0.5.2
 - @0xproject/sol-cov@0.1.1
 - @0xproject/sol-resolver@0.0.7
 - @0xproject/sra-report@0.1.4
 - @0xproject/subproviders@0.10.4
 - @0xproject/testnet-faucets@1.0.34
 - @0xproject/tslint-config@0.4.20
 - @0xproject/types@0.8.1
 - @0xproject/typescript-typings@0.4.1
 - @0xproject/utils@0.7.1
 - @0xproject/web3-wrapper@0.7.1
 - @0xproject/website@0.0.37
2018-06-19 10:48:07 +02:00
Fabio Berger
40a061a5ca Updated CHANGELOGS 2018-06-19 10:48:00 +02:00
Fabio Berger
2ef82592a3 Improve error message 2018-06-19 10:36:19 +02:00
Fabio Berger
14b5448d70 Add missing timestamp 2018-06-19 10:35:22 +02:00
Fabio Berger
e7d45e47bf Remove the hotfix for Ethersjs and instead update to the fixed version in all packages 2018-06-19 10:30:49 +02:00
Fabio Berger
28268d4355 Update versions and CHANGELOG's to account for unpublished versions on NPM 2018-06-18 23:18:42 +02:00
Fabio Berger
50fa02c1d1 Small fixes 2018-06-18 23:16:44 +02:00
Fabio Berger
b36ff9103d Merge pull request #718 from 0xProject/improvement/publishing-flow
Improve Pre-publishing flow
2018-06-18 23:01:36 +02:00
Fabio Berger
f032c2466c Use semver package instead of getNextPatchVersion 2018-06-18 19:22:31 +02:00
Fabio Berger
b63ddc9be4 Use semver external librarty instead of semverUtils 2018-06-18 19:00:39 +02:00
Fabio Berger
171430b617 small fixes 2018-06-18 17:58:17 +02:00
Fabio Berger
d561043774 Show all errors of a given kind at once rather then throwing after the first instance is encountered 2018-06-18 17:41:03 +02:00
Fabio Berger
b1871e9ddd fix package.json 2018-06-18 16:57:22 +02:00
Fabio Berger
b4a5e7258c Add the following prePublish checks:
- That package version matches latest NPM package version (including unpublished versions)
- That changelogs are properly formatted (lastEntry version >= currentVersion, no accidental timestamps)
- Checks for and removes any git tags locally and remotely that might be left-over from a previous failed publish

Moved changelog related helpers to changelogUtils and other small cleanup refactors.
2018-06-18 16:55:59 +02:00
Fabio Berger
3c75debdf9 Remove the remove_tags script 2018-06-18 16:46:54 +02:00
Fabio Berger
84d1053f73 Add missing timestamp to web3-wrapper changelog 2018-06-15 17:11:30 +02:00
Fabio Berger
f9df42f5d9 Fix incorrect merges 2018-06-15 16:58:36 +02:00
Leonid Logvinov
4414ef0a0f fix cherry-pick 2018-06-15 16:51:13 +02:00
Leonid Logvinov
b7729ada38 fix cherry-pick 2018-06-15 16:48:29 +02:00
Leonid Logvinov
3da67feeb2 Add prepublish_checks 2018-06-15 16:45:18 +02:00
Leonid Logvinov
8a0d563a32 Add CHANGELOG entry 2018-06-15 16:44:48 +02:00
Leonid Logvinov
612fc4a949 Fix cherry-pick 2018-06-15 16:44:35 +02:00
Fabio Berger
bf915ce403 Merge pull request #709 from 0xProject/feature/pin-deps
[DEVELOPMENT] Ethersjs Issue Hot Fix
2018-06-15 14:14:45 +02:00
Fabio Berger
0f9ea9773e Add lib/test and ganache.log to npmignore 2018-06-15 14:14:30 +02:00
Fabio Berger
447a3a6c26 Fix prettier 2018-06-15 13:53:26 +02:00
Fabio Berger
f1cc16c44d Export OrderWatcherConfig from 0x.js 2018-06-15 13:38:25 +02:00
Fabio Berger
aae16b6343 Add ganache.log to gitignore 2018-06-15 13:37:08 +02:00
Fabio Berger
834e1538d1 Fix typos, versions and other mistypings 2018-06-15 11:48:52 +02:00
Leonid Logvinov
afc489bc2c Pin all external dependencies 2018-06-14 21:25:36 -07:00
Leonid Logvinov
3e061e7364 Fix the is not a function bug caused by breaking patch version https://github.com/ethers-io/ethers.js/issues/201 2018-06-14 12:31:57 -07:00
Leonid Logvinov
6395c2a8b2 Update changelogs 2018-06-04 11:19:59 -07:00
Leonid Logvinov
c8225288cd v0.7.0 2018-06-04 11:15:00 -07:00
Leonid Logvinov
4a108aa67d Set default params and jsonrpc in Web3Wrapper._sendRawPayloadAsync 2018-06-04 11:11:18 -07:00
Leonid Logvinov
fd9b3e0dcf Add default jsonRpcId to raw payloads sent from web3Wrapper 2018-06-01 16:01:04 -07:00
Leonid Logvinov
f94b647e61 Publish
- 0x.js@0.38.3
 - contracts@2.1.32
 - @0xproject/order-watcher@0.0.5
 - @0xproject/sra-report@0.1.3
 - @0xproject/testnet-faucets@1.0.33
 - @0xproject/website@0.0.36
2018-05-29 11:29:07 -07:00
Leonid Logvinov
2eccc3efaf Updated CHANGELOGS 2018-05-29 11:29:01 -07:00
Leonid Logvinov
972341725e Remove UMD bundles from order-watcher 2018-05-29 11:13:50 -07:00
Leonid Logvinov
40b10fd29d Publish
- 0x.js@0.38.2
 - @0xproject/contract-wrappers@0.0.4
 - contracts@2.1.31
 - @0xproject/order-watcher@0.0.4
 - @0xproject/sra-report@0.1.2
 - @0xproject/testnet-faucets@1.0.32
 - @0xproject/website@0.0.35
2018-05-29 11:12:33 -07:00
Leonid Logvinov
b31fcffc76 Updated CHANGELOGS 2018-05-29 11:12:26 -07:00
Leonid Logvinov
ec222ea0cd Remove UMD bundles from contract-wrappers 2018-05-29 11:04:00 -07:00
Leonid Logvinov
5533220da0 Publish
- 0x.js@0.38.1
 - @0xproject/connect@0.6.14
 - @0xproject/contract-wrappers@0.0.3
 - contracts@2.1.30
 - @0xproject/fill-scenarios@0.0.3
 - @0xproject/order-utils@0.0.6
 - @0xproject/order-watcher@0.0.3
 - @0xproject/sra-report@0.1.1
 - @0xproject/testnet-faucets@1.0.31
 - @0xproject/website@0.0.34
2018-05-29 11:01:25 -07:00
Leonid Logvinov
6ee7024457 Updated CHANGELOGS 2018-05-29 11:01:18 -07:00
Fabio Berger
f839ac9c58 Merge branch 'development' of github.com:0xProject/0x-monorepo into development
* 'development' of github.com:0xProject/0x-monorepo:
  Correct documentation variable name
  Publish
  Updated CHANGELOGS
  Updated CHANGELOGS
  Change publish command name
2018-05-22 16:39:15 -07:00
Fabio Berger
1a8b1460a6 Fix signature verification test 2018-05-22 16:38:57 -07:00
Leonid Logvinov
feac0779a4 Merge pull request #608 from prettymuchbryce/docs-fix
Correct documentation variable name
2018-05-22 15:38:27 -07:00
Bryce Neal
d9eeb0421c Correct documentation variable name 2018-05-22 13:37:38 -07:00
Leonid Logvinov
031f97e97c Publish
- 0x.js@0.38.0
 - @0xproject/abi-gen@0.3.0
 - @0xproject/assert@0.2.10
 - @0xproject/base-contract@0.3.2
 - @0xproject/connect@0.6.13
 - @0xproject/contract-wrappers@0.0.2
 - contracts@2.1.29
 - @0xproject/dev-utils@0.4.2
 - @0xproject/fill-scenarios@0.0.2
 - @0xproject/json-schemas@0.7.24
 - @0xproject/metacoin@0.0.7
 - @0xproject/migrations@0.0.6
 - @0xproject/monorepo-scripts@0.1.20
 - @0xproject/order-utils@0.0.5
 - @0xproject/order-watcher@0.0.2
 - @0xproject/react-docs-example@0.0.12
 - @0xproject/react-docs@0.0.12
 - @0xproject/react-shared@0.1.7
 - @0xproject/sol-compiler@0.5.0
 - @0xproject/sol-cov@0.0.11
 - @0xproject/sol-resolver@0.0.5
 - @0xproject/sra-report@0.1.0
 - @0xproject/subproviders@0.10.2
 - @0xproject/testnet-faucets@1.0.30
 - @0xproject/tslint-config@0.4.18
 - @0xproject/types@0.7.0
 - @0xproject/typescript-typings@0.3.2
 - @0xproject/utils@0.6.2
 - @0xproject/web3-wrapper@0.6.4
 - @0xproject/website@0.0.33
2018-05-22 10:26:47 -07:00
Leonid Logvinov
b9e1c3c34f Updated CHANGELOGS 2018-05-22 10:26:39 -07:00
Leonid Logvinov
1a35107a1d Updated CHANGELOGS 2018-05-22 10:16:53 -07:00
Leonid Logvinov
d3e086c850 Change publish command name 2018-05-22 10:16:53 -07:00
Fabio Berger
ab9cfd293b remove generated contract_wrappers during clean 2018-05-22 09:21:20 -07:00
Fabio Berger
cc840a6911 Merge pull request #594 from 0xProject/improvement/addCustomTslintRules
Add more tslint rules
2018-05-22 18:04:50 +02:00
Fabio Berger
c4a2f70017 Make lint run in parallel 2018-05-21 18:36:06 -07:00
Alex Browne
a26cc7c14d Merge pull request #597 from 0xProject/make-promises-safe
Use make-promises-safe to catch unhandled rejections in tests
2018-05-17 11:58:31 -07:00
Fabio Berger
7fab782907 Improve naming 2018-05-17 14:07:55 +02:00
Fabio Berger
cf7967e629 Disable magic number rule in more places where it isn't helping code readability 2018-05-17 14:07:44 +02:00
Fabio Berger
0eacbac8f6 Merge branch 'development' into improvement/addCustomTslintRules
* development:
  Remove "Order utils" from menu for now
  Fix top tokens key
  Improve about page descriptions
  Do not remove artifacts when running `clean`
2018-05-17 13:57:51 +02:00
Fabio Berger
cec76c33b6 Remove "Order utils" from menu for now 2018-05-17 13:21:37 +02:00
Brandon Millman
18dcf98998 Fix top tokens key 2018-05-16 18:07:47 -07:00
Alex Browne
251218af8b Use make-promises-safe to catch unhandled rejections in tests 2018-05-16 17:36:37 -07:00
fragosti
c06ed58582 Improve about page descriptions 2018-05-16 10:15:04 -07:00
Fabio Berger
4de6221825 Do not remove artifacts when running clean 2018-05-16 16:08:15 +02:00
Fabio Berger
22f3f57f44 Merge branch 'development' into improvement/addCustomTslintRules
* development:
  fix style errors
  Fix circular dependency
  Add my profile image to images
  Add myself to about page
  Add dogfood configs to website
  Change minimum Node version to 6.12
  Document Node.js version requirement and add it to package.json
2018-05-16 15:15:23 +02:00
Fabio Berger
b2f362225c Fix comments 2018-05-16 15:14:31 +02:00
Fabio Berger
40ed59ce28 Improve name 2018-05-16 15:14:24 +02:00
Fabio Berger
839db68571 Fix TSLint rules 2018-05-16 14:59:10 +02:00
Fabio Berger
fec6ac3ff0 Enforce new rules, including no-switch-case-fall-through 2018-05-16 14:58:28 +02:00
Fabio Berger
45fa26dc6c Implement boolean variable naming custom TSLint rule 2018-05-16 14:58:01 +02:00
Fabio Berger
f49d432fdc Implement custom no-magic-numbers rule that doesn't include magic numbers passed into BigNumber instantiations (e.g const amount = new BigNumber(5); ) 2018-05-16 14:57:28 +02:00
Fabio Berger
1a31ceff8e Run linter sequentially 2018-05-16 14:56:11 +02:00
Francesco Agosti
cc486cb86d Merge pull request #593 from 0xProject/bug/website/fix-cirular-dependency
Fix circular dependency
2018-05-15 16:35:05 -07:00
Francesco Agosti
7a45a579c0 Merge pull request #592 from 0xProject/feature/website/add-francesco-about
Add myself to about page
2018-05-15 15:59:24 -07:00
fragosti
dc58d539c2 fix style errors 2018-05-15 15:54:17 -07:00
fragosti
2ba78eb740 Fix circular dependency 2018-05-15 15:27:27 -07:00
fragosti
f43b275f16 Add my profile image to images 2018-05-15 14:50:33 -07:00
fragosti
509a81a572 Add myself to about page 2018-05-15 14:44:57 -07:00
Brandon Millman
184232ba4f Add dogfood configs to website 2018-05-15 13:51:43 -07:00
Alex Browne
0bc338ba42 Merge pull request #578 from 0xProject/document-node-version
Document Node.js version requirement and add it to package.json
2018-05-15 10:51:49 -07:00
Fabio Berger
406e91d387 Merge pull request #588 from 0xProject/improvement/use-wsrun
Individual package building & watching!!! 💪 🌹
2018-05-15 11:41:51 +02:00
Fabio Berger
473acafd14 Revert to lerna:run lint 2018-05-15 11:21:49 +02:00
Fabio Berger
7474e6b1c9 Do lint sequentially 2018-05-15 11:05:02 +02:00
Fabio Berger
323955277c Exclude monorepo-scripts from tslint as test 2018-05-15 10:47:00 +02:00
Fabio Berger
03b5b09122 Fix prettier 2018-05-15 10:43:41 +02:00
Fabio Berger
fe00c06d4b Merge development 2018-05-15 10:22:22 +02:00
Brandon Millman
ca08dd9705 Add hover state to top tokens 2018-05-15 00:52:51 -07:00
Brandon Millman
b3e53b609b Change to weekly txn volume 2018-05-14 22:49:08 -07:00
Alex Browne
fdeab0475c Change minimum Node version to 6.12 2018-05-14 18:46:53 -07:00
Alex Browne
f86cc0dc7a Document Node.js version requirement and add it to package.json 2018-05-14 18:46:52 -07:00
Alex Browne
0457c959dd Merge pull request #590 from 0xProject/fix-prettier
Apply prettier to some files which were not formatted correctly
2018-05-14 18:41:45 -07:00
Alex Browne
c520b7f1fb Apply prettier to some files which were not formatted correctly 2018-05-14 15:44:09 -07:00
Fabio Berger
5422bf5733 Fix TSLint issues 2018-05-14 23:27:41 +02:00
Fabio Berger
a703160226 Merge branch 'development' into improvement/use-wsrun
* development:
  Update ethereeumjs-testrpc to ganache-cli

# Conflicts:
#	package.json
2018-05-14 22:31:53 +02:00
Fabio Berger
d0905eda49 Fix TSLint issues 2018-05-14 21:48:46 +02:00
Leonid Logvinov
da60008048 Update ethereeumjs-testrpc to ganache-cli 2018-05-14 20:16:13 +02:00
Fabio Berger
7c023233f2 Fix infinite loop 2018-05-14 20:02:41 +02:00
Fabio Berger
1e7003a307 Add changelog entries for packages where executable binary exporting fixed 2018-05-14 19:57:41 +02:00
Fabio Berger
8cb074657d Rename bin to server in testnet-faucets since bin is no longer gitignored 2018-05-14 19:33:45 +02:00
Fabio Berger
5f72b86ce4 Fix sra-report binary 2018-05-14 19:33:23 +02:00
Fabio Berger
09d33792f3 rename build:watch to watch and remove build from docs:stage 2018-05-14 19:32:52 +02:00
Fabio Berger
a6773b85d2 Fix sol-compiler binary so it can be called directly from packages 2018-05-14 19:32:32 +02:00
Fabio Berger
5f678acf46 Fix abi-gen binary so it can be called directly from packages 2018-05-14 19:31:56 +02:00
Fabio Berger
76f9ad0705 Remove build from docs:stage commands 2018-05-14 19:24:47 +02:00
Fabio Berger
478f6ed011 Move from using lerna multi-package commands to wsrun, update README's accordingly 2018-05-14 19:23:50 +02:00
Fabio Berger
c94d1b2275 Merge branch 'development' of github.com:0xProject/0x-monorepo into development
* 'development' of github.com:0xProject/0x-monorepo:
  Add missing type definitions
2018-05-14 11:30:51 +02:00
Fabio Berger
7d60356fac Remove tslint-config as dep to monorepo-scripts to avoid circular dependency. Since monorepo-scripts is only expected to be used from within the monorepo, we reference tslint-config w/ a relative path 2018-05-14 11:30:15 +02:00
Leonid Logvinov
58fa35641d Merge pull request #585 from 0xProject/feature/typedef
Add missing type definitions. Enable typedef linter rule
2018-05-14 10:36:13 +02:00
Leonid Logvinov
b74957acdf Add missing type definitions 2018-05-14 10:35:13 +02:00
Fabio Berger
6aed4fb1ae Merge pull request #579 from 0xProject/breakUp0xjs
Split 0x.js into: contract-wrappers & order-watcher
2018-05-11 19:11:27 +02:00
Fabio Berger
ad8e12eeae Add missing .gitkeeps 2018-05-11 18:54:33 +02:00
Fabio Berger
31763a018c Revert "Remove gitkeeps"
This reverts commit 3f6876c419.
2018-05-11 18:50:50 +02:00
Fabio Berger
bc20f8a004 improve wording 2018-05-11 18:24:07 +02:00
Fabio Berger
3f6876c419 Remove gitkeeps 2018-05-11 17:41:35 +02:00
Fabio Berger
fb9c774558 Create coverage dir if doesn't exist 2018-05-11 17:41:25 +02:00
Fabio Berger
7df9393d29 Add compilerSettings to compiler.json 2018-05-11 16:26:08 +02:00
Fabio Berger
c6439def2c Add deployedBytecode to artifacts since it is needed by sol-cov 2018-05-11 16:25:52 +02:00
Fabio Berger
273d3445e4 Revert throw conditions since it messes with the expected test timing 2018-05-11 16:04:03 +02:00
Fabio Berger
bc3dc52377 Revert back to hack, we need the configured web3Wrapper 2018-05-11 15:40:19 +02:00
Fabio Berger
ef1d484d9e Add comment to TransactionReceiptWithDecodedLogs explaining that it doesn't always return "decodedLogs" 2018-05-11 15:39:15 +02:00
Fabio Berger
63cd5a6296 Get rid of hack 2018-05-11 15:24:31 +02:00
Fabio Berger
657dc785ea Get networkId from web3Wrapper 2018-05-11 15:23:50 +02:00
Fabio Berger
461e74d8be Throw if tx reverts 2018-05-11 15:23:34 +02:00
Fabio Berger
a7daea1728 Remove unused methods and imports 2018-05-11 15:22:57 +02:00
Fabio Berger
c4416f9696 Prettier ignore artifact files 2018-05-11 14:45:50 +02:00
Fabio Berger
f9ad34170d Add compiler dep 2018-05-11 14:25:48 +02:00
Fabio Berger
45f2a8ad06 Update yarn.lock 2018-05-11 13:31:49 +02:00
Fabio Berger
3dad802c90 Fix version 2018-05-11 13:18:13 +02:00
Fabio Berger
735166f06c remove unused modules 2018-05-11 13:15:41 +02:00
Fabio Berger
042df52e5c Fix deps 2018-05-11 13:15:21 +02:00
Fabio Berger
294a65f842 Fix prettier 2018-05-11 13:11:50 +02:00
Fabio Berger
bf8550ae1e Update artifacts 2018-05-11 12:59:14 +02:00
Fabio Berger
91549ef28c Update yarn.lock 2018-05-11 12:58:45 +02:00
Fabio Berger
95956eff64 Update global_hooks 2018-05-11 12:58:34 +02:00
Fabio Berger
bcae71dfa4 Remove legacy test 2018-05-11 12:33:39 +02:00
Fabio Berger
d370296e82 Merge branch 'development' into breakUp0xjs
* development:
  Fix ganache subprovider config
  Fix a bug in compiler config precedence
  Fix linter errors
  Fix templates
  Remove unused deployer docs configs
  Add a legacy endpoint for the deployer
  Add a check for compiler output
  Add a comment
  Put ARTIFACTS_VERSION in a config
  Improve a comment
  Remove _applyDefaultsToDeployTxDataAsync
  Add a HACK comment
  Fix linter issues
  Rename deployer to sol-compiler
  Remove deployer
  Remove deployer from 0x.js and migrations
  Configure migrations with a compiler.json
  Remove deployer from metacoin and contract tests
  Update wallet footer and add remove token functionality

# Conflicts:
#	.gitignore
#	packages/0x.js/package.json
#	packages/0x.js/src/0x.ts
#	packages/contracts/package.json
#	packages/contracts/test/multi_sig_with_time_lock.ts
#	packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts
#	packages/contracts/util/artifacts.ts
#	packages/deployer/test/deployer_test.ts
#	packages/migrations/package.json
2018-05-11 12:32:57 +02:00
Leonid Logvinov
f42f608f3f Merge pull request #574 from 0xProject/feature/rm-rf-deployer
Remove @0xproject/deployer.Deployer. Make contracts able to deploy themselves
2018-05-11 12:12:39 +02:00
Fabio Berger
f78b5741c3 Add missing version directory to path 2018-05-11 12:05:46 +02:00
Fabio Berger
733fe5b335 Add artifacts to clean command 2018-05-11 12:05:32 +02:00
Leonid Logvinov
c093aab350 Fix ganache subprovider config 2018-05-11 11:59:08 +02:00
Brandon Millman
44f17c1706 Merge pull request #580 from 0xProject/feature/website/remove-tokens
Update wallet footer and add remove token functionality
2018-05-10 10:55:17 -07:00
Fabio Berger
8302e1687a Remove unnecessary compile command 2018-05-10 19:03:58 +02:00
Fabio Berger
7ad4380653 Standardize gitignores and remove migrations/artifacts 2018-05-10 19:02:59 +02:00
Fabio Berger
bea185ce8b Commit v1 artifacts to migrations package and remove compile step from prebuild 2018-05-10 19:02:41 +02:00
Fabio Berger
5a73b8a8e6 Replace mkdir with mkdirp so it also created any missing intermediate directories 2018-05-10 18:56:32 +02:00
Fabio Berger
da62a0af3b Fix path to artifacts 2018-05-10 18:55:30 +02:00
Leonid Logvinov
1137abfd33 Fix a bug in compiler config precedence 2018-05-10 18:26:44 +02:00
Leonid Logvinov
e972ed8456 Fix linter errors 2018-05-10 18:12:34 +02:00
Leonid Logvinov
2e1c2d9dfe Fix templates 2018-05-10 17:56:57 +02:00
Fabio Berger
83dd333eba Fix tslint errors 2018-05-10 17:55:27 +02:00
Leonid Logvinov
f854f3ee2b Remove unused deployer docs configs 2018-05-10 17:47:38 +02:00
Leonid Logvinov
1055ca6d44 Add a legacy endpoint for the deployer 2018-05-10 17:47:38 +02:00
Leonid Logvinov
a5fea3b9c3 Add a check for compiler output 2018-05-10 17:47:38 +02:00
Leonid Logvinov
62f1430a2c Add a comment 2018-05-10 17:47:38 +02:00
Leonid Logvinov
1dec6a442e Put ARTIFACTS_VERSION in a config 2018-05-10 17:47:38 +02:00
Leonid Logvinov
97831e3702 Improve a comment 2018-05-10 17:47:38 +02:00
Leonid Logvinov
7eb9444458 Remove _applyDefaultsToDeployTxDataAsync 2018-05-10 17:47:38 +02:00
Leonid Logvinov
ebc296ea31 Add a HACK comment 2018-05-10 17:47:38 +02:00
Leonid Logvinov
75d24dea0e Fix linter issues 2018-05-10 17:47:38 +02:00
Leonid Logvinov
a6f72de09d Rename deployer to sol-compiler 2018-05-10 17:47:38 +02:00
Leonid Logvinov
96037aed52 Remove deployer 2018-05-10 17:46:57 +02:00
Leonid Logvinov
f9d80adaee Remove deployer from 0x.js and migrations 2018-05-10 17:46:57 +02:00
Leonid Logvinov
422e5a19d4 Configure migrations with a compiler.json 2018-05-10 17:46:57 +02:00
Leonid Logvinov
3d58b38e4e Remove deployer from metacoin and contract tests 2018-05-10 17:46:57 +02:00
Fabio Berger
0a044199a1 Add missing DummyToken 2018-05-10 17:29:59 +02:00
Fabio Berger
cd5f00ac4d Merge branch 'development' into breakUp0xjs
* development: (38 commits)
  Add fallback image support to relayer grid tile
  Clear relayer grid state when fetching
  Configure the compiler to generate artifacts with deployedBytecode
  Implement loading and error state for relayer grid
  Fallback image for relayer grid tile
  Change relayer grid tile to link on header
  Display top tokens from backend
  Remove overflowZ property from portal
  Suggestions and fix bad merge
  Fix typo
  Only show untracked tokens
  Make wallet scrollable
  Add token flow
  Update The Ocean logo
  Fix artifacts paths
  Create an artifacts folder
  Introduce a var
  Add removeHexPrefix util method
  CHeck if ABI exists
  Improve the readability of the check for should compile
  ...

# Conflicts:
#	.gitignore
#	packages/contracts/test/multi_sig_with_time_lock.ts
#	packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts
#	packages/contracts/util/artifacts.ts
2018-05-10 17:08:07 +02:00
Fabio Berger
23c4027c83 Add missing uuid types 2018-05-10 16:53:12 +02:00
Fabio Berger
eeb08b7fae Fix type error for latched on property 2018-05-10 16:53:03 +02:00
Fabio Berger
20beb2bdb6 Add generated contracts in contract-wrappers to gitignore 2018-05-10 16:52:47 +02:00
Fabio Berger
c6882d0bd8 Rename zeroExContract... to contractWrappers... 2018-05-10 16:51:45 +02:00
Fabio Berger
ce47e83939 Update yarn.lock 2018-05-10 16:41:05 +02:00
Fabio Berger
832e1e2cf7 Add missing quote 2018-05-10 15:26:19 +02:00
Fabio Berger
6d61616492 Add PR number 2018-05-10 15:23:17 +02:00
Fabio Berger
d5304fb5bd Remove provider instance variable 2018-05-10 15:23:04 +02:00
Fabio Berger
13a61db289 Add var returns 2018-05-10 15:22:51 +02:00
Fabio Berger
93b74cc766 Remove unneeded tslint disable 2018-05-10 15:22:33 +02:00
Fabio Berger
28e83c21e2 Remove uneeded tslint config 2018-05-10 15:22:13 +02:00
Fabio Berger
33ed5cd437 Remove generated contract wrappers 2018-05-10 15:21:37 +02:00
Fabio Berger
37c8e21f25 Remove extra tslint config 2018-05-10 15:00:06 +02:00
Fabio Berger
7b726650e9 Improve createOrderWatcherAsync 2018-05-10 14:59:54 +02:00
Fabio Berger
d3adb48c2e Fix no-any-propagation 2018-05-10 14:59:37 +02:00
Fabio Berger
9838124abc Remove unnecessary tslint config 2018-05-10 14:59:10 +02:00
Fabio Berger
4df847c349 Add pr number to changelogs 2018-05-10 14:58:15 +02:00
Brandon Millman
c64ad1af28 Add fallback image support to relayer grid tile 2018-05-09 17:29:02 -07:00
Brandon Millman
e83b056bd4 Clear relayer grid state when fetching 2018-05-09 15:59:53 -07:00
Brandon Millman
eba6dcc497 Update wallet footer and add remove token functionality 2018-05-09 15:46:18 -07:00
Fabio Berger
017b5a23d8 Fix website and 0x.js docs 2018-05-09 23:26:51 +02:00
Leonid Logvinov
c7a147f49d Configure the compiler to generate artifacts with deployedBytecode 2018-05-09 23:14:44 +02:00
Fabio Berger
f84a466d16 Remove last artifact 2018-05-09 22:15:35 +02:00
Fabio Berger
382a805c7e Remove artifacts 2018-05-09 22:14:19 +02:00
Fabio Berger
0b38e575d6 Fix package.json 2018-05-09 22:08:41 +02:00
Fabio Berger
209266dbed Split 0x.js into contract-wrappers, order-watcher but keep 0x.js as a unifying library with the same interface 2018-05-09 20:36:28 +02:00
Brandon Millman
20f6d8d3d0 Implement loading and error state for relayer grid 2018-05-09 10:57:26 -07:00
Brandon Millman
09b26645ee Fallback image for relayer grid tile 2018-05-09 10:04:28 -07:00
Brandon Millman
9f2258ebd9 Change relayer grid tile to link on header 2018-05-09 09:28:57 -07:00
Brandon Millman
71e2ee62e4 Merge pull request #576 from 0xProject/feature/website/top-tokens
Display top tokens from backend
2018-05-08 14:30:26 -07:00
Brandon Millman
6c8ee4d55d Merge pull request #557 from 0xProject/feature/website/top-bar-redesign
Redesign top bar for portal v2
2018-05-08 14:29:30 -07:00
Brandon Millman
f94d4b492d Display top tokens from backend 2018-05-08 11:32:44 -07:00
Brandon Millman
e01a4fcbb4 Merge branch 'development' into feature/website/top-bar-redesign
* development:
  Remove overflowZ property from portal
  Fix typo
  Only show untracked tokens
  Make wallet scrollable
  Add token flow
2018-05-08 11:17:00 -07:00
Brandon Millman
5ed9b8b1dc Remove overflowZ property from portal 2018-05-08 11:16:12 -07:00
Brandon Millman
17f3d5f6ba Suggestions and fix bad merge 2018-05-08 11:12:46 -07:00
Brandon Millman
607d738342 Merge branch 'development' into feature/website/top-bar-redesign
* development: (63 commits)
  Update The Ocean logo
  Fix artifacts paths
  Create an artifacts folder
  Introduce a var
  Add removeHexPrefix util method
  CHeck if ABI exists
  Improve the readability of the check for should compile
  Use named constants
  Add a comment
  Fix comments
  Rename args to constructor-args
  Fix a typo
  Define a separator const
  Move artifacts from src/artifacts to artifacts/v1
  Fix sol-cov to work with the new artifacts format
  Implement new artifacts format
  Publish
  Updated CHANGELOGS
  Make node types a dependency
  Fix type errors in CSS properties
  ...
2018-05-08 11:04:31 -07:00
Brandon Millman
1b102f9ed3 Merge pull request #570 from 0xProject/feature/website/wallet-add-tokens
Portal v2 add tokens flow
2018-05-08 11:01:40 -07:00
Brandon Millman
6c38481550 Fix typo 2018-05-08 10:17:04 -07:00
Brandon Millman
9cbd151658 Only show untracked tokens 2018-05-08 10:16:08 -07:00
Brandon Millman
419b670aa3 Make wallet scrollable 2018-05-08 10:16:08 -07:00
Brandon Millman
a44874d2eb Add token flow 2018-05-08 10:16:08 -07:00
Brandon Millman
e9d70b7b1e Merge pull request #556 from 0xProject/feature/website/portal-v2
Add new top-level portal component with wallet and relayer index layout
2018-05-08 10:14:33 -07:00
Fabio Berger
73c6f11c9c Update The Ocean logo 2018-05-08 10:47:35 +02:00
Leonid Logvinov
a9c5488620 Merge pull request #537 from 0xProject/feature/artifacts-v2
Implement the new artifacts format
2018-05-07 14:46:28 +02:00
Leonid Logvinov
906af858a5 Fix artifacts paths 2018-05-07 14:32:17 +02:00
Leonid Logvinov
b699a61f56 Create an artifacts folder 2018-05-07 14:23:24 +02:00
Leonid Logvinov
8eabc49e9d Introduce a var 2018-05-07 14:06:00 +02:00
Leonid Logvinov
9e67e12732 Add removeHexPrefix util method 2018-05-07 14:04:58 +02:00
Leonid Logvinov
2d30183d65 CHeck if ABI exists 2018-05-07 13:57:03 +02:00
Leonid Logvinov
fcb0a05880 Improve the readability of the check for should compile 2018-05-07 13:49:21 +02:00
Leonid Logvinov
fad7dc9f04 Use named constants 2018-05-07 13:46:44 +02:00
Leonid Logvinov
7c1e05d33c Add a comment 2018-05-07 13:42:47 +02:00
Leonid Logvinov
02147f546e Fix comments 2018-05-07 13:41:50 +02:00
Leonid Logvinov
3d51bc1ada Rename args to constructor-args 2018-05-07 13:40:53 +02:00
Leonid Logvinov
95df4433dc Fix a typo 2018-05-07 13:40:05 +02:00
Leonid Logvinov
0f1589a43f Define a separator const 2018-05-07 13:37:21 +02:00
Leonid Logvinov
27262c4e56 Move artifacts from src/artifacts to artifacts/v1 2018-05-07 13:32:24 +02:00
Leonid Logvinov
c9b8f2a397 Fix sol-cov to work with the new artifacts format 2018-05-07 10:52:28 +02:00
Leonid Logvinov
72b2a1c66f Implement new artifacts format 2018-05-07 10:23:08 +02:00
Leonid Logvinov
69a6166b6a Publish
- 0x.js@0.37.2
 - @0xproject/abi-gen@0.2.13
 - @0xproject/assert@0.2.9
 - @0xproject/base-contract@0.3.1
 - @0xproject/connect@0.6.12
 - contracts@2.1.28
 - @0xproject/deployer@0.4.3
 - @0xproject/dev-utils@0.4.1
 - @0xproject/json-schemas@0.7.23
 - @0xproject/metacoin@0.0.6
 - @0xproject/migrations@0.0.5
 - @0xproject/order-utils@0.0.4
 - @0xproject/react-docs-example@0.0.11
 - @0xproject/react-docs@0.0.11
 - @0xproject/react-shared@0.1.6
 - @0xproject/sol-cov@0.0.10
 - @0xproject/sol-resolver@0.0.4
 - @0xproject/sra-report@0.0.14
 - @0xproject/subproviders@0.10.1
 - @0xproject/testnet-faucets@1.0.29
 - @0xproject/types@0.6.3
 - @0xproject/typescript-typings@0.3.1
 - @0xproject/utils@0.6.1
 - @0xproject/web3-wrapper@0.6.3
 - @0xproject/website@0.0.32
2018-05-05 01:55:12 +02:00
Leonid Logvinov
bf87b1a6af Updated CHANGELOGS 2018-05-05 01:55:04 +02:00
Leonid Logvinov
2e8a5602b2 Make node types a dependency 2018-05-05 01:33:35 +02:00
Leonid Logvinov
0ec1c4ad6d Fix type errors in CSS properties 2018-05-05 01:26:02 +02:00
Leonid Logvinov
15a3a8c62f Use a single version of react types 2018-05-05 01:13:22 +02:00
Leonid Logvinov
f001181e39 Revert yarn.lock changes 2018-05-05 01:10:48 +02:00
Leonid Logvinov
2c659d3d82 Publish
- @0xproject/react-docs-example@0.0.10
 - @0xproject/react-docs@0.0.10
 - @0xproject/react-shared@0.1.5
 - @0xproject/website@0.0.31
2018-05-04 23:55:03 +02:00
Leonid Logvinov
5ffff7397e Updated CHANGELOGS 2018-05-04 23:54:57 +02:00
Leonid Logvinov
1a36459ab8 Fix property name 2018-05-04 22:41:39 +02:00
Leonid Logvinov
33cc79c13b Upgrade react types version 2018-05-04 21:17:07 +02:00
Leonid Logvinov
b4cb21b55e Publish
- 0x.js@0.37.1
 - contracts@2.1.27
 - @0xproject/order-utils@0.0.3
 - @0xproject/sra-report@0.0.13
 - @0xproject/testnet-faucets@1.0.28
 - @0xproject/website@0.0.30
2018-05-04 20:44:18 +02:00
Brandon Millman
939e2c70c4 Add headers to wallet and relayer index 2018-05-04 11:04:58 -07:00
Brandon Millman
14b29172b1 Add scrolling to relayer index 2018-05-04 11:04:58 -07:00
Brandon Millman
58794fc8e9 Lay out wallet and relayers 2018-05-04 11:04:58 -07:00
Brandon Millman
b8c611de2b ProviderDisplay changes 2018-04-24 01:11:01 -07:00
Brandon Millman
9c827a0298 Top bar expanded display type 2018-04-23 23:47:37 -07:00
Brandon Millman
766aeaa9e1 Relayer grid spacing tweaks 2018-04-23 23:47:04 -07:00
Brandon Millman
567768c66a Add headers to wallet and relayer index 2018-04-23 22:17:26 -07:00
Brandon Millman
deaa5f3211 Add scrolling to relayer index 2018-04-23 21:45:05 -07:00
Brandon Millman
11f1ccf3ff Lay out wallet and relayers 2018-04-23 21:17:23 -07:00
559 changed files with 23587 additions and 10714 deletions

View File

@@ -22,7 +22,7 @@ jobs:
- run: wget https://s3.amazonaws.com/testrpc-shapshots/${CONTRACTS_COMMIT_HASH}.zip
- run: unzip ${CONTRACTS_COMMIT_HASH}.zip -d testrpc_snapshot
- run: node ./node_modules/lerna/bin/lerna.js bootstrap
- run: yarn lerna:run build
- run: yarn build
- save_cache:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -48,7 +48,7 @@ jobs:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn lerna:run --scope 0x.js test:circleci
- run: yarn wsrun test:circleci 0x.js
- save_cache:
key: coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -65,12 +65,12 @@ jobs:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn lerna:run --scope contracts test:circleci
- run: yarn wsrun test:circleci contracts
- save_cache:
key: coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contracts/coverage/lcov.info
test-deployer:
test-sol-compiler:
docker:
- image: circleci/node:6.12
working_directory: ~/repo
@@ -82,11 +82,11 @@ jobs:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn lerna:run --scope @0xproject/deployer test:circleci
- run: yarn wsrun test:circleci @0xproject/sol-compiler
- save_cache:
key: coverage-deployer-{{ .Environment.CIRCLE_SHA1 }}
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/deployer/coverage/lcov.info
- ~/repo/packages/sol-compiler/coverage/lcov.info
test-rest:
docker:
- image: circleci/node:6.12
@@ -99,7 +99,7 @@ jobs:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn lerna:run --ignore contracts --ignore 0x.js --ignore @0xproject/deployer test:circleci
- run: yarn wsrun test:circleci --exclude contracts --exclude 0x.js --exclude @0xproject/sol-compiler --stages --exclude-missing
- save_cache:
key: coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -177,7 +177,7 @@ jobs:
- coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-deployer-{{ .Environment.CIRCLE_SHA1 }}
- coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
@@ -199,7 +199,7 @@ workflows:
- test-contracts:
requires:
- build
- test-deployer:
- test-sol-compiler:
requires:
- build
- test-rest:
@@ -214,6 +214,6 @@ workflows:
- submit-coverage:
requires:
- test-0xjs
- test-deployer
- test-sol-compiler
- test-rest
- test-contracts

24
.gitignore vendored
View File

@@ -70,22 +70,28 @@ TODO.md
packages/website/public/bundle*
packages/react-docs/example/public/bundle*
# generated binaries
bin/
# server cli
packages/testnet-faucets/server/
# generated contract artifacts
packages/sol-cov/test/fixtures/artifacts
packages/metacoin/artifacts
packages/0x.js/test/artifacts
packages/migrations/src/artifacts
# generated contract artifacts/
packages/sol-cov/test/fixtures/artifacts/
packages/metacoin/artifacts/
packages/order-watcher/test/artifacts/
packages/contract-wrappers/test/artifacts/
# generated contract wrappers
packages/0x.js/src/contract_wrappers/generated/
packages/contracts/src/contract_wrappers/generated/
packages/contract-wrappers/src/contract_wrappers/generated/
packages/metacoin/src/contract_wrappers
packages/fill-scenarios/src/generated_contract_wrappers/
packages/order-watcher/src/generated_contract_wrappers/
packages/migrations/src/contract_wrappers
# solc-bin in deployer
packages/deployer/solc_bin/
# solc-bin in sol-compiler
packages/sol-compiler/solc_bin/
# Monorepo scripts
packages/*/scripts/
ganache.log

View File

@@ -1,7 +1,10 @@
lib
.nyc_output
/packages/0x.js/test/artifacts
/packages/contracts/src/artifacts
/packages/metacoin/artifacts
/packages/migrations/src/artifacts
/packages/contract-wrappers/test/artifacts
/packages/order-watcher/test/artifacts
/packages/migrations/artifacts/1.0.0
package.json
scripts/postpublish_utils.js

123
README.md
View File

@@ -17,27 +17,27 @@ This repository is a monorepo including the 0x protocol smart contracts and nume
### Published Packages
| Package | Version | Description |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| [`0x.js`](/packages/0x.js) | [![npm](https://img.shields.io/npm/v/0x.js.svg)](https://www.npmjs.com/package/0x.js) | A Javascript library for interacting with the 0x protocol |
| [`@0xproject/abi-gen`](/packages/abi-gen) | [![npm](https://img.shields.io/npm/v/@0xproject/abi-gen.svg)](https://www.npmjs.com/package/@0xproject/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
| [`@0xproject/assert`](/packages/assert) | [![npm](https://img.shields.io/npm/v/@0xproject/assert.svg)](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages |
| [`@0xproject/base-contract`](/packages/base-contract) | [![npm](https://img.shields.io/npm/v/@0xproject/base-contract.svg)](https://www.npmjs.com/package/@0xproject/base-contract) | BaseContract used by auto-generated `abi-gen` wrapper contracts |
| [`@0xproject/connect`](/packages/connect) | [![npm](https://img.shields.io/npm/v/@0xproject/connect.svg)](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the Standard Relayer API |
| [`@0xproject/deployer`](/packages/deployer) | [![npm](https://img.shields.io/npm/v/@0xproject/deployer.svg)](https://www.npmjs.com/package/@0xproject/deployer) | Solidity project compiler and deployer framework |
| [`@0xproject/dev-utils`](/packages/dev-utils) | [![npm](https://img.shields.io/npm/v/@0xproject/dev-utils.svg)](https://www.npmjs.com/package/@0xproject/dev-utils) | Dev utils to be shared across 0x projects and packages |
| [`@0xproject/json-schemas`](/packages/json-schemas) | [![npm](https://img.shields.io/npm/v/@0xproject/json-schemas.svg)](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas |
| [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts) | [![npm](https://img.shields.io/npm/v/@0xproject/monorepo-scripts.svg)](https://www.npmjs.com/package/@0xproject/monorepo-scripts) | Monorepo scripts |
| [`@0xproject/react-docs`](/packages/react-docs) | [![npm](https://img.shields.io/npm/v/@0xproject/react-docs.svg)](https://www.npmjs.com/package/@0xproject/react-docs) | React documentation component for rendering TypeDoc & Doxity generated JSON |
| [`@0xproject/react-shared`](/packages/react-shared) | [![npm](https://img.shields.io/npm/v/@0xproject/react-shared.svg)](https://www.npmjs.com/package/@0xproject/react-shared) | 0x shared react components |
| [`@0xproject/sra-report`](/packages/sra-report) | [![npm](https://img.shields.io/npm/v/@0xproject/sra-report.svg)](https://www.npmjs.com/package/@0xproject/sra-report) | Generate reports for standard relayer API compliance |
| [`@0xproject/sol-cov`](/packages/sol-cov) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-cov.svg)](https://www.npmjs.com/package/@0xproject/sol-cov) | Solidity test coverage tool |
| [`@0xproject/subproviders`](/packages/subproviders) | [![npm](https://img.shields.io/npm/v/@0xproject/subproviders.svg)](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
| [`@0xproject/tslint-config`](/packages/tslint-config) | [![npm](https://img.shields.io/npm/v/@0xproject/tslint-config.svg)](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules |
| [`@0xproject/types`](/packages/types) | [![npm](https://img.shields.io/npm/v/@0xproject/types.svg)](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations |
| [`@0xproject/typescript-typings`](/packages/typescript-typings) | [![npm](https://img.shields.io/npm/v/@0xproject/typescript-typings.svg)](https://www.npmjs.com/package/@0xproject/typescript-typings) | Repository of types for external packages |
| [`@0xproject/utils`](/packages/utils) | [![npm](https://img.shields.io/npm/v/@0xproject/utils.svg)](https://www.npmjs.com/package/@0xproject/utils) | Shared utilities |
| [`@0xproject/web3-wrapper`](/packages/web3-wrapper) | [![npm](https://img.shields.io/npm/v/@0xproject/web3-wrapper.svg)](https://www.npmjs.com/package/@0xproject/web3-wrapper) | Web3 wrapper |
| Package | Version | Description |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| [`0x.js`](/packages/0x.js) | [![npm](https://img.shields.io/npm/v/0x.js.svg)](https://www.npmjs.com/package/0x.js) | A Javascript library for interacting with the 0x protocol |
| [`@0xproject/abi-gen`](/packages/abi-gen) | [![npm](https://img.shields.io/npm/v/@0xproject/abi-gen.svg)](https://www.npmjs.com/package/@0xproject/abi-gen) | Tool to generate TS wrappers from smart contract ABIs |
| [`@0xproject/assert`](/packages/assert) | [![npm](https://img.shields.io/npm/v/@0xproject/assert.svg)](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages |
| [`@0xproject/base-contract`](/packages/base-contract) | [![npm](https://img.shields.io/npm/v/@0xproject/base-contract.svg)](https://www.npmjs.com/package/@0xproject/base-contract) | BaseContract used by auto-generated `abi-gen` wrapper contracts |
| [`@0xproject/connect`](/packages/connect) | [![npm](https://img.shields.io/npm/v/@0xproject/connect.svg)](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the Standard Relayer API |
| [`@0xproject/sol-compiler`](/packages/sol-compiler) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-compiler.svg)](https://www.npmjs.com/package/@0xproject/sol-compiler) | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties. |
| [`@0xproject/dev-utils`](/packages/dev-utils) | [![npm](https://img.shields.io/npm/v/@0xproject/dev-utils.svg)](https://www.npmjs.com/package/@0xproject/dev-utils) | Dev utils to be shared across 0x projects and packages |
| [`@0xproject/json-schemas`](/packages/json-schemas) | [![npm](https://img.shields.io/npm/v/@0xproject/json-schemas.svg)](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas |
| [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts) | [![npm](https://img.shields.io/npm/v/@0xproject/monorepo-scripts.svg)](https://www.npmjs.com/package/@0xproject/monorepo-scripts) | Monorepo scripts |
| [`@0xproject/react-docs`](/packages/react-docs) | [![npm](https://img.shields.io/npm/v/@0xproject/react-docs.svg)](https://www.npmjs.com/package/@0xproject/react-docs) | React documentation component for rendering TypeDoc & Doxity generated JSON |
| [`@0xproject/react-shared`](/packages/react-shared) | [![npm](https://img.shields.io/npm/v/@0xproject/react-shared.svg)](https://www.npmjs.com/package/@0xproject/react-shared) | 0x shared react components |
| [`@0xproject/sra-report`](/packages/sra-report) | [![npm](https://img.shields.io/npm/v/@0xproject/sra-report.svg)](https://www.npmjs.com/package/@0xproject/sra-report) | Generate reports for standard relayer API compliance |
| [`@0xproject/sol-cov`](/packages/sol-cov) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-cov.svg)](https://www.npmjs.com/package/@0xproject/sol-cov) | Solidity test coverage tool |
| [`@0xproject/subproviders`](/packages/subproviders) | [![npm](https://img.shields.io/npm/v/@0xproject/subproviders.svg)](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) |
| [`@0xproject/tslint-config`](/packages/tslint-config) | [![npm](https://img.shields.io/npm/v/@0xproject/tslint-config.svg)](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules |
| [`@0xproject/types`](/packages/types) | [![npm](https://img.shields.io/npm/v/@0xproject/types.svg)](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations |
| [`@0xproject/typescript-typings`](/packages/typescript-typings) | [![npm](https://img.shields.io/npm/v/@0xproject/typescript-typings.svg)](https://www.npmjs.com/package/@0xproject/typescript-typings) | Repository of types for external packages |
| [`@0xproject/utils`](/packages/utils) | [![npm](https://img.shields.io/npm/v/@0xproject/utils.svg)](https://www.npmjs.com/package/@0xproject/utils) | Shared utilities |
| [`@0xproject/web3-wrapper`](/packages/web3-wrapper) | [![npm](https://img.shields.io/npm/v/@0xproject/web3-wrapper.svg)](https://www.npmjs.com/package/@0xproject/web3-wrapper) | Web3 wrapper |
### Private Packages
@@ -56,12 +56,14 @@ Dedicated documentation pages:
* [0x Connect](https://0xproject.com/docs/connect)
* [Smart contracts](https://0xproject.com/docs/contracts)
* [Subproviders](https://0xproject.com/docs/subproviders)
* [Deployer](https://0xproject.com/docs/deployer)
* [Sol Compiler](https://0xproject.com/docs/sol-compiler)
* [Web3-wrapper](https://0xproject.com/docs/web3-wrapper)
* [JSON-schemas](https://0xproject.com/docs/json-schemas)
* [Sol-cov](https://0xproject.com/docs/sol-cov)
* [Standard Relayer API](https://github.com/0xProject/standard-relayer-api/blob/master/README.md)
Node version >= 6.12 is required.
Most of the packages require additional typings for external dependencies.
You can include those by prepending @0xproject/typescript-typings package to your [`typeRoots`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) config.
@@ -91,32 +93,87 @@ yarn install
### Build
Build all packages. You need to do this before working on any given package. Although these packages
as independent, when run from within the monorepo, they are internally symlinked, to make development
easier. You can change several packages and run the changes without publishing them first to NPM. When
running `rebuild`, Lerna will figure out the dependency order of all the packages, and build them in
this order.
To build all packages:
```bash
yarn lerna:rebuild
yarn build
```
Or continuously rebuild on change:
To build a specific package:
```bash
yarn dev
PKG=@0xproject/web3-wrapper yarn build
```
### Watch
To re-build all packages on change:
```bash
yarn watch
```
To watch a specific package and all it's dependent packages:
```bash
PKG=[NPM_PACKAGE_NAME] yarn watch
e.g
PKG=@0xproject/web3-wrapper yarn watch
```
### Clean
Clean all packages:
```bash
yarn clean
```
Clean a specific package
```bash
PKG=0x.js yarn clean
```
### Rebuild
To re-build (clean & build) all packages:
```bash
yarn rebuild
```
To re-build (clean & build) a specific package & it's deps:
```bash
PKG=0x.js yarn rebuild
```
### Lint
Lint all packages
Lint all packages:
```bash
yarn lerna:run lint
yarn lint
```
Lint a specific package:
```bash
PKG=0x.js yarn lint
```
### Run Tests
Run all tests:
```bash
yarn lerna:test
yarn test
```
Run a specific package's test:
```bash
PKG=@0xproject/web3-wrapper yarn test
```

View File

@@ -1,38 +1,46 @@
{
"private": true,
"name": "0x-monorepo",
"engines": {
"node" : ">=6.12"
},
"workspaces": [
"packages/*"
],
"scripts": {
"dev": "lerna run --parallel build:watch",
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
"ganache": "ganache-cli -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
"prettier": "prettier --write '**/*.{ts,tsx,json,md}' --config .prettierrc",
"prettier:ci": "prettier --list-different '**/*.{ts,tsx,json,md}' --config .prettierrc",
"report_coverage": "lcov-result-merger 'packages/*/coverage/lcov.info' | coveralls",
"test:installation": "node ./packages/monorepo-scripts/lib/test_installation.js",
"lerna:install": "yarn install",
"lerna:run": "lerna run",
"lerna:test": "lerna run test",
"lerna:clean": "lerna run clean",
"lerna:build": "lerna run build",
"lerna:rebuild": "run-s lerna:clean lerna:build",
"lerna:publish": "run-s lerna:install lerna:rebuild script:publish",
"lerna:publish:dry": "run-s lerna:install lerna:rebuild script:publish:dry",
"lerna:stage_docs": "lerna run docs:stage",
"run:publish": "run-s install:all build:monorepo_scripts script:prepublish_checks rebuild script:publish",
"run:publish:dry": "run-s install:all build:monorepo_scripts script:prepublish_checks rebuild script:publish:dry",
"script:prepublish_checks": "node ./packages/monorepo-scripts/lib/prepublish_checks.js",
"script:publish": "node ./packages/monorepo-scripts/lib/publish.js",
"script:publish:dry": "IS_DRY_RUN=true yarn script:publish"
"script:publish:dry": "IS_DRY_RUN=true yarn script:publish",
"install:all": "yarn install",
"wsrun": "wsrun",
"lerna:run": "lerna run",
"watch": "wsrun watch $PKG --fast-exit -r --stages --done-criteria='complete|successfully'",
"build": "wsrun build $PKG --fast-exit -r --stages",
"build:monorepo_scripts": "PKG=@0xproject/monorepo-scripts yarn build",
"clean": "wsrun clean $PKG --fast-exit -r --parallel",
"rebuild": "run-s clean build",
"test": "wsrun test $PKG --serial --exclude-missing",
"stage_docs": "wsrun docs:stage $PKG --parallel --exclude-missing",
"lint": "wsrun lint $PKG --parallel --exclude-missing"
},
"config": {
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
},
"devDependencies": {
"async-child-process": "^1.1.1",
"async-child-process": "1.1.1",
"coveralls": "^3.0.0",
"ethereumjs-testrpc": "^6.0.3",
"ganache-cli": "^6.1.0",
"lcov-result-merger": "^2.0.0",
"lerna": "^2.5.1",
"npm-run-all": "^4.1.2",
"prettier": "^1.11.1"
"npm-run-all": "4.1.2",
"prettier": "1.12.1",
"wsrun": "^2.2.0"
}
}

View File

@@ -9,3 +9,5 @@ test/
/generated_docs/
/scripts/
/lib/src/monorepo_scripts/
/lib/test/
ganache.log

View File

@@ -1,4 +1,64 @@
[
{
"timestamp": 1529397769,
"version": "0.38.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527617805,
"version": "0.38.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527617227,
"version": "0.38.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527616612,
"version": "0.38.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.38.0",
"changes": [
{
"note": "Renamed createOrderStateWatcher to createOrderWatcherAsync since it is now async",
"pr": 579
},
{
"note":
"Renamed ZeroExError to ContractWrappersErrors since they now lives in the @0xproject/contract-wrappers subpackage",
"pr": 579
}
],
"timestamp": 1527008270
},
{
"timestamp": 1525477860,
"version": "0.37.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525453812,
"version": "0.37.1",

View File

@@ -5,6 +5,31 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.38.4 - _June 19, 2018_
* Dependencies updated
## v0.38.3 - _May 29, 2018_
* Dependencies updated
## v0.38.2 - _May 29, 2018_
* Dependencies updated
## v0.38.1 - _May 29, 2018_
* Dependencies updated
## v0.38.0 - _May 22, 2018_
* Renamed createOrderStateWatcher to createOrderWatcherAsync since it is now async (#579)
* Renamed ZeroExError to ContractWrappersErrors since they now lives in the @0xproject/contract-wrappers subpackage (#579)
## v0.37.2 - _May 5, 2018_
* Dependencies updated
## v0.37.1 - _May 4, 2018_
* Dependencies updated

View File

@@ -44,7 +44,7 @@ Download the UMD module from our [releases page](https://github.com/0xProject/0x
## Contributing
We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
We strongly recommend that the community help us make improvements and determine the future direction of 0x protocol. To report bugs within this package, please create an issue in this repository.
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
@@ -64,28 +64,16 @@ yarn install
### Build
If this is your **first** time building this package, you must first build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory:
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
yarn lerna:rebuild
PKG=0x.js yarn build
```
Or continuously rebuild on change:
```bash
yarn dev
```
You can also build this specific package by running the following from within its directory:
```bash
yarn build
```
or continuously rebuild on change:
```bash
yarn build:watch
PKG=0x.js yarn watch
```
### Clean

View File

@@ -1,6 +1,9 @@
{
"name": "0x.js",
"version": "0.37.0",
"version": "0.38.4",
"engines": {
"node": ">=6.12"
},
"description": "A javascript library for interacting with the 0x protocol",
"keywords": [
"0x.js",
@@ -12,29 +15,27 @@
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
"watch": "tsc -w",
"prebuild": "run-s clean generate_contract_wrappers",
"build": "run-p build:umd:prod build:commonjs; exit 0;",
"generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
"generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
"lint": "tslint --project .",
"test:circleci": "run-s test:coverage",
"test": "run-s clean test:commonjs",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/src/artifacts/$i.json test/artifacts; done;",
"clean": "shx rm -rf _bundles lib test_temp scripts",
"clean": "shx rm -rf _bundles lib test_temp scripts src/contract_wrappers/generated",
"build:umd:prod": "NODE_ENV=production webpack",
"build:commonjs": "tsc && yarn update_artifacts && copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"build:commonjs": "tsc && copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"test:commonjs": "run-s build:commonjs run_mocha",
"run_mocha": "mocha lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
"docs:stage": "yarn build && node ./scripts/stage_docs.js",
"docs:stage": "node scripts/stage_docs.js",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
"upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json"
},
"config": {
"compact_artifacts": "Exchange DummyToken ZRXToken Token EtherToken TokenTransferProxy TokenRegistry",
"contracts": "Exchange DummyToken ZRXToken Token WETH9 TokenTransferProxy MultiSigWallet MultiSigWalletWithTimeLock MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress MaliciousToken TokenRegistry Arbitrage EtherDelta AccountLevels",
"postpublish": {
"assets": [
"packages/0x.js/_bundles/index.js",
@@ -43,6 +44,13 @@
"docPublishConfigs": {
"extraFileIncludes": [
"../types/src/index.ts",
"../contract-wrappers/src/types.ts",
"../contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts",
"../contract-wrappers/src/contract_wrappers/exchange_wrapper.ts",
"../contract-wrappers/src/contract_wrappers/token_registry_wrapper.ts",
"../contract-wrappers/src/contract_wrappers/token_transfer_proxy_wrapper.ts",
"../contract-wrappers/src/contract_wrappers/token_wrapper.ts",
"../order-watcher/src/order_watcher/order_watcher.ts",
"./src/contract_wrappers/generated/ether_token.ts",
"./src/contract_wrappers/generated/token.ts",
"./src/contract_wrappers/generated/exchange.ts"
@@ -57,64 +65,50 @@
"url": "https://github.com/0xProject/0x-monorepo"
},
"license": "Apache-2.0",
"engines": {
"node": ">=6.0.0"
},
"devDependencies": {
"@0xproject/deployer": "^0.4.2",
"@0xproject/dev-utils": "^0.4.0",
"@0xproject/migrations": "^0.0.4",
"@0xproject/monorepo-scripts": "^0.1.19",
"@0xproject/subproviders": "^0.10.0",
"@0xproject/tslint-config": "^0.4.17",
"@types/bintrees": "^1.0.2",
"@0xproject/abi-gen": "^0.3.2",
"@0xproject/dev-utils": "^0.4.4",
"@0xproject/migrations": "^0.0.8",
"@0xproject/monorepo-scripts": "^0.2.1",
"@0xproject/tslint-config": "^0.4.20",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.53",
"@types/request": "2.47.0",
"@types/sinon": "^2.2.2",
"@types/uuid": "^3.4.2",
"awesome-typescript-loader": "^3.1.3",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^2.0.1",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"json-loader": "^0.5.4",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"opn-cli": "^3.1.0",
"prettier": "^1.11.1",
"request": "^2.81.0",
"shx": "^0.2.2",
"sinon": "^4.0.0",
"source-map-support": "^0.5.0",
"@types/mocha": "2.2.48",
"@types/node": "9.6.0",
"@types/sinon": "2.3.7",
"awesome-typescript-loader": "3.5.0",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"chai-bignumber": "2.0.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"json-loader": "0.5.7",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"opn-cli": "3.1.0",
"prettier": "1.12.1",
"shx": "0.2.2",
"sinon": "4.4.9",
"source-map-support": "0.5.4",
"tslint": "5.8.0",
"typedoc": "0xProject/typedoc",
"typescript": "2.7.1",
"web3-provider-engine": "^14.0.4",
"webpack": "^3.1.0"
"webpack": "3.11.0"
},
"dependencies": {
"@0xproject/assert": "^0.2.8",
"@0xproject/base-contract": "^0.3.0",
"@0xproject/json-schemas": "^0.7.22",
"@0xproject/order-utils": "^0.0.2",
"@0xproject/types": "^0.6.2",
"@0xproject/typescript-typings": "^0.3.0",
"@0xproject/utils": "^0.6.0",
"@0xproject/web3-wrapper": "^0.6.2",
"bintrees": "^1.0.2",
"bn.js": "^4.11.8",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-blockstream": "^2.0.6",
"ethereumjs-util": "^5.1.1",
"ethers": "^3.0.15",
"js-sha3": "^0.7.0",
"lodash": "^4.17.4",
"uuid": "^3.1.0",
"web3": "^0.20.0"
"@0xproject/assert": "^0.2.12",
"@0xproject/base-contract": "^0.3.4",
"@0xproject/contract-wrappers": "^0.0.5",
"@0xproject/order-utils": "^0.0.7",
"@0xproject/order-watcher": "^0.0.6",
"@0xproject/sol-compiler": "^0.5.2",
"@0xproject/types": "^0.8.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"@0xproject/web3-wrapper": "^0.7.1",
"ethers": "3.0.22",
"lodash": "4.17.10"
},
"publishConfig": {
"access": "public"

View File

@@ -1,4 +1,13 @@
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
import { assert } from '@0xproject/assert';
import {
ContractWrappers,
ContractWrappersConfig,
EtherTokenWrapper,
ExchangeWrapper,
TokenRegistryWrapper,
TokenTransferProxyWrapper,
TokenWrapper,
} from '@0xproject/contract-wrappers';
import {
generatePseudoRandomSalt,
getOrderHashHex,
@@ -6,27 +15,13 @@ import {
isValidSignature,
signOrderHashAsync,
} from '@0xproject/order-utils';
import { OrderWatcher, OrderWatcherConfig } from '@0xproject/order-watcher';
import { ECSignature, Order, Provider, SignedOrder, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
import { AbiDecoder, BigNumber, intervalUtils } from '@0xproject/utils';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
import { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper';
import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper';
import { TokenWrapper } from './contract_wrappers/token_wrapper';
import { OrderStateWatcher } from './order_watcher/order_state_watcher';
import { zeroExConfigSchema } from './schemas/zero_ex_config_schema';
import { zeroExPrivateNetworkConfigSchema } from './schemas/zero_ex_private_network_config_schema';
import { zeroExPublicNetworkConfigSchema } from './schemas/zero_ex_public_network_config_schema';
import { OrderStateWatcherConfig, ZeroExConfig, ZeroExError } from './types';
import { assert } from './utils/assert';
import { constants } from './utils/constants';
import { decorators } from './utils/decorators';
import { utils } from './utils/utils';
/**
* The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality
@@ -62,7 +57,7 @@ export class ZeroEx {
* tokenTransferProxy smart contract.
*/
public proxy: TokenTransferProxyWrapper;
private _web3Wrapper: Web3Wrapper;
private _contractWrappers: ContractWrappers;
/**
* Generates a pseudo-random 256-bit salt.
* The salt can be included in a 0x order, ensuring that the order generates a unique orderHash
@@ -136,40 +131,15 @@ export class ZeroEx {
* @param config The configuration object. Look up the type for the description.
* @return An instance of the 0x.js ZeroEx class.
*/
constructor(provider: Provider, config: ZeroExConfig) {
constructor(provider: Provider, config: ContractWrappersConfig) {
assert.isWeb3Provider('provider', provider);
assert.doesConformToSchema('config', config, zeroExConfigSchema, [
zeroExPrivateNetworkConfigSchema,
zeroExPublicNetworkConfigSchema,
]);
const artifactJSONs = _.values(artifacts);
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
const defaults = {
gasPrice: config.gasPrice,
};
this._web3Wrapper = new Web3Wrapper(provider, defaults);
_.forEach(abiArrays, abi => {
this._web3Wrapper.abiDecoder.addABI(abi);
});
this.proxy = new TokenTransferProxyWrapper(
this._web3Wrapper,
config.networkId,
config.tokenTransferProxyContractAddress,
);
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this.proxy);
this.exchange = new ExchangeWrapper(
this._web3Wrapper,
config.networkId,
this.token,
config.exchangeContractAddress,
config.zrxContractAddress,
);
this.tokenRegistry = new TokenRegistryWrapper(
this._web3Wrapper,
config.networkId,
config.tokenRegistryContractAddress,
);
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this.token);
this._contractWrappers = new ContractWrappers(provider, config);
this.proxy = this._contractWrappers.proxy;
this.token = this._contractWrappers.token;
this.exchange = this._contractWrappers.exchange;
this.tokenRegistry = this._contractWrappers.tokenRegistry;
this.etherToken = this._contractWrappers.etherToken;
}
/**
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
@@ -178,31 +148,23 @@ export class ZeroEx {
* @param networkId The id of the network your provider is connected to
*/
public setProvider(provider: Provider, networkId: number): void {
this._web3Wrapper.setProvider(provider);
(this.exchange as any)._invalidateContractInstances();
(this.exchange as any)._setNetworkId(networkId);
(this.tokenRegistry as any)._invalidateContractInstance();
(this.tokenRegistry as any)._setNetworkId(networkId);
(this.token as any)._invalidateContractInstances();
(this.token as any)._setNetworkId(networkId);
(this.proxy as any)._invalidateContractInstance();
(this.proxy as any)._setNetworkId(networkId);
(this.etherToken as any)._invalidateContractInstance();
(this.etherToken as any)._setNetworkId(networkId);
this._contractWrappers.setProvider(provider, networkId);
}
/**
* Get the provider instance currently used by 0x.js
* @return Web3 provider instance
*/
public getProvider(): Provider {
return this._web3Wrapper.getProvider();
return this._contractWrappers.getProvider();
}
/**
* Get user Ethereum addresses available through the supplied web3 provider available for sending transactions.
* @return An array of available user Ethereum addresses.
*/
public async getAvailableAddressesAsync(): Promise<string[]> {
const availableAddresses = await this._web3Wrapper.getAvailableAddressesAsync();
// Hack: Get Web3Wrapper from ContractWrappers
const web3Wrapper: Web3Wrapper = (this._contractWrappers as any)._web3Wrapper;
const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
return availableAddresses;
}
/**
@@ -223,7 +185,7 @@ export class ZeroEx {
shouldAddPersonalMessagePrefix: boolean,
): Promise<ECSignature> {
return signOrderHashAsync(
this._web3Wrapper.getProvider(),
this._contractWrappers.getProvider(),
orderHash,
signerAddress,
shouldAddPersonalMessagePrefix,
@@ -238,10 +200,12 @@ export class ZeroEx {
*/
public async awaitTransactionMinedAsync(
txHash: string,
pollingIntervalMs = 1000,
pollingIntervalMs: number = 1000,
timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> {
const transactionReceiptWithDecodedLogs = await this._web3Wrapper.awaitTransactionMinedAsync(
// Hack: Get Web3Wrapper from ContractWrappers
const web3Wrapper: Web3Wrapper = (this._contractWrappers as any)._web3Wrapper;
const transactionReceiptWithDecodedLogs = await web3Wrapper.awaitTransactionMinedAsync(
txHash,
pollingIntervalMs,
timeoutMs,
@@ -249,22 +213,17 @@ export class ZeroEx {
return transactionReceiptWithDecodedLogs;
}
/**
* Instantiates and returns a new OrderStateWatcher instance.
* Instantiates and returns a new OrderWatcher instance.
* Defaults to watching the pending state.
* @param config The configuration object. Look up the type for the description.
* @return An instance of the 0x.js OrderStateWatcher class.
* @return An instance of the 0x.js OrderWatcher class.
*/
public createOrderStateWatcher(config?: OrderStateWatcherConfig) {
return new OrderStateWatcher(this._web3Wrapper, this.token, this.exchange, config);
}
/*
* HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from
* an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle.
* In order to break this - we create this function here and pass it as a parameter to the `TokenWrapper`
* and `ProxyWrapper`.
*/
private async _getTokenTransferProxyAddressAsync(): Promise<string> {
const tokenTransferProxyAddress = await (this.exchange as any)._getTokenTransferProxyAddressAsync();
return tokenTransferProxyAddress;
public async createOrderWatcherAsync(config?: OrderWatcherConfig): Promise<OrderWatcher> {
// Hack: Get Web3Wrapper from ContractWrappers
const web3Wrapper: Web3Wrapper = (this._contractWrappers as any)._web3Wrapper;
const networkId = await web3Wrapper.getNetworkIdAsync();
const provider = this._contractWrappers.getProvider();
const orderWatcher = new OrderWatcher(provider, networkId, config);
return orderWatcher;
}
}

View File

@@ -1,18 +0,0 @@
import * as DummyTokenArtifact from './compact_artifacts/DummyToken.json';
import * as EtherTokenArtifact from './compact_artifacts/EtherToken.json';
import * as ExchangeArtifact from './compact_artifacts/Exchange.json';
import * as TokenArtifact from './compact_artifacts/Token.json';
import * as TokenRegistryArtifact from './compact_artifacts/TokenRegistry.json';
import * as TokenTransferProxyArtifact from './compact_artifacts/TokenTransferProxy.json';
import * as ZRXArtifact from './compact_artifacts/ZRX.json';
import { Artifact } from './types';
export const artifacts = {
ZRXArtifact: (ZRXArtifact as any) as Artifact,
DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
TokenArtifact: (TokenArtifact as any) as Artifact,
ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
};

View File

@@ -1,61 +1,53 @@
export { ZeroEx } from './0x';
export {
ZeroExError,
EventCallback,
ExchangeContractErrs,
ContractEvent,
Token,
IndexedFilterValues,
BlockRange,
OrderCancellationRequest,
OrderFillRequest,
ContractEventArgs,
ZeroExConfig,
MethodOpts,
OrderTransactionOpts,
TransactionOpts,
LogEvent,
DecodedLogEvent,
EventWatcherCallback,
OnOrderStateChangeCallback,
OrderStateValid,
OrderStateInvalid,
OrderState,
} from './types';
export {
BlockParamLiteral,
FilterObject,
BlockParam,
ContractEventArg,
ExchangeContractErrs,
LogWithDecodedArgs,
Order,
Provider,
SignedOrder,
ECSignature,
OrderStateValid,
OrderStateInvalid,
OrderState,
Token,
TransactionReceipt,
TransactionReceiptWithDecodedLogs,
} from '@0xproject/types';
export { OrderWatcherConfig } from '@0xproject/order-watcher';
export {
EventCallback,
ContractEvent,
IndexedFilterValues,
BlockRange,
OrderCancellationRequest,
OrderFillRequest,
ContractEventArgs,
MethodOpts,
OrderTransactionOpts,
TransactionOpts,
LogEvent,
DecodedLogEvent,
OnOrderStateChangeCallback,
ContractWrappersError,
EtherTokenContractEventArgs,
WithdrawalContractEventArgs,
DepositContractEventArgs,
EtherTokenEvents,
} from './contract_wrappers/generated/ether_token';
export {
TransferContractEventArgs,
ApprovalContractEventArgs,
TokenContractEventArgs,
TokenEvents,
} from './contract_wrappers/generated/token';
export {
LogErrorContractEventArgs,
LogCancelContractEventArgs,
LogFillContractEventArgs,
ExchangeContractEventArgs,
ExchangeEvents,
} from './contract_wrappers/generated/exchange';
ContractWrappersConfig,
} from '@0xproject/contract-wrappers';

View File

@@ -1,9 +1,23 @@
const networkNameToId: { [networkName: string]: number } = {
mainnet: 1,
ropsten: 3,
rinkeby: 4,
kovan: 42,
ganache: 50,
};
export const zeroExPublicNetworkConfigSchema = {
id: '/ZeroExPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
enum: [1, 3, 4, 42, 50],
enum: [
networkNameToId.mainnet,
networkNameToId.ropsten,
networkNameToId.rinkeby,
networkNameToId.kovan,
networkNameToId.ganache,
],
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },

View File

@@ -1,276 +1,20 @@
import { BigNumber } from '@0xproject/utils';
import {
BlockParam,
BlockParamLiteral,
ContractAbi,
ContractEventArg,
ExchangeContractErrs,
FilterObject,
LogEntryEvent,
LogWithDecodedArgs,
Order,
OrderState,
SignedOrder,
} from '@0xproject/types';
import * as Web3 from 'web3';
import { EtherTokenContractEventArgs, EtherTokenEvents } from './contract_wrappers/generated/ether_token';
import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/generated/exchange';
import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token';
export enum ZeroExError {
ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
TokenContractDoesNotExist = 'TOKEN_CONTRACT_DOES_NOT_EXIST',
UnhandledError = 'UNHANDLED_ERROR',
UserHasNoAssociatedAddress = 'USER_HAS_NO_ASSOCIATED_ADDRESSES',
ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER',
InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT',
InsufficientWEthBalanceForWithdrawal = 'INSUFFICIENT_WETH_BALANCE_FOR_WITHDRAWAL',
InvalidJump = 'INVALID_JUMP',
OutOfGas = 'OUT_OF_GAS',
NoNetworkId = 'NO_NETWORK_ID',
SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND',
SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
}
export enum InternalZeroExError {
NoAbiDecoder = 'NO_ABI_DECODER',
ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY',
WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
}
export type OrderAddresses = [string, string, string, string, string];
export type OrderValues = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber];
export type LogEvent = LogEntryEvent;
export interface DecodedLogEvent<ArgsType> {
isRemoved: boolean;
log: LogWithDecodedArgs<ArgsType>;
}
export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void;
export type EventWatcherCallback = (err: null | Error, log?: LogEvent) => void;
export enum ExchangeContractErrCodes {
ERROR_FILL_EXPIRED, // Order has already expired
ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled
ERROR_FILL_TRUNCATION, // Rounding error too large
ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer
ERROR_CANCEL_EXPIRED, // Order has already expired
ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled
}
export enum ExchangeContractErrs {
OrderFillExpired = 'ORDER_FILL_EXPIRED',
OrderCancelExpired = 'ORDER_CANCEL_EXPIRED',
OrderCancelAmountZero = 'ORDER_CANCEL_AMOUNT_ZERO',
OrderAlreadyCancelledOrFilled = 'ORDER_ALREADY_CANCELLED_OR_FILLED',
OrderFillAmountZero = 'ORDER_FILL_AMOUNT_ZERO',
OrderRemainingFillAmountZero = 'ORDER_REMAINING_FILL_AMOUNT_ZERO',
OrderFillRoundingError = 'ORDER_FILL_ROUNDING_ERROR',
FillBalanceAllowanceError = 'FILL_BALANCE_ALLOWANCE_ERROR',
InsufficientTakerBalance = 'INSUFFICIENT_TAKER_BALANCE',
InsufficientTakerAllowance = 'INSUFFICIENT_TAKER_ALLOWANCE',
InsufficientMakerBalance = 'INSUFFICIENT_MAKER_BALANCE',
InsufficientMakerAllowance = 'INSUFFICIENT_MAKER_ALLOWANCE',
InsufficientTakerFeeBalance = 'INSUFFICIENT_TAKER_FEE_BALANCE',
InsufficientTakerFeeAllowance = 'INSUFFICIENT_TAKER_FEE_ALLOWANCE',
InsufficientMakerFeeBalance = 'INSUFFICIENT_MAKER_FEE_BALANCE',
InsufficientMakerFeeAllowance = 'INSUFFICIENT_MAKER_FEE_ALLOWANCE',
TransactionSenderIsNotFillOrderTaker = 'TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER',
MultipleMakersInSingleCancelBatchDisallowed = 'MULTIPLE_MAKERS_IN_SINGLE_CANCEL_BATCH_DISALLOWED',
InsufficientRemainingFillAmount = 'INSUFFICIENT_REMAINING_FILL_AMOUNT',
MultipleTakerTokensInFillUpToDisallowed = 'MULTIPLE_TAKER_TOKENS_IN_FILL_UP_TO_DISALLOWED',
BatchOrdersMustHaveSameExchangeAddress = 'BATCH_ORDERS_MUST_HAVE_SAME_EXCHANGE_ADDRESS',
BatchOrdersMustHaveAtLeastOneItem = 'BATCH_ORDERS_MUST_HAVE_AT_LEAST_ONE_ITEM',
}
export interface ContractEvent {
logIndex: number;
transactionIndex: number;
transactionHash: string;
blockHash: string;
blockNumber: number;
address: string;
type: string;
event: string;
args: ContractEventArgs;
}
export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
// [address, name, symbol, decimals, ipfsHash, swarmHash]
export type TokenMetadata = [string, string, string, number, string, string];
export interface Token {
name: string;
address: string;
symbol: string;
decimals: number;
}
export interface TxOpts {
from: string;
gas?: number;
value?: BigNumber;
gasPrice?: BigNumber;
}
export interface TokenAddressBySymbol {
[symbol: string]: string;
}
export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents;
export interface IndexedFilterValues {
[index: string]: ContractEventArg;
}
export interface BlockRange {
fromBlock: BlockParam;
toBlock: BlockParam;
}
export type DoneCallback = (err?: Error) => void;
export interface OrderCancellationRequest {
order: Order | SignedOrder;
takerTokenCancelAmount: BigNumber;
}
export interface OrderFillRequest {
signedOrder: SignedOrder;
takerTokenFillAmount: BigNumber;
}
export type AsyncMethod = (...args: any[]) => Promise<any>;
export type SyncMethod = (...args: any[]) => any;
/**
* orderExpirationCheckingIntervalMs: How often to check for expired orders. Default=50.
* eventPollingIntervalMs: How often to poll the Ethereum node for new events. Default=200.
* expirationMarginMs: Amount of time before order expiry that you'd like to be notified
* of an orders expiration. Default=0.
* cleanupJobIntervalMs: How often to run a cleanup job which revalidates all the orders. Default=1hr.
* stateLayer: Optional blockchain state layer OrderWatcher will monitor for new events. Default=latest.
*/
export interface OrderStateWatcherConfig {
orderExpirationCheckingIntervalMs?: number;
eventPollingIntervalMs?: number;
expirationMarginMs?: number;
cleanupJobIntervalMs?: number;
stateLayer: BlockParamLiteral;
}
/**
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc)
* gasPrice: Gas price to use with every transaction
* exchangeContractAddress: The address of an exchange contract to use
* zrxContractAddress: The address of the ZRX contract to use
* tokenRegistryContractAddress: The address of a token registry contract to use
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
* orderWatcherConfig: All the configs related to the orderWatcher
*/
export interface ZeroExConfig {
networkId: number;
gasPrice?: BigNumber;
exchangeContractAddress?: string;
zrxContractAddress?: string;
tokenRegistryContractAddress?: string;
tokenTransferProxyContractAddress?: string;
orderWatcherConfig?: OrderStateWatcherConfig;
}
export type ArtifactContractName = 'ZRX' | 'TokenTransferProxy' | 'TokenRegistry' | 'Token' | 'Exchange' | 'EtherToken';
export interface Artifact {
contract_name: ArtifactContractName;
abi: ContractAbi;
networks: {
[networkId: number]: {
address: string;
};
};
}
/**
* expectedFillTakerTokenAmount: If specified, the validation method will ensure that the
* supplied order maker has a sufficient allowance/balance to fill this amount of the order's
* takerTokenAmount. If not specified, the validation method ensures that the maker has a sufficient
* allowance/balance to fill the entire remaining order amount.
*/
export interface ValidateOrderFillableOpts {
expectedFillTakerTokenAmount?: BigNumber;
}
/**
* defaultBlock: The block up to which to query the blockchain state. Setting this to a historical block number
* let's the user query the blockchain's state at an arbitrary point in time. In order for this to work, the
* backing Ethereum node must keep the entire historical state of the chain (e.g setting `--pruning=archive`
* flag when running Parity).
*/
export interface MethodOpts {
defaultBlock?: BlockParam;
}
/**
* gasPrice: Gas price in Wei to use for a transaction
* gasLimit: The amount of gas to send with a transaction
*/
export interface TransactionOpts {
gasPrice?: BigNumber;
gasLimit?: number;
}
/**
* shouldValidate: Flag indicating whether the library should make attempts to validate a transaction before
* broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc. Default=true.
*/
export interface OrderTransactionOpts extends TransactionOpts {
shouldValidate?: boolean;
}
export enum TradeSide {
Maker = 'maker',
Taker = 'taker',
}
export enum TransferType {
Trade = 'trade',
Fee = 'fee',
}
export interface OrderRelevantState {
makerBalance: BigNumber;
makerProxyAllowance: BigNumber;
makerFeeBalance: BigNumber;
makerFeeProxyAllowance: BigNumber;
filledTakerTokenAmount: BigNumber;
cancelledTakerTokenAmount: BigNumber;
remainingFillableMakerTokenAmount: BigNumber;
remainingFillableTakerTokenAmount: BigNumber;
}
export interface OrderStateValid {
isValid: true;
orderHash: string;
orderRelevantState: OrderRelevantState;
}
export interface OrderStateInvalid {
isValid: false;
orderHash: string;
error: ExchangeContractErrs;
}
export type OrderState = OrderStateValid | OrderStateInvalid;
export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void;
// tslint:disable:max-file-line-count

View File

@@ -3,9 +3,4 @@ import { BigNumber } from '@0xproject/utils';
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
TESTRPC_NETWORK_ID: 50,
INVALID_JUMP_PATTERN: 'invalid JUMP at',
OUT_OF_GAS_PATTERN: 'out of gas',
INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
};

View File

@@ -1,7 +1,9 @@
import { ContractWrappers } from '@0xproject/contract-wrappers';
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'make-promises-safe';
import 'mocha';
import * as path from 'path';
import * as Sinon from 'sinon';
@@ -41,9 +43,9 @@ describe('ZeroEx library', () => {
expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
// Check that all nested web3 wrapper instances return the updated provider
const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getProvider();
expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
// Check that all nested zeroExContract/web3Wrapper instances return the updated provider
const nestedWeb3WrapperProvider = ((zeroEx as any)._contractWrappers as ContractWrappers).getProvider();
expect((nestedWeb3WrapperProvider as any).zeroExTestId).to.be.a('number');
const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getProvider();
expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getProvider();

View File

@@ -1,5 +1,6 @@
import { web3Factory } from '@0xproject/dev-utils';
import * as fs from 'fs';
import 'make-promises-safe';
import { ZeroEx } from '../src';

View File

@@ -1,7 +1,19 @@
import { devConstants } from '@0xproject/dev-utils';
import { runMigrationsAsync } from '@0xproject/migrations';
import * as path from 'path';
import { deployer } from './utils/deployer';
import { constants } from './utils/constants';
import { provider } from './utils/web3_wrapper';
before('migrate contracts', async () => {
await runMigrationsAsync(deployer);
before('migrate contracts', async function(): Promise<void> {
// HACK: Since the migrations take longer then our global mocha timeout limit
// we manually increase it for this before hook.
const mochaTestTimeoutMs = 20000;
this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
const artifactsDir = `../migrations/artifacts/1.0.0`;
await runMigrationsAsync(provider, artifactsDir, txDefaults);
});

View File

@@ -4,7 +4,7 @@ import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai';
export const chaiSetup = {
configure() {
configure(): void {
chai.config.includeStack = true;
chai.use(ChaiBigNumber());
chai.use(dirtyChai);

View File

@@ -1,18 +0,0 @@
import { Deployer } from '@0xproject/deployer';
import { devConstants } from '@0xproject/dev-utils';
import * as path from 'path';
import { constants } from './constants';
import { provider } from './web3_wrapper';
const artifactsDir = path.resolve('test', 'artifacts');
const deployerOpts = {
artifactsDir,
provider,
networkId: constants.TESTRPC_NETWORK_ID,
defaults: {
gas: devConstants.GAS_ESTIMATE,
},
};
export const deployer = new Deployer(deployerOpts);

View File

@@ -1,66 +0,0 @@
import * as chai from 'chai';
import * as _ from 'lodash';
import { DoneCallback } from '../../src/types';
const expect = chai.expect;
export const reportNoErrorCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
return <T>(f?: (value: T) => void) => {
const wrapped = (value: T) => {
if (_.isUndefined(f)) {
done();
return;
}
try {
f(value);
if (expectToBeCalledOnce) {
done();
}
} catch (err) {
done(err);
}
};
return wrapped;
};
};
export const reportNodeCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => {
return <T>(f?: (value: T) => void) => {
const wrapped = (error: Error | null, value: T | undefined) => {
if (!_.isNull(error)) {
done(error);
} else {
if (_.isUndefined(f)) {
done();
return;
}
try {
f(value as T);
if (expectToBeCalledOnce) {
done();
}
} catch (err) {
done(err);
}
}
};
return wrapped;
};
};
export const assertNodeCallbackError = (done: DoneCallback, errMsg: string) => {
const wrapped = <T>(error: Error | null, value: T | undefined) => {
if (_.isNull(error)) {
done(new Error('Expected callback to receive an error'));
} else {
try {
expect(error.message).to.be.equal(errMsg);
done();
} catch (err) {
done(err);
}
}
};
return wrapped;
};

View File

@@ -1,6 +1,7 @@
import { Token } from '@0xproject/types';
import * as _ from 'lodash';
import { InternalZeroExError, Token } from '../../src/types';
import { InternalZeroExError } from '../../src/types';
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
const WETH_TOKEN_SYMBOL = 'WETH';

View File

@@ -1,4 +1,41 @@
[
{
"timestamp": 1529397769,
"version": "0.3.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.3.1",
"changes": [
{
"note": "Incorrect publish that was unpublished"
}
],
"timestamp": 1527810075
},
{
"version": "0.3.0",
"changes": [
{
"note": "Properly export the executable binary",
"pr": 588
}
],
"timestamp": 1527008270
},
{
"timestamp": 1525477860,
"version": "0.2.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525428773,
"version": "0.2.12",

View File

@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.3.2 - _June 19, 2018_
* Dependencies updated
## v0.3.1 - _June 1, 2018_
* Incorrect publish that was unpublished
## v0.3.0 - _May 22, 2018_
* Properly export the executable binary (#588)
## v0.2.13 - _May 5, 2018_
* Dependencies updated
## v0.2.12 - _May 4, 2018_
* Dependencies updated

View File

@@ -80,28 +80,16 @@ yarn install
### Build
If this is your **first** time building this package, you must first build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory:
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
yarn lerna:rebuild
PKG=@0xproject/abi-gen yarn build
```
Or continuously rebuild on change:
```bash
yarn dev
```
You can also build this specific package by running the following from within its directory:
```bash
yarn build
```
or continuously rebuild on change:
```bash
yarn build:watch
PKG=@0xproject/abi-gen yarn watch
```
### Clean

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
require('../lib/index.js')

View File

@@ -1,18 +1,21 @@
{
"name": "@0xproject/abi-gen",
"version": "0.2.12",
"version": "0.3.2",
"engines": {
"node": ">=6.12"
},
"description": "Generate contract wrappers from ABI and handlebars templates",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
"lint": "tslint --project . 'src/**/*.ts'",
"watch": "tsc -w",
"lint": "tslint --project .",
"clean": "shx rm -rf lib scripts",
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
},
"bin": {
"abi-gen": "lib/index.js"
"abi-gen": "bin/abi-gen.js"
},
"repository": {
"type": "git",
@@ -24,28 +27,29 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
"dependencies": {
"@0xproject/types": "^0.6.2",
"@0xproject/typescript-typings": "^0.3.0",
"@0xproject/utils": "^0.6.0",
"chalk": "^2.3.0",
"glob": "^7.1.2",
"handlebars": "^4.0.11",
"lodash": "^4.17.4",
"mkdirp": "^0.5.1",
"to-snake-case": "^1.0.0",
"yargs": "^10.0.3"
"@0xproject/types": "^0.8.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"chalk": "2.3.2",
"glob": "7.1.1",
"handlebars": "4.0.11",
"lodash": "4.17.10",
"mkdirp": "0.5.1",
"to-snake-case": "1.0.0",
"yargs": "11.1.0"
},
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.19",
"@0xproject/tslint-config": "^0.4.17",
"@types/glob": "^5.0.33",
"@types/handlebars": "^4.0.36",
"@types/mkdirp": "^0.5.1",
"@types/node": "^8.0.53",
"@types/yargs": "^10.0.0",
"copyfiles": "^1.2.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"@0xproject/monorepo-scripts": "^0.2.1",
"@0xproject/tslint-config": "^0.4.20",
"@types/glob": "5.0.35",
"@types/handlebars": "4.0.36",
"@types/mkdirp": "0.5.2",
"@types/node": "9.6.0",
"@types/yargs": "10.0.2",
"copyfiles": "1.2.0",
"make-promises-safe": "1.1.0",
"npm-run-all": "4.1.2",
"shx": "0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1"
},

View File

@@ -61,14 +61,13 @@ const args = yargs
'Full usage example',
).argv;
function registerPartials(partialsGlob: string) {
function registerPartials(partialsGlob: string): void {
const partialTemplateFileNames = globSync(partialsGlob);
logUtils.log(`Found ${chalk.green(`${partialTemplateFileNames.length}`)} ${chalk.bold('partial')} templates`);
for (const partialTemplateFileName of partialTemplateFileNames) {
const namedContent = utils.getNamedContent(partialTemplateFileName);
Handlebars.registerPartial(namedContent.name, namedContent.content);
}
return partialsGlob;
}
function writeOutputFile(name: string, renderedTsCode: string): void {
@@ -108,13 +107,13 @@ for (const abiFileName of abiFileNames) {
ABI = parsedContent; // ABI file
} else if (!_.isUndefined(parsedContent.abi)) {
ABI = parsedContent.abi; // Truffle artifact
} else if (!_.isUndefined(parsedContent.networks) && !_.isUndefined(parsedContent.networks[args.networkId])) {
ABI = parsedContent.networks[args.networkId].abi; // 0x contracts package artifact
} else if (!_.isUndefined(parsedContent.compilerOutput.abi)) {
ABI = parsedContent.compilerOutput.abi; // 0x artifact
}
if (_.isUndefined(ABI)) {
logUtils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
logUtils.log(
`Please make sure your ABI file is either an array with ABI entries or a truffle artifact or 0x deployer artifact`,
`Please make sure your ABI file is either an array with ABI entries or a truffle artifact or 0x sol-compiler artifact`,
);
process.exit(1);
}

View File

@@ -1,4 +1,40 @@
[
{
"timestamp": 1529397769,
"version": "0.2.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.2.11",
"changes": [
{
"note": "Incorrect publish that was unpublished"
}
],
"timestamp": 1527810075
},
{
"timestamp": 1527008270,
"version": "0.2.10",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525477860,
"version": "0.2.9",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525428773,
"version": "0.2.8",

View File

@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.2.12 - _June 19, 2018_
* Dependencies updated
## v0.2.11 - _June 1, 2018_
* Incorrect publish that was unpublished
## v0.2.10 - _May 22, 2018_
* Dependencies updated
## v0.2.9 - _May 5, 2018_
* Dependencies updated
## v0.2.8 - _May 4, 2018_
* Dependencies updated

View File

@@ -46,28 +46,16 @@ yarn install
### Build
If this is your **first** time building this package, you must first build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory:
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
yarn lerna:rebuild
PKG=@0xproject/assert yarn build
```
Or continuously rebuild on change:
```bash
yarn dev
```
You can also build this specific package by running the following from within its directory:
```bash
yarn build
```
or continuously rebuild on change:
```bash
yarn build:watch
PKG=@0xproject/assert yarn watch
```
### Clean

View File

@@ -1,14 +1,17 @@
{
"name": "@0xproject/assert",
"version": "0.2.8",
"version": "0.2.12",
"engines": {
"node": ">=6.12"
},
"description": "Provides a standard way of performing type and schema validation across 0x projects",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
"watch": "tsc -w",
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib test_temp scripts",
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
"lint": "tslint --project .",
"run_mocha": "mocha lib/test/**/*_test.js --exit",
"prepublishOnly": "run-p build",
"test": "run-s clean build run_mocha",
@@ -27,27 +30,28 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.19",
"@0xproject/tslint-config": "^0.4.17",
"@0xproject/monorepo-scripts": "^0.2.1",
"@0xproject/tslint-config": "^0.4.20",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/valid-url": "^1.0.2",
"chai": "^4.0.1",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"shx": "^0.2.2",
"@types/mocha": "2.2.48",
"@types/valid-url": "1.0.2",
"chai": "4.1.2",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"shx": "0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1"
},
"dependencies": {
"@0xproject/json-schemas": "^0.7.22",
"@0xproject/typescript-typings": "^0.3.0",
"@0xproject/utils": "^0.6.0",
"lodash": "^4.17.4",
"valid-url": "^1.0.9"
"@0xproject/json-schemas": "^0.8.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"lodash": "4.17.10",
"valid-url": "1.0.9"
},
"publishConfig": {
"access": "public"

View File

@@ -10,7 +10,7 @@ export const assert = {
const isBigNumber = _.isObject(value) && (value as any).isBigNumber;
this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value));
},
isValidBaseUnitAmount(variableName: string, value: BigNumber) {
isValidBaseUnitAmount(variableName: string, value: BigNumber): void {
assert.isBigNumber(variableName, value);
const isNegative = value.lessThan(0);
this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);

View File

@@ -2,6 +2,7 @@ import { schemas } from '@0xproject/json-schemas';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as dirtyChai from 'dirty-chai';
import 'make-promises-safe';
import 'mocha';
import { assert } from '../src/index';
@@ -10,6 +11,7 @@ chai.config.includeStack = true;
chai.use(dirtyChai);
const expect = chai.expect;
// tslint:disable:custom-no-magic-numbers
describe('Assertions', () => {
const variableName = 'variable';
describe('#isBigNumber', () => {
@@ -251,3 +253,4 @@ describe('Assertions', () => {
});
});
});
// tslint:enable:custom-no-magic-numbers

View File

@@ -1,4 +1,41 @@
[
{
"version": "0.3.4",
"changes": [
{
"note":
"Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201"
}
],
"timestamp": 1529397769
},
{
"timestamp": 1527810075,
"version": "0.3.3",
"changes": [
{
"note": "Incorrect publish that was unpublished"
}
]
},
{
"timestamp": 1527008270,
"version": "0.3.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525477860,
"version": "0.3.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.3.0",
"changes": [

View File

@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.3.4 - _June 19, 2018_
* Update EthersJs to fix the `value.toLowerCase()` is not a function bug caused by `ethers.js` breaking patch version https://github.com/ethers-io/ethers.js/issues/201
## v0.3.3 - _June 1, 2018_
* Incorrect publish that was unpublished
## v0.3.2 - _May 22, 2018_
* Dependencies updated
## v0.3.1 - _May 5, 2018_
* Dependencies updated
## v0.3.0 - _May 4, 2018_
* Update ethers-contracts to ethers.js (#540)

View File

@@ -44,14 +44,16 @@ yarn install
### Build
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
yarn build
PKG=@0xproject/base-contract yarn build
```
or
Or continuously rebuild on change:
```bash
yarn build:watch
PKG=@0xproject/base-contract yarn watch
```
### Lint

View File

@@ -1,11 +1,14 @@
{
"name": "@0xproject/base-contract",
"version": "0.3.0",
"version": "0.3.4",
"engines": {
"node": ">=6.12"
},
"description": "0x Base TS contract",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
"watch": "tsc -w",
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib scripts",
"test": "run-s clean build run_mocha",
@@ -26,24 +29,25 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.19",
"@0xproject/tslint-config": "^0.4.17",
"@0xproject/monorepo-scripts": "^0.2.1",
"@0xproject/tslint-config": "^0.4.20",
"@types/lodash": "4.14.104",
"chai": "^4.0.1",
"copyfiles": "^1.2.0",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"chai": "4.1.2",
"copyfiles": "1.2.0",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"shx": "0.2.2",
"tslint": "5.8.0",
"typescript": "2.7.1"
},
"dependencies": {
"@0xproject/types": "^0.6.2",
"@0xproject/typescript-typings": "^0.3.0",
"@0xproject/utils": "^0.6.0",
"@0xproject/web3-wrapper": "^0.6.2",
"ethers": "^3.0.15",
"lodash": "^4.17.4"
"@0xproject/types": "^0.8.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"@0xproject/web3-wrapper": "^0.7.1",
"ethers": "3.0.22",
"lodash": "4.17.10"
},
"publishConfig": {
"access": "public"

View File

@@ -1,6 +1,7 @@
import {
AbiDefinition,
AbiType,
ConstructorAbi,
ContractAbi,
DataItem,
MethodAbi,
@@ -24,6 +25,8 @@ export class BaseContract {
protected _web3Wrapper: Web3Wrapper;
public abi: ContractAbi;
public address: string;
public contractName: string;
public constructorArgs: any[] = [];
protected static _formatABIDataItemList(
abis: DataItem[],
values: any[],
@@ -37,11 +40,31 @@ export class BaseContract {
protected static _bigNumberToString(type: string, value: any): any {
return _.isObject(value) && value.isBigNumber ? value.toString() : value;
}
protected static _lookupConstructorAbi(abi: ContractAbi): ConstructorAbi {
const constructorAbiIfExists = _.find(
abi,
(abiDefinition: AbiDefinition) => abiDefinition.type === AbiType.Constructor,
) as ConstructorAbi | undefined;
if (!_.isUndefined(constructorAbiIfExists)) {
return constructorAbiIfExists;
} else {
// If the constructor is not explicitly defined, it won't be included in the ABI. It is
// still callable however, so we construct what the ABI would look like were it to exist.
const defaultConstructorAbi: ConstructorAbi = {
type: AbiType.Constructor,
stateMutability: 'nonpayable',
payable: false,
inputs: [],
};
return defaultConstructorAbi;
}
}
protected static _bnToBigNumber(type: string, value: any): any {
return _.isObject(value) && value._bn ? new BigNumber(value.toString()) : value;
}
protected async _applyDefaultsToTxDataAsync<T extends Partial<TxData | TxDataPayable>>(
protected static async _applyDefaultsToTxDataAsync<T extends Partial<TxData | TxDataPayable>>(
txData: T,
txDefaults: Partial<TxData>,
estimateGasAsync?: (txData: T) => Promise<number>,
): Promise<TxData> {
// Gas amount sourced with the following priorities:
@@ -49,13 +72,12 @@ export class BaseContract {
// 2. Global config passed in at library instantiation
// 3. Gas estimate calculation + safety margin
const removeUndefinedProperties = _.pickBy;
const txDataWithDefaults = ({
to: this.address,
...removeUndefinedProperties(this._web3Wrapper.getContractDefaults()),
const txDataWithDefaults: TxData = {
...removeUndefinedProperties(txDefaults),
...removeUndefinedProperties(txData as any),
// HACK: TS can't prove that T is spreadable.
// Awaiting https://github.com/Microsoft/TypeScript/pull/13288 to be merged
} as any) as TxData;
} as any;
if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) {
const estimatedGas = await estimateGasAsync(txData);
txDataWithDefaults.gas = estimatedGas;
@@ -82,8 +104,15 @@ export class BaseContract {
}) as MethodAbi;
return methodAbi;
}
constructor(abi: ContractAbi, address: string, provider: Provider, defaults?: Partial<TxData>) {
this._web3Wrapper = new Web3Wrapper(provider, defaults);
constructor(
contractName: string,
abi: ContractAbi,
address: string,
provider: Provider,
txDefaults?: Partial<TxData>,
) {
this.contractName = contractName;
this._web3Wrapper = new Web3Wrapper(provider, txDefaults);
this.abi = abi;
this.address = address;
const methodAbis = this.abi.filter(

View File

@@ -1,5 +1,6 @@
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'make-promises-safe';
import 'mocha';
import { formatABIDataItem } from '../src/utils';

View File

@@ -1,4 +1,40 @@
[
{
"timestamp": 1529397769,
"version": "0.6.15",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527616612,
"version": "0.6.14",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527008270,
"version": "0.6.13",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525477860,
"version": "0.6.12",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1525428773,
"version": "0.6.11",

View File

@@ -5,6 +5,22 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
## v0.6.15 - _June 19, 2018_
* Dependencies updated
## v0.6.14 - _May 29, 2018_
* Dependencies updated
## v0.6.13 - _May 22, 2018_
* Dependencies updated
## v0.6.12 - _May 5, 2018_
* Dependencies updated
## v0.6.11 - _May 4, 2018_
* Dependencies updated

View File

@@ -43,28 +43,16 @@ yarn install
### Build
If this is your **first** time building this package, you must first build **all** packages within the monorepo. This is because packages that depend on other packages located inside this monorepo are symlinked when run from **within** the monorepo. This allows you to make changes across multiple packages without first publishing dependent packages to NPM. To build all packages, run the following from the monorepo root directory:
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
yarn lerna:rebuild
PKG=@0xproject/connect yarn build
```
Or continuously rebuild on change:
```bash
yarn dev
```
You can also build this specific package by running the following from within its directory:
```bash
yarn build
```
or continuously rebuild on change:
```bash
yarn build:watch
PKG=@0xproject/connect yarn watch
```
### Clean

View File

@@ -1,6 +1,9 @@
{
"name": "@0xproject/connect",
"version": "0.6.11",
"version": "0.6.15",
"engines": {
"node": ">=6.12"
},
"description": "A javascript library for interacting with the standard relayer api",
"keywords": [
"connect",
@@ -12,18 +15,18 @@
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
"watch": "tsc -w",
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib test_temp scripts",
"copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
"lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
"lint": "tslint --project .",
"run_mocha": "mocha lib/test/**/*_test.js --exit",
"test": "run-s clean build copy_test_fixtures run_mocha",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"test:circleci": "yarn test:coverage",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
"docs:stage": "yarn build && node ./scripts/stage_docs.js",
"docs:stage": "node scripts/stage_docs.js",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
"upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json"
},
@@ -42,44 +45,42 @@
},
"author": "Brandon Millman",
"license": "Apache-2.0",
"engines": {
"node": ">=6.0.0"
},
"bugs": {
"url": "https://github.com/0xProject/0x-monorepo/issues"
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
"dependencies": {
"@0xproject/assert": "^0.2.8",
"@0xproject/json-schemas": "^0.7.22",
"@0xproject/types": "^0.6.2",
"@0xproject/typescript-typings": "^0.3.0",
"@0xproject/utils": "^0.6.0",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.4",
"query-string": "^5.0.1",
"websocket": "^1.0.25"
"@0xproject/assert": "^0.2.12",
"@0xproject/json-schemas": "^0.8.1",
"@0xproject/types": "^0.8.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"isomorphic-fetch": "2.2.1",
"lodash": "4.17.10",
"query-string": "4.3.4",
"websocket": "1.0.25"
},
"devDependencies": {
"@0xproject/monorepo-scripts": "^0.1.19",
"@0xproject/tslint-config": "^0.4.17",
"@types/fetch-mock": "^5.12.1",
"@0xproject/monorepo-scripts": "^0.2.1",
"@0xproject/tslint-config": "^0.4.20",
"@types/fetch-mock": "5.12.2",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/query-string": "^5.0.1",
"@types/websocket": "^0.0.34",
"async-child-process": "^1.1.1",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"copyfiles": "^1.2.0",
"dirty-chai": "^2.0.1",
"fetch-mock": "^5.13.1",
"mocha": "^4.0.1",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"shx": "^0.2.2",
"@types/mocha": "2.2.48",
"@types/query-string": "5.1.0",
"@types/websocket": "0.0.34",
"async-child-process": "1.1.1",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"fetch-mock": "5.13.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"shx": "0.2.2",
"tslint": "5.8.0",
"typedoc": "~0.8.0",
"typedoc": "0.8.0",
"typescript": "2.7.1"
},
"publishConfig": {

View File

@@ -16,7 +16,7 @@ export interface OrderbookChannel {
}
/**
* heartbeatInterval: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
* heartbeatIntervalMs: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
*/
export interface WebSocketOrderbookChannelConfig {
heartbeatIntervalMs?: number;

View File

@@ -91,7 +91,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
/**
* Close the websocket and stop receiving updates
*/
public close() {
public close(): void {
if (!_.isUndefined(this._connectionIfExists)) {
this._connectionIfExists.close();
}
@@ -99,7 +99,7 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
clearInterval(this._heartbeatTimerIfExists);
}
}
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void) {
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void): void {
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
callback(undefined, this._connectionIfExists);
} else {

View File

@@ -3,6 +3,7 @@ import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import * as dirtyChai from 'dirty-chai';
import * as fetchMock from 'fetch-mock';
import 'make-promises-safe';
import 'mocha';
import { HttpClient } from '../src/index';

View File

@@ -1,5 +1,6 @@
import * as chai from 'chai';
import * as dirtyChai from 'dirty-chai';
import 'make-promises-safe';
import 'mocha';
import { orderbookChannelMessageParser } from '../src/utils/orderbook_channel_message_parser';

View File

@@ -1,6 +1,7 @@
import * as chai from 'chai';
import * as dirtyChai from 'dirty-chai';
import * as _ from 'lodash';
import 'make-promises-safe';
import 'mocha';
import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';

View File

@@ -0,0 +1,11 @@
.*
tsconfig.json
webpack.config.js
yarn-error.log
test/
/src/
/_bundles/
/contract_templates/
/generated_docs/
/scripts/
/lib/src/monorepo_scripts/

View File

@@ -0,0 +1,48 @@
[
{
"timestamp": 1529397769,
"version": "0.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527617227,
"version": "0.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1527616612,
"version": "0.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "0.0.2",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1527008544
},
{
"timestamp": 1527008270,
"version": "0.0.1",
"changes": [
{
"note": "Moved contractWrappers out of 0x.js",
"pr": 579
}
]
}
]

View File

@@ -0,0 +1,26 @@
<!--
This file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v0.0.5 - _June 19, 2018_
* Dependencies updated
## v0.0.4 - _May 29, 2018_
* Dependencies updated
## v0.0.3 - _May 29, 2018_
* Dependencies updated
## v0.0.2 - _May 22, 2018_
* Dependencies updated
## v0.0.1 - _May 22, 2018_
* Moved contractWrappers out of 0x.js (#579)

View File

@@ -0,0 +1,89 @@
## @0xproject/contract-wrappers
Smart TS wrappers for 0x smart contracts. The wrappers have simplified interfaces, perform client-side validation on transactions and throw helpful error messages.
### Read the [Documentation](https://0xproject.com/docs/0x.js).
## Installation
**Install**
```bash
npm install @0xproject/contract-wrappers --save
```
**Import**
```javascript
import { ContractWrappers } from '@0xproject/contract-wrappers';
```
If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:
```json
"compilerOptions": {
"typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"],
}
```
## Contributing
We strongly recommend that the community help us make improvements and determine the future direction of the protocol. To report bugs within this package, please create an issue in this repository.
Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started.
### Install dependencies
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
```bash
yarn config set workspaces-experimental true
```
Then install dependencies
```bash
yarn install
```
### Build
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
PKG=@0xproject/contract-wrappers yarn build
```
Or continuously rebuild on change:
```bash
PKG=@0xproject/contract-wrappers yarn watch
```
```bash
yarn build
```
or continuously rebuild on change:
```bash
yarn watch
```
### Clean
```bash
yarn clean
```
### Lint
```bash
yarn lint
```
### Run Tests
```bash
yarn test
```

View File

@@ -0,0 +1,92 @@
{
"name": "@0xproject/contract-wrappers",
"version": "0.0.5",
"description": "Smart TS wrappers for 0x smart contracts",
"keywords": [
"0xproject",
"ethereum",
"tokens",
"exchange"
],
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"watch": "tsc -w",
"prebuild": "run-s clean generate_contract_wrappers",
"generate_contract_wrappers": "abi-gen --abis 'src/compact_artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
"lint": "tslint --project .",
"test:circleci": "run-s test:coverage",
"test": "run-s clean build run_mocha",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/1.0.0/$i.json test/artifacts; done;",
"clean": "shx rm -rf _bundles lib test_temp scripts test/artifacts src/contract_wrappers/generated",
"build": "tsc && yarn update_artifacts && copyfiles -u 2 './src/compact_artifacts/**/*.json' ./lib/src/compact_artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"run_mocha": "mocha lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
},
"config": {
"compact_artifacts": "Exchange DummyToken ZRXToken Token EtherToken TokenTransferProxy TokenRegistry",
"contracts": "Exchange DummyToken ZRXToken Token WETH9 TokenTransferProxy MultiSigWallet MultiSigWalletWithTimeLock MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress MaliciousToken TokenRegistry Arbitrage EtherDelta AccountLevels"
},
"repository": {
"type": "git",
"url": "https://github.com/0xProject/0x-monorepo"
},
"license": "Apache-2.0",
"engines": {
"node": ">=6.0.0"
},
"devDependencies": {
"@0xproject/abi-gen": "^0.3.2",
"@0xproject/dev-utils": "^0.4.4",
"@0xproject/migrations": "^0.0.8",
"@0xproject/monorepo-scripts": "^0.2.1",
"@0xproject/sol-compiler": "^0.5.2",
"@0xproject/subproviders": "^0.10.4",
"@0xproject/tslint-config": "^0.4.20",
"@types/lodash": "4.14.104",
"@types/mocha": "2.2.48",
"@types/node": "9.6.0",
"@types/sinon": "2.3.7",
"@types/uuid": "3.4.3",
"awesome-typescript-loader": "3.5.0",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"chai-bignumber": "2.0.1",
"copyfiles": "1.2.0",
"dirty-chai": "2.0.1",
"make-promises-safe": "1.1.0",
"mocha": "4.1.0",
"npm-run-all": "4.1.2",
"nyc": "11.6.0",
"opn-cli": "3.1.0",
"prettier": "1.12.1",
"shx": "0.2.2",
"sinon": "4.4.9",
"source-map-support": "0.5.4",
"tslint": "5.8.0",
"typescript": "2.7.1",
"web3-provider-engine": "13.8.0"
},
"dependencies": {
"@0xproject/assert": "^0.2.12",
"@0xproject/base-contract": "^0.3.4",
"@0xproject/fill-scenarios": "^0.0.4",
"@0xproject/json-schemas": "^0.8.1",
"@0xproject/order-utils": "^0.0.7",
"@0xproject/types": "^0.8.1",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/utils": "^0.7.1",
"@0xproject/web3-wrapper": "^0.7.1",
"ethereumjs-blockstream": "2.0.7",
"ethereumjs-util": "5.1.5",
"ethers": "3.0.22",
"js-sha3": "0.7.0",
"lodash": "4.17.10",
"uuid": "3.2.1"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,18 @@
import { Artifact } from '@0xproject/types';
import * as DummyToken from './compact_artifacts/DummyToken.json';
import * as EtherToken from './compact_artifacts/EtherToken.json';
import * as Exchange from './compact_artifacts/Exchange.json';
import * as Token from './compact_artifacts/Token.json';
import * as TokenRegistry from './compact_artifacts/TokenRegistry.json';
import * as TokenTransferProxy from './compact_artifacts/TokenTransferProxy.json';
import * as ZRX from './compact_artifacts/ZRX.json';
export const artifacts = {
ZRX: (ZRX as any) as Artifact,
DummyToken: (DummyToken as any) as Artifact,
Token: (Token as any) as Artifact,
Exchange: (Exchange as any) as Artifact,
EtherToken: (EtherToken as any) as Artifact,
TokenRegistry: (TokenRegistry as any) as Artifact,
TokenTransferProxy: (TokenTransferProxy as any) as Artifact,
};

View File

@@ -0,0 +1,22 @@
{
"contract_name": "DummyToken",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_target",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "setBalance",
"outputs": [],
"payable": false,
"type": "function"
}
]
}

View File

@@ -0,0 +1,287 @@
{
"contract_name": "EtherToken",
"abi": [
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "amount",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "deposit",
"outputs": [],
"payable": true,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"payable": true,
"type": "fallback"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_spender",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Deposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Withdrawal",
"type": "event"
}
],
"networks": {
"1": {
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
},
"3": {
"address": "0xc00fd9820cd2898cc4c054b7bf142de637ad129a"
},
"4": {
"address": "0xc778417e063141139fce010982780140aa0cd5ab"
},
"42": {
"address": "0x653e49e301e508a13237c0ddc98ae7d4cd2667a1"
},
"50": {
"address": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c"
}
}
}

View File

@@ -0,0 +1,610 @@
{
"contract_name": "Exchange",
"abi": [
{
"constant": true,
"inputs": [
{
"name": "numerator",
"type": "uint256"
},
{
"name": "denominator",
"type": "uint256"
},
{
"name": "target",
"type": "uint256"
}
],
"name": "isRoundingError",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "bytes32"
}
],
"name": "filled",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "bytes32"
}
],
"name": "cancelled",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5][]"
},
{
"name": "orderValues",
"type": "uint256[6][]"
},
{
"name": "fillTakerTokenAmount",
"type": "uint256"
},
{
"name": "shouldThrowOnInsufficientBalanceOrAllowance",
"type": "bool"
},
{
"name": "v",
"type": "uint8[]"
},
{
"name": "r",
"type": "bytes32[]"
},
{
"name": "s",
"type": "bytes32[]"
}
],
"name": "fillOrdersUpTo",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5]"
},
{
"name": "orderValues",
"type": "uint256[6]"
},
{
"name": "cancelTakerTokenAmount",
"type": "uint256"
}
],
"name": "cancelOrder",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "ZRX_TOKEN_CONTRACT",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5][]"
},
{
"name": "orderValues",
"type": "uint256[6][]"
},
{
"name": "fillTakerTokenAmounts",
"type": "uint256[]"
},
{
"name": "v",
"type": "uint8[]"
},
{
"name": "r",
"type": "bytes32[]"
},
{
"name": "s",
"type": "bytes32[]"
}
],
"name": "batchFillOrKillOrders",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5]"
},
{
"name": "orderValues",
"type": "uint256[6]"
},
{
"name": "fillTakerTokenAmount",
"type": "uint256"
},
{
"name": "v",
"type": "uint8"
},
{
"name": "r",
"type": "bytes32"
},
{
"name": "s",
"type": "bytes32"
}
],
"name": "fillOrKillOrder",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "orderHash",
"type": "bytes32"
}
],
"name": "getUnavailableTakerTokenAmount",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "signer",
"type": "address"
},
{
"name": "hash",
"type": "bytes32"
},
{
"name": "v",
"type": "uint8"
},
{
"name": "r",
"type": "bytes32"
},
{
"name": "s",
"type": "bytes32"
}
],
"name": "isValidSignature",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "numerator",
"type": "uint256"
},
{
"name": "denominator",
"type": "uint256"
},
{
"name": "target",
"type": "uint256"
}
],
"name": "getPartialAmount",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "TOKEN_TRANSFER_PROXY_CONTRACT",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5][]"
},
{
"name": "orderValues",
"type": "uint256[6][]"
},
{
"name": "fillTakerTokenAmounts",
"type": "uint256[]"
},
{
"name": "shouldThrowOnInsufficientBalanceOrAllowance",
"type": "bool"
},
{
"name": "v",
"type": "uint8[]"
},
{
"name": "r",
"type": "bytes32[]"
},
{
"name": "s",
"type": "bytes32[]"
}
],
"name": "batchFillOrders",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5][]"
},
{
"name": "orderValues",
"type": "uint256[6][]"
},
{
"name": "cancelTakerTokenAmounts",
"type": "uint256[]"
}
],
"name": "batchCancelOrders",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5]"
},
{
"name": "orderValues",
"type": "uint256[6]"
},
{
"name": "fillTakerTokenAmount",
"type": "uint256"
},
{
"name": "shouldThrowOnInsufficientBalanceOrAllowance",
"type": "bool"
},
{
"name": "v",
"type": "uint8"
},
{
"name": "r",
"type": "bytes32"
},
{
"name": "s",
"type": "bytes32"
}
],
"name": "fillOrder",
"outputs": [
{
"name": "filledTakerTokenAmount",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "orderAddresses",
"type": "address[5]"
},
{
"name": "orderValues",
"type": "uint256[6]"
}
],
"name": "getOrderHash",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "EXTERNAL_QUERY_GAS_LIMIT",
"outputs": [
{
"name": "",
"type": "uint16"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "VERSION",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"type": "function"
},
{
"inputs": [
{
"name": "_zrxToken",
"type": "address"
},
{
"name": "_tokenTransferProxy",
"type": "address"
}
],
"payable": false,
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "maker",
"type": "address"
},
{
"indexed": false,
"name": "taker",
"type": "address"
},
{
"indexed": true,
"name": "feeRecipient",
"type": "address"
},
{
"indexed": false,
"name": "makerToken",
"type": "address"
},
{
"indexed": false,
"name": "takerToken",
"type": "address"
},
{
"indexed": false,
"name": "filledMakerTokenAmount",
"type": "uint256"
},
{
"indexed": false,
"name": "filledTakerTokenAmount",
"type": "uint256"
},
{
"indexed": false,
"name": "paidMakerFee",
"type": "uint256"
},
{
"indexed": false,
"name": "paidTakerFee",
"type": "uint256"
},
{
"indexed": true,
"name": "tokens",
"type": "bytes32"
},
{
"indexed": false,
"name": "orderHash",
"type": "bytes32"
}
],
"name": "LogFill",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "maker",
"type": "address"
},
{
"indexed": true,
"name": "feeRecipient",
"type": "address"
},
{
"indexed": false,
"name": "makerToken",
"type": "address"
},
{
"indexed": false,
"name": "takerToken",
"type": "address"
},
{
"indexed": false,
"name": "cancelledMakerTokenAmount",
"type": "uint256"
},
{
"indexed": false,
"name": "cancelledTakerTokenAmount",
"type": "uint256"
},
{
"indexed": true,
"name": "tokens",
"type": "bytes32"
},
{
"indexed": false,
"name": "orderHash",
"type": "bytes32"
}
],
"name": "LogCancel",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "errorId",
"type": "uint8"
},
{
"indexed": true,
"name": "orderHash",
"type": "bytes32"
}
],
"name": "LogError",
"type": "event"
}
],
"networks": {
"1": {
"address": "0x12459c951127e0c374ff9105dda097662a027093"
},
"3": {
"address": "0x479cc461fecd078f766ecc58533d6f69580cf3ac"
},
"4": {
"address": "0x1d16ef40fac01cec8adac2ac49427b9384192c05"
},
"42": {
"address": "0x90fe2af704b34e0224bf2299c838e04d4dcf1364"
},
"50": {
"address": "0x48bacb9266a570d521063ef5dd96e61686dbe788"
}
}
}

View File

@@ -0,0 +1,172 @@
{
"contract_name": "Token",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "supply",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "remaining",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_spender",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
}
]
}

View File

@@ -0,0 +1,547 @@
{
"contract_name": "TokenRegistry",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_index",
"type": "uint256"
}
],
"name": "removeToken",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "string"
}
],
"name": "getTokenAddressByName",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_symbol",
"type": "string"
}
],
"name": "getTokenAddressBySymbol",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_swarmHash",
"type": "bytes"
}
],
"name": "setTokenSwarmHash",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_token",
"type": "address"
}
],
"name": "getTokenMetaData",
"outputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "uint8"
},
{
"name": "",
"type": "bytes"
},
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_name",
"type": "string"
},
{
"name": "_symbol",
"type": "string"
},
{
"name": "_decimals",
"type": "uint8"
},
{
"name": "_ipfsHash",
"type": "bytes"
},
{
"name": "_swarmHash",
"type": "bytes"
}
],
"name": "addToken",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_name",
"type": "string"
}
],
"name": "setTokenName",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "tokens",
"outputs": [
{
"name": "token",
"type": "address"
},
{
"name": "name",
"type": "string"
},
{
"name": "symbol",
"type": "string"
},
{
"name": "decimals",
"type": "uint8"
},
{
"name": "ipfsHash",
"type": "bytes"
},
{
"name": "swarmHash",
"type": "bytes"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "tokenAddresses",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_name",
"type": "string"
}
],
"name": "getTokenByName",
"outputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "uint8"
},
{
"name": "",
"type": "bytes"
},
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getTokenAddresses",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_ipfsHash",
"type": "bytes"
}
],
"name": "setTokenIpfsHash",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_symbol",
"type": "string"
}
],
"name": "getTokenBySymbol",
"outputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "string"
},
{
"name": "",
"type": "uint8"
},
{
"name": "",
"type": "bytes"
},
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_symbol",
"type": "string"
}
],
"name": "setTokenSymbol",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"payable": false,
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "token",
"type": "address"
},
{
"indexed": false,
"name": "name",
"type": "string"
},
{
"indexed": false,
"name": "symbol",
"type": "string"
},
{
"indexed": false,
"name": "decimals",
"type": "uint8"
},
{
"indexed": false,
"name": "ipfsHash",
"type": "bytes"
},
{
"indexed": false,
"name": "swarmHash",
"type": "bytes"
}
],
"name": "LogAddToken",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "token",
"type": "address"
},
{
"indexed": false,
"name": "name",
"type": "string"
},
{
"indexed": false,
"name": "symbol",
"type": "string"
},
{
"indexed": false,
"name": "decimals",
"type": "uint8"
},
{
"indexed": false,
"name": "ipfsHash",
"type": "bytes"
},
{
"indexed": false,
"name": "swarmHash",
"type": "bytes"
}
],
"name": "LogRemoveToken",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "token",
"type": "address"
},
{
"indexed": false,
"name": "oldName",
"type": "string"
},
{
"indexed": false,
"name": "newName",
"type": "string"
}
],
"name": "LogTokenNameChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "token",
"type": "address"
},
{
"indexed": false,
"name": "oldSymbol",
"type": "string"
},
{
"indexed": false,
"name": "newSymbol",
"type": "string"
}
],
"name": "LogTokenSymbolChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "token",
"type": "address"
},
{
"indexed": false,
"name": "oldIpfsHash",
"type": "bytes"
},
{
"indexed": false,
"name": "newIpfsHash",
"type": "bytes"
}
],
"name": "LogTokenIpfsHashChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "token",
"type": "address"
},
{
"indexed": false,
"name": "oldSwarmHash",
"type": "bytes"
},
{
"indexed": false,
"name": "newSwarmHash",
"type": "bytes"
}
],
"name": "LogTokenSwarmHashChange",
"type": "event"
}
],
"networks": {
"1": {
"address": "0x926a74c5c36adf004c87399e65f75628b0f98d2c"
},
"3": {
"address": "0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed"
},
"4": {
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
},
"42": {
"address": "0xf18e504561f4347bea557f3d4558f559dddbae7f"
},
"50": {
"address": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082"
}
}
}

View File

@@ -0,0 +1,187 @@
{
"contract_name": "TokenTransferProxy",
"abi": [
{
"constant": false,
"inputs": [
{
"name": "token",
"type": "address"
},
{
"name": "from",
"type": "address"
},
{
"name": "to",
"type": "address"
},
{
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "target",
"type": "address"
}
],
"name": "addAuthorizedAddress",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "authorities",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "target",
"type": "address"
}
],
"name": "removeAuthorizedAddress",
"outputs": [],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "owner",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "authorized",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getAuthorizedAddresses",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"payable": false,
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "target",
"type": "address"
},
{
"indexed": true,
"name": "caller",
"type": "address"
}
],
"name": "LogAuthorizedAddressAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "target",
"type": "address"
},
{
"indexed": true,
"name": "caller",
"type": "address"
}
],
"name": "LogAuthorizedAddressRemoved",
"type": "event"
}
],
"networks": {
"1": {
"address": "0x8da0d80f5007ef1e431dd2127178d224e32c2ef4"
},
"3": {
"address": "0x4e9aad8184de8833365fea970cd9149372fdf1e6"
},
"4": {
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
},
"42": {
"address": "0x087eed4bc1ee3de49befbd66c662b434b15d49d4"
},
"50": {
"address": "0x1dc4c1cefef38a777b15aa20260a54e584b16c48"
}
}
}

View File

@@ -0,0 +1,20 @@
{
"contract_name": "ZRX",
"networks": {
"1": {
"address": "0xe41d2489571d322189246dafa5ebde1f4699f498"
},
"3": {
"address": "0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d"
},
"4": {
"address": "0x00f58d6d585f84b2d7267940cede30ce2fe6eae8"
},
"42": {
"address": "0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570"
},
"50": {
"address": "0x1d7022f5b17d2f8b695918fb48fa1089c9f85401"
}
}
}

View File

@@ -0,0 +1,112 @@
import { Provider } from '@0xproject/types';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
import { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
import { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper';
import { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper';
import { TokenWrapper } from './contract_wrappers/token_wrapper';
import { ContractWrappersConfigSchema } from './schemas/contract_wrappers_config_schema';
import { contractWrappersPrivateNetworkConfigSchema } from './schemas/contract_wrappers_private_network_config_schema';
import { contractWrappersPublicNetworkConfigSchema } from './schemas/contract_wrappers_public_network_config_schema';
import { ContractWrappersConfig } from './types';
import { assert } from './utils/assert';
/**
* The ContractWrappers class contains smart contract wrappers helpful when building on 0x protocol.
*/
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 TokenRegistryWrapper class containing methods for interacting with the 0x
* TokenRegistry smart contract.
*/
public tokenRegistry: TokenRegistryWrapper;
/**
* An instance of the TokenWrapper class containing methods for interacting with any ERC20 token smart contract.
*/
public token: TokenWrapper;
/**
* An instance of the EtherTokenWrapper class containing methods for interacting with the
* wrapped ETH ERC20 token smart contract.
*/
public etherToken: EtherTokenWrapper;
/**
* An instance of the TokenTransferProxyWrapper class containing methods for interacting with the
* tokenTransferProxy smart contract.
*/
public proxy: TokenTransferProxyWrapper;
private _web3Wrapper: Web3Wrapper;
/**
* Instantiates a new ContractWrappers instance.
* @param provider The Provider instance you would like the 0x.js library to use for interacting with
* the Ethereum network.
* @param config The configuration object. Look up the type for the description.
* @return An instance of the ContractWrappers class.
*/
constructor(provider: Provider, config: ContractWrappersConfig) {
assert.isWeb3Provider('provider', provider);
assert.doesConformToSchema('config', config, ContractWrappersConfigSchema, [
contractWrappersPrivateNetworkConfigSchema,
contractWrappersPublicNetworkConfigSchema,
]);
const artifactJSONs = _.values(artifacts);
const abiArrays = _.map(artifactJSONs, artifact => artifact.abi);
const txDefaults = {
gasPrice: config.gasPrice,
};
this._web3Wrapper = new Web3Wrapper(provider, txDefaults);
_.forEach(abiArrays, abi => {
this._web3Wrapper.abiDecoder.addABI(abi);
});
this.proxy = new TokenTransferProxyWrapper(
this._web3Wrapper,
config.networkId,
config.tokenTransferProxyContractAddress,
);
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this.proxy);
this.exchange = new ExchangeWrapper(
this._web3Wrapper,
config.networkId,
this.token,
config.exchangeContractAddress,
config.zrxContractAddress,
);
this.tokenRegistry = new TokenRegistryWrapper(
this._web3Wrapper,
config.networkId,
config.tokenRegistryContractAddress,
);
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this.token);
}
/**
* Sets a new web3 provider for 0x.js. Updating the provider will stop all
* subscriptions so you will need to re-subscribe to all events relevant to your app after this call.
* @param provider The Web3Provider you would like the 0x.js library to use from now on.
* @param networkId The id of the network your provider is connected to
*/
public setProvider(provider: Provider, networkId: number): void {
this._web3Wrapper.setProvider(provider);
(this.exchange as any)._invalidateContractInstances();
(this.exchange as any)._setNetworkId(networkId);
(this.tokenRegistry as any)._invalidateContractInstance();
(this.tokenRegistry as any)._setNetworkId(networkId);
(this.token as any)._invalidateContractInstances();
(this.token as any)._setNetworkId(networkId);
(this.proxy as any)._invalidateContractInstance();
(this.proxy as any)._setNetworkId(networkId);
(this.etherToken as any)._invalidateContractInstance();
(this.etherToken as any)._setNetworkId(networkId);
}
/**
* Get the provider instance currently used by 0x.js
* @return Web3 provider instance
*/
public getProvider(): Provider {
return this._web3Wrapper.getProvider();
}
}

View File

@@ -1,32 +1,38 @@
import { BlockParamLiteral, ContractAbi, FilterObject, LogEntry, LogWithDecodedArgs, RawLog } from '@0xproject/types';
import {
Artifact,
BlockParamLiteral,
ContractAbi,
FilterObject,
LogEntry,
LogWithDecodedArgs,
RawLog,
} from '@0xproject/types';
import { AbiDecoder, intervalUtils } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Block, BlockAndLogStreamer } from 'ethereumjs-blockstream';
import * as _ from 'lodash';
import * as Web3 from 'web3';
import {
Artifact,
BlockRange,
ContractEventArgs,
ContractEvents,
ContractWrappersError,
EventCallback,
IndexedFilterValues,
InternalZeroExError,
ZeroExError,
InternalContractWrappersError,
} from '../types';
import { constants } from '../utils/constants';
import { filterUtils } from '../utils/filter_utils';
const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
[contractName: string]: ZeroExError;
[contractName: string]: ContractWrappersError;
} = {
ZRX: ZeroExError.ZRXContractDoesNotExist,
EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
Token: ZeroExError.TokenContractDoesNotExist,
TokenRegistry: ZeroExError.TokenRegistryContractDoesNotExist,
TokenTransferProxy: ZeroExError.TokenTransferProxyContractDoesNotExist,
Exchange: ZeroExError.ExchangeContractDoesNotExist,
ZRX: ContractWrappersError.ZRXContractDoesNotExist,
EtherToken: ContractWrappersError.EtherTokenContractDoesNotExist,
Token: ContractWrappersError.TokenContractDoesNotExist,
TokenRegistry: ContractWrappersError.TokenRegistryContractDoesNotExist,
TokenTransferProxy: ContractWrappersError.TokenTransferProxyContractDoesNotExist,
Exchange: ContractWrappersError.ExchangeContractDoesNotExist,
};
export class ContractWrapper {
@@ -57,7 +63,7 @@ export class ContractWrapper {
}
protected _unsubscribe(filterToken: string, err?: Error): void {
if (_.isUndefined(this._filters[filterToken])) {
throw new Error(ZeroExError.SubscriptionNotFound);
throw new Error(ContractWrappersError.SubscriptionNotFound);
}
if (!_.isUndefined(err)) {
const callback = this._filterCallbacks[filterToken];
@@ -101,7 +107,7 @@ export class ContractWrapper {
log: LogEntry,
): LogWithDecodedArgs<ArgsType> | RawLog {
if (_.isUndefined(this._web3Wrapper.abiDecoder)) {
throw new Error(InternalZeroExError.NoAbiDecoder);
throw new Error(InternalContractWrappersError.NoAbiDecoder);
}
const logWithDecodedArgs = this._web3Wrapper.abiDecoder.tryToDecodeLogOrNoop(log);
return logWithDecodedArgs;
@@ -113,7 +119,7 @@ export class ContractWrapper {
let contractAddress: string;
if (_.isUndefined(addressIfExists)) {
if (_.isUndefined(artifact.networks[this._networkId])) {
throw new Error(ZeroExError.ContractNotDeployedOnNetwork);
throw new Error(ContractWrappersError.ContractNotDeployedOnNetwork);
}
contractAddress = artifact.networks[this._networkId].address.toLowerCase();
} else {
@@ -130,7 +136,7 @@ export class ContractWrapper {
if (_.isUndefined(addressIfExists)) {
const contractAddress = artifact.networks[this._networkId].address;
if (_.isUndefined(contractAddress)) {
throw new Error(ZeroExError.ExchangeContractDoesNotExist);
throw new Error(ContractWrappersError.ExchangeContractDoesNotExist);
}
return contractAddress;
} else {
@@ -151,7 +157,7 @@ export class ContractWrapper {
}
private _startBlockAndLogStream(): void {
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
throw new Error(ContractWrappersError.SubscriptionAlreadyPresent);
}
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
@@ -184,7 +190,7 @@ export class ContractWrapper {
}
private _stopBlockAndLogStream(): void {
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
throw new Error(ZeroExError.SubscriptionNotFound);
throw new Error(ContractWrappersError.SubscriptionNotFound);
}
this._blockAndLogStreamerIfExists.unsubscribeFromOnLogAdded(this._onLogAddedSubscriptionToken as string);
this._blockAndLogStreamerIfExists.unsubscribeFromOnLogRemoved(this._onLogRemovedSubscriptionToken as string);

View File

@@ -5,7 +5,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
import { artifacts } from '../artifacts';
import { BlockRange, EventCallback, IndexedFilterValues, TransactionOpts, ZeroExError } from '../types';
import { BlockRange, ContractWrappersError, EventCallback, IndexedFilterValues, TransactionOpts } from '../types';
import { assert } from '../utils/assert';
import { ContractWrapper } from './contract_wrapper';
@@ -48,7 +48,7 @@ export class EtherTokenWrapper extends ContractWrapper {
const normalizedDepositorAddress = depositor.toLowerCase();
const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(normalizedDepositorAddress);
assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit);
assert.assert(ethBalanceInWei.gte(amountInWei), ContractWrappersError.InsufficientEthBalanceForDeposit);
const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
const txHash = await wethContract.deposit.sendTransactionAsync({
@@ -84,7 +84,10 @@ export class EtherTokenWrapper extends ContractWrapper {
normalizedEtherTokenAddress,
normalizedWithdrawerAddress,
);
assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
assert.assert(
WETHBalanceInBaseUnits.gte(amountInWei),
ContractWrappersError.InsufficientWEthBalanceForWithdrawal,
);
const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress);
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
@@ -119,7 +122,7 @@ export class EtherTokenWrapper extends ContractWrapper {
eventName,
blockRange,
indexFilterValues,
artifacts.EtherTokenArtifact.abi,
artifacts.EtherToken.abi,
);
return logs;
}
@@ -147,7 +150,7 @@ export class EtherTokenWrapper extends ContractWrapper {
normalizedEtherTokenAddress,
eventName,
indexFilterValues,
artifacts.EtherTokenArtifact.abi,
artifacts.EtherToken.abi,
callback,
);
return subscriptionToken;
@@ -172,7 +175,7 @@ export class EtherTokenWrapper extends ContractWrapper {
* @returns The Ethereum address of the EtherToken contract or undefined.
*/
public getContractAddressIfExists(): string | undefined {
const networkSpecificArtifact = artifacts.EtherTokenArtifact.networks[this._networkId];
const networkSpecificArtifact = artifacts.EtherToken.networks[this._networkId];
const contractAddressIfExists = _.isUndefined(networkSpecificArtifact)
? undefined
: networkSpecificArtifact.address;
@@ -188,7 +191,7 @@ export class EtherTokenWrapper extends ContractWrapper {
return etherTokenContract;
}
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
artifacts.EtherTokenArtifact,
artifacts.EtherToken,
etherTokenAddress,
);
const contractInstance = new EtherTokenContract(

View File

@@ -1,12 +1,16 @@
import { schemas } from '@0xproject/json-schemas';
import { getOrderHashHex } from '@0xproject/order-utils';
import { formatters, getOrderHashHex, OrderStateUtils } from '@0xproject/order-utils';
import {
BlockParamLiteral,
DecodedLogArgs,
ECSignature,
ExchangeContractErrs,
LogEntry,
LogWithDecodedArgs,
Order,
OrderAddresses,
OrderState,
OrderValues,
SignedOrder,
} from '@0xproject/types';
import { AbiDecoder, BigNumber } from '@0xproject/utils';
@@ -20,21 +24,16 @@ import {
BlockRange,
EventCallback,
ExchangeContractErrCodes,
ExchangeContractErrs,
IndexedFilterValues,
MethodOpts,
OrderAddresses,
OrderCancellationRequest,
OrderFillRequest,
OrderState,
OrderTransactionOpts,
OrderValues,
ValidateOrderFillableOpts,
} from '../types';
import { assert } from '../utils/assert';
import { decorators } from '../utils/decorators';
import { ExchangeTransferSimulator } from '../utils/exchange_transfer_simulator';
import { OrderStateUtils } from '../utils/order_state_utils';
import { OrderValidationUtils } from '../utils/order_validation_utils';
import { utils } from '../utils/utils';
@@ -70,24 +69,6 @@ export class ExchangeWrapper extends ContractWrapper {
};
private _contractAddressIfExists?: string;
private _zrxContractAddressIfExists?: string;
private static _getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] {
const orderAddresses: OrderAddresses = [
order.maker,
order.taker,
order.makerTokenAddress,
order.takerTokenAddress,
order.feeRecipient,
];
const orderValues: OrderValues = [
order.makerTokenAmount,
order.takerTokenAmount,
order.makerFee,
order.takerFee,
order.expirationUnixTimestampSec,
order.salt,
];
return [orderAddresses, orderValues];
}
constructor(
web3Wrapper: Web3Wrapper,
networkId: number,
@@ -209,7 +190,7 @@ export class ExchangeWrapper extends ContractWrapper {
);
}
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(signedOrder);
const txHash: string = await exchangeInstance.fillOrder.sendTransactionAsync(
orderAddresses,
@@ -296,7 +277,7 @@ export class ExchangeWrapper extends ContractWrapper {
const orderAddressesValuesAndSignatureArray = _.map(signedOrders, signedOrder => {
return [
...ExchangeWrapper._getOrderAddressesAndValues(signedOrder),
...formatters.getOrderAddressesAndValues(signedOrder),
signedOrder.ecSignature.v,
signedOrder.ecSignature.r,
signedOrder.ecSignature.s,
@@ -384,7 +365,7 @@ export class ExchangeWrapper extends ContractWrapper {
const orderAddressesValuesAmountsAndSignatureArray = _.map(orderFillRequests, orderFillRequest => {
return [
...ExchangeWrapper._getOrderAddressesAndValues(orderFillRequest.signedOrder),
...formatters.getOrderAddressesAndValues(orderFillRequest.signedOrder),
orderFillRequest.takerTokenFillAmount,
orderFillRequest.signedOrder.ecSignature.v,
orderFillRequest.signedOrder.ecSignature.r,
@@ -453,7 +434,7 @@ export class ExchangeWrapper extends ContractWrapper {
);
}
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(signedOrder);
const txHash = await exchangeInstance.fillOrKillOrder.sendTransactionAsync(
orderAddresses,
orderValues,
@@ -519,7 +500,7 @@ export class ExchangeWrapper extends ContractWrapper {
const orderAddressesValuesAndTakerTokenFillAmounts = _.map(orderFillRequests, request => {
return [
...ExchangeWrapper._getOrderAddressesAndValues(request.signedOrder),
...formatters.getOrderAddressesAndValues(request.signedOrder),
request.takerTokenFillAmount,
request.signedOrder.ecSignature.v,
request.signedOrder.ecSignature.r,
@@ -580,7 +561,7 @@ export class ExchangeWrapper extends ContractWrapper {
);
}
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(order);
const txHash = await exchangeInstance.cancelOrder.sendTransactionAsync(
orderAddresses,
orderValues,
@@ -645,7 +626,7 @@ export class ExchangeWrapper extends ContractWrapper {
const exchangeInstance = await this._getExchangeContractAsync();
const orderAddressesValuesAndTakerTokenCancelAmounts = _.map(orderCancellationRequests, cancellationRequest => {
return [
...ExchangeWrapper._getOrderAddressesAndValues(cancellationRequest.order),
...formatters.getOrderAddressesAndValues(cancellationRequest.order),
cancellationRequest.takerTokenCancelAmount,
];
});
@@ -686,7 +667,7 @@ export class ExchangeWrapper extends ContractWrapper {
exchangeContractAddress,
eventName,
indexFilterValues,
artifacts.ExchangeArtifact.abi,
artifacts.Exchange.abi,
callback,
);
return subscriptionToken;
@@ -726,7 +707,7 @@ export class ExchangeWrapper extends ContractWrapper {
eventName,
blockRange,
indexFilterValues,
artifacts.ExchangeArtifact.abi,
artifacts.Exchange.abi,
);
return logs;
}
@@ -736,7 +717,7 @@ export class ExchangeWrapper extends ContractWrapper {
* @returns The Ethereum address of the Exchange contract being used.
*/
public getContractAddress(): string {
const contractAddress = this._getContractAddress(artifacts.ExchangeArtifact, this._contractAddressIfExists);
const contractAddress = this._getContractAddress(artifacts.Exchange, this._contractAddressIfExists);
return contractAddress;
}
/**
@@ -904,7 +885,7 @@ export class ExchangeWrapper extends ContractWrapper {
* @return Address of ZRX token
*/
public getZRXTokenAddress(): string {
const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
const contractAddress = this._getContractAddress(artifacts.ZRX, this._zrxContractAddressIfExists);
return contractAddress;
}
private _invalidateContractInstances(): void {
@@ -934,7 +915,7 @@ export class ExchangeWrapper extends ContractWrapper {
}
private async _getOrderHashHexUsingContractCallAsync(order: Order | SignedOrder): Promise<string> {
const exchangeInstance = await this._getExchangeContractAsync();
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
const [orderAddresses, orderValues] = formatters.getOrderAddressesAndValues(order);
const orderHashHex = await exchangeInstance.getOrderHash.callAsync(orderAddresses, orderValues);
return orderHashHex;
}
@@ -943,7 +924,7 @@ export class ExchangeWrapper extends ContractWrapper {
return this._exchangeContractIfExists;
}
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
artifacts.ExchangeArtifact,
artifacts.Exchange,
this._contractAddressIfExists,
);
const contractInstance = new ExchangeContract(
@@ -955,10 +936,4 @@ export class ExchangeWrapper extends ContractWrapper {
this._exchangeContractIfExists = contractInstance;
return this._exchangeContractIfExists;
}
private async _getTokenTransferProxyAddressAsync(): Promise<string> {
const exchangeInstance = await this._getExchangeContractAsync();
const tokenTransferProxyAddress = await exchangeInstance.TOKEN_TRANSFER_PROXY_CONTRACT.callAsync();
const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase();
return tokenTransferProxyAddressLowerCase;
}
} // tslint:disable:max-file-line-count

View File

@@ -1,8 +1,9 @@
import { Token } from '@0xproject/types';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
import { artifacts } from '../artifacts';
import { Token, TokenMetadata } from '../types';
import { TokenMetadata } from '../types';
import { assert } from '../utils/assert';
import { constants } from '../utils/constants';
@@ -104,10 +105,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
* @returns The Ethereum address of the TokenRegistry contract being used.
*/
public getContractAddress(): string {
const contractAddress = this._getContractAddress(
artifacts.TokenRegistryArtifact,
this._contractAddressIfExists,
);
const contractAddress = this._getContractAddress(artifacts.TokenRegistry, this._contractAddressIfExists);
return contractAddress;
}
private _invalidateContractInstance(): void {
@@ -118,7 +116,7 @@ export class TokenRegistryWrapper extends ContractWrapper {
return this._tokenRegistryContractIfExists;
}
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
artifacts.TokenRegistryArtifact,
artifacts.TokenRegistry,
this._contractAddressIfExists,
);
const contractInstance = new TokenRegistryContract(

View File

@@ -46,10 +46,7 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
* @returns The Ethereum address of the TokenTransferProxy contract being used.
*/
public getContractAddress(): string {
const contractAddress = this._getContractAddress(
artifacts.TokenTransferProxyArtifact,
this._contractAddressIfExists,
);
const contractAddress = this._getContractAddress(artifacts.TokenTransferProxy, this._contractAddressIfExists);
return contractAddress;
}
private _invalidateContractInstance(): void {
@@ -60,7 +57,7 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
return this._tokenTransferProxyContractIfExists;
}
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
artifacts.TokenTransferProxyArtifact,
artifacts.TokenTransferProxy,
this._contractAddressIfExists,
);
const contractInstance = new TokenTransferProxyContract(

View File

@@ -5,7 +5,14 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
import { artifacts } from '../artifacts';
import { BlockRange, EventCallback, IndexedFilterValues, MethodOpts, TransactionOpts, ZeroExError } from '../types';
import {
BlockRange,
ContractWrappersError,
EventCallback,
IndexedFilterValues,
MethodOpts,
TransactionOpts,
} from '../types';
import { assert } from '../utils/assert';
import { constants } from '../utils/constants';
@@ -266,7 +273,7 @@ export class TokenWrapper extends ContractWrapper {
const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress);
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
throw new Error(ContractWrappersError.InsufficientBalanceForTransfer);
}
const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, {
@@ -316,12 +323,12 @@ export class TokenWrapper extends ContractWrapper {
normalizedSenderAddress,
);
if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
throw new Error(ContractWrappersError.InsufficientAllowanceForTransfer);
}
const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress);
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
throw new Error(ContractWrappersError.InsufficientBalanceForTransfer);
}
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
@@ -360,7 +367,7 @@ export class TokenWrapper extends ContractWrapper {
normalizedTokenAddress,
eventName,
indexFilterValues,
artifacts.TokenArtifact.abi,
artifacts.Token.abi,
callback,
);
return subscriptionToken;
@@ -403,7 +410,7 @@ export class TokenWrapper extends ContractWrapper {
eventName,
blockRange,
indexFilterValues,
artifacts.TokenArtifact.abi,
artifacts.Token.abi,
);
return logs;
}
@@ -418,7 +425,7 @@ export class TokenWrapper extends ContractWrapper {
return tokenContract;
}
const [abi, address] = await this._getContractAbiAndAddressFromArtifactsAsync(
artifacts.TokenArtifact,
artifacts.Token,
normalizedTokenAddress,
);
const contractInstance = new TokenContract(

View File

@@ -1,10 +1,10 @@
import { AbstractBalanceAndProxyAllowanceFetcher } from '@0xproject/order-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { BalanceAndProxyAllowanceFetcher } from '../abstract/balance_and_proxy_allowance_fetcher';
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
export class SimpleBalanceAndProxyAllowanceFetcher implements BalanceAndProxyAllowanceFetcher {
export class SimpleBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher {
private _tokenWrapper: TokenWrapper;
private _defaultBlock: BlockParamLiteral;
constructor(token: TokenWrapper, defaultBlock: BlockParamLiteral) {

View File

@@ -1,10 +1,10 @@
import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { OrderFilledCancelledFetcher } from '../abstract/order_filled_cancelled_fetcher';
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
export class SimpleOrderFilledCancelledFetcher implements OrderFilledCancelledFetcher {
export class SimpleOrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher {
private _exchangeWrapper: ExchangeWrapper;
private _defaultBlock: BlockParamLiteral;
constructor(exchange: ExchangeWrapper, defaultBlock: BlockParamLiteral) {
@@ -25,4 +25,12 @@ export class SimpleOrderFilledCancelledFetcher implements OrderFilledCancelledFe
const cancelledTakerAmount = this._exchangeWrapper.getCancelledTakerAmountAsync(orderHash, methodOpts);
return cancelledTakerAmount;
}
public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
const unavailableTakerAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
return unavailableTakerAmount;
}
public getZRXTokenAddress(): string {
const zrxToken = this._exchangeWrapper.getZRXTokenAddress();
return zrxToken;
}
}

View File

@@ -0,0 +1,68 @@
export { ContractWrappers } from './contract_wrappers';
export { ExchangeWrapper } from './contract_wrappers/exchange_wrapper';
export { TokenWrapper } from './contract_wrappers/token_wrapper';
export { TokenRegistryWrapper } from './contract_wrappers/token_registry_wrapper';
export { EtherTokenWrapper } from './contract_wrappers/ether_token_wrapper';
export { TokenTransferProxyWrapper } from './contract_wrappers/token_transfer_proxy_wrapper';
export {
ContractWrappersError,
EventCallback,
ContractEvent,
Token,
IndexedFilterValues,
BlockRange,
OrderCancellationRequest,
OrderFillRequest,
ContractEventArgs,
ContractWrappersConfig,
MethodOpts,
OrderTransactionOpts,
TransactionOpts,
LogEvent,
DecodedLogEvent,
OnOrderStateChangeCallback,
} from './types';
export {
BlockParamLiteral,
FilterObject,
BlockParam,
ContractEventArg,
ExchangeContractErrs,
LogWithDecodedArgs,
Order,
Provider,
SignedOrder,
ECSignature,
OrderStateValid,
OrderStateInvalid,
OrderState,
TransactionReceipt,
TransactionReceiptWithDecodedLogs,
} from '@0xproject/types';
export {
EtherTokenContractEventArgs,
WithdrawalContractEventArgs,
DepositContractEventArgs,
EtherTokenEvents,
} from './contract_wrappers/generated/ether_token';
export {
TransferContractEventArgs,
ApprovalContractEventArgs,
TokenContractEventArgs,
TokenEvents,
} from './contract_wrappers/generated/token';
export {
LogErrorContractEventArgs,
LogCancelContractEventArgs,
LogFillContractEventArgs,
ExchangeContractEventArgs,
ExchangeEvents,
} from './contract_wrappers/generated/exchange';
export { BalanceAndProxyAllowanceLazyStore } from './stores/balance_proxy_allowance_lazy_store';
export { OrderFilledCancelledLazyStore } from './stores/order_filled_cancelled_lazy_store';

View File

@@ -0,0 +1,5 @@
export const ContractWrappersConfigSchema = {
id: '/ContractWrappersConfig',
oneOf: [{ $ref: '/ZeroExContractPrivateNetworkConfig' }, { $ref: '/ZeroExContractPublicNetworkConfig' }],
type: 'object',
};

View File

@@ -0,0 +1,35 @@
export const contractWrappersPrivateNetworkConfigSchema = {
id: '/ZeroExContractPrivateNetworkConfig',
properties: {
networkId: {
type: 'number',
minimum: 1,
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: [
'networkId',
'zrxContractAddress',
'exchangeContractAddress',
'tokenRegistryContractAddress',
'tokenTransferProxyContractAddress',
],
};

View File

@@ -0,0 +1,43 @@
const networkNameToId: { [networkName: string]: number } = {
mainnet: 1,
ropsten: 3,
rinkeby: 4,
kovan: 42,
ganache: 50,
};
export const contractWrappersPublicNetworkConfigSchema = {
id: '/ZeroExContractPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
enum: [
networkNameToId.mainnet,
networkNameToId.kovan,
networkNameToId.ropsten,
networkNameToId.rinkeby,
networkNameToId.ganache,
],
},
gasPrice: { $ref: '/Number' },
zrxContractAddress: { $ref: '/Address' },
exchangeContractAddress: { $ref: '/Address' },
tokenRegistryContractAddress: { $ref: '/Address' },
tokenTransferProxyContractAddress: { $ref: '/Address' },
orderWatcherConfig: {
type: 'object',
properties: {
pollingIntervalMs: {
type: 'number',
minimum: 0,
},
numConfirmations: {
type: 'number',
minimum: 0,
},
},
},
},
type: 'object',
required: ['networkId'],
};

View File

@@ -1,14 +1,14 @@
import { AbstractBalanceAndProxyAllowanceFetcher } from '@0xproject/order-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { BalanceAndProxyAllowanceFetcher } from '../abstract/balance_and_proxy_allowance_fetcher';
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
/**
* Copy on read store for balances/proxyAllowances of tokens/accounts
*/
export class BalanceAndProxyAllowanceLazyStore implements BalanceAndProxyAllowanceFetcher {
export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProxyAllowanceFetcher {
private _tokenWrapper: TokenWrapper;
private _defaultBlock: BlockParamLiteral;
private _balance: {

View File

@@ -1,14 +1,14 @@
import { AbstractOrderFilledCancelledFetcher } from '@0xproject/order-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { OrderFilledCancelledFetcher } from '../abstract/order_filled_cancelled_fetcher';
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
/**
* Copy on read store for filled/cancelled taker amounts
*/
export class OrderFilledCancelledLazyStore implements OrderFilledCancelledFetcher {
export class OrderFilledCancelledLazyStore implements AbstractOrderFilledCancelledFetcher {
private _exchangeWrapper: ExchangeWrapper;
private _defaultBlock: BlockParamLiteral;
private _filledTakerAmount: {
@@ -64,4 +64,12 @@ export class OrderFilledCancelledLazyStore implements OrderFilledCancelledFetche
this._filledTakerAmount = {};
this._cancelledTakerAmount = {};
}
public async getUnavailableTakerAmountAsync(orderHash: string): Promise<BigNumber> {
const unavailableTakerAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
return unavailableTakerAmount;
}
public getZRXTokenAddress(): string {
const zrxToken = this._exchangeWrapper.getZRXTokenAddress();
return zrxToken;
}
}

View File

@@ -0,0 +1,186 @@
import { BigNumber } from '@0xproject/utils';
import {
BlockParam,
BlockParamLiteral,
ContractAbi,
ContractEventArg,
ExchangeContractErrs,
FilterObject,
LogEntryEvent,
LogWithDecodedArgs,
Order,
OrderState,
SignedOrder,
} from '@0xproject/types';
import { EtherTokenContractEventArgs, EtherTokenEvents } from './contract_wrappers/generated/ether_token';
import { ExchangeContractEventArgs, ExchangeEvents } from './contract_wrappers/generated/exchange';
import { TokenContractEventArgs, TokenEvents } from './contract_wrappers/generated/token';
export enum ContractWrappersError {
ExchangeContractDoesNotExist = 'EXCHANGE_CONTRACT_DOES_NOT_EXIST',
ZRXContractDoesNotExist = 'ZRX_CONTRACT_DOES_NOT_EXIST',
EtherTokenContractDoesNotExist = 'ETHER_TOKEN_CONTRACT_DOES_NOT_EXIST',
TokenTransferProxyContractDoesNotExist = 'TOKEN_TRANSFER_PROXY_CONTRACT_DOES_NOT_EXIST',
TokenRegistryContractDoesNotExist = 'TOKEN_REGISTRY_CONTRACT_DOES_NOT_EXIST',
TokenContractDoesNotExist = 'TOKEN_CONTRACT_DOES_NOT_EXIST',
ContractNotDeployedOnNetwork = 'CONTRACT_NOT_DEPLOYED_ON_NETWORK',
InsufficientAllowanceForTransfer = 'INSUFFICIENT_ALLOWANCE_FOR_TRANSFER',
InsufficientBalanceForTransfer = 'INSUFFICIENT_BALANCE_FOR_TRANSFER',
InsufficientEthBalanceForDeposit = 'INSUFFICIENT_ETH_BALANCE_FOR_DEPOSIT',
InsufficientWEthBalanceForWithdrawal = 'INSUFFICIENT_WETH_BALANCE_FOR_WITHDRAWAL',
InvalidJump = 'INVALID_JUMP',
OutOfGas = 'OUT_OF_GAS',
SubscriptionNotFound = 'SUBSCRIPTION_NOT_FOUND',
SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
}
export enum InternalContractWrappersError {
NoAbiDecoder = 'NO_ABI_DECODER',
ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY',
WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
}
export type LogEvent = LogEntryEvent;
export interface DecodedLogEvent<ArgsType> {
isRemoved: boolean;
log: LogWithDecodedArgs<ArgsType>;
}
export type EventCallback<ArgsType> = (err: null | Error, log?: DecodedLogEvent<ArgsType>) => void;
export enum ExchangeContractErrCodes {
ERROR_FILL_EXPIRED, // Order has already expired
ERROR_FILL_NO_VALUE, // Order has already been fully filled or cancelled
ERROR_FILL_TRUNCATION, // Rounding error too large
ERROR_FILL_BALANCE_ALLOWANCE, // Insufficient balance or allowance for token transfer
ERROR_CANCEL_EXPIRED, // Order has already expired
ERROR_CANCEL_NO_VALUE, // Order has already been fully filled or cancelled
}
export interface ContractEvent {
logIndex: number;
transactionIndex: number;
transactionHash: string;
blockHash: string;
blockNumber: number;
address: string;
type: string;
event: string;
args: ContractEventArgs;
}
export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
// [address, name, symbol, decimals, ipfsHash, swarmHash]
export type TokenMetadata = [string, string, string, number, string, string];
export interface Token {
name: string;
address: string;
symbol: string;
decimals: number;
}
export interface TxOpts {
from: string;
gas?: number;
value?: BigNumber;
gasPrice?: BigNumber;
}
export interface TokenAddressBySymbol {
[symbol: string]: string;
}
export type ContractEvents = TokenEvents | ExchangeEvents | EtherTokenEvents;
export interface IndexedFilterValues {
[index: string]: ContractEventArg;
}
export interface BlockRange {
fromBlock: BlockParam;
toBlock: BlockParam;
}
export interface OrderCancellationRequest {
order: Order | SignedOrder;
takerTokenCancelAmount: BigNumber;
}
export interface OrderFillRequest {
signedOrder: SignedOrder;
takerTokenFillAmount: BigNumber;
}
export type AsyncMethod = (...args: any[]) => Promise<any>;
export type SyncMethod = (...args: any[]) => any;
/**
* networkId: The id of the underlying ethereum network your provider is connected to. (1-mainnet, 3-ropsten, 4-rinkeby, 42-kovan, 50-testrpc)
* gasPrice: Gas price to use with every transaction
* exchangeContractAddress: The address of an exchange contract to use
* zrxContractAddress: The address of the ZRX contract to use
* tokenRegistryContractAddress: The address of a token registry contract to use
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
* orderWatcherConfig: All the configs related to the orderWatcher
*/
export interface ContractWrappersConfig {
networkId: number;
gasPrice?: BigNumber;
exchangeContractAddress?: string;
zrxContractAddress?: string;
tokenRegistryContractAddress?: string;
tokenTransferProxyContractAddress?: string;
}
/**
* expectedFillTakerTokenAmount: If specified, the validation method will ensure that the
* supplied order maker has a sufficient allowance/balance to fill this amount of the order's
* takerTokenAmount. If not specified, the validation method ensures that the maker has a sufficient
* allowance/balance to fill the entire remaining order amount.
*/
export interface ValidateOrderFillableOpts {
expectedFillTakerTokenAmount?: BigNumber;
}
/**
* defaultBlock: The block up to which to query the blockchain state. Setting this to a historical block number
* let's the user query the blockchain's state at an arbitrary point in time. In order for this to work, the
* backing Ethereum node must keep the entire historical state of the chain (e.g setting `--pruning=archive`
* flag when running Parity).
*/
export interface MethodOpts {
defaultBlock?: BlockParam;
}
/**
* gasPrice: Gas price in Wei to use for a transaction
* gasLimit: The amount of gas to send with a transaction
*/
export interface TransactionOpts {
gasPrice?: BigNumber;
gasLimit?: number;
}
/**
* shouldValidate: Flag indicating whether the library should make attempts to validate a transaction before
* broadcasting it. For example, order has a valid signature, maker has sufficient funds, etc. Default=true.
*/
export interface OrderTransactionOpts extends TransactionOpts {
shouldValidate?: boolean;
}
export enum TradeSide {
Maker = 'maker',
Taker = 'taker',
}
export enum TransferType {
Trade = 'trade',
Fee = 'fee',
}
export type OnOrderStateChangeCallback = (err: Error | null, orderState?: OrderState) => void;

View File

@@ -12,7 +12,7 @@ import { isValidSignature } from '@0xproject/order-utils';
export const assert = {
...sharedAssert,
isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string) {
isValidSignature(orderHash: string, ecSignature: ECSignature, signerAddress: string): void {
const isValid = isValidSignature(orderHash, ecSignature, signerAddress);
this.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`);
},

View File

@@ -0,0 +1,12 @@
import { BigNumber } from '@0xproject/utils';
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
TESTRPC_NETWORK_ID: 50,
INVALID_JUMP_PATTERN: 'invalid JUMP at',
OUT_OF_GAS_PATTERN: 'out of gas',
INVALID_TAKER_FORMAT: 'instance.taker is not of a type(s) string',
// tslint:disable-next-line:custom-no-magic-numbers
UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
DEFAULT_BLOCK_POLLING_INTERVAL: 1000,
};

View File

@@ -1,6 +1,6 @@
import * as _ from 'lodash';
import { AsyncMethod, SyncMethod, ZeroExError } from '../types';
import { AsyncMethod, ContractWrappersError, SyncMethod } from '../types';
import { constants } from './constants';
@@ -8,10 +8,10 @@ type ErrorTransformer = (err: Error) => Error;
const contractCallErrorTransformer = (error: Error) => {
if (_.includes(error.message, constants.INVALID_JUMP_PATTERN)) {
return new Error(ZeroExError.InvalidJump);
return new Error(ContractWrappersError.InvalidJump);
}
if (_.includes(error.message, constants.OUT_OF_GAS_PATTERN)) {
return new Error(ZeroExError.OutOfGas);
return new Error(ContractWrappersError.OutOfGas);
}
return error;
};
@@ -39,7 +39,7 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
// Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method
// tslint:disable-next-line:only-arrow-functions
descriptor.value = async function(...args: any[]) {
descriptor.value = async function(...args: any[]): Promise<any> {
try {
const result = await originalMethod.apply(this, args);
return result;
@@ -66,7 +66,7 @@ const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
// Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method
// tslint:disable-next-line:only-arrow-functions
descriptor.value = function(...args: any[]) {
descriptor.value = function(...args: any[]): any {
try {
const result = originalMethod.apply(this, args);
return result;

View File

@@ -1,10 +1,10 @@
import { BlockParamLiteral } from '@0xproject/types';
import { BlockParamLiteral, ExchangeContractErrs } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
import { ExchangeContractErrs, TradeSide, TransferType } from '../types';
import { TradeSide, TransferType } from '../types';
import { constants } from '../utils/constants';
enum FailureReason {

View File

@@ -73,14 +73,14 @@ export const filterUtils = {
return false;
}
if (!_.isUndefined(filter.topics)) {
return filterUtils.matchesTopics(log.topics, filter.topics);
return filterUtils.doesMatchTopics(log.topics, filter.topics);
}
return true;
},
matchesTopics(logTopics: string[], filterTopics: Array<string[] | string | null>): boolean {
doesMatchTopics(logTopics: string[], filterTopics: Array<string[] | string | null>): boolean {
const matchesTopic = _.zipWith(logTopics, filterTopics, filterUtils.matchesTopic.bind(filterUtils));
const matchesTopics = _.every(matchesTopic);
return matchesTopics;
const doesMatchTopics = _.every(matchesTopic);
return doesMatchTopics;
},
matchesTopic(logTopic: string, filterTopic: string[] | string | null): boolean {
if (_.isArray(filterTopic)) {

View File

@@ -1,11 +1,10 @@
import { getOrderHashHex, OrderError } from '@0xproject/order-utils';
import { Order, SignedOrder } from '@0xproject/types';
import { getOrderHashHex, isValidSignature, OrderError } from '@0xproject/order-utils';
import { ExchangeContractErrs, Order, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { ZeroEx } from '../0x';
import { ExchangeWrapper } from '../contract_wrappers/exchange_wrapper';
import { ExchangeContractErrs, TradeSide, TransferType, ZeroExError } from '../types';
import { ContractWrappersError, TradeSide, TransferType } from '../types';
import { constants } from '../utils/constants';
import { utils } from '../utils/utils';
@@ -87,12 +86,12 @@ export class OrderValidationUtils {
private static _validateRemainingFillAmountNotZeroOrThrow(
takerTokenAmount: BigNumber,
unavailableTakerTokenAmount: BigNumber,
) {
): void {
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
}
}
private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) {
private static _validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber): void {
const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
throw new Error(ExchangeContractErrs.OrderFillExpired);
@@ -144,7 +143,7 @@ export class OrderValidationUtils {
throw new Error(ExchangeContractErrs.OrderFillAmountZero);
}
const orderHash = getOrderHashHex(signedOrder);
if (!ZeroEx.isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) {
if (!isValidSignature(orderHash, signedOrder.ecSignature, signedOrder.maker)) {
throw new Error(OrderError.InvalidSignature);
}
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);

View File

@@ -5,7 +5,8 @@ export const utils = {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
},
getCurrentUnixTimestampSec(): BigNumber {
return new BigNumber(Date.now() / 1000).round();
const milisecondsInSecond = 1000;
return new BigNumber(Date.now() / milisecondsInSecond).round();
},
getCurrentUnixTimestampMs(): BigNumber {
return new BigNumber(Date.now());

View File

@@ -0,0 +1,50 @@
import { web3Factory } from '@0xproject/dev-utils';
import * as fs from 'fs';
import 'make-promises-safe';
import { ContractWrappers } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
chaiSetup.configure();
// Those tests are slower cause they're talking to a remote node
const TIMEOUT = 10000;
describe('Artifacts', () => {
describe('contracts are deployed on kovan', () => {
const kovanRpcUrl = constants.KOVAN_RPC_URL;
const provider = web3Factory.create({ rpcUrl: kovanRpcUrl }).currentProvider;
const config = {
networkId: constants.KOVAN_NETWORK_ID,
};
const contractWrappers = new ContractWrappers(provider, config);
it('token registry contract is deployed', async () => {
await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync();
}).timeout(TIMEOUT);
it('proxy contract is deployed', async () => {
await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
it('exchange contract is deployed', async () => {
await (contractWrappers.exchange as any)._getExchangeContractAsync();
}).timeout(TIMEOUT);
});
describe('contracts are deployed on ropsten', () => {
const ropstenRpcUrl = constants.ROPSTEN_RPC_URL;
const provider = web3Factory.create({ rpcUrl: ropstenRpcUrl }).currentProvider;
const config = {
networkId: constants.ROPSTEN_NETWORK_ID,
};
const contractWrappers = new ContractWrappers(provider, config);
it('token registry contract is deployed', async () => {
await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync();
}).timeout(TIMEOUT);
it('proxy contract is deployed', async () => {
await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
it('exchange contract is deployed', async () => {
await (contractWrappers.exchange as any)._getExchangeContractAsync();
}).timeout(TIMEOUT);
});
});

View File

@@ -1,27 +1,27 @@
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
import { BlockchainLifecycle, callbackErrorReporter, devConstants, web3Factory } from '@0xproject/dev-utils';
import { DoneCallback } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
import 'make-promises-safe';
import 'mocha';
import {
ApprovalContractEventArgs,
BlockParamLiteral,
BlockRange,
ContractWrappers,
ContractWrappersError,
DecodedLogEvent,
DepositContractEventArgs,
EtherTokenEvents,
Token,
TransferContractEventArgs,
WithdrawalContractEventArgs,
ZeroEx,
ZeroExError,
} from '../src';
import { DoneCallback } from '../src/types';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
import { TokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
@@ -36,13 +36,13 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
describe('EtherTokenWrapper', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
let tokens: Token[];
let userAddresses: string[];
let addressWithETH: string;
let wethContractAddress: string;
let depositWeiAmount: BigNumber;
let decimalPlaces: number;
const decimalPlaces = 7;
let addressWithoutFunds: string;
const gasPrice = new BigNumber(1);
const zeroExConfig = {
@@ -54,13 +54,12 @@ describe('EtherTokenWrapper', () => {
const depositAmount = new BigNumber(42);
const withdrawalAmount = new BigNumber(42);
before(async () => {
zeroEx = new ZeroEx(provider, zeroExConfig);
tokens = await zeroEx.tokenRegistry.getTokensAsync();
userAddresses = await zeroEx.getAvailableAddressesAsync();
contractWrappers = new ContractWrappers(provider, zeroExConfig);
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
addressWithETH = userAddresses[0];
wethContractAddress = zeroEx.etherToken.getContractAddressIfExists() as string;
wethContractAddress = contractWrappers.etherToken.getContractAddressIfExists() as string;
depositWeiAmount = Web3Wrapper.toWei(new BigNumber(5));
decimalPlaces = 7;
addressWithoutFunds = userAddresses[1];
});
beforeEach(async () => {
@@ -71,14 +70,14 @@ describe('EtherTokenWrapper', () => {
});
describe('#getContractAddressIfExists', async () => {
it('should return contract address if connected to a known network', () => {
const contractAddressIfExists = zeroEx.etherToken.getContractAddressIfExists();
const contractAddressIfExists = contractWrappers.etherToken.getContractAddressIfExists();
expect(contractAddressIfExists).to.not.be.undefined();
});
it('should throw if connected to a private network and contract addresses are not specified', () => {
const UNKNOWN_NETWORK_NETWORK_ID = 10;
expect(
() =>
new ZeroEx(provider, {
new ContractWrappers(provider, {
networkId: UNKNOWN_NETWORK_NETWORK_ID,
} as any),
).to.throw();
@@ -86,16 +85,23 @@ describe('EtherTokenWrapper', () => {
});
describe('#depositAsync', () => {
it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
expect(preETHBalance).to.be.bignumber.gt(0);
expect(preWETHBalance).to.be.bignumber.equal(0);
const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
const txHash = await contractWrappers.etherToken.depositAsync(
wethContractAddress,
depositWeiAmount,
addressWithETH,
);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
wethContractAddress,
addressWithETH,
);
expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(depositWeiAmount);
const remainingETHInWei = preETHBalance.minus(depositWeiAmount);
@@ -103,34 +109,41 @@ describe('EtherTokenWrapper', () => {
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
});
it('should throw if user has insufficient ETH balance for deposit', async () => {
const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const extraETHBalance = Web3Wrapper.toWei(new BigNumber(5));
const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
return expect(
zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
contractWrappers.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
).to.be.rejectedWith(ContractWrappersError.InsufficientEthBalanceForDeposit);
});
});
describe('#withdrawAsync', () => {
it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const ETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await contractWrappers.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
let gasCost = expectedPreETHBalance.minus(preETHBalance);
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
const txHash = await contractWrappers.etherToken.withdrawAsync(
wethContractAddress,
depositWeiAmount,
addressWithETH,
);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const postWETHBalanceInBaseUnits = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
wethContractAddress,
addressWithETH,
);
expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(0);
const expectedETHBalance = preETHBalance.add(depositWeiAmount).round(decimalPlaces);
@@ -138,14 +151,15 @@ describe('EtherTokenWrapper', () => {
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
});
it('should throw if user has insufficient WETH balance for withdrawal', async () => {
const preWETHBalance = await zeroEx.token.getBalanceAsync(wethContractAddress, addressWithETH);
const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
expect(preWETHBalance).to.be.bignumber.equal(0);
// tslint:disable-next-line:custom-no-magic-numbers
const overWETHBalance = preWETHBalance.add(999999999);
return expect(
zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
contractWrappers.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
).to.be.rejectedWith(ContractWrappersError.InsufficientWEthBalanceForWithdrawal);
});
});
describe('#subscribe', () => {
@@ -157,7 +171,7 @@ describe('EtherTokenWrapper', () => {
etherTokenAddress = etherToken.address;
});
afterEach(() => {
zeroEx.etherToken.unsubscribeAll();
contractWrappers.etherToken.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
@@ -166,7 +180,7 @@ describe('EtherTokenWrapper', () => {
// Source: https://github.com/mochajs/mocha/issues/2407
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
@@ -179,9 +193,14 @@ describe('EtherTokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(transferAmount);
},
);
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
await zeroEx.token.transferAsync(
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Transfer,
indexFilterValues,
callback,
);
await contractWrappers.token.transferAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -191,7 +210,7 @@ describe('EtherTokenWrapper', () => {
});
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
@@ -201,8 +220,13 @@ describe('EtherTokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(allowanceAmount);
},
);
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
await zeroEx.token.setAllowanceAsync(
contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Approval,
indexFilterValues,
callback,
);
await contractWrappers.token.setAllowanceAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -212,7 +236,7 @@ describe('EtherTokenWrapper', () => {
});
it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
@@ -221,13 +245,18 @@ describe('EtherTokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(depositAmount);
},
);
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Deposit,
indexFilterValues,
callback,
);
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
})().catch(done);
});
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
@@ -236,39 +265,39 @@ describe('EtherTokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(depositAmount);
},
);
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
zeroEx.etherToken.subscribe(
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Withdrawal,
indexFilterValues,
callback,
);
await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
await contractWrappers.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
})().catch(done);
});
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
zeroEx.etherToken.subscribe(
contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
const callbackToBeCalled = reportNodeCallbackErrors(done)();
zeroEx.setProvider(provider, constants.TESTRPC_NETWORK_ID);
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
zeroEx.etherToken.subscribe(
const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)();
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Transfer,
indexFilterValues,
callbackToBeCalled,
);
await zeroEx.token.transferAsync(
await contractWrappers.token.transferAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -278,20 +307,20 @@ describe('EtherTokenWrapper', () => {
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
const subscriptionToken = zeroEx.etherToken.subscribe(
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
const subscriptionToken = contractWrappers.etherToken.subscribe(
etherTokenAddress,
EtherTokenEvents.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
zeroEx.etherToken.unsubscribe(subscriptionToken);
await zeroEx.token.transferAsync(
contractWrappers.etherToken.unsubscribe(subscriptionToken);
await contractWrappers.token.transferAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -314,14 +343,14 @@ describe('EtherTokenWrapper', () => {
const tokenUtils = new TokenUtils(tokens);
const etherToken = tokenUtils.getWethTokenOrThrow();
etherTokenAddress = etherToken.address;
tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress();
});
it('should get logs with decoded args emitted by Approval', async () => {
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = EtherTokenEvents.Approval;
const indexFilterValues = {};
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
etherTokenAddress,
eventName,
blockRange,
@@ -332,13 +361,13 @@ describe('EtherTokenWrapper', () => {
expect(logs[0].event).to.be.equal(eventName);
expect(args._owner).to.be.equal(addressWithETH);
expect(args._spender).to.be.equal(tokenTransferProxyAddress);
expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should get logs with decoded args emitted by Deposit', async () => {
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
const eventName = EtherTokenEvents.Deposit;
const indexFilterValues = {};
const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
const logs = await contractWrappers.etherToken.getLogsAsync<DepositContractEventArgs>(
etherTokenAddress,
eventName,
blockRange,
@@ -351,11 +380,11 @@ describe('EtherTokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(depositAmount);
});
it('should only get the logs with the correct event name', async () => {
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentEventName = EtherTokenEvents.Transfer;
const indexFilterValues = {};
const logs = await zeroEx.etherToken.getLogsAsync(
const logs = await contractWrappers.etherToken.getLogsAsync(
etherTokenAddress,
differentEventName,
blockRange,
@@ -364,15 +393,18 @@ describe('EtherTokenWrapper', () => {
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithoutFunds);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(
etherTokenAddress,
addressWithoutFunds,
);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = EtherTokenEvents.Approval;
const indexFilterValues = {
_owner: addressWithETH,
};
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
etherTokenAddress,
eventName,
blockRange,

View File

@@ -1,9 +1,10 @@
import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BlockParamLiteral, Token } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'make-promises-safe';
import { ExchangeContractErrs, Token, ZeroEx } from '../src';
import { ContractWrappers, ExchangeContractErrs } from '../src';
import { TradeSide, TransferType } from '../src/types';
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
@@ -19,7 +20,7 @@ describe('ExchangeTransferSimulator', () => {
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
};
const zeroEx = new ZeroEx(provider, config);
const contractWrappers = new ContractWrappers(provider, config);
const transferAmount = new BigNumber(5);
let userAddresses: string[];
let tokens: Token[];
@@ -30,9 +31,9 @@ describe('ExchangeTransferSimulator', () => {
let exchangeTransferSimulator: ExchangeTransferSimulator;
let txHash: string;
before(async () => {
userAddresses = await zeroEx.getAvailableAddressesAsync();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
[coinbase, sender, recipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
exampleTokenAddress = tokens[0].address;
});
beforeEach(async () => {
@@ -43,7 +44,7 @@ describe('ExchangeTransferSimulator', () => {
});
describe('#transferFromAsync', () => {
beforeEach(() => {
exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
exchangeTransferSimulator = new ExchangeTransferSimulator(contractWrappers.token, BlockParamLiteral.Latest);
});
it("throws if the user doesn't have enough allowance", async () => {
return expect(
@@ -58,8 +59,8 @@ describe('ExchangeTransferSimulator', () => {
).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
});
it("throws if the user doesn't have enough balance", async () => {
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
return expect(
exchangeTransferSimulator.transferFromAsync(
exampleTokenAddress,
@@ -72,10 +73,10 @@ describe('ExchangeTransferSimulator', () => {
).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
});
it('updates balances and proxyAllowance after transfer', async () => {
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
await exchangeTransferSimulator.transferFromAsync(
exampleTokenAddress,
sender,
@@ -93,10 +94,10 @@ describe('ExchangeTransferSimulator', () => {
expect(senderProxyAllowance).to.be.bignumber.equal(0);
});
it("doesn't update proxyAllowance after transfer if unlimited", async () => {
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
await exchangeTransferSimulator.transferFromAsync(
exampleTokenAddress,
sender,
@@ -111,7 +112,9 @@ describe('ExchangeTransferSimulator', () => {
const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
expect(senderBalance).to.be.bignumber.equal(0);
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
expect(senderProxyAllowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
expect(senderProxyAllowance).to.be.bignumber.equal(
contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
);
});
});
});

View File

@@ -1,12 +1,17 @@
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BlockchainLifecycle, callbackErrorReporter, devConstants, web3Factory } from '@0xproject/dev-utils';
import { FillScenarios } from '@0xproject/fill-scenarios';
import { getOrderHashHex } from '@0xproject/order-utils';
import { BlockParamLiteral, DoneCallback, OrderState } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'make-promises-safe';
import 'mocha';
import {
BlockRange,
ContractWrappers,
DecodedLogEvent,
ExchangeContractErrs,
ExchangeEvents,
@@ -14,17 +19,12 @@ import {
LogFillContractEventArgs,
OrderCancellationRequest,
OrderFillRequest,
OrderState,
SignedOrder,
Token,
ZeroEx,
} from '../src';
import { DoneCallback } from '../src/types';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { FillScenarios } from './utils/fill_scenarios';
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
import { TokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
@@ -35,7 +35,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
describe('ExchangeWrapper', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
let tokenUtils: TokenUtils;
let tokens: Token[];
let userAddresses: string[];
@@ -46,13 +46,13 @@ describe('ExchangeWrapper', () => {
networkId: constants.TESTRPC_NETWORK_ID,
};
before(async () => {
zeroEx = new ZeroEx(provider, config);
exchangeContractAddress = zeroEx.exchange.getContractAddress();
userAddresses = await zeroEx.getAvailableAddressesAsync();
tokens = await zeroEx.tokenRegistry.getTokensAsync();
contractWrappers = new ContractWrappers(provider, config);
exchangeContractAddress = contractWrappers.exchange.getContractAddress();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
tokenUtils = new TokenUtils(tokens);
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
await fillScenarios.initTokenBalancesAsync();
});
beforeEach(async () => {
@@ -71,7 +71,7 @@ describe('ExchangeWrapper', () => {
const takerTokenFillAmount = new BigNumber(5);
before(async () => {
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
@@ -104,7 +104,7 @@ describe('ExchangeWrapper', () => {
takerTokenFillAmount: partialFillTakerAmount,
},
];
await zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
await contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
});
describe('order transaction options', () => {
let signedOrder: SignedOrder;
@@ -127,19 +127,19 @@ describe('ExchangeWrapper', () => {
});
it('should validate when orderTransactionOptions are not present', async () => {
return expect(
zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
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(
zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
shouldValidate: false,
}),
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
@@ -160,66 +160,70 @@ describe('ExchangeWrapper', () => {
});
describe('successful fills', () => {
it('should fill a valid order', async () => {
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
fillableAmount,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
0,
);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
0,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
fillableAmount,
);
await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
fillableAmount.minus(takerTokenFillAmount),
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
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 zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
takerTokenFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
fillableAmount.minus(takerTokenFillAmount),
);
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 zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
fillableAmount.minus(partialFillAmount),
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
partialFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
partialFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
fillableAmount.minus(partialFillAmount),
);
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(
zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
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(
zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
shouldValidate: false,
}),
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
@@ -239,7 +243,7 @@ describe('ExchangeWrapper', () => {
const shouldThrowOnInsufficientBalanceOrAllowance = true;
before(async () => {
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
@@ -254,37 +258,37 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
fillableAmount,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
0,
);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
0,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
fillableAmount,
);
const txHash = await zeroEx.exchange.fillOrderAsync(
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 zeroEx.awaitTransactionMinedAsync(txHash);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
fillableAmount.minus(takerTokenFillAmount),
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
takerTokenFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
takerTokenFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
fillableAmount.minus(takerTokenFillAmount),
);
await web3Wrapper.awaitTransactionMinedAsync(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(
@@ -295,25 +299,25 @@ describe('ExchangeWrapper', () => {
fillableAmount,
);
const partialFillAmount = new BigNumber(3);
const txHash = await zeroEx.exchange.fillOrderAsync(
const txHash = await contractWrappers.exchange.fillOrderAsync(
signedOrder,
partialFillAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
fillableAmount.minus(partialFillAmount),
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
partialFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
partialFillAmount,
);
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
fillableAmount.minus(partialFillAmount),
);
await web3Wrapper.awaitTransactionMinedAsync(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);
@@ -328,16 +332,16 @@ describe('ExchangeWrapper', () => {
fillableAmount,
feeRecipient,
);
const txHash = await zeroEx.exchange.fillOrderAsync(
const txHash = await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
makerFee.plus(takerFee),
);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
expect(
await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient),
).to.be.bignumber.equal(makerFee.plus(takerFee));
});
});
describe('order transaction options', () => {
@@ -354,7 +358,7 @@ describe('ExchangeWrapper', () => {
});
it('should validate when orderTransactionOptions are not present', async () => {
return expect(
zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.fillOrderAsync(
signedOrder,
emptyFillTakerAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -364,7 +368,7 @@ describe('ExchangeWrapper', () => {
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.fillOrderAsync(
signedOrder,
emptyFillTakerAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -377,7 +381,7 @@ describe('ExchangeWrapper', () => {
});
it('should not validate when orderTransactionOptions specify not to validate', async () => {
return expect(
zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.fillOrderAsync(
signedOrder,
emptyFillTakerAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -403,7 +407,7 @@ describe('ExchangeWrapper', () => {
});
it('should not allow the exchange wrapper to fill if amount is negative', async () => {
return expect(
zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.fillOrderAsync(
signedOrder,
negativeFillTakerAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -427,7 +431,7 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
signedOrderHashHex = getOrderHashHex(signedOrder);
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress,
takerTokenAddress,
@@ -435,7 +439,7 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
});
describe('successful batch fills', () => {
beforeEach(() => {
@@ -452,7 +456,7 @@ describe('ExchangeWrapper', () => {
});
it('should throw if a batch is empty', async () => {
return expect(
zeroEx.exchange.batchFillOrdersAsync(
contractWrappers.exchange.batchFillOrdersAsync(
[],
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
@@ -460,14 +464,16 @@ describe('ExchangeWrapper', () => {
).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
});
it('should successfully fill multiple orders', async () => {
const txHash = await zeroEx.exchange.batchFillOrdersAsync(
const txHash = await contractWrappers.exchange.batchFillOrdersAsync(
orderFillBatch,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
await web3Wrapper.awaitTransactionMinedAsync(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);
});
@@ -488,7 +494,7 @@ describe('ExchangeWrapper', () => {
});
it('should validate when orderTransactionOptions are not present', async () => {
return expect(
zeroEx.exchange.batchFillOrdersAsync(
contractWrappers.exchange.batchFillOrdersAsync(
orderFillBatch,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
@@ -497,7 +503,7 @@ describe('ExchangeWrapper', () => {
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.batchFillOrdersAsync(
contractWrappers.exchange.batchFillOrdersAsync(
orderFillBatch,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
@@ -509,7 +515,7 @@ describe('ExchangeWrapper', () => {
});
it('should not validate when orderTransactionOptions specify not to validate', async () => {
return expect(
zeroEx.exchange.batchFillOrdersAsync(
contractWrappers.exchange.batchFillOrdersAsync(
orderFillBatch,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
@@ -536,7 +542,7 @@ describe('ExchangeWrapper', () => {
});
it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
return expect(
zeroEx.exchange.batchFillOrdersAsync(
contractWrappers.exchange.batchFillOrdersAsync(
orderFillBatch,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
@@ -560,7 +566,7 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
signedOrderHashHex = getOrderHashHex(signedOrder);
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress,
takerTokenAddress,
@@ -568,13 +574,13 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
signedOrders = [signedOrder, anotherSignedOrder];
});
describe('successful batch fills', () => {
it('should throw if a batch is empty', async () => {
return expect(
zeroEx.exchange.fillOrdersUpToAsync(
contractWrappers.exchange.fillOrdersUpToAsync(
[],
fillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -583,45 +589,54 @@ describe('ExchangeWrapper', () => {
).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
});
it('should successfully fill up to specified amount when all orders are fully funded', async () => {
const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
fillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
await web3Wrapper.awaitTransactionMinedAsync(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 zeroEx.exchange.fillOrdersUpToAsync(
const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
fillableAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const zeroAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
await web3Wrapper.awaitTransactionMinedAsync(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 zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
await contractWrappers.token.transferAsync(
makerTokenAddress,
makerAddress,
coinbase,
missingBalance,
);
const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
fillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
await web3Wrapper.awaitTransactionMinedAsync(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);
@@ -630,9 +645,14 @@ describe('ExchangeWrapper', () => {
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 zeroEx.token.transferAsync(makerTokenAddress, makerAddress, coinbase, missingBalance);
await contractWrappers.token.transferAsync(
makerTokenAddress,
makerAddress,
coinbase,
missingBalance,
);
return expect(
zeroEx.exchange.fillOrdersUpToAsync(
contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
fillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -645,7 +665,7 @@ describe('ExchangeWrapper', () => {
const emptyFillUpToAmount = new BigNumber(0);
it('should validate when orderTransactionOptions are not present', async () => {
return expect(
zeroEx.exchange.fillOrdersUpToAsync(
contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
emptyFillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -655,7 +675,7 @@ describe('ExchangeWrapper', () => {
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.fillOrdersUpToAsync(
contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
emptyFillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -668,7 +688,7 @@ describe('ExchangeWrapper', () => {
});
it('should not validate when orderTransactionOptions specify not to validate', async () => {
return expect(
zeroEx.exchange.fillOrdersUpToAsync(
contractWrappers.exchange.fillOrdersUpToAsync(
signedOrders,
emptyFillUpToAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -704,14 +724,14 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
orderHashHex = getOrderHashHex(signedOrder);
});
describe('#cancelOrderAsync', () => {
describe('successful cancels', () => {
it('should cancel an order', async () => {
const txHash = await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
await zeroEx.awaitTransactionMinedAsync(txHash);
const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex);
expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
});
});
@@ -719,19 +739,19 @@ describe('ExchangeWrapper', () => {
const emptyCancelTakerTokenAmount = new BigNumber(0);
it('should validate when orderTransactionOptions are not present', async () => {
return expect(
zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
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(
zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
shouldValidate: false,
}),
).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
@@ -750,7 +770,7 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
cancelBatch = [
{
order: signedOrder,
@@ -772,7 +792,7 @@ describe('ExchangeWrapper', () => {
fillableAmount,
);
return expect(
zeroEx.exchange.batchCancelOrdersAsync([
contractWrappers.exchange.batchCancelOrdersAsync([
cancelBatch[0],
{
order: signedOrderWithDifferentMaker,
@@ -784,9 +804,9 @@ describe('ExchangeWrapper', () => {
});
describe('successful batch cancels', () => {
it('should cancel a batch of orders', async () => {
await zeroEx.exchange.batchCancelOrdersAsync(cancelBatch);
const cancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHashHex);
const anotherCancelledAmount = await zeroEx.exchange.getCancelledTakerAmountAsync(
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);
@@ -808,20 +828,20 @@ describe('ExchangeWrapper', () => {
];
});
it('should validate when orderTransactionOptions are not present', async () => {
return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
return expect(contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
ExchangeContractErrs.OrderCancelAmountZero,
);
});
it('should validate when orderTransactionOptions specify to validate', async () => {
return expect(
zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, {
shouldValidate: true,
}),
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
});
it('should not validate when orderTransactionOptions specify not to validate', async () => {
return expect(
zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, {
shouldValidate: false,
}),
).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
@@ -854,53 +874,63 @@ describe('ExchangeWrapper', () => {
fillableAmount,
partialFillAmount,
);
orderHash = ZeroEx.getOrderHashHex(signedOrder);
orderHash = getOrderHashHex(signedOrder);
});
describe('#getUnavailableTakerAmountAsync', () => {
it('should throw if passed an invalid orderHash', async () => {
const invalidOrderHashHex = '0x123';
return expect(zeroEx.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
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 zeroEx.exchange.getUnavailableTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
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 zeroEx.exchange.getUnavailableTakerAmountAsync(orderHash);
const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(orderHash);
expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
});
});
describe('#getFilledTakerAmountAsync', () => {
it('should throw if passed an invalid orderHash', async () => {
const invalidOrderHashHex = '0x123';
return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
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 zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
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 zeroEx.exchange.getFilledTakerAmountAsync(orderHash);
const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(orderHash);
expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
});
});
describe('#getCancelledTakerAmountAsync', () => {
it('should throw if passed an invalid orderHash', async () => {
const invalidOrderHashHex = '0x123';
return expect(zeroEx.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
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 zeroEx.exchange.getCancelledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
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 zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
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 zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
const cancelledValueT = await zeroEx.exchange.getCancelledTakerAmountAsync(orderHash);
await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash);
expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
});
});
@@ -934,7 +964,7 @@ describe('ExchangeWrapper', () => {
);
});
afterEach(async () => {
zeroEx.exchange.unsubscribeAll();
contractWrappers.exchange.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
@@ -943,13 +973,13 @@ describe('ExchangeWrapper', () => {
// Source: https://github.com/mochajs/mocha/issues/2407
it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
},
);
zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
await zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -959,33 +989,33 @@ describe('ExchangeWrapper', () => {
});
it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
},
);
zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
contractWrappers.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
})().catch(done);
});
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
zeroEx.setProvider(provider, constants.TESTRPC_NETWORK_ID);
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
},
);
zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
await zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -995,18 +1025,18 @@ describe('ExchangeWrapper', () => {
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
const subscriptionToken = zeroEx.exchange.subscribe(
const subscriptionToken = contractWrappers.exchange.subscribe(
ExchangeEvents.LogFill,
indexFilterValues,
callbackNeverToBeCalled,
);
zeroEx.exchange.unsubscribe(subscriptionToken);
await zeroEx.exchange.fillOrderAsync(
contractWrappers.exchange.unsubscribe(subscriptionToken);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
shouldThrowOnInsufficientBalanceOrAllowance,
@@ -1036,8 +1066,8 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
const orderHash = getOrderHashHex(signedOrder);
const orderHashFromContract = await (contractWrappers.exchange as any)._getOrderHashHexUsingContractCallAsync(
signedOrder,
);
expect(orderHash).to.equal(orderHashFromContract);
@@ -1045,7 +1075,7 @@ describe('ExchangeWrapper', () => {
});
describe('#getZRXTokenAddressAsync', () => {
it('gets the same token as is in token registry', () => {
const zrxAddress = zeroEx.exchange.getZRXTokenAddress();
const zrxAddress = contractWrappers.exchange.getZRXTokenAddress();
const zrxToken = tokenUtils.getProtocolTokenOrThrow();
expect(zrxAddress).to.equal(zrxToken.address);
});
@@ -1076,16 +1106,16 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
txHash = await zeroEx.exchange.fillOrderAsync(
txHash = await contractWrappers.exchange.fillOrderAsync(
signedOrder,
fillableAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = ExchangeEvents.LogFill;
const indexFilterValues = {};
const logs = await zeroEx.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
expect(logs).to.have.length(1);
expect(logs[0].event).to.be.equal(eventName);
});
@@ -1097,16 +1127,20 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
txHash = await zeroEx.exchange.fillOrderAsync(
txHash = await contractWrappers.exchange.fillOrderAsync(
signedOrder,
fillableAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentEventName = ExchangeEvents.LogCancel;
const indexFilterValues = {};
const logs = await zeroEx.exchange.getLogsAsync(differentEventName, blockRange, indexFilterValues);
const logs = await contractWrappers.exchange.getLogsAsync(
differentEventName,
blockRange,
indexFilterValues,
);
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
@@ -1117,13 +1151,13 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
txHash = await zeroEx.exchange.fillOrderAsync(
txHash = await contractWrappers.exchange.fillOrderAsync(
signedOrder,
fillableAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentMakerAddress = userAddresses[2];
const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
@@ -1133,19 +1167,19 @@ describe('ExchangeWrapper', () => {
takerAddress,
fillableAmount,
);
txHash = await zeroEx.exchange.fillOrderAsync(
txHash = await contractWrappers.exchange.fillOrderAsync(
anotherSignedOrder,
fillableAmount,
shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
await zeroEx.awaitTransactionMinedAsync(txHash);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = ExchangeEvents.LogFill;
const indexFilterValues = {
maker: differentMakerAddress,
};
const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
const logs = await contractWrappers.exchange.getLogsAsync<LogFillContractEventArgs>(
eventName,
blockRange,
indexFilterValues,
@@ -1162,10 +1196,10 @@ describe('ExchangeWrapper', () => {
let takerToken: Token;
let signedOrder: SignedOrder;
let orderState: OrderState;
const fillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(5), constants.ZRX_DECIMALS);
const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), constants.ZRX_DECIMALS);
before(async () => {
[, maker, taker] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
[makerToken, takerToken] = tokenUtils.getDummyTokens();
});
it('should report orderStateValid when order is fillable', async () => {
@@ -1176,7 +1210,7 @@ describe('ExchangeWrapper', () => {
taker,
fillableAmount,
);
orderState = await zeroEx.exchange.getOrderStateAsync(signedOrder);
orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder);
expect(orderState.isValid).to.be.true();
});
it('should report orderStateInvalid when maker allowance set to 0', async () => {
@@ -1187,8 +1221,8 @@ describe('ExchangeWrapper', () => {
taker,
fillableAmount,
);
await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
orderState = await zeroEx.exchange.getOrderStateAsync(signedOrder);
await contractWrappers.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder);
expect(orderState.isValid).to.be.false();
});
});

View File

@@ -0,0 +1,19 @@
import { devConstants } from '@0xproject/dev-utils';
import { runMigrationsAsync } from '@0xproject/migrations';
import * as path from 'path';
import { constants } from './utils/constants';
import { provider } from './utils/web3_wrapper';
before('migrate contracts', async function(): Promise<void> {
// HACK: Since the migrations take longer then our global mocha timeout limit
// we manually increase it for this before hook.
const mochaTestTimeoutMs = 20000;
this.timeout(mochaTestTimeoutMs);
const txDefaults = {
gas: devConstants.GAS_ESTIMATE,
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
const artifactsDir = `../migrations/artifacts/1.0.0`;
await runMigrationsAsync(provider, artifactsDir, txDefaults);
});

View File

@@ -1,18 +1,19 @@
import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
import { FillScenarios } from '@0xproject/fill-scenarios';
import { OrderError } from '@0xproject/order-utils';
import { BlockParamLiteral } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'make-promises-safe';
import * as Sinon from 'sinon';
import { ExchangeContractErrs, SignedOrder, Token, ZeroEx, ZeroExError } from '../src';
import { ContractWrappers, ContractWrappersError, ExchangeContractErrs, SignedOrder, Token } from '../src';
import { TradeSide, TransferType } from '../src/types';
import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
import { OrderValidationUtils } from '../src/utils/order_validation_utils';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { FillScenarios } from './utils/fill_scenarios';
import { TokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
@@ -21,7 +22,7 @@ const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('OrderValidation', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
let userAddresses: string[];
let tokens: Token[];
let tokenUtils: TokenUtils;
@@ -40,14 +41,14 @@ describe('OrderValidation', () => {
networkId: constants.TESTRPC_NETWORK_ID,
};
before(async () => {
zeroEx = new ZeroEx(provider, config);
exchangeContractAddress = zeroEx.exchange.getContractAddress();
userAddresses = await zeroEx.getAvailableAddressesAsync();
contractWrappers = new ContractWrappers(provider, config);
exchangeContractAddress = contractWrappers.exchange.getContractAddress();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
[coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
tokens = await zeroEx.tokenRegistry.getTokensAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
tokenUtils = new TokenUtils(tokens);
zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
const [makerToken, takerToken] = tokenUtils.getDummyTokens();
makerTokenAddress = makerToken.address;
takerTokenAddress = takerToken.address;
@@ -67,7 +68,7 @@ describe('OrderValidation', () => {
takerAddress,
fillableAmount,
);
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
});
it('should succeed if the maker is buying ZRX and has no ZRX balance', async () => {
const makerFee = new BigNumber(2);
@@ -82,9 +83,9 @@ describe('OrderValidation', () => {
fillableAmount,
feeRecipient,
);
const zrxMakerBalance = await zeroEx.token.getBalanceAsync(zrxTokenAddress, makerAddress);
await zeroEx.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress);
await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
});
it('should succeed if the maker is buying ZRX and has no ZRX balance and there is no specified taker', async () => {
const makerFee = new BigNumber(2);
@@ -99,12 +100,13 @@ describe('OrderValidation', () => {
fillableAmount,
feeRecipient,
);
const zrxMakerBalance = await zeroEx.token.getBalanceAsync(zrxTokenAddress, makerAddress);
await zeroEx.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress);
await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
});
it('should succeed if the order is asymmetric and fillable', async () => {
const makerFillableAmount = fillableAmount;
// tslint:disable-next-line:custom-no-magic-numbers
const takerFillableAmount = fillableAmount.minus(4);
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
makerTokenAddress,
@@ -114,7 +116,7 @@ describe('OrderValidation', () => {
makerFillableAmount,
takerFillableAmount,
);
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
});
it('should throw when the order is fully filled or cancelled', async () => {
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
@@ -124,8 +126,8 @@ describe('OrderValidation', () => {
takerAddress,
fillableAmount,
);
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
ExchangeContractErrs.OrderRemainingFillAmountZero,
);
});
@@ -139,7 +141,7 @@ describe('OrderValidation', () => {
fillableAmount,
expirationInPast,
);
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
ExchangeContractErrs.OrderFillExpired,
);
});
@@ -155,7 +157,11 @@ describe('OrderValidation', () => {
);
const zeroFillAmount = new BigNumber(0);
return expect(
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
signedOrder,
zeroFillAmount,
takerAddress,
),
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
});
it('should throw when the signature is invalid', async () => {
@@ -167,9 +173,14 @@ describe('OrderValidation', () => {
fillableAmount,
);
// 27 <--> 28
// tslint:disable-next-line:custom-no-magic-numbers
signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
return expect(
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
signedOrder,
fillableAmount,
takerAddress,
),
).to.be.rejectedWith(OrderError.InvalidSignature);
});
it('should throw when the order is fully filled or cancelled', async () => {
@@ -180,9 +191,13 @@ describe('OrderValidation', () => {
takerAddress,
fillableAmount,
);
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
return expect(
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
signedOrder,
fillableAmount,
takerAddress,
),
).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
});
it('should throw when sender is not a taker', async () => {
@@ -193,9 +208,14 @@ describe('OrderValidation', () => {
takerAddress,
fillableAmount,
);
// tslint:disable-next-line:custom-no-magic-numbers
const nonTakerAddress = userAddresses[6];
return expect(
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
signedOrder,
fillTakerAmount,
nonTakerAddress,
),
).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
});
it('should throw when order is expired', async () => {
@@ -209,7 +229,11 @@ describe('OrderValidation', () => {
expirationInPast,
);
return expect(
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
signedOrder,
fillTakerAmount,
takerAddress,
),
).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
});
it('should throw when there a rounding error would have occurred', async () => {
@@ -225,7 +249,7 @@ describe('OrderValidation', () => {
);
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
return expect(
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
signedOrder,
fillTakerAmountThatCausesRoundingError,
takerAddress,
@@ -244,13 +268,13 @@ describe('OrderValidation', () => {
);
const tooLargeFillAmount = new BigNumber(7);
const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
await zeroEx.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
await contractWrappers.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
await contractWrappers.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
await contractWrappers.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
await contractWrappers.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
return expect(
zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
contractWrappers.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
signedOrder,
tooLargeFillAmount,
takerAddress,
@@ -277,7 +301,7 @@ describe('OrderValidation', () => {
it('should throw when cancel amount is zero', async () => {
const zeroCancelAmount = new BigNumber(0);
return expect(
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
});
it('should throw when order is expired', async () => {
@@ -291,13 +315,13 @@ describe('OrderValidation', () => {
expirationInPast,
);
return expect(
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
});
it('should throw when order is already cancelled or filled', async () => {
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
return expect(
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
});
});
@@ -308,7 +332,7 @@ describe('OrderValidation', () => {
return Sinon.match((value: BigNumber) => value.eq(expected));
};
beforeEach('create exchangeTransferSimulator', async () => {
exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
exchangeTransferSimulator = new ExchangeTransferSimulator(contractWrappers.token, BlockParamLiteral.Latest);
transferFromAsync = Sinon.spy();
exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
});
@@ -332,6 +356,7 @@ describe('OrderValidation', () => {
takerAddress,
zrxTokenAddress,
);
// tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
expect(
transferFromAsync
@@ -391,7 +416,7 @@ describe('OrderValidation', () => {
makerFee,
takerFee,
makerAddress,
ZeroEx.NULL_ADDRESS,
constants.NULL_ADDRESS,
fillableAmount,
feeRecipient,
);
@@ -402,6 +427,7 @@ describe('OrderValidation', () => {
takerAddress,
zrxTokenAddress,
);
// tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
expect(
transferFromAsync
@@ -470,6 +496,7 @@ describe('OrderValidation', () => {
takerAddress,
zrxTokenAddress,
);
// tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
const makerFillAmount = transferFromAsync.getCall(0).args[3];
expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
@@ -485,7 +512,7 @@ describe('OrderValidation', () => {
makerAddress,
takerAddress,
fillableAmount,
ZeroEx.NULL_ADDRESS,
constants.NULL_ADDRESS,
);
const fillTakerTokenAmount = fillableAmount.div(2).round(0);
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
@@ -497,6 +524,7 @@ describe('OrderValidation', () => {
);
const makerPartialFee = makerFee.div(2);
const takerPartialFee = takerFee.div(2);
// tslint:disable-next-line:custom-no-magic-numbers
expect(transferFromAsync.callCount).to.be.equal(4);
const partialMakerFee = transferFromAsync.getCall(2).args[3];
expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);

View File

@@ -1,22 +1,22 @@
import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
import { BlockchainLifecycle, callbackErrorReporter, devConstants } from '@0xproject/dev-utils';
import { DoneCallback } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import 'make-promises-safe';
import 'mocha';
import * as Sinon from 'sinon';
import { ApprovalContractEventArgs, DecodedLogEvent, Token, TokenEvents, ZeroEx } from '../src';
import { DoneCallback } from '../src/types';
import { ApprovalContractEventArgs, ContractWrappers, DecodedLogEvent, Token, TokenEvents } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { assertNodeCallbackError } from './utils/report_callback_errors';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('SubscriptionTest', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
let userAddresses: string[];
let tokens: Token[];
let coinbase: string;
@@ -25,9 +25,9 @@ describe('SubscriptionTest', () => {
networkId: constants.TESTRPC_NETWORK_ID,
};
before(async () => {
zeroEx = new ZeroEx(provider, config);
userAddresses = await zeroEx.getAvailableAddressesAsync();
tokens = await zeroEx.tokenRegistry.getTokensAsync();
contractWrappers = new ContractWrappers(provider, config);
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
coinbase = userAddresses[0];
addressWithoutFunds = userAddresses[1];
});
@@ -47,34 +47,48 @@ describe('SubscriptionTest', () => {
tokenAddress = token.address;
});
afterEach(() => {
zeroEx.token.unsubscribeAll();
contractWrappers.token.unsubscribeAll();
_.each(stubs, s => s.restore());
stubs = [];
});
it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
(async () => {
const errMsg = 'Error fetching block';
const callback = assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await contractWrappers.token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
allowanceAmount,
);
})().catch(done);
});
it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
(async () => {
const errMsg = 'Error fetching logs';
const callback = assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await contractWrappers.token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
allowanceAmount,
);
})().catch(done);
});
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
(async () => {
const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
zeroEx.token.unsubscribeAll();
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
stubs = [
Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(
new Error('JSON RPC error'),
),
];
contractWrappers.token.unsubscribeAll();
done();
})().catch(done);
});

View File

@@ -2,9 +2,10 @@ import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
import * as chai from 'chai';
import * as _ from 'lodash';
import 'make-promises-safe';
import 'mocha';
import { Token, ZeroEx } from '../src';
import { ContractWrappers, Token } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
@@ -17,7 +18,7 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
describe('TokenRegistryWrapper', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
let tokens: Token[];
const tokenAddressBySymbol: { [symbol: string]: string } = {};
const tokenAddressByName: { [symbol: string]: string } = {};
@@ -31,8 +32,8 @@ describe('TokenRegistryWrapper', () => {
networkId: constants.TESTRPC_NETWORK_ID,
};
before(async () => {
zeroEx = new ZeroEx(provider, config);
tokens = await zeroEx.tokenRegistry.getTokensAsync();
contractWrappers = new ContractWrappers(provider, config);
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
_.map(tokens, token => {
tokenAddressBySymbol[token.symbol] = token.address;
tokenAddressByName[token.name] = token.address;
@@ -59,54 +60,62 @@ describe('TokenRegistryWrapper', () => {
});
describe('#getTokenAddressesAsync', () => {
it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
const tokenAddresses = await zeroEx.tokenRegistry.getTokenAddressesAsync();
const tokenAddresses = await contractWrappers.tokenRegistry.getTokenAddressesAsync();
expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
const schemaValidator = new SchemaValidator();
_.each(tokenAddresses, tokenAddress => {
const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
expect(validationResult.errors).to.have.lengthOf(0);
expect(tokenAddress).to.not.be.equal(ZeroEx.NULL_ADDRESS);
expect(tokenAddress).to.not.be.equal(constants.NULL_ADDRESS);
});
});
});
describe('#getTokenAddressBySymbol', () => {
it('should return correct address for a token in the registry', async () => {
const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(registeredSymbol);
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(
registeredSymbol,
);
expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
});
it('should return undefined for a token out of registry', async () => {
const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(unregisteredSymbol);
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(
unregisteredSymbol,
);
expect(tokenAddress).to.be.undefined();
});
});
describe('#getTokenAddressByName', () => {
it('should return correct address for a token in the registry', async () => {
const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(registeredName);
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync(
registeredName,
);
expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
});
it('should return undefined for a token out of registry', async () => {
const tokenAddress = await zeroEx.tokenRegistry.getTokenAddressByNameIfExistsAsync(unregisteredName);
const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync(
unregisteredName,
);
expect(tokenAddress).to.be.undefined();
});
});
describe('#getTokenBySymbol', () => {
it('should return correct token for a token in the registry', async () => {
const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
});
it('should return undefined for a token out of registry', async () => {
const token = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
expect(token).to.be.undefined();
});
});
describe('#getTokenByName', () => {
it('should return correct token for a token in the registry', async () => {
const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
expect(token).to.be.deep.equal(tokenByName[registeredName]);
});
it('should return undefined for a token out of registry', async () => {
const token = await zeroEx.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
expect(token).to.be.undefined();
});
});
@@ -114,14 +123,14 @@ describe('TokenRegistryWrapper', () => {
it('should return the token added to the tokenRegistry during the migration', async () => {
const aToken = tokens[0];
const token = await zeroEx.tokenRegistry.getTokenIfExistsAsync(aToken.address);
const token = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(aToken.address);
const schemaValidator = new SchemaValidator();
const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
expect(validationResult.errors).to.have.lengthOf(0);
});
it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
const tokenIfExists = await zeroEx.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
const tokenIfExists = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
expect(tokenIfExists).to.be.undefined();
});
});

View File

@@ -1,6 +1,7 @@
import * as chai from 'chai';
import 'make-promises-safe';
import { ZeroEx } from '../src';
import { ContractWrappers } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
@@ -10,24 +11,24 @@ chaiSetup.configure();
const expect = chai.expect;
describe('TokenTransferProxyWrapper', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
};
before(async () => {
zeroEx = new ZeroEx(provider, config);
contractWrappers = new ContractWrappers(provider, config);
});
describe('#isAuthorizedAsync', () => {
it('should return false if the address is not authorized', async () => {
const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(ZeroEx.NULL_ADDRESS);
const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
expect(isAuthorized).to.be.false();
});
});
describe('#getAuthorizedAddressesAsync', () => {
it('should return the list of authorized addresses', async () => {
const authorizedAddresses = await zeroEx.proxy.getAuthorizedAddressesAsync();
const authorizedAddresses = await contractWrappers.proxy.getAuthorizedAddressesAsync();
for (const authorizedAddress of authorizedAddresses) {
const isAuthorized = await zeroEx.proxy.isAuthorizedAsync(authorizedAddress);
const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(authorizedAddress);
expect(isAuthorized).to.be.true();
}
});

View File

@@ -1,8 +1,9 @@
import { BlockchainLifecycle, devConstants } from '@0xproject/dev-utils';
import { BlockchainLifecycle, callbackErrorReporter, devConstants } from '@0xproject/dev-utils';
import { EmptyWalletSubprovider } from '@0xproject/subproviders';
import { Provider } from '@0xproject/types';
import { DoneCallback, Provider } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'make-promises-safe';
import 'mocha';
import Web3ProviderEngine = require('web3-provider-engine');
@@ -10,18 +11,16 @@ import {
ApprovalContractEventArgs,
BlockParamLiteral,
BlockRange,
ContractWrappers,
ContractWrappersError,
DecodedLogEvent,
Token,
TokenEvents,
TransferContractEventArgs,
ZeroEx,
ZeroExError,
} from '../src';
import { DoneCallback } from '../src/types';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { reportNodeCallbackErrors } from './utils/report_callback_errors';
import { TokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
@@ -30,7 +29,7 @@ const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('TokenWrapper', () => {
let zeroEx: ZeroEx;
let contractWrappers: ContractWrappers;
let userAddresses: string[];
let tokens: Token[];
let tokenUtils: TokenUtils;
@@ -40,9 +39,9 @@ describe('TokenWrapper', () => {
networkId: constants.TESTRPC_NETWORK_ID,
};
before(async () => {
zeroEx = new ZeroEx(provider, config);
userAddresses = await zeroEx.getAvailableAddressesAsync();
tokens = await zeroEx.tokenRegistry.getTokensAsync();
contractWrappers = new ContractWrappers(provider, config);
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
tokens = await contractWrappers.tokenRegistry.getTokensAsync();
tokenUtils = new TokenUtils(tokens);
coinbase = userAddresses[0];
addressWithoutFunds = userAddresses[1];
@@ -63,26 +62,26 @@ describe('TokenWrapper', () => {
it('should successfully transfer tokens', async () => {
const fromAddress = coinbase;
const toAddress = addressWithoutFunds;
const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
expect(preBalance).to.be.bignumber.equal(0);
await zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
await contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
return expect(postBalance).to.be.bignumber.equal(transferAmount);
});
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
const fromAddress = addressWithoutFunds;
const toAddress = coinbase;
return expect(
zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
).to.be.rejectedWith(ContractWrappersError.InsufficientBalanceForTransfer);
});
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
const fromAddress = coinbase;
const toAddress = coinbase;
return expect(
zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
contractWrappers.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
});
});
describe('#transferFromAsync', () => {
@@ -98,35 +97,51 @@ describe('TokenWrapper', () => {
const fromAddress = coinbase;
const transferAmount = new BigNumber(42);
const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress);
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync(
token.address,
fromAddress,
toAddress,
);
expect(fromAddressAllowance).to.be.bignumber.equal(0);
return expect(
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
contractWrappers.token.transferFromAsync(
token.address,
fromAddress,
toAddress,
senderAddress,
transferAmount,
),
).to.be.rejectedWith(ContractWrappersError.InsufficientAllowanceForTransfer);
});
it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
const fromAddress = coinbase;
const transferAmount = new BigNumber(42);
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
return expect(
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
contractWrappers.token.transferFromAsync(
token.address,
fromAddress,
toAddress,
senderAddress,
transferAmount,
),
).to.be.rejectedWith(ContractWrappersError.InsufficientAllowanceForTransfer);
});
it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
const fromAddress = addressWithoutFunds;
const transferAmount = new BigNumber(42);
const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress);
expect(fromAddressBalance).to.be.bignumber.equal(0);
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync(
token.address,
fromAddress,
senderAddress,
@@ -134,34 +149,46 @@ describe('TokenWrapper', () => {
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
return expect(
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
contractWrappers.token.transferFromAsync(
token.address,
fromAddress,
toAddress,
senderAddress,
transferAmount,
),
).to.be.rejectedWith(ContractWrappersError.InsufficientBalanceForTransfer);
});
it('should successfully transfer tokens', async () => {
const fromAddress = coinbase;
const preBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
expect(preBalance).to.be.bignumber.equal(0);
const transferAmount = new BigNumber(42);
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
await contractWrappers.token.transferFromAsync(
token.address,
fromAddress,
toAddress,
senderAddress,
transferAmount,
);
const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
return expect(postBalance).to.be.bignumber.equal(transferAmount);
});
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
const fromAddress = coinbase;
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
return expect(
zeroEx.token.transferFromAsync(
contractWrappers.token.transferFromAsync(
nonExistentTokenAddress,
fromAddress,
toAddress,
senderAddress,
new BigNumber(42),
),
).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
});
});
describe('#getBalanceAsync', () => {
@@ -169,36 +196,36 @@ describe('TokenWrapper', () => {
it('should return the balance for an existing ERC20 token', async () => {
const token = tokens[0];
const ownerAddress = coinbase;
const balance = await zeroEx.token.getBalanceAsync(token.address, ownerAddress);
const balance = await contractWrappers.token.getBalanceAsync(token.address, ownerAddress);
const expectedBalance = new BigNumber('1000000000000000000000000000');
return expect(balance).to.be.bignumber.equal(expectedBalance);
});
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
const ownerAddress = coinbase;
return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
ZeroExError.TokenContractDoesNotExist,
);
return expect(
contractWrappers.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress),
).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
});
it('should return a balance of 0 for a non-existent owner address', async () => {
const token = tokens[0];
const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
const balance = await zeroEx.token.getBalanceAsync(token.address, nonExistentOwner);
const balance = await contractWrappers.token.getBalanceAsync(token.address, nonExistentOwner);
const expectedBalance = new BigNumber(0);
return expect(balance).to.be.bignumber.equal(expectedBalance);
});
});
describe('With provider without accounts', () => {
let zeroExWithoutAccounts: ZeroEx;
let zeroExContractWithoutAccounts: ContractWrappers;
before(async () => {
const hasAddresses = false;
const emptyWalletProvider = addEmptyWalletSubprovider(provider);
zeroExWithoutAccounts = new ZeroEx(emptyWalletProvider, config);
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
});
it('should return balance even when called with provider instance without addresses', async () => {
const token = tokens[0];
const ownerAddress = coinbase;
const balance = await zeroExWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
const balance = await zeroExContractWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
const expectedBalance = new BigNumber('1000000000000000000000000000');
return expect(balance).to.be.bignumber.equal(expectedBalance);
});
@@ -210,7 +237,7 @@ describe('TokenWrapper', () => {
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
const allowanceBeforeSet = await contractWrappers.token.getAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
@@ -219,9 +246,18 @@ describe('TokenWrapper', () => {
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
const amountInBaseUnits = new BigNumber(50);
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
await contractWrappers.token.setAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
amountInBaseUnits,
);
const allowanceAfterSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
const allowanceAfterSet = await contractWrappers.token.getAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
);
const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
});
@@ -232,30 +268,39 @@ describe('TokenWrapper', () => {
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
await zeroEx.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
await contractWrappers.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
const allowance = await contractWrappers.token.getAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
);
return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
const transferAmount = new BigNumber(5);
const zrx = tokenUtils.getProtocolTokenOrThrow();
const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
await zeroEx.token.setAllowanceAsync(zrx.address, coinbase, userWithNormalAllowance, transferAmount);
await zeroEx.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
await contractWrappers.token.setAllowanceAsync(
zrx.address,
coinbase,
userWithNormalAllowance,
transferAmount,
);
await contractWrappers.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
userWithUnlimitedAllowance,
);
await zeroEx.token.transferFromAsync(
await contractWrappers.token.transferFromAsync(
zrx.address,
coinbase,
userWithNormalAllowance,
userWithNormalAllowance,
transferAmount,
);
await zeroEx.token.transferFromAsync(
await contractWrappers.token.transferFromAsync(
zrx.address,
coinbase,
userWithUnlimitedAllowance,
@@ -285,9 +330,18 @@ describe('TokenWrapper', () => {
const spenderAddress = addressWithoutFunds;
const amountInBaseUnits = new BigNumber(50);
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
await contractWrappers.token.setAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
amountInBaseUnits,
);
const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
const allowance = await contractWrappers.token.getAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
);
const expectedAllowance = amountInBaseUnits;
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
});
@@ -295,17 +349,21 @@ describe('TokenWrapper', () => {
const token = tokens[0];
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
const allowance = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress, spenderAddress);
const allowance = await contractWrappers.token.getAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
);
const expectedAllowance = new BigNumber(0);
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
});
});
describe('With provider without accounts', () => {
let zeroExWithoutAccounts: ZeroEx;
let zeroExContractWithoutAccounts: ContractWrappers;
before(async () => {
const hasAddresses = false;
const emptyWalletProvider = addEmptyWalletSubprovider(provider);
zeroExWithoutAccounts = new ZeroEx(emptyWalletProvider, config);
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
});
it('should get the proxy allowance', async () => {
const token = tokens[0];
@@ -313,9 +371,14 @@ describe('TokenWrapper', () => {
const spenderAddress = addressWithoutFunds;
const amountInBaseUnits = new BigNumber(50);
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
await contractWrappers.token.setAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
amountInBaseUnits,
);
const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
const allowance = await zeroExContractWithoutAccounts.token.getAllowanceAsync(
token.address,
ownerAddress,
spenderAddress,
@@ -331,9 +394,9 @@ describe('TokenWrapper', () => {
const ownerAddress = coinbase;
const amountInBaseUnits = new BigNumber(50);
await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
const expectedAllowance = amountInBaseUnits;
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
});
@@ -343,14 +406,14 @@ describe('TokenWrapper', () => {
const token = tokens[0];
const ownerAddress = coinbase;
const allowanceBeforeSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
const allowanceBeforeSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
const amountInBaseUnits = new BigNumber(50);
await zeroEx.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
const allowanceAfterSet = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
const allowanceAfterSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
});
@@ -360,9 +423,9 @@ describe('TokenWrapper', () => {
const token = tokens[0];
const ownerAddress = coinbase;
await zeroEx.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
const allowance = await zeroEx.token.getProxyAllowanceAsync(token.address, ownerAddress);
return expect(allowance).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
await contractWrappers.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
});
describe('#subscribe', () => {
@@ -375,7 +438,7 @@ describe('TokenWrapper', () => {
tokenAddress = token.address;
});
afterEach(() => {
zeroEx.token.unsubscribeAll();
contractWrappers.token.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
@@ -384,7 +447,7 @@ describe('TokenWrapper', () => {
// Source: https://github.com/mochajs/mocha/issues/2407
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
expect(logEvent.isRemoved).to.be.false();
expect(logEvent.log.logIndex).to.be.equal(0);
@@ -396,13 +459,13 @@ describe('TokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(transferAmount);
},
);
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
})().catch(done);
});
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
(async () => {
const callback = reportNodeCallbackErrors(done)(
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
@@ -412,39 +475,54 @@ describe('TokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(allowanceAmount);
},
);
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
await contractWrappers.token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
allowanceAmount,
);
})().catch(done);
});
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
const callbackToBeCalled = reportNodeCallbackErrors(done)();
zeroEx.setProvider(provider, constants.TESTRPC_NETWORK_ID);
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
})().catch(done);
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
const subscriptionToken = zeroEx.token.subscribe(
contractWrappers.token.subscribe(
tokenAddress,
TokenEvents.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
zeroEx.token.unsubscribe(subscriptionToken);
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)();
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
contractWrappers.token.subscribe(
tokenAddress,
TokenEvents.Transfer,
indexFilterValues,
callbackToBeCalled,
);
await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
})().catch(done);
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
(logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
const subscriptionToken = contractWrappers.token.subscribe(
tokenAddress,
TokenEvents.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
contractWrappers.token.unsubscribe(subscriptionToken);
await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
done();
})().catch(done);
});
@@ -460,14 +538,14 @@ describe('TokenWrapper', () => {
before(() => {
const token = tokens[0];
tokenAddress = token.address;
tokenTransferProxyAddress = zeroEx.proxy.getContractAddress();
tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress();
});
it('should get logs with decoded args emitted by Approval', async () => {
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = TokenEvents.Approval;
const indexFilterValues = {};
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
tokenAddress,
eventName,
blockRange,
@@ -478,14 +556,14 @@ describe('TokenWrapper', () => {
expect(logs[0].event).to.be.equal(eventName);
expect(args._owner).to.be.equal(coinbase);
expect(args._spender).to.be.equal(tokenTransferProxyAddress);
expect(args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should only get the logs with the correct event name', async () => {
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const differentEventName = TokenEvents.Transfer;
const indexFilterValues = {};
const logs = await zeroEx.token.getLogsAsync(
const logs = await contractWrappers.token.getLogsAsync(
tokenAddress,
differentEventName,
blockRange,
@@ -494,15 +572,15 @@ describe('TokenWrapper', () => {
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
await zeroEx.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
await web3Wrapper.awaitTransactionMinedAsync(txHash);
const eventName = TokenEvents.Approval;
const indexFilterValues = {
_owner: coinbase,
};
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
tokenAddress,
eventName,
blockRange,

View File

@@ -0,0 +1,13 @@
import * as chai from 'chai';
import chaiAsPromised = require('chai-as-promised');
import ChaiBigNumber = require('chai-bignumber');
import * as dirtyChai from 'dirty-chai';
export const chaiSetup = {
configure(): void {
chai.config.includeStack = true;
chai.use(ChaiBigNumber());
chai.use(dirtyChai);
chai.use(chaiAsPromised);
},
};

Some files were not shown because too many files have changed in this diff Show More