Compare commits

..

80 Commits

Author SHA1 Message Date
Fabio Berger
dfeea78615 Publish
- 0x.js@0.38.6
 - @0xproject/abi-gen@0.3.4
 - @0xproject/assert@0.2.14
 - @0xproject/base-contract@0.3.6
 - @0xproject/connect@0.6.17
 - @0xproject/contract-wrappers@0.1.1
 - contracts@2.1.35
 - @0xproject/dev-utils@0.4.6
 - @0xproject/fill-scenarios@0.0.6
 - @0xproject/json-schemas@0.8.3
 - @0xproject/metacoin@0.0.10
 - @0xproject/migrations@0.0.10
 - @0xproject/order-utils@0.0.9
 - @0xproject/order-watcher@0.0.8
 - @0xproject/react-docs-example@0.0.15
 - @0xproject/react-docs@0.0.16
 - @0xproject/react-shared@0.2.3
 - @0xproject/sol-compiler@0.5.4
 - @0xproject/sol-cov@0.1.3
 - @0xproject/sra-report@0.1.6
 - @0xproject/subproviders@0.10.6
 - @0xproject/testnet-faucets@1.0.36
 - @0xproject/typescript-typings@0.4.3
 - @0xproject/utils@0.7.3
 - @0xproject/web3-wrapper@0.7.3
 - @0xproject/website@0.0.39
2018-07-18 15:10:58 +02:00
Fabio Berger
c8b93adcd0 Updated CHANGELOGS 2018-07-18 15:10:52 +02:00
Fabio Berger
2b02ddc588 Merge pull request #885 from 0xProject/bug-fixes
Development Bug Fixes
2018-07-18 14:21:21 +02:00
Fabio Berger
80c7c23151 Add missing dep 2018-07-18 12:55:49 +02:00
Fabio Berger
c068b574e5 Add PR nr. 2018-07-17 18:49:00 +02:00
Fabio Berger
9a20d4e1c9 Update comments 2018-07-17 18:48:53 +02:00
Fabio Berger
cca471a1ce Add back ethers-contracts types for Aquaduct 2018-07-17 17:05:37 +02:00
Fabio Berger
66d63e8f4f Add isVerbose flag to contract-wrappers subscribe methods 2018-07-17 16:55:55 +02:00
Fabio Berger
e678fed55b Fix bug where we accidentally force Blockstream to always call bound methods with latest param 2018-07-17 16:47:10 +02:00
Fabio Berger
9b10349b7c Remove stateLayer option from OrderWatcher 2018-07-17 16:46:06 +02:00
Fabio Berger
48838e1e98 Add .vscode to gitignore 2018-07-10 14:44:49 +02:00
Fabio Berger
eafd666ecd Move sol-compiler to deps to fix type error 2018-07-10 14:44:07 +02:00
Fabio Berger
599554b785 Publish
- 0x.js@0.38.5
 - @0xproject/abi-gen@0.3.3
 - @0xproject/assert@0.2.13
 - @0xproject/base-contract@0.3.5
 - @0xproject/connect@0.6.16
 - @0xproject/contract-wrappers@0.1.0
 - contracts@2.1.34
 - @0xproject/dev-utils@0.4.5
 - @0xproject/fill-scenarios@0.0.5
 - @0xproject/json-schemas@0.8.2
 - @0xproject/metacoin@0.0.9
 - @0xproject/migrations@0.0.9
 - @0xproject/monorepo-scripts@0.2.2
 - @0xproject/order-utils@0.0.8
 - @0xproject/order-watcher@0.0.7
 - @0xproject/react-docs-example@0.0.14
 - @0xproject/react-docs@0.0.15
 - @0xproject/react-shared@0.2.2
 - @0xproject/sol-compiler@0.5.3
 - @0xproject/sol-cov@0.1.2
 - @0xproject/sol-resolver@0.0.8
 - @0xproject/sra-report@0.1.5
 - @0xproject/subproviders@0.10.5
 - @0xproject/testnet-faucets@1.0.35
 - @0xproject/tslint-config@0.4.21
 - @0xproject/types@0.8.2
 - @0xproject/typescript-typings@0.4.2
 - @0xproject/utils@0.7.2
 - @0xproject/web3-wrapper@0.7.2
 - @0xproject/website@0.0.38
2018-07-09 17:24:22 +02:00
Fabio Berger
d57d282cab Updated CHANGELOGS 2018-07-09 17:24:12 +02:00
Fabio Berger
562bef98e2 reset dep cache 2018-07-09 16:57:40 +02:00
Fabio Berger
900f819be8 Use node v9 everywhere 2018-07-09 16:54:34 +02:00
Fabio Berger
e7337c2451 Update yarn.lock 2018-07-09 16:30:46 +02:00
Fabio Berger
dc81193132 Update package so works with node v9 2018-07-09 16:22:46 +02:00
Fabio Berger
fa868b4963 Bump up node version to v9 2018-07-09 16:09:31 +02:00
Fabio Berger
62945ad363 Updated contract-wrappers to use blockstream v5 and stop unsubscribing on blocksteam error 2018-07-09 15:35:08 +02:00
Fabio Berger
61c38d35be Update yarn.lock 2018-07-09 14:14:03 +02:00
Fabio Berger
4e0ec72896 Merge branch 'development' of github.com:0xProject/0x-monorepo into development
* 'development' of github.com:0xProject/0x-monorepo:
  Add missing import
  Extend from DecodedLogArgs and fix type names
  Update ethers typings & changelog
  Back-port order-watcher changes from v2-prototype
  Back-port over utils changes from v2-prototype
2018-07-09 14:10:29 +02:00
Fabio Berger
c28289e9a8 Back-port prePublish fixes 2018-07-09 14:05:29 +02:00
Fabio Berger
e7e9ddf232 remove excess new line 2018-07-09 14:03:17 +02:00
Fabio Berger
f03784ba37 update web3-provider-engine in subproviders 2018-07-09 14:01:47 +02:00
Fabio Berger
2445e23c0b Merge pull request #842 from 0xProject/back-port-v2-prototype
Back-port changes from v2-prototype in order to publish working Order-watcher
2018-07-09 13:53:15 +02:00
Fabio Berger
cd29483187 merge development 2018-07-09 13:52:21 +02:00
Fabio Berger
9bacbdab48 Add missing import 2018-07-09 13:47:33 +02:00
Fabio Berger
551d484fb7 Extend from DecodedLogArgs and fix type names 2018-07-09 13:03:53 +02:00
Fabio Berger
ff66432b83 Update ethers typings & changelog 2018-07-09 12:33:44 +02:00
Fabio Berger
a7ae82a2d1 Back-port order-watcher changes from v2-prototype 2018-07-09 12:31:06 +02:00
Fabio Berger
5f34b5a80e Back-port over utils changes from v2-prototype 2018-07-09 11:48:30 +02:00
Leonid Logvinov
8fca2a8116 Merge pull request #768 from galkin/development
Improve 'web3-provider-engine' typings
2018-06-27 09:24:33 +03:00
Nikita Galkin
5472500119 Improve 'web3-provider-engine' typings 2018-06-25 12:22:54 +03:00
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
1383 changed files with 41751 additions and 108602 deletions

View File

@@ -2,7 +2,6 @@ version: 2
jobs:
build:
resource_class: medium+
docker:
- image: circleci/node:9
environment:
@@ -12,34 +11,23 @@ jobs:
- checkout
- run: echo 'export PATH=$HOME/CIRCLE_PROJECT_REPONAME/node_modules/.bin:$PATH' >> $BASH_ENV
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
- yarn-packages-{{ .Branch }}
- yarn-packages-master
- yarn-packages-
- run:
name: install-yarn
command: sudo npm install --global yarn@1.9.4
key: dependency-cache-v1-{{ checksum "package.json" }}
- run:
name: yarn
command: yarn --frozen-lockfile install || yarn --frozen-lockfile install
command: yarn --frozen-lockfile
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ .Branch }}-{{ checksum "yarn.lock" }}
key: dependency-cache-v1-{{ checksum "package.json" }}
paths:
- node_modules/
- run: >
if [ -z "$(git diff --name-only development packages/website)" ]; then
yarn build --exclude website
else
yarn build
fi
- ./node_modules
- 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 build
- save_cache:
key: repo-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo
test-contracts-ganache:
test-installation:
docker:
- image: circleci/node:9
working_directory: ~/repo
@@ -47,31 +35,42 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn test:installation
test-0xjs:
docker:
- image: circleci/node:9
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci 0x.js
- save_cache:
key: coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/0x.js/coverage/lcov.info
test-contracts:
docker:
- image: circleci/node:9
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci contracts
test-contracts-geth:
docker:
- image: circleci/node:9
- image: albrow/0x-devnet
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
# HACK(albrow): we need to sleep 10 seconds to ensure the devnet is
# initialized
- run: sleep 10 && TEST_PROVIDER=geth yarn wsrun test contracts
test-publish:
resource_class: medium+
docker:
- image: circleci/node:9
- image: verdaccio/verdaccio
working_directory: ~/repo
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn test:publish:circleci
test-doc-generation:
- save_cache:
key: coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contracts/coverage/lcov.info
test-sol-compiler:
docker:
- image: circleci/node:9
working_directory: ~/repo
@@ -79,7 +78,15 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn test:generate_docs:circleci
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- run: yarn wsrun test:circleci @0xproject/sol-compiler
- save_cache:
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/sol-compiler/coverage/lcov.info
test-rest:
docker:
- image: circleci/node:9
@@ -88,42 +95,19 @@ jobs:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn wsrun test:circleci @0xproject/abi-gen
- run: yarn wsrun test:circleci @0xproject/assert
- run: yarn wsrun test:circleci @0xproject/base-contract
- run: yarn wsrun test:circleci @0xproject/connect
- run: yarn wsrun test:circleci @0xproject/contract-wrappers
- run: yarn wsrun test:circleci @0xproject/dev-utils
- run: yarn wsrun test:circleci @0xproject/json-schemas
- run: yarn wsrun test:circleci @0xproject/metacoin
- run: yarn wsrun test:circleci @0xproject/order-utils
- run: yarn wsrun test:circleci @0xproject/order-watcher
- run: yarn wsrun test:circleci @0xproject/sol-compiler
- run: yarn wsrun test:circleci @0xproject/sol-cov
- run: yarn wsrun test:circleci @0xproject/sra-report
- run: yarn wsrun test:circleci @0xproject/subproviders
- run: yarn wsrun test:circleci @0xproject/web3-wrapper
- run: yarn wsrun test:circleci @0xproject/utils
- save_cache:
key: coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/abi-gen/coverage/lcov.info
- run:
name: testrpc
command: npm run testrpc -- --db testrpc_snapshot
background: true
- 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:
- ~/repo/packages/assert/coverage/lcov.info
- save_cache:
key: coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/base-contract/coverage/lcov.info
- save_cache:
key: coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/connect/coverage/lcov.info
- save_cache:
key: coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/contract-wrappers/coverage/lcov.info
- save_cache:
key: coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
paths:
@@ -133,38 +117,27 @@ jobs:
paths:
- ~/repo/packages/json-schemas/coverage/lcov.info
- save_cache:
key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
key: coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/metacoin/coverage/lcov.info
- save_cache:
key: coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/order-utils/coverage/lcov.info
- save_cache:
key: coverage-order-watcher-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/order-watcher/coverage/lcov.info
- save_cache:
key: coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/sol-compiler/coverage/lcov.info
- ~/repo/packages/subproviders/coverage/lcov.info
- save_cache:
key: coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/sol-cov/coverage/lcov.info
- save_cache:
key: coverage-sra-report-{{ .Environment.CIRCLE_SHA1 }}
key: coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/sra-report/coverage/lcov.info
- save_cache:
key: coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/subproviders/coverage/lcov.info
- save_cache:
key: coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/repo/packages/web3-wrapper/coverage/lcov.info
static-tests:
- ~/repo/packages/metacoin/coverage/lcov.info
lint:
working_directory: ~/repo
docker:
- image: circleci/node:9
steps:
- restore_cache:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn lerna:run lint
prettier:
working_directory: ~/repo
docker:
- image: circleci/node:9
@@ -173,7 +146,6 @@ jobs:
keys:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn prettier:ci
- run: yarn lerna run lint
submit-coverage:
docker:
- image: circleci/node:9
@@ -184,19 +156,13 @@ jobs:
- repo-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-abi-gen-{{ .Environment.CIRCLE_SHA1 }}
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-assert-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-base-contract-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-connect-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contract-wrappers-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-dev-utils-{{ .Environment.CIRCLE_SHA1 }}
@@ -205,55 +171,49 @@ jobs:
- coverage-json-schemas-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-order-utils-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-order-watcher-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
- coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-sra-report-{{ .Environment.CIRCLE_SHA1 }}
- coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-subproviders-{{ .Environment.CIRCLE_SHA1 }}
- coverage-0xjs-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-web3-wrapper-{{ .Environment.CIRCLE_SHA1 }}
- restore_cache:
keys:
- coverage-contracts-{{ .Environment.CIRCLE_SHA1 }}
- coverage-metacoin-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn report_coverage
workflows:
version: 2
main:
jobs:
- build
- test-contracts-ganache:
- test-installation:
requires:
- build
- test-contracts-geth:
- test-0xjs:
requires:
- build
- test-contracts:
requires:
- build
- test-sol-compiler:
requires:
- build
- test-rest:
requires:
- build
- static-tests:
- prettier:
requires:
- build
- test-publish:
requires:
- build
- test-doc-generation:
- lint:
requires:
- build
- submit-coverage:
requires:
- test-0xjs
- test-sol-compiler
- test-rest
- test-contracts

22
.gitignore vendored
View File

@@ -41,7 +41,6 @@ typings/
# Optional npm cache directory
.npm
.npmrc
# Optional eslint cache
.eslintcache
@@ -82,29 +81,20 @@ packages/sol-cov/test/fixtures/artifacts/
packages/metacoin/artifacts/
packages/order-watcher/test/artifacts/
packages/contract-wrappers/test/artifacts/
packages/contract-wrappers/src/artifacts/
packages/order-watcher/src/artifacts/
packages/0x.js/src/artifacts/
packages/order-utils/src/artifacts/
# unstable generated contract artifacts:
packages/migrations/artifacts/development/
# generated contract watcher
packages/0x.js/src/generated_contract_wrappers/
packages/contracts/generated_contract_wrappers/
# 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/order-utils/src/generated_contract_wrappers/
packages/migrations/src/1.0.0/contract_wrappers
packages/migrations/src/2.0.0-testnet/contract_wrappers
packages/migrations/src/2.0.0/contract_wrappers
packages/migrations/src/development/contract_wrappers
packages/migrations/src/contract_wrappers
# solc-bin in sol-compiler
packages/sol-compiler/solc_bin/
# Monorepo scripts
packages/*/scripts/
ganache.log

View File

@@ -1,27 +1,10 @@
lib
.nyc_output
/packages/contract-wrappers/src/contract_wrappers/generated/
/packages/metacoin/src/contract_wrappers
/packages/0x.js/src/generated_contract_wrappers/
/packages/contracts/generated_contract_wrappers/
/packages/fill-scenarios/src/generated_contract_wrappers/
/packages/order-watcher/src/generated_contract_wrappers/
/packages/order-utils/src/generated_contract_wrappers/
/packages/migrations/src/1.0.0/contract_wrappers
/packages/migrations/src/2.0.0-testnet/contract_wrappers
/packages/migrations/src/2.0.0/contract_wrappers
/packages/0x.js/src/artifacts
/packages/0x.js/test/artifacts
/packages/contracts/src/artifacts
/packages/contract-wrappers/src/artifacts
/packages/order-watcher/src/artifacts
/packages/metacoin/artifacts
/packages/sra-spec/public/
/packages/contract-wrappers/test/artifacts
/packages/order-watcher/test/artifacts
/packages/migrations/artifacts/1.0.0
/packages/migrations/artifacts/2.0.0-testnet
/packages/migrations/artifacts/2.0.0
/packages/migrations/artifacts/development
package.json
scripts/postpublish_utils.js
packages/sol-cov/test/fixtures/artifacts

View File

@@ -1,8 +0,0 @@
# See https://help.github.com/articles/about-codeowners/
# for more info about CODEOWNERS file
# It uses the same pattern rule for gitignore file
# https://git-scm.com/docs/gitignore#_pattern_format
# Website
packages/website/ @BMillman19 @fragosti

View File

@@ -21,18 +21,6 @@ If you're adding a new public function/member, make sure you document it with Ja
If the sub-package you are modifying has a `CHANGELOG.md` file, make sure to add an entry in it for the change made to the package. For published packages, only changes that modify the public interface or behavior of the package need a CHANGELOG entry.
#### Enabling code coverage checks on your fork
If you simply fork the repo and then create a PR sourced from it, your PR will fail its test coverage check. This is because the 0x CircleCI configuration sets the `COVERALLS_REPO_TOKEN` environment variable to the token for 0xProject/0x-monorepo, but when running the check against your fork the token needs to match the repo that is your fork, rather than the 0x repo.
To facilitate this check, after creating your fork, but before creating the branch for your PR, do the following:
1. Log in to [coveralls.io](https://coveralls.io/), go to Add Repos, and enable your fork. Then go to the settings for that repo, and copy the Repo Token identifier.
2. Log in to [CircleCI](https://circleci.com/login), go to Add Projects, click the Set Up Project button corresponding to your fork, and then click Start Building. (Aside from step 3 below, no actual set up is needed, since it will use the `.circleci/config.yml` file in 0x-monorepo, so you can ignore all of the instruction/explanation given on the page with the Start Building button.)
3. In CircleCI, configure your project to add an Environment Variable, with name `COVERALLS_REPO_TOKEN`, and for the value paste in the Repo Token you copied in step 1.
Now, when you push to your branch, CircleCI will automatically run all of the checks in your own instance, and the coverage check will work since it has the proper Repo Token, and the PR will magically refer to your own checks rather than running them in the 0x CircleCI instance.
### Styleguide
We use [TSLint](https://palantir.github.io/tslint/) with [custom configs](https://github.com/0xProject/0x-monorepo/tree/development/packages/tslint-config) to keep our code style consistent.

View File

@@ -1,27 +1,41 @@
<!--- Thank you for taking the time to submit a Pull Request -->
<!--- Provide a general summary of the issue in the Title above -->
## Description
<!--- Describe your changes in detail -->
## Testing instructions
## Motivation and Context
<!--- Please describe how reviewers can test your changes -->
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
## Types of changes
<!--- What types of changes does your code introduce? Uncomment all the bullets that apply: -->
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
<!-- * Bug fix (non-breaking change which fixes an issue) -->
<!-- * New feature (non-breaking change which adds functionality) -->
<!-- * Breaking change (fix or feature that would cause existing functionality to change) -->
* [ ] Bug fix (non-breaking change which fixes an issue)
* [ ] New feature (non-breaking change which adds functionality)
* [ ] Breaking change (fix or feature that would cause existing functionality to change)
## Checklist:
<!--- The following points should be used to indicate the progress of your PR. Put an `x` in all the boxes that apply right now, and come back over time and check them off as you make progress. If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
* [ ] Prefix PR title with `[WIP]` if necessary.
* [ ] Prefix PR title with bracketed package name(s) corresponding to the changed package(s). For example: `[sol-cov] Fixed bug`.
* [ ] Add tests to cover changes as needed.
* [ ] Update documentation as needed.
* [ ] Add new entries to the relevant CHANGELOG.jsons.
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
* [ ] Change requires a change to the documentation.
* [ ] Added tests to cover my changes.
* [ ] Added new entries to the relevant CHANGELOG.jsons.
* [ ] Labeled this PR with the 'WIP' label if it is a work in progress.
* [ ] Labeled this PR with the labels corresponding to the changed package.

View File

@@ -6,11 +6,8 @@
This repository is a monorepo including the 0x protocol smart contracts and numerous developer tools. Each public sub-package is independently published to NPM.
If you're developing on 0x now or are interested in using 0x infrastructure in the future, please join our [developer mailing list][dev-mailing-list-url] for updates.
[website-url]: https://0xproject.com
[website-url]: https://0xproject.com/
[whitepaper-url]: https://0xproject.com/pdfs/0x_white_paper.pdf
[dev-mailing-list-url]: http://eepurl.com/dx4cPf
[![CircleCI](https://circleci.com/gh/0xProject/0x-monorepo.svg?style=svg&circle-token=61bf7cd8c9b4e11b132089dfcffdd1be277d1e0c)](https://circleci.com/gh/0xProject/0x-monorepo)
[![Coverage Status](https://coveralls.io/repos/github/0xProject/0x-monorepo/badge.svg?branch=development)](https://coveralls.io/github/0xProject/0x-monorepo?branch=development)
@@ -33,7 +30,6 @@ If you're developing on 0x now or are interested in using 0x infrastructure in t
| [`@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-spec`](/packages/sra-spec) | [![npm](https://img.shields.io/npm/v/@0xproject/sra-spec.svg)](https://www.npmjs.com/package/@0xproject/sra-spec) | OpenAPI specification for the standard relayer API |
| [`@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) |
@@ -69,7 +65,7 @@ Dedicated documentation pages:
Node version >= 6.12 is required.
Most of the packages require additional typings for external dependencies.
You can include those by prepending the `@0xproject/typescript-typings` package to your [`typeRoots`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) config.
You can include those by prepending @0xproject/typescript-typings package to your [`typeRoots`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) config.
```json
"typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"],
@@ -83,7 +79,11 @@ We strongly recommend that the community help us make improvements and determine
### Install dependencies
Make sure you are using Yarn v1.9.4. To install using brew:
If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them:
```bash
yarn config set workspaces-experimental true
```
Then install dependencies

View File

@@ -1,10 +1,15 @@
{
"lerna": "3.0.0-beta.23",
"lerna": "2.5.1",
"packages": ["packages/*"],
"version": "independent",
"command": {
"commands": {
"publish": {
"ignoreChanges": ["test/**/*", "*.md", "scripts", "lib", "tslint.json", "tsconfig.json"]
"allowBranch": "development"
}
},
"version": "independent",
"commands": {
"publish": {
"ignore": ["test/**/*", "*.md", "scripts", "lib", "tslint.json", "tsconfig.json"]
}
},
"npmClient": "yarn",

View File

@@ -2,7 +2,7 @@
"private": true,
"name": "0x-monorepo",
"engines": {
"node": ">=6.12"
"node" : ">=6.12"
},
"workspaces": [
"packages/*"
@@ -13,49 +13,34 @@
"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",
"test:installation:local": "IS_LOCAL_PUBLISH=true node ./packages/monorepo-scripts/lib/test_installation.js",
"test:publish:circleci:comment": "HACK(albrow) We need an automated way to login to npm and echo+sleep piped to stdin was the only way I could find to do it.",
"test:publish:circleci": "yarn npm-cli-login -u test -p test -e test@example.com -r http://localhost:4873 && IS_LOCAL_PUBLISH=true run-s script:publish test:installation:local",
"run:publish": "run-s install:all build:monorepo_scripts script:prepublish_checks rebuild:no_website script:publish",
"run:publish:local": "IS_LOCAL_PUBLISH=true yarn run:publish",
"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",
"install:all": "yarn install",
"wsrun": "wsrun",
"lerna": "lerna",
"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:no_website": "wsrun build $PKG --fast-exit -r --stages --exclude @0xproject/website",
"build:monorepo_scripts": "PKG=@0xproject/monorepo-scripts yarn build",
"build:ts": "tsc -b",
"watch:ts": "tsc -b -w",
"clean": "wsrun clean $PKG --fast-exit -r --parallel",
"remove_node_modules": "lerna clean --yes; rm -rf node_modules",
"rebuild": "run-s clean build",
"rebuild:no_website": "run-s clean build:no_website",
"test": "wsrun test $PKG --fast-exit --serial --exclude-missing",
"generate_doc": "node ./packages/monorepo-scripts/lib/doc_generate_and_upload.js",
"test:generate_docs:circleci": "for i in ${npm_package_config_packagesWithDocPages}; do yarn generate_doc --package $i --shouldUpload false --isStaging true || break -1; done;",
"lint": "wsrun lint $PKG --fast-exit --parallel --exclude-missing",
"comment:postinstall": "HACK: For some reason `yarn` is not setting up symlinks properly for order-utils. We temporarily set them manually. Remove this after V2 refactor is complete."
"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",
"packagesWithDocPages": "0x.js connect json-schemas subproviders web3-wrapper contract-wrappers order-utils order-watcher sol-compiler sol-cov ethereum-types"
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
},
"devDependencies": {
"@0x-lerna-fork/lerna": "3.0.0-beta.25",
"async-child-process": "^1.1.1",
"async-child-process": "1.1.1",
"coveralls": "^3.0.0",
"ganache-cli": "6.1.3",
"ganache-cli": "^6.1.0",
"lcov-result-merger": "^3.0.0",
"npm-cli-login": "^0.0.10",
"npm-run-all": "^4.1.2",
"prettier": "^1.11.1",
"source-map-support": "^0.5.6",
"typescript": "3.0.1",
"lerna": "^2.5.1",
"npm-run-all": "4.1.2",
"prettier": "1.12.1",
"wsrun": "^2.2.0"
},
"resolutions": {
"ethers": "0xproject/ethers.js#eip-838-reasons"
}
}

View File

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

View File

@@ -1,150 +1,4 @@
[
{
"version": "1.0.3",
"changes": [
{
"note": "Drastically reduce the bundle size by removing unused parts of included contract artifacts."
}
],
"timestamp": 1537369748
},
{
"version": "1.0.2",
"changes": [
{
"note": "Add ZRX & WETH mainnet contract addresses into the included artifacts"
}
],
"timestamp": 1537265493
},
{
"timestamp": 1536142250,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.0.1-rc.6",
"changes": [
{
"note": "Fix missing `BlockParamLiteral` type import issue"
}
],
"timestamp": 1535377027
},
{
"version": "1.0.1-rc.5",
"changes": [
{
"note":
"Fix `main` and `types` package.json entries so that they point to the new location of index.d.ts and index.js"
}
]
},
{
"version": "1.0.1-rc.4",
"changes": [
{
"note":
"Re-organize the exported interface of 0x.js. Remove the `ZeroEx` class, and instead export the same exports as `0x.js`'s sub-packages: `@0xproject/contract-wrappers`, `@0xproject/order-utils` and `@0xproject/order-watcher`",
"pr": 963
}
],
"timestamp": 1535133899
},
{
"version": "1.0.1-rc.3",
"changes": [
{
"note": "Dependencies updated"
},
{
"pr": 914,
"note": "Update ecSignOrderHashAsync to return the signature as a string for immediate use in contracts"
}
],
"timestamp": 1534210131
},
{
"version": "1.0.1-rc.2",
"changes": [
{
"note": "Fixed bug caused by importing non-existent dep"
}
],
"timestamp": 1532619515
},
{
"version": "1.0.1-rc.1",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1532605697
},
{
"timestamp": 1532357734,
"version": "1.0.0",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532043100,
"version": "1.0.0-rc.2",
"changes": [
{
"note": "Remove `zeroEx.assetData` and instead re-export it's static functions directly off `ZeroEx`"
}
]
},
{
"timestamp": 1532043000,
"version": "1.0.0-rc.1",
"changes": [
{
"note": "Remove tokenRegistry wrapper",
"pr": 863
},
{
"note": "Rename `zeroEx.token` to `zeroEx.erc20Token`, and add `zeroEx.erc721Token`",
"pr": 863
},
{
"note": "Rename `zeroEx.proxy` to `zeroEx.erc20Proxy` and add `zeroEx.erc721Proxy`",
"pr": 863
},
{
"note":
"Refactored `ZeroEx.isValidSignature` to `zeroEx.isValidSignatureAsync`. It is now async so that it can verify contract-dependent signature types",
"pr": 863
},
{
"note":
"Refactored `signOrderHashAsync` to `ecSignOrderHashAsync`. There are now many non-ECSignature ways to sign orders too.",
"pr": 863
},
{
"note":
"Removed `createOrderWatcherAsync` method. Will be added back once OrderWatcher is refactored for V2",
"pr": 863
},
{
"note": "0x.js exports renamed contract events and event arg types",
"pr": 863
},
{
"note": "Export `ZeroEx.assetData` with methods to decode/encode assetData fields found in 0x orders",
"pr": 884
}
]
},
{
"timestamp": 1531919263,
"version": "0.38.6",

View File

@@ -1,66 +1,10 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
This file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v1.0.3 - _September 19, 2018_
* Drastically reduce the bundle size by removing unused parts of included contract artifacts.
## v1.0.2 - _September 18, 2018_
* Add ZRX & WETH mainnet contract addresses into the included artifacts
## v1.0.1 - _September 5, 2018_
* Dependencies updated
## v1.0.1-rc.6 - _August 27, 2018_
* Fix missing `BlockParamLiteral` type import issue
## v1.0.1-rc.5 - _Invalid date_
* Fix `main` and `types` package.json entries so that they point to the new location of index.d.ts and index.js
## v1.0.1-rc.4 - _August 24, 2018_
* Re-organize the exported interface of 0x.js. Remove the `ZeroEx` class, and instead export the same exports as `0x.js`'s sub-packages: `@0xproject/contract-wrappers`, `@0xproject/order-utils` and `@0xproject/order-watcher` (#963)
## v1.0.1-rc.3 - _August 14, 2018_
* Dependencies updated
* Update ecSignOrderHashAsync to return the signature as a string for immediate use in contracts (#914)
## v1.0.1-rc.2 - _July 26, 2018_
* Fixed bug caused by importing non-existent dep
## v1.0.1-rc.1 - _July 26, 2018_
* Dependencies updated
## v1.0.0 - _July 23, 2018_
* Dependencies updated
## v1.0.0-rc.2 - _July 20, 2018_
* Remove `zeroEx.assetData` and instead re-export it's static functions directly off `ZeroEx`
## v1.0.0-rc.1 - _July 20, 2018_
* Remove tokenRegistry wrapper (#863)
* Rename `zeroEx.token` to `zeroEx.erc20Token`, and add `zeroEx.erc721Token` (#863)
* Rename `zeroEx.proxy` to `zeroEx.erc20Proxy` and add `zeroEx.erc721Proxy` (#863)
* Refactored `ZeroEx.isValidSignature` to `zeroEx.isValidSignatureAsync`. It is now async so that it can verify contract-dependent signature types (#863)
* Refactored `signOrderHashAsync` to `ecSignOrderHashAsync`. There are now many non-ECSignature ways to sign orders too. (#863)
* Removed `createOrderWatcherAsync` method. Will be added back once OrderWatcher is refactored for V2 (#863)
* 0x.js exports renamed contract events and event arg types (#863)
* Export `ZeroEx.assetData` with methods to decode/encode assetData fields found in 0x orders (#884)
## v0.38.6 - _July 18, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
## 0x.js
A TypeScript/Javascript library for interacting with the 0x protocol. It is a high level package which combines a number of underlying packages such as order-utils and order-watcher.
A TypeScript/Javascript library for interacting with the 0x protocol.
### Read the [Documentation](https://0xproject.com/docs/0x.js).
@@ -19,14 +19,7 @@ npm install 0x.js --save
**Import**
```javascript
import {
assetDataUtils,
BigNumber,
ContractWrappers,
generatePseudoRandomSalt,
orderHashUtils,
signatureUtils,
} from '0x.js';
import { ZeroEx } from '0x.js';
```
If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`:

View File

@@ -1,6 +1,6 @@
{
"name": "0x.js",
"version": "1.0.3",
"version": "0.38.6",
"engines": {
"node": ">=6.12"
},
@@ -12,27 +12,52 @@
"tokens",
"exchange"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build": "yarn build:all",
"build:all": "run-p build:umd:prod build:commonjs",
"lint": "tslint --project . --exclude **/src/generated_contract_wrappers/**/*",
"watch": "tsc -w",
"prebuild": "run-s clean generate_contract_wrappers",
"build": "run-p build:umd:prod build:commonjs; exit 0;",
"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",
"rebuild_and_test": "run-s build test",
"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",
"clean": "shx rm -rf _bundles lib test_temp src/generated_contract_wrappers generated_docs",
"clean": "shx rm -rf _bundles lib test_temp scripts src/contract_wrappers/generated",
"build:umd:prod": "NODE_ENV=production webpack",
"build:commonjs": "tsc -b",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
"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": "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",
"postpublish": {
"assets": [
"packages/0x.js/_bundles/index.js",
"packages/0x.js/_bundles/index.min.js"
]
],
"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"
],
"s3BucketPath": "s3://doc-jsons/0x.js/",
"s3StagingBucketPath": "s3://staging-doc-jsons/0x.js/"
}
}
},
"repository": {
@@ -41,52 +66,49 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@0xproject/abi-gen": "^1.0.8",
"@0xproject/dev-utils": "^1.0.7",
"@0xproject/migrations": "^1.0.9",
"@0xproject/monorepo-scripts": "^1.0.8",
"@0xproject/tslint-config": "^1.0.7",
"@0xproject/abi-gen": "^0.3.4",
"@0xproject/dev-utils": "^0.4.6",
"@0xproject/migrations": "^0.0.10",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.53",
"@types/sinon": "^2.2.2",
"@types/web3-provider-engine": "^14.0.0",
"awesome-typescript-loader": "^3.1.3",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^2.0.1",
"copyfiles": "^2.0.0",
"dirty-chai": "^2.0.1",
"json-loader": "^0.5.4",
"make-promises-safe": "^1.1.0",
"mocha": "^4.1.0",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"opn-cli": "^3.1.0",
"shx": "^0.2.2",
"sinon": "^4.0.0",
"source-map-support": "^0.5.0",
"tslint": "5.11.0",
"typedoc": "0.12.0",
"typescript": "3.0.1",
"uglifyjs-webpack-plugin": "^1.3.0",
"webpack": "^3.1.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",
"webpack": "3.11.0"
},
"dependencies": {
"@0xproject/assert": "^1.0.8",
"@0xproject/base-contract": "^2.0.2",
"@0xproject/contract-wrappers": "^1.0.3",
"@0xproject/order-utils": "^1.0.2",
"@0xproject/order-watcher": "^1.0.3",
"@0xproject/subproviders": "^2.0.2",
"@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.6",
"@0xproject/assert": "^0.2.14",
"@0xproject/base-contract": "^0.3.6",
"@0xproject/contract-wrappers": "^0.1.1",
"@0xproject/order-utils": "^0.0.9",
"@0xproject/order-watcher": "^0.0.8",
"@0xproject/sol-compiler": "^0.5.4",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.3",
"@0xproject/utils": "^0.7.3",
"@0xproject/web3-wrapper": "^0.7.3",
"ethers": "3.0.22",
"lodash": "^4.17.5",
"web3-provider-engine": "14.0.6"
"lodash": "4.17.10"
},
"publishConfig": {
"access": "public"

229
packages/0x.js/src/0x.ts Normal file
View File

@@ -0,0 +1,229 @@
import { assert } from '@0xproject/assert';
import {
ContractWrappers,
ContractWrappersConfig,
EtherTokenWrapper,
ExchangeWrapper,
TokenRegistryWrapper,
TokenTransferProxyWrapper,
TokenWrapper,
} from '@0xproject/contract-wrappers';
import {
generatePseudoRandomSalt,
getOrderHashHex,
isValidOrderHash,
isValidSignature,
signOrderHashAsync,
} from '@0xproject/order-utils';
import { OrderWatcher, OrderWatcherConfig } from '@0xproject/order-watcher';
import { ECSignature, Order, Provider, SignedOrder, TransactionReceiptWithDecodedLogs } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
import { constants } from './utils/constants';
/**
* The ZeroEx class is the single entry-point into the 0x.js library. It contains all of the library's functionality
* and all calls to the library should be made through a ZeroEx instance.
*/
export class ZeroEx {
/**
* When creating an order without a specified taker or feeRecipient you must supply the Solidity
* address null type (as opposed to Javascripts `null`, `undefined` or empty string). We expose
* this constant for your convenience.
*/
public static NULL_ADDRESS = constants.NULL_ADDRESS;
/**
* 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 _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
* and will not collide with other outstanding orders that are identical in all other parameters.
* @return A pseudo-random 256-bit number that can be used as a salt.
*/
public static generatePseudoRandomSalt(): BigNumber {
return generatePseudoRandomSalt();
}
/**
* Verifies that the elliptic curve signature `signature` was generated
* by signing `data` with the private key corresponding to the `signerAddress` address.
* @param data The hex encoded data signed by the supplied signature.
* @param signature An object containing the elliptic curve signature parameters.
* @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
* @return Whether the signature is valid for the supplied signerAddress and data.
*/
public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
return isValidSignature(data, signature, signerAddress);
}
/**
* Computes the orderHash for a supplied order.
* @param order An object that conforms to the Order or SignedOrder interface definitions.
* @return The resulting orderHash from hashing the supplied order.
*/
public static getOrderHashHex(order: Order | SignedOrder): string {
return getOrderHashHex(order);
}
/**
* Checks if the supplied hex encoded order hash is valid.
* Note: Valid means it has the expected format, not that an order with the orderHash exists.
* Use this method when processing orderHashes submitted as user input.
* @param orderHash Hex encoded orderHash.
* @return Whether the supplied orderHash has the expected format.
*/
public static isValidOrderHash(orderHash: string): boolean {
return isValidOrderHash(orderHash);
}
/**
* A unit amount is defined as the amount of a token above the specified decimal places (integer part).
* E.g: If a currency has 18 decimal places, 1e18 or one quintillion of the currency is equivalent
* to 1 unit.
* @param amount The amount in baseUnits that you would like converted to units.
* @param decimals The number of decimal places the unit amount has.
* @return The amount in units.
*/
public static toUnitAmount(amount: BigNumber, decimals: number): BigNumber {
assert.isValidBaseUnitAmount('amount', amount);
assert.isNumber('decimals', decimals);
const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals);
return unitAmount;
}
/**
* A baseUnit is defined as the smallest denomination of a token. An amount expressed in baseUnits
* is the amount expressed in the smallest denomination.
* E.g: 1 unit of a token with 18 decimal places is expressed in baseUnits as 1000000000000000000
* @param amount The amount of units that you would like converted to baseUnits.
* @param decimals The number of decimal places the unit amount has.
* @return The amount in baseUnits.
*/
public static toBaseUnitAmount(amount: BigNumber, decimals: number): BigNumber {
assert.isBigNumber('amount', amount);
assert.isNumber('decimals', decimals);
const baseUnitAmount = Web3Wrapper.toBaseUnitAmount(amount, decimals);
return baseUnitAmount;
}
/**
* Instantiates a new ZeroEx instance that provides the public interface to the 0x.js library.
* @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 0x.js ZeroEx class.
*/
constructor(provider: Provider, config: ContractWrappersConfig) {
assert.isWeb3Provider('provider', provider);
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
* 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._contractWrappers.setProvider(provider, networkId);
}
/**
* Get the provider instance currently used by 0x.js
* @return Web3 provider instance
*/
public getProvider(): Provider {
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[]> {
// Hack: Get Web3Wrapper from ContractWrappers
const web3Wrapper: Web3Wrapper = (this._contractWrappers as any)._web3Wrapper;
const availableAddresses = await web3Wrapper.getAvailableAddressesAsync();
return availableAddresses;
}
/**
* Signs an orderHash and returns it's elliptic curve signature.
* This method currently supports TestRPC, Geth and Parity above and below V1.6.6
* @param orderHash Hex encoded orderHash to sign.
* @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address
* must be available via the Provider supplied to 0x.js.
* @param shouldAddPersonalMessagePrefix Some signers add the personal message prefix `\x19Ethereum Signed Message`
* themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
* (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
* before sending the request.
* @return An object containing the Elliptic curve signature parameters generated by signing the orderHash.
*/
public async signOrderHashAsync(
orderHash: string,
signerAddress: string,
shouldAddPersonalMessagePrefix: boolean,
): Promise<ECSignature> {
return signOrderHashAsync(
this._contractWrappers.getProvider(),
orderHash,
signerAddress,
shouldAddPersonalMessagePrefix,
);
}
/**
* Waits for a transaction to be mined and returns the transaction receipt.
* @param txHash Transaction hash
* @param pollingIntervalMs How often (in ms) should we check if the transaction is mined.
* @param timeoutMs How long (in ms) to poll for transaction mined until aborting.
* @return Transaction receipt with decoded log args.
*/
public async awaitTransactionMinedAsync(
txHash: string,
pollingIntervalMs: number = 1000,
timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> {
// Hack: Get Web3Wrapper from ContractWrappers
const web3Wrapper: Web3Wrapper = (this._contractWrappers as any)._web3Wrapper;
const transactionReceiptWithDecodedLogs = await web3Wrapper.awaitTransactionMinedAsync(
txHash,
pollingIntervalMs,
timeoutMs,
);
return transactionReceiptWithDecodedLogs;
}
/**
* 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 OrderWatcher class.
*/
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

@@ -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

@@ -1,104 +1,53 @@
export { assetDataUtils, signatureUtils, generatePseudoRandomSalt, orderHashUtils } from '@0xproject/order-utils';
export {
ContractWrappers,
ERC20TokenWrapper,
ERC721TokenWrapper,
EtherTokenWrapper,
ExchangeWrapper,
ERC20ProxyWrapper,
ERC721ProxyWrapper,
ForwarderWrapper,
OrderValidatorWrapper,
IndexedFilterValues,
BlockRange,
ContractWrappersConfig,
MethodOpts,
OrderTransactionOpts,
TransactionOpts,
OrderStatus,
OrderInfo,
WETH9Events,
WETH9WithdrawalEventArgs,
WETH9ApprovalEventArgs,
WETH9EventArgs,
WETH9DepositEventArgs,
WETH9TransferEventArgs,
ERC20TokenTransferEventArgs,
ERC20TokenApprovalEventArgs,
ERC20TokenEvents,
ERC20TokenEventArgs,
ERC721TokenApprovalEventArgs,
ERC721TokenApprovalForAllEventArgs,
ERC721TokenTransferEventArgs,
ERC721TokenEvents,
ERC721TokenEventArgs,
ExchangeCancelUpToEventArgs,
ExchangeAssetProxyRegisteredEventArgs,
ExchangeSignatureValidatorApprovalEventArgs,
ExchangeFillEventArgs,
ExchangeCancelEventArgs,
ExchangeEvents,
EventCallback,
DecodedLogEvent,
ExchangeEventArgs,
TransactionEncoder,
BalanceAndAllowance,
OrderAndTraderInfo,
TraderInfo,
ValidateOrderFillableOpts,
} from '@0xproject/contract-wrappers';
export { OrderWatcher, OnOrderStateChangeCallback, OrderWatcherConfig } from '@0xproject/order-watcher';
export import Web3ProviderEngine = require('web3-provider-engine');
export { RPCSubprovider, Callback, JSONRPCRequestPayloadWithMethod, ErrorCallback } from '@0xproject/subproviders';
export { AbiDecoder } from '@0xproject/utils';
export { BigNumber } from '@0xproject/utils';
export { ZeroEx } from './0x';
export {
BlockParamLiteral,
FilterObject,
BlockParam,
ContractEventArg,
ExchangeContractErrs,
LogWithDecodedArgs,
Order,
Provider,
SignedOrder,
ECSignature,
OrderStateValid,
OrderStateInvalid,
OrderState,
AssetProxyId,
SignerType,
ERC20AssetData,
ERC721AssetData,
SignatureType,
OrderRelevantState,
Token,
TransactionReceipt,
TransactionReceiptWithDecodedLogs,
} from '@0xproject/types';
export { OrderWatcherConfig } from '@0xproject/order-watcher';
export {
BlockParamLiteral,
ContractAbi,
BlockParam,
LogWithDecodedArgs,
ContractEventArg,
Provider,
JSONRPCRequestPayload,
JSONRPCResponsePayload,
JSONRPCErrorCallback,
LogEntry,
DecodedLogArgs,
LogEntryEvent,
DecodedLogEntry,
DecodedLogEntryEvent,
RawLog,
AbiDefinition,
FunctionAbi,
EventAbi,
EventParameter,
MethodAbi,
ConstructorAbi,
FallbackAbi,
DataItem,
ConstructorStateMutability,
StateMutability,
} from 'ethereum-types';
EventCallback,
ContractEvent,
IndexedFilterValues,
BlockRange,
OrderCancellationRequest,
OrderFillRequest,
ContractEventArgs,
MethodOpts,
OrderTransactionOpts,
TransactionOpts,
LogEvent,
DecodedLogEvent,
OnOrderStateChangeCallback,
ContractWrappersError,
EtherTokenContractEventArgs,
WithdrawalContractEventArgs,
DepositContractEventArgs,
EtherTokenEvents,
TransferContractEventArgs,
ApprovalContractEventArgs,
TokenContractEventArgs,
TokenEvents,
LogErrorContractEventArgs,
LogCancelContractEventArgs,
LogFillContractEventArgs,
ExchangeContractEventArgs,
ExchangeEvents,
ContractWrappersConfig,
} from '@0xproject/contract-wrappers';

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.publishDocsToStagingAsync(packageJSON, tsConfigJSON, cwd);

View File

@@ -0,0 +1,5 @@
export const zeroExConfigSchema = {
id: '/ZeroExConfig',
oneOf: [{ $ref: '/ZeroExPrivateNetworkConfig' }, { $ref: '/ZeroExPublicNetworkConfig' }],
type: 'object',
};

View File

@@ -0,0 +1,35 @@
export const zeroExPrivateNetworkConfigSchema = {
id: '/ZeroExPrivateNetworkConfig',
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 zeroExPublicNetworkConfigSchema = {
id: '/ZeroExPublicNetworkConfig',
properties: {
networkId: {
type: 'number',
enum: [
networkNameToId.mainnet,
networkNameToId.ropsten,
networkNameToId.rinkeby,
networkNameToId.kovan,
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

@@ -0,0 +1,20 @@
import {
BlockParam,
BlockParamLiteral,
ContractAbi,
ContractEventArg,
ExchangeContractErrs,
FilterObject,
LogWithDecodedArgs,
Order,
OrderState,
SignedOrder,
} from '@0xproject/types';
export enum InternalZeroExError {
NoAbiDecoder = 'NO_ABI_DECODER',
ZrxNotInTokenRegistry = 'ZRX_NOT_IN_TOKEN_REGISTRY',
WethNotInTokenRegistry = 'WETH_NOT_IN_TOKEN_REGISTRY',
}
// tslint:disable:max-file-line-count

View File

@@ -0,0 +1,6 @@
import { BigNumber } from '@0xproject/utils';
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
TESTRPC_NETWORK_ID: 50,
};

View File

@@ -0,0 +1,167 @@
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';
import { ApprovalContractEventArgs, LogWithDecodedArgs, Order, TokenEvents, ZeroEx } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
import { TokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
chaiSetup.configure();
const expect = chai.expect;
describe('ZeroEx library', () => {
let zeroEx: ZeroEx;
before(async () => {
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
};
zeroEx = new ZeroEx(provider, config);
});
describe('#setProvider', () => {
it('overrides provider in nested web3s and invalidates contractInstances', async () => {
// Instantiate the contract instances with the current provider
await (zeroEx.exchange as any)._getExchangeContractAsync();
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
expect((zeroEx.exchange as any)._exchangeContractIfExists).to.not.be.undefined();
expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.not.be.undefined();
// Add property to newProvider so that we can differentiate it from old provider
(provider as any).zeroExTestId = 1;
zeroEx.setProvider(provider, constants.TESTRPC_NETWORK_ID);
// Check that contractInstances with old provider are removed after provider update
expect((zeroEx.exchange as any)._exchangeContractIfExists).to.be.undefined();
expect((zeroEx.tokenRegistry as any)._tokenRegistryContractIfExists).to.be.undefined();
// 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();
expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
});
});
describe('#isValidSignature', () => {
// The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
// the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
const signature = {
v: 27,
r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
};
const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
it("should return false if the data doesn't pertain to the signature & address", async () => {
return expect(
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
).to.become(false);
});
it("should return false if the address doesn't pertain to the signature & data", async () => {
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
return expect(
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
dataHex,
signature,
validUnrelatedAddress,
),
).to.become(false);
});
it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
const wrongSignature = _.assign({}, signature, { v: 28 });
return expect(
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, wrongSignature, address),
).to.become(false);
});
it('should return true if the signature does pertain to the dataHex & address', async () => {
return expect(
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
).to.become(true);
});
});
describe('#toUnitAmount', () => {
it('should throw if invalid baseUnit amount supplied as argument', () => {
const invalidBaseUnitAmount = new BigNumber(1000000000.4);
const decimals = 6;
expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
'amount should be in baseUnits (no decimals), found value: 1000000000.4',
);
});
it('Should return the expected unit amount for the decimals passed in', () => {
const baseUnitAmount = new BigNumber(1000000000);
const decimals = 6;
const unitAmount = ZeroEx.toUnitAmount(baseUnitAmount, decimals);
const expectedUnitAmount = new BigNumber(1000);
expect(unitAmount).to.be.bignumber.equal(expectedUnitAmount);
});
});
describe('#toBaseUnitAmount', () => {
it('Should return the expected base unit amount for the decimals passed in', () => {
const unitAmount = new BigNumber(1000);
const decimals = 6;
const baseUnitAmount = ZeroEx.toBaseUnitAmount(unitAmount, decimals);
const expectedUnitAmount = new BigNumber(1000000000);
expect(baseUnitAmount).to.be.bignumber.equal(expectedUnitAmount);
});
it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
const unitAmount = new BigNumber(0.823091);
const decimals = 5;
expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
'Invalid unit amount: 0.823091 - Too many decimal places',
);
});
});
describe('#awaitTransactionMinedAsync', () => {
beforeEach(async () => {
await blockchainLifecycle.startAsync();
});
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
it('returns transaction receipt with decoded logs', async () => {
const availableAddresses = await zeroEx.getAvailableAddressesAsync();
const coinbase = availableAddresses[0];
const tokens = await zeroEx.tokenRegistry.getTokensAsync();
const tokenUtils = new TokenUtils(tokens);
const zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
const proxyAddress = zeroEx.proxy.getContractAddress();
const txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(zrxTokenAddress, coinbase);
const txReceiptWithDecodedLogs = await zeroEx.awaitTransactionMinedAsync(txHash);
const log = txReceiptWithDecodedLogs.logs[0] as LogWithDecodedArgs<ApprovalContractEventArgs>;
expect(log.event).to.be.equal(TokenEvents.Approval);
expect(log.args._owner).to.be.equal(coinbase);
expect(log.args._spender).to.be.equal(proxyAddress);
expect(log.args._value).to.be.bignumber.equal(zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
});
describe('#config', () => {
it('allows to specify exchange contract address', async () => {
const zeroExConfig = {
exchangeContractAddress: ZeroEx.NULL_ADDRESS,
networkId: constants.TESTRPC_NETWORK_ID,
};
const zeroExWithWrongExchangeAddress = new ZeroEx(provider, zeroExConfig);
expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
});
it('allows to specify token registry token contract address', async () => {
const zeroExConfig = {
tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,
networkId: constants.TESTRPC_NETWORK_ID,
};
const zeroExWithWrongTokenRegistryAddress = new ZeroEx(provider, zeroExConfig);
expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
ZeroEx.NULL_ADDRESS,
);
});
});
});

View File

@@ -0,0 +1,50 @@
import { web3Factory } from '@0xproject/dev-utils';
import * as fs from 'fs';
import 'make-promises-safe';
import { ZeroEx } 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 zeroEx = new ZeroEx(provider, config);
it('token registry contract is deployed', async () => {
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
}).timeout(TIMEOUT);
it('proxy contract is deployed', async () => {
await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
it('exchange contract is deployed', async () => {
await (zeroEx.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 zeroEx = new ZeroEx(provider, config);
it('token registry contract is deployed', async () => {
await (zeroEx.tokenRegistry as any)._getTokenRegistryContractAsync();
}).timeout(TIMEOUT);
it('proxy contract is deployed', async () => {
await (zeroEx.proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
it('exchange contract is deployed', async () => {
await (zeroEx.exchange as any)._getExchangeContractAsync();
}).timeout(TIMEOUT);
});
});

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

@@ -0,0 +1,9 @@
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
ROPSTEN_NETWORK_ID: 3,
KOVAN_NETWORK_ID: 42,
TESTRPC_NETWORK_ID: 50,
KOVAN_RPC_URL: 'https://kovan.infura.io/',
ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
ZRX_DECIMALS: 18,
};

View File

@@ -0,0 +1,34 @@
import { Token } from '@0xproject/types';
import * as _ from 'lodash';
import { InternalZeroExError } from '../../src/types';
const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
const WETH_TOKEN_SYMBOL = 'WETH';
export class TokenUtils {
private _tokens: Token[];
constructor(tokens: Token[]) {
this._tokens = tokens;
}
public getProtocolTokenOrThrow(): Token {
const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
if (_.isUndefined(zrxToken)) {
throw new Error(InternalZeroExError.ZrxNotInTokenRegistry);
}
return zrxToken;
}
public getWethTokenOrThrow(): Token {
const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
if (_.isUndefined(wethToken)) {
throw new Error(InternalZeroExError.WethNotInTokenRegistry);
}
return wethToken;
}
public getDummyTokens(): Token[] {
const dummyTokens = _.filter(this._tokens, token => {
return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
});
return dummyTokens;
}
}

View File

@@ -0,0 +1,9 @@
import { devConstants, web3Factory } from '@0xproject/dev-utils';
import { Provider } from '@0xproject/types';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
const web3 = web3Factory.create({ shouldUseInProcessGanache: true });
const provider: Provider = web3.currentProvider;
const web3Wrapper = new Web3Wrapper(web3.currentProvider);
export { provider, web3Wrapper };

View File

@@ -1,8 +1,7 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
"outDir": "lib"
},
"include": ["./src/**/*"]
"include": ["./src/**/*", "./test/**/*"]
}

View File

@@ -1,7 +0,0 @@
{
"extends": "../../typedoc-tsconfig",
"compilerOptions": {
"outDir": "lib"
},
"include": ["./src/**/*", "./test/**/*"]
}

View File

@@ -3,7 +3,6 @@
*/
const _ = require('lodash');
const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const production = process.env.NODE_ENV === 'production';
@@ -28,16 +27,10 @@ module.exports = {
},
devtool: 'source-map',
plugins: [
// TODO: Revert to webpack bundled version with webpack v4.
// The v3 series bundled version does not support ES6 and
// fails to build.
new UglifyJsPlugin({
new webpack.optimize.UglifyJsPlugin({
minimize: true,
sourceMap: true,
uglifyOptions: {
mangle: {
reserved: ['BigNumber'],
},
},
include: /\.min\.js$/,
}),
],
module: {
@@ -47,13 +40,8 @@ module.exports = {
use: [
{
loader: 'awesome-typescript-loader',
// tsconfig.json contains some options required for
// project references which do not work with webback.
// We override those options here.
query: {
declaration: false,
declarationMap: false,
composite: false,
},
},
],

View File

@@ -1,95 +1,4 @@
[
{
"timestamp": 1536142250,
"version": "1.0.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1535377027,
"version": "1.0.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1535133899,
"version": "1.0.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1534210131,
"version": "1.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532619515,
"version": "1.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532614997,
"version": "1.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532605697,
"version": "1.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "1.0.1",
"changes": [
{
"note": "Fix the abi-gen entry point in package.json",
"pr": 901
}
],
"timestamp": 1532357734
},
{
"timestamp": 1532043000,
"version": "1.0.0",
"changes": [
{
"note": "Convert e_r_c to erc in generated file names",
"pr": 822
},
{
"note": "Remove the output directory before writing to it",
"pr": 822
},
{
"note": "skip generation of wrappers that are already up to date",
"pr": 788
}
]
},
{
"timestamp": 1531919263,
"version": "0.3.4",

View File

@@ -1,48 +1,10 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
This file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v1.0.8 - _September 5, 2018_
* Dependencies updated
## v1.0.7 - _August 27, 2018_
* Dependencies updated
## v1.0.6 - _August 24, 2018_
* Dependencies updated
## v1.0.5 - _August 14, 2018_
* Dependencies updated
## v1.0.4 - _July 26, 2018_
* Dependencies updated
## v1.0.3 - _July 26, 2018_
* Dependencies updated
## v1.0.2 - _July 26, 2018_
* Dependencies updated
## v1.0.1 - _July 23, 2018_
* Fix the abi-gen entry point in package.json (#901)
## v1.0.0 - _July 20, 2018_
* Convert e_r_c to erc in generated file names (#822)
* Remove the output directory before writing to it (#822)
* skip generation of wrappers that are already up to date (#788)
## v0.3.4 - _July 18, 2018_
* Dependencies updated

View File

@@ -4,7 +4,8 @@ This package allows you to generate TypeScript contract wrappers from ABI files.
It's heavily inspired by [Geth abigen](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) but takes a different approach.
You can write your custom handlebars templates which will allow you to seamlessly integrate the generated code into your existing codebase with existing conventions.
[Here](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) are the templates used to generate the contract wrappers used by 0x.js.e
For an example of the generated [wrapper files](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/src/contract_wrappers/generated) check out 0x.js.
[Here](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) are the templates used to generate those files.
## Installation
@@ -44,7 +45,7 @@ You need to also specify the location of your main template used for every contr
## How to write custom templates?
The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x-monorepo/tree/development/packages/contract_templates) and start adjusting them for your needs.
The best way to get started is to copy [0x.js templates](https://github.com/0xProject/0x-monorepo/tree/development/packages/0x.js/contract_templates) and start adjusting them for your needs.
We use [handlebars](http://handlebarsjs.com/) template engine under the hood.
You need to have a master template called `contract.mustache`. it will be used to generate each contract wrapper. Although - you don't need and probably shouldn't write all your logic in a single template file. You can write [partial templates](http://handlebarsjs.com/partials.html) and as long as they are within a partials folder - they will be registered and available.

View File

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

View File

@@ -1,21 +1,18 @@
{
"name": "@0xproject/abi-gen",
"version": "1.0.8",
"version": "0.3.4",
"engines": {
"node": ">=6.12"
},
"description": "Generate contract wrappers from ABI and handlebars templates",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"watch": "tsc -w",
"lint": "tslint --project .",
"clean": "shx rm -rf lib",
"build": "tsc -b",
"test": "yarn run_mocha",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --bail --exit",
"test:circleci": "yarn test:coverage",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info"
"clean": "shx rm -rf lib scripts",
"build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
},
"bin": {
"abi-gen": "bin/abi-gen.js"
@@ -30,37 +27,31 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
"dependencies": {
"@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.8",
"chalk": "^2.3.0",
"ethereum-types": "^1.0.6",
"glob": "^7.1.2",
"handlebars": "^4.0.11",
"lodash": "^4.17.5",
"mkdirp": "^0.5.1",
"sleep": "^5.1.1",
"tmp": "^0.0.33",
"to-snake-case": "^1.0.0",
"yargs": "^10.0.3"
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.3",
"@0xproject/utils": "^0.7.3",
"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/tslint-config": "^1.0.7",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/glob": "5.0.35",
"@types/handlebars": "^4.0.36",
"@types/mkdirp": "^0.5.1",
"@types/node": "^8.0.53",
"@types/sleep": "^0.0.7",
"@types/tmp": "^0.0.33",
"@types/yargs": "^10.0.0",
"chai": "^4.1.2",
"copyfiles": "^2.0.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^5.2.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"tslint": "5.11.0",
"typescript": "3.0.1"
"@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"
},
"publishConfig": {
"access": "public"

View File

@@ -1,15 +1,18 @@
#!/usr/bin/env node
import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from '@0xproject/types';
import { abiUtils, logUtils } from '@0xproject/utils';
import chalk from 'chalk';
import { AbiDefinition, ConstructorAbi, EventAbi, MethodAbi } from 'ethereum-types';
import * as fs from 'fs';
import { sync as globSync } from 'glob';
import * as Handlebars from 'handlebars';
import * as _ from 'lodash';
import * as mkdirp from 'mkdirp';
import * as yargs from 'yargs';
import { ContextData, ContractsBackend, ParamKind } from './types';
import toSnakeCase = require('to-snake-case');
import { ContextData, ContractsBackend, Method, ParamKind } from './types';
import { utils } from './utils';
const ABI_TYPE_CONSTRUCTOR = 'constructor';
@@ -67,6 +70,16 @@ function registerPartials(partialsGlob: string): void {
}
}
function writeOutputFile(name: string, renderedTsCode: string): void {
let fileName = toSnakeCase(name);
if (fileName === 'z_r_x_token') {
fileName = 'zrx_token';
}
const filePath = `${args.output}/${fileName}.ts`;
fs.writeFileSync(filePath, renderedTsCode);
logUtils.log(`Created: ${chalk.bold(filePath)}`);
}
Handlebars.registerHelper('parameterType', utils.solTypeToTsType.bind(utils, ParamKind.Input, args.backend));
Handlebars.registerHelper('returnType', utils.solTypeToTsType.bind(utils, ParamKind.Output, args.backend));
if (args.partials) {
@@ -105,14 +118,6 @@ for (const abiFileName of abiFileNames) {
process.exit(1);
}
const outFileName = utils.makeOutputFileName(namedContent.name);
const outFilePath = `${args.output}/${outFileName}.ts`;
if (utils.isOutputFileUpToDate(abiFileName, outFilePath)) {
logUtils.log(`Already up to date: ${chalk.bold(outFilePath)}`);
continue;
}
let ctor = ABI.find((abi: AbiDefinition) => abi.type === ABI_TYPE_CONSTRUCTOR) as ConstructorAbi;
if (_.isUndefined(ctor)) {
ctor = utils.getEmptyConstructor(); // The constructor exists, but it's implicit in JSON's ABI definition
@@ -147,6 +152,5 @@ for (const abiFileName of abiFileNames) {
events: eventAbis,
};
const renderedTsCode = template(contextData);
utils.writeOutputFile(outFilePath, renderedTsCode);
logUtils.log(`Created: ${chalk.bold(outFilePath)}`);
writeOutputFile(namedContent.name, renderedTsCode);
}

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);

View File

@@ -1,4 +1,4 @@
import { EventAbi, MethodAbi } from 'ethereum-types';
import { EventAbi, MethodAbi } from '@0xproject/types';
export enum ParamKind {
Input = 'input',

View File

@@ -1,8 +1,7 @@
import { AbiType, ConstructorAbi, DataItem } from 'ethereum-types';
import { AbiType, ConstructorAbi, DataItem } from '@0xproject/types';
import * as fs from 'fs';
import * as _ from 'lodash';
import * as path from 'path';
import toSnakeCase = require('to-snake-case');
import { ContractsBackend, ParamKind } from './types';
@@ -57,7 +56,7 @@ export const utils = {
const componentType = `${component.name}: ${componentValueType}`;
return componentType;
});
const tsType = `{${componentsType.join(';')}}`;
const tsType = `{${componentsType}}`;
return tsType;
}
throw new Error(`Unknown Solidity type found: ${solType}`);
@@ -93,27 +92,4 @@ export const utils = {
inputs: [],
};
},
makeOutputFileName(name: string): string {
let fileName = toSnakeCase(name);
// HACK: Snake case doesn't make a lot of sense for abbreviated names but we can't reliably detect abbreviations
// so we special-case the abbreviations we use.
fileName = fileName.replace('z_r_x', 'zrx').replace('e_r_c', 'erc');
return fileName;
},
writeOutputFile(filePath: string, renderedTsCode: string): void {
fs.writeFileSync(filePath, renderedTsCode);
},
isOutputFileUpToDate(abiFile: string, outputFile: string): boolean {
const abiFileModTimeMs = fs.statSync(abiFile).mtimeMs;
try {
const outFileModTimeMs = fs.statSync(outputFile).mtimeMs;
return outFileModTimeMs > abiFileModTimeMs;
} catch (err) {
if (err.code === 'ENOENT') {
return false;
} else {
throw err;
}
}
},
};

View File

@@ -1,86 +0,0 @@
import * as chai from 'chai';
import * as dirtyChai from 'dirty-chai';
import * as fs from 'fs';
import 'mocha';
import * as tmp from 'tmp';
import { utils } from '../src/utils';
tmp.setGracefulCleanup(); // remove tmp files even if there are failures
chai.use(dirtyChai);
const expect = chai.expect;
describe('makeOutputFileName()', () => {
it('should handle Metacoin usage', () => {
expect(utils.makeOutputFileName('Metacoin')).to.equal('metacoin');
});
it('should handle special zrx_token case', () => {
expect(utils.makeOutputFileName('ZRXToken')).to.equal('zrx_token');
});
it('should handle special erc_token case', () => {
expect(utils.makeOutputFileName('ERC20Token')).to.equal('erc20_token');
});
});
describe('writeOutputFile()', () => {
let tempFilePath: string;
before(() => {
tempFilePath = tmp.fileSync(
{ discardDescriptor: true }, // close file (so we can update it)
).name;
});
it('should write content to output file', () => {
const content = 'hello world';
utils.writeOutputFile(tempFilePath, content);
expect(fs.readFileSync(tempFilePath).toString()).to.equal(content);
});
});
describe('isOutputFileUpToDate()', () => {
it('should throw ENOENT when there is no abi file', () => {
expect(utils.isOutputFileUpToDate.bind('nonexistant1', 'nonexistant2')).to.throw('ENOENT');
});
describe('when the abi input file exists', () => {
let abiFile: string;
before(() => {
abiFile = tmp.fileSync(
{ discardDescriptor: true }, // close file (set timestamp)
).name;
});
describe('without an existing output file', () => {
it('should return false', () => {
expect(utils.isOutputFileUpToDate(abiFile, 'nonexistant_file')).to.be.false();
});
});
describe('with an existing output file', () => {
let outputFile: string;
before(() => {
outputFile = tmp.fileSync(
{ discardDescriptor: true }, // close file (set timestamp)
).name;
const abiFileModTimeMs = fs.statSync(abiFile).mtimeMs;
const outfileModTimeMs = abiFileModTimeMs + 1;
fs.utimesSync(outputFile, outfileModTimeMs, outfileModTimeMs);
});
it('should return true when output file is newer than abi file', async () => {
expect(utils.isOutputFileUpToDate(abiFile, outputFile)).to.be.true();
});
it('should return false when output file exists but is older than abi file', () => {
const outFileModTimeMs = fs.statSync(outputFile).mtimeMs;
const abiFileModTimeMs = outFileModTimeMs + 1;
fs.utimesSync(abiFile, abiFileModTimeMs, abiFileModTimeMs);
expect(utils.isOutputFileUpToDate(abiFile, outputFile)).to.be.false();
});
});
});
});

View File

@@ -1,8 +1,7 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "."
"outDir": "lib"
},
"include": ["./src/**/*", "./test/**/*"]
}

View File

@@ -1,87 +1,4 @@
[
{
"timestamp": 1536142250,
"version": "1.0.8",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1535377027,
"version": "1.0.7",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1535133899,
"version": "1.0.6",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1534210131,
"version": "1.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532619515,
"version": "1.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532614997,
"version": "1.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532605697,
"version": "1.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532357734,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532043000,
"version": "1.0.0",
"changes": [
{
"note":
"Fix bug in string enum assertion. We erroneously were checking against the enum keys, not values",
"pr": 821
}
]
},
{
"timestamp": 1531919263,
"version": "0.2.14",

View File

@@ -1,46 +1,10 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
This file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v1.0.8 - _September 5, 2018_
* Dependencies updated
## v1.0.7 - _August 27, 2018_
* Dependencies updated
## v1.0.6 - _August 24, 2018_
* Dependencies updated
## v1.0.5 - _August 14, 2018_
* Dependencies updated
## v1.0.4 - _July 26, 2018_
* Dependencies updated
## v1.0.3 - _July 26, 2018_
* Dependencies updated
## v1.0.2 - _July 26, 2018_
* Dependencies updated
## v1.0.1 - _July 23, 2018_
* Dependencies updated
## v1.0.0 - _July 20, 2018_
* Fix bug in string enum assertion. We erroneously were checking against the enum keys, not values (#821)
## v0.2.14 - _July 18, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/assert",
"version": "1.0.8",
"version": "0.2.14",
"engines": {
"node": ">=6.12"
},
@@ -8,15 +8,17 @@
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build": "tsc -b",
"clean": "shx rm -rf lib test_temp",
"watch": "tsc -w",
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
"clean": "shx rm -rf lib test_temp scripts",
"lint": "tslint --project .",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s clean build test",
"run_mocha": "mocha lib/test/**/*_test.js --exit",
"prepublishOnly": "run-p build",
"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",
"test:circleci": "yarn test:coverage"
"test:circleci": "yarn test:coverage",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
},
"license": "Apache-2.0",
"repository": {
@@ -28,27 +30,28 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
"devDependencies": {
"@0xproject/tslint-config": "^1.0.7",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/valid-url": "^1.0.2",
"chai": "^4.0.1",
"copyfiles": "^2.0.0",
"dirty-chai": "^2.0.1",
"make-promises-safe": "^1.1.0",
"mocha": "^4.1.0",
"npm-run-all": "^4.1.2",
"nyc": "^11.0.1",
"shx": "^0.2.2",
"tslint": "5.11.0",
"typescript": "3.0.1"
"@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": "^1.0.1",
"@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.8",
"lodash": "^4.17.5",
"valid-url": "^1.0.9"
"@0xproject/json-schemas": "^0.8.3",
"@0xproject/typescript-typings": "^0.4.3",
"@0xproject/utils": "^0.7.3",
"lodash": "4.17.10",
"valid-url": "1.0.9"
},
"publishConfig": {
"access": "public"

View File

@@ -8,41 +8,41 @@ const HEX_REGEX = /^0x[0-9A-F]*$/i;
export const assert = {
isBigNumber(variableName: string, value: BigNumber): void {
const isBigNumber = _.isObject(value) && (value as any).isBigNumber;
assert.assert(isBigNumber, assert.typeAssertionMessage(variableName, 'BigNumber', value));
this.assert(isBigNumber, this.typeAssertionMessage(variableName, 'BigNumber', value));
},
isValidBaseUnitAmount(variableName: string, value: BigNumber): void {
assert.isBigNumber(variableName, value);
const isNegative = value.lessThan(0);
assert.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
this.assert(!isNegative, `${variableName} cannot be a negative number, found value: ${value.toNumber()}`);
const hasDecimals = value.decimalPlaces() !== 0;
assert.assert(
this.assert(
!hasDecimals,
`${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
);
},
isString(variableName: string, value: string): void {
assert.assert(_.isString(value), assert.typeAssertionMessage(variableName, 'string', value));
this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
},
isFunction(variableName: string, value: any): void {
assert.assert(_.isFunction(value), assert.typeAssertionMessage(variableName, 'function', value));
this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value));
},
isHexString(variableName: string, value: string): void {
assert.assert(
this.assert(
_.isString(value) && HEX_REGEX.test(value),
assert.typeAssertionMessage(variableName, 'HexString', value),
this.typeAssertionMessage(variableName, 'HexString', value),
);
},
isETHAddressHex(variableName: string, value: string): void {
assert.assert(_.isString(value), assert.typeAssertionMessage(variableName, 'string', value));
assert.assert(addressUtils.isAddress(value), assert.typeAssertionMessage(variableName, 'ETHAddressHex', value));
this.assert(_.isString(value), this.typeAssertionMessage(variableName, 'string', value));
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
},
doesBelongToStringEnum(
variableName: string,
value: string,
stringEnum: any /* There is no base type for every string enum */,
): void {
const enumValues = _.values(stringEnum);
const doesBelongToStringEnum = _.includes(enumValues, value);
const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]);
const enumValues = _.keys(stringEnum);
const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`);
const enumValuesAsString = enumValuesAsStrings.join(', ');
assert.assert(
@@ -51,22 +51,19 @@ export const assert = {
);
},
hasAtMostOneUniqueValue(value: any[], errMsg: string): void {
assert.assert(_.uniq(value).length <= 1, errMsg);
this.assert(_.uniq(value).length <= 1, errMsg);
},
isNumber(variableName: string, value: number): void {
assert.assert(_.isFinite(value), assert.typeAssertionMessage(variableName, 'number', value));
this.assert(_.isFinite(value), this.typeAssertionMessage(variableName, 'number', value));
},
isBoolean(variableName: string, value: boolean): void {
assert.assert(_.isBoolean(value), assert.typeAssertionMessage(variableName, 'boolean', value));
this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value));
},
isWeb3Provider(variableName: string, value: any): void {
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
assert.assert(isWeb3Provider, assert.typeAssertionMessage(variableName, 'Provider', value));
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Provider', value));
},
doesConformToSchema(variableName: string, value: any, schema: Schema, subSchemas?: Schema[]): void {
if (_.isUndefined(value)) {
throw new Error(`${variableName} can't be undefined`);
}
const schemaValidator = new SchemaValidator();
if (!_.isUndefined(subSchemas)) {
_.map(subSchemas, schemaValidator.addSchema.bind(schemaValidator));
@@ -76,15 +73,15 @@ export const assert = {
const msg = `Expected ${variableName} to conform to schema ${schema.id}
Encountered: ${JSON.stringify(value, null, '\t')}
Validation errors: ${validationResult.errors.join(', ')}`;
assert.assert(!hasValidationErrors, msg);
this.assert(!hasValidationErrors, msg);
},
isWebUri(variableName: string, value: any): void {
const isValidUrl = !_.isUndefined(validUrl.isWebUri(value));
assert.assert(isValidUrl, assert.typeAssertionMessage(variableName, 'web uri', value));
this.assert(isValidUrl, this.typeAssertionMessage(variableName, 'web uri', value));
},
isUri(variableName: string, value: any): void {
const isValidUri = !_.isUndefined(validUrl.isUri(value));
assert.assert(isValidUri, assert.typeAssertionMessage(variableName, 'uri', value));
this.assert(isValidUri, this.typeAssertionMessage(variableName, 'uri', value));
},
assert(condition: boolean, message: string): void {
if (!condition) {

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);

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';
@@ -49,7 +50,7 @@ describe('Assertions', () => {
});
describe('#isFunction', () => {
it('should not throw for valid input', () => {
const validInputs = [BigNumber, assert.isString.bind(assert)];
const validInputs = [BigNumber, assert.isString];
validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
});
it('should throw for invalid input', () => {

View File

@@ -1,8 +1,7 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "."
"outDir": "lib"
},
"include": ["./src/**/*", "./test/**/*"]
}

View File

@@ -1,86 +1,4 @@
[
{
"timestamp": 1536142250,
"version": "2.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1535377027,
"version": "2.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1535133899,
"version": "2.0.0",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.0.0-rc.1",
"changes": [
{
"pr": 915,
"note": "Added strict encoding/decoding checks for sendTransaction and call"
}
],
"timestamp": 1534210131
},
{
"timestamp": 1532619515,
"version": "1.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532614997,
"version": "1.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532605697,
"version": "1.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532357734,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532043000,
"version": "1.0.0",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1531919263,
"version": "0.3.6",

View File

@@ -1,46 +1,10 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
This file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v2.0.2 - _September 5, 2018_
* Dependencies updated
## v2.0.1 - _August 27, 2018_
* Dependencies updated
## v2.0.0 - _August 24, 2018_
* Dependencies updated
## v2.0.0-rc.1 - _August 14, 2018_
* Added strict encoding/decoding checks for sendTransaction and call (#915)
## v1.0.4 - _July 26, 2018_
* Dependencies updated
## v1.0.3 - _July 26, 2018_
* Dependencies updated
## v1.0.2 - _July 26, 2018_
* Dependencies updated
## v1.0.1 - _July 23, 2018_
* Dependencies updated
## v1.0.0 - _July 20, 2018_
* Dependencies updated
## v0.3.6 - _July 18, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/base-contract",
"version": "2.0.2",
"version": "0.3.6",
"engines": {
"node": ">=6.12"
},
@@ -8,15 +8,16 @@
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build": "tsc -b",
"clean": "shx rm -rf lib",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s clean build test",
"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",
"test:circleci": "yarn test:coverage",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --bail --exit",
"run_mocha": "mocha lib/test/**/*_test.js --bail --exit",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"lint": "tslint --project . --exclude **/src/contract_wrappers/**/*"
"lint": "tslint --project .",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js"
},
"license": "Apache-2.0",
"repository": {
@@ -28,24 +29,25 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
"devDependencies": {
"@0xproject/tslint-config": "^1.0.7",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/lodash": "4.14.104",
"chai": "^4.0.1",
"copyfiles": "^2.0.0",
"make-promises-safe": "^1.1.0",
"mocha": "^4.1.0",
"npm-run-all": "^4.1.2",
"shx": "^0.2.2",
"tslint": "5.11.0",
"typescript": "3.0.1"
"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/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.8",
"@0xproject/web3-wrapper": "^2.0.2",
"ethereum-types": "^1.0.6",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.3",
"@0xproject/utils": "^0.7.3",
"@0xproject/web3-wrapper": "^0.7.3",
"ethers": "3.0.22",
"lodash": "^4.17.5"
"lodash": "4.17.10"
},
"publishConfig": {
"access": "public"

View File

@@ -1,5 +1,3 @@
import { abiUtils, BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import {
AbiDefinition,
AbiType,
@@ -10,7 +8,9 @@ import {
Provider,
TxData,
TxDataPayable,
} from 'ethereum-types';
} from '@0xproject/types';
import { abiUtils, BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as ethers from 'ethers';
import * as _ from 'lodash';
@@ -37,14 +37,13 @@ export class BaseContract {
protected static _lowercaseAddress(type: string, value: string): string {
return type === 'address' ? value.toLowerCase() : value;
}
protected static _bigNumberToString(_type: string, value: any): any {
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,
// tslint:disable-next-line:no-unnecessary-type-assertion
) as ConstructorAbi | undefined;
if (!_.isUndefined(constructorAbiIfExists)) {
return constructorAbiIfExists;
@@ -60,7 +59,7 @@ export class BaseContract {
return defaultConstructorAbi;
}
}
protected static _bnToBigNumber(_type: string, value: any): any {
protected static _bnToBigNumber(type: string, value: any): any {
return _.isObject(value) && value._bn ? new BigNumber(value.toString()) : value;
}
protected static async _applyDefaultsToTxDataAsync<T extends Partial<TxData | TxDataPayable>>(
@@ -72,37 +71,19 @@ export class BaseContract {
// 1. Optional param passed in to public method call
// 2. Global config passed in at library instantiation
// 3. Gas estimate calculation + safety margin
const removeUndefinedProperties = _.pickBy.bind(_);
const txDataWithDefaults = {
const removeUndefinedProperties = _.pickBy;
const txDataWithDefaults: TxData = {
...removeUndefinedProperties(txDefaults),
...removeUndefinedProperties(txData),
};
...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;
if (_.isUndefined(txDataWithDefaults.gas) && !_.isUndefined(estimateGasAsync)) {
txDataWithDefaults.gas = await estimateGasAsync(txDataWithDefaults);
const estimatedGas = await estimateGasAsync(txData);
txDataWithDefaults.gas = estimatedGas;
}
return txDataWithDefaults;
}
// Throws if the given arguments cannot be safely/correctly encoded based on
// the given inputAbi. An argument may not be considered safely encodeable
// if it overflows the corresponding Solidity type, there is a bug in the
// encoder, or the encoder performs unsafe type coercion.
public static strictArgumentEncodingCheck(inputAbi: DataItem[], args: any[]): void {
const coder = ethers.utils.AbiCoder.defaultCoder;
const params = abiUtils.parseEthersParams(inputAbi);
const rawEncoded = coder.encode(params.names, params.types, args);
const rawDecoded = coder.decode(params.names, params.types, rawEncoded);
for (let i = 0; i < rawDecoded.length; i++) {
const original = args[i];
const decoded = rawDecoded[i];
if (!abiUtils.isAbiDataEqual(params.names[i], params.types[i], original, decoded)) {
throw new Error(
`Cannot safely encode argument: ${params.names[i]} (${original}) of type ${
params.types[i]
}. (Possible type overflow or other encoding error)`,
);
}
}
}
protected _lookupEthersInterface(functionSignature: string): ethers.Interface {
const ethersInterface = this._ethersInterfacesByFunctionSignature[functionSignature];
if (_.isUndefined(ethersInterface)) {

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);

View File

@@ -1,4 +1,4 @@
import { DataItem } from 'ethereum-types';
import { DataItem } from '@0xproject/types';
import * as _ from 'lodash';
// tslint:disable-next-line:completed-docs

View File

@@ -1,114 +0,0 @@
import * as chai from 'chai';
import 'mocha';
import { BaseContract } from '../src';
const { expect } = chai;
describe('BaseContract', () => {
describe('strictArgumentEncodingCheck', () => {
it('works for simple types', () => {
BaseContract.strictArgumentEncodingCheck(
[{ name: 'to', type: 'address' }],
['0xe834ec434daba538cd1b9fe1582052b880bd7e63'],
);
});
it('works for array types', () => {
const inputAbi = [
{
name: 'takerAssetFillAmounts',
type: 'uint256[]',
},
];
const args = [
['9000000000000000000', '79000000000000000000', '979000000000000000000', '7979000000000000000000'],
];
BaseContract.strictArgumentEncodingCheck(inputAbi, args);
});
it('works for tuple/struct types', () => {
const inputAbi = [
{
components: [
{
name: 'makerAddress',
type: 'address',
},
{
name: 'takerAddress',
type: 'address',
},
{
name: 'feeRecipientAddress',
type: 'address',
},
{
name: 'senderAddress',
type: 'address',
},
{
name: 'makerAssetAmount',
type: 'uint256',
},
{
name: 'takerAssetAmount',
type: 'uint256',
},
{
name: 'makerFee',
type: 'uint256',
},
{
name: 'takerFee',
type: 'uint256',
},
{
name: 'expirationTimeSeconds',
type: 'uint256',
},
{
name: 'salt',
type: 'uint256',
},
{
name: 'makerAssetData',
type: 'bytes',
},
{
name: 'takerAssetData',
type: 'bytes',
},
],
name: 'order',
type: 'tuple',
},
];
const args = [
{
makerAddress: '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb',
takerAddress: '0x0000000000000000000000000000000000000000',
feeRecipientAddress: '0xe834ec434daba538cd1b9fe1582052b880bd7e63',
senderAddress: '0x0000000000000000000000000000000000000000',
makerAssetAmount: '0',
takerAssetAmount: '200000000000000000000',
makerFee: '1000000000000000000',
takerFee: '1000000000000000000',
expirationTimeSeconds: '1532563026',
salt: '59342956082154660870994022243365949771115859664887449740907298019908621891376',
makerAssetData: '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48',
takerAssetData: '0xf47261b00000000000000000000000001d7022f5b17d2f8b695918fb48fa1089c9f85401',
},
];
BaseContract.strictArgumentEncodingCheck(inputAbi, args);
});
it('throws for integer overflows', () => {
expect(() =>
BaseContract.strictArgumentEncodingCheck([{ name: 'amount', type: 'uint8' }], ['256']),
).to.throw();
});
it('throws for fixed byte array overflows', () => {
expect(() =>
BaseContract.strictArgumentEncodingCheck([{ name: 'hash', type: 'bytes8' }], ['0x001122334455667788']),
).to.throw();
});
});
});

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,8 +1,7 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "."
"outDir": "lib"
},
"include": ["src/**/*", "test/**/*"]
}

View File

@@ -1,101 +1,4 @@
[
{
"timestamp": 1537369748,
"version": "2.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"version": "2.0.0",
"changes": [
{
"note": "Change `OrderConfigRequest` to use BigNumber instead of string for relevant fields.",
"pr": 1058
}
],
"timestamp": 1536142250
},
{
"version": "2.0.0-rc.2",
"changes": [
{
"note": "Dependencies updated"
}
],
"timestamp": 1535377027
},
{
"version": "2.0.0-rc.1",
"changes": [
{
"note": "Updated for SRA v2",
"pr": 974
},
{
"note": "Stopped exporting `Order` type",
"pr": 924
}
],
"timestamp": 1535133899
},
{
"timestamp": 1534210131,
"version": "1.0.5",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532619515,
"version": "1.0.4",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532614997,
"version": "1.0.3",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532605697,
"version": "1.0.2",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532357734,
"version": "1.0.1",
"changes": [
{
"note": "Dependencies updated"
}
]
},
{
"timestamp": 1532043000,
"version": "1.0.0",
"changes": [
{
"note":
"Remove `WebSocketOrderbookChannel` from the public interface and replace with `orderbookChannelFactory`"
}
]
},
{
"timestamp": 1531919263,
"version": "0.6.17",

View File

@@ -1,51 +1,10 @@
<!--
changelogUtils.file is auto-generated using the monorepo-scripts package. Don't edit directly.
This file is auto-generated using the monorepo-scripts package. Don't edit directly.
Edit the package's CHANGELOG.json file only.
-->
CHANGELOG
## v2.0.1 - _September 19, 2018_
* Dependencies updated
## v2.0.0 - _September 5, 2018_
* Change `OrderConfigRequest` to use BigNumber instead of string for relevant fields. (#1058)
## v2.0.0-rc.2 - _August 27, 2018_
* Dependencies updated
## v2.0.0-rc.1 - _August 24, 2018_
* Updated for SRA v2 (#974)
* Stopped exporting `Order` type (#924)
## v1.0.5 - _August 14, 2018_
* Dependencies updated
## v1.0.4 - _July 26, 2018_
* Dependencies updated
## v1.0.3 - _July 26, 2018_
* Dependencies updated
## v1.0.2 - _July 26, 2018_
* Dependencies updated
## v1.0.1 - _July 23, 2018_
* Dependencies updated
## v1.0.0 - _July 20, 2018_
* Remove `WebSocketOrderbookChannel` from the public interface and replace with `orderbookChannelFactory`
## v0.6.17 - _July 18, 2018_
* Dependencies updated

View File

@@ -1,6 +1,6 @@
{
"name": "@0xproject/connect",
"version": "2.0.1",
"version": "0.6.17",
"engines": {
"node": ">=6.12"
},
@@ -15,21 +15,28 @@
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build": "tsc -b",
"clean": "shx rm -rf lib test_temp generated_docs",
"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 .",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js --exit",
"test": "run-s copy_test_fixtures run_mocha",
"rebuild_and_test": "run-s clean build test",
"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",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
"docs:stage": "node scripts/stage_docs.js",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
"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": {
"postpublish": {
"assets": []
"assets": [],
"docPublishConfigs": {
"s3BucketPath": "s3://doc-jsons/connect/",
"s3StagingBucketPath": "s3://staging-doc-jsons/connect/"
}
}
},
"repository": {
@@ -43,41 +50,38 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
"dependencies": {
"@0xproject/assert": "^1.0.8",
"@0xproject/json-schemas": "^1.0.1",
"@0xproject/order-utils": "^1.0.2",
"@0xproject/types": "^1.0.1",
"@0xproject/typescript-typings": "^2.0.0",
"@0xproject/utils": "^1.0.8",
"lodash": "^4.17.5",
"query-string": "^5.0.1",
"sinon": "^4.0.0",
"uuid": "^3.3.2",
"websocket": "^1.0.25"
"@0xproject/assert": "^0.2.14",
"@0xproject/json-schemas": "^0.8.3",
"@0xproject/types": "^0.8.2",
"@0xproject/typescript-typings": "^0.4.3",
"@0xproject/utils": "^0.7.3",
"isomorphic-fetch": "2.2.1",
"lodash": "4.17.10",
"query-string": "4.3.4",
"websocket": "1.0.25"
},
"devDependencies": {
"@0xproject/tslint-config": "^1.0.7",
"@types/fetch-mock": "^6.0.3",
"@0xproject/monorepo-scripts": "^0.2.2",
"@0xproject/tslint-config": "^0.4.21",
"@types/fetch-mock": "5.12.2",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
"@types/query-string": "^5.0.1",
"@types/sinon": "^2.2.2",
"@types/uuid": "^3.4.3",
"@types/websocket": "^0.0.39",
"async-child-process": "^1.1.1",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"copyfiles": "^2.0.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.0.1",
"shx": "^0.2.2",
"tslint": "5.11.0",
"typedoc": "0.12.0",
"typescript": "3.0.1"
"@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",
"typescript": "2.7.1"
},
"publishConfig": {
"access": "public"

View File

@@ -1,38 +1,44 @@
import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas';
import { SignedOrder } from '@0xproject/types';
import { fetchAsync } from '@0xproject/utils';
import 'isomorphic-fetch';
import * as _ from 'lodash';
import * as queryString from 'query-string';
import { schemas as clientSchemas } from './schemas/schemas';
import {
APIOrder,
AssetPairsRequestOpts,
AssetPairsResponse,
Client,
FeeRecipientsResponse,
FeesRequest,
FeesResponse,
HttpRequestOptions,
HttpRequestType,
OrderbookRequest,
OrderbookResponse,
OrderConfigRequest,
OrderConfigResponse,
OrdersRequestOpts,
OrdersResponse,
PagedRequestOpts,
RequestOpts,
TokenPairsItem,
TokenPairsRequestOpts,
} from './types';
import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers';
const TRAILING_SLASHES_REGEX = /\/+$/;
const DEFAULT_PAGED_REQUEST_OPTS: PagedRequestOpts = {
page: 1,
perPage: 100,
};
/**
* This mapping defines how an option property name gets converted into an HTTP request query field
*/
const OPTS_TO_QUERY_FIELD_MAP = {
perPage: 'per_page',
};
/**
* This class includes all the functionality related to interacting with a set of HTTP endpoints
* that implement the standard relayer API v0
*/
export class HttpClient implements Client {
private readonly _apiEndpointUrl: string;
private _apiEndpointUrl: string;
/**
* Format parameters to be appended to http requests into query string form
*/
@@ -41,8 +47,12 @@ export class HttpClient implements Client {
if (_.isUndefined(params) || _.isEmpty(params)) {
return '';
}
// format params into a form the api expects
const formattedParams = _.mapKeys(params, (value: any, key: string) => {
return _.get(OPTS_TO_QUERY_FIELD_MAP, key, key);
});
// stringify the formatted object
const stringifiedParams = queryString.stringify(params);
const stringifiedParams = queryString.stringify(formattedParams);
return `?${stringifiedParams}`;
}
/**
@@ -55,40 +65,34 @@ export class HttpClient implements Client {
this._apiEndpointUrl = url.replace(TRAILING_SLASHES_REGEX, ''); // remove trailing slashes
}
/**
* Retrieve assetData pair info from the API
* @param requestOpts Options specifying assetData information to retrieve, page information, and network id.
* @return The resulting AssetPairsResponse that match the request
* Retrieve token pair info from the API
* @param requestOpts Options specifying token information to retrieve and page information, defaults to { page: 1, perPage: 100 }
* @return The resulting TokenPairsItems that match the request
*/
public async getAssetPairsAsync(
requestOpts?: RequestOpts & AssetPairsRequestOpts & PagedRequestOpts,
): Promise<AssetPairsResponse> {
public async getTokenPairsAsync(requestOpts?: TokenPairsRequestOpts & PagedRequestOpts): Promise<TokenPairsItem[]> {
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.assetPairsRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.tokenPairsRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
params: requestOpts,
params: _.defaults({}, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
};
const responseJson = await this._requestAsync('/asset_pairs', HttpRequestType.Get, httpRequestOpts);
const assetDataPairs = relayerResponseJsonParsers.parseAssetDataPairsJson(responseJson);
return assetDataPairs;
const responseJson = await this._requestAsync('/token_pairs', HttpRequestType.Get, httpRequestOpts);
const tokenPairs = relayerResponseJsonParsers.parseTokenPairsJson(responseJson);
return tokenPairs;
}
/**
* Retrieve orders from the API
* @param requestOpts Options specifying orders to retrieve and page information, page information, and network id.
* @return The resulting OrdersResponse that match the request
* @param requestOpts Options specifying orders to retrieve and page information, defaults to { page: 1, perPage: 100 }
* @return The resulting SignedOrders that match the request
*/
public async getOrdersAsync(
requestOpts?: RequestOpts & OrdersRequestOpts & PagedRequestOpts,
): Promise<OrdersResponse> {
public async getOrdersAsync(requestOpts?: OrdersRequestOpts & PagedRequestOpts): Promise<SignedOrder[]> {
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.ordersRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
params: requestOpts,
params: _.defaults({}, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
};
const responseJson = await this._requestAsync(`/orders`, HttpRequestType.Get, httpRequestOpts);
const orders = relayerResponseJsonParsers.parseOrdersJson(responseJson);
@@ -97,37 +101,30 @@ export class HttpClient implements Client {
/**
* Retrieve a specific order from the API
* @param orderHash An orderHash generated from the desired order
* @return The APIOrder that matches the supplied orderHash
* @return The SignedOrder that matches the supplied orderHash
*/
public async getOrderAsync(orderHash: string, requestOpts?: RequestOpts): Promise<APIOrder> {
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
public async getOrderAsync(orderHash: string): Promise<SignedOrder> {
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
const httpRequestOpts = {
params: requestOpts,
};
const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get, httpRequestOpts);
const order = relayerResponseJsonParsers.parseAPIOrderJson(responseJson);
const responseJson = await this._requestAsync(`/order/${orderHash}`, HttpRequestType.Get);
const order = relayerResponseJsonParsers.parseOrderJson(responseJson);
return order;
}
/**
* Retrieve an orderbook from the API
* @param request An OrderbookRequest instance describing the specific orderbook to retrieve
* @param requestOpts Options specifying page information, and network id.
* @param requestOpts Options specifying page information, defaults to { page: 1, perPage: 100 }
* @return The resulting OrderbookResponse that matches the request
*/
public async getOrderbookAsync(
request: OrderbookRequest,
requestOpts?: RequestOpts & PagedRequestOpts,
requestOpts?: PagedRequestOpts,
): Promise<OrderbookResponse> {
assert.doesConformToSchema('request', request, clientSchemas.orderBookRequestSchema);
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
params: _.defaults({}, request, requestOpts),
params: _.defaults({}, request, requestOpts, DEFAULT_PAGED_REQUEST_OPTS),
};
const responseJson = await this._requestAsync('/orderbook', HttpRequestType.Get, httpRequestOpts);
const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(responseJson);
@@ -135,55 +132,28 @@ export class HttpClient implements Client {
}
/**
* Retrieve fee information from the API
* @param request A OrderConfigRequest instance describing the specific fees to retrieve
* @param requestOpts Options specifying network id.
* @return The resulting OrderConfigResponse that matches the request
* @param request A FeesRequest instance describing the specific fees to retrieve
* @return The resulting FeesResponse that matches the request
*/
public async getOrderConfigAsync(
request: OrderConfigRequest,
requestOpts?: RequestOpts,
): Promise<OrderConfigResponse> {
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
assert.doesConformToSchema('request', request, clientSchemas.orderConfigRequestSchema);
public async getFeesAsync(request: FeesRequest): Promise<FeesResponse> {
assert.doesConformToSchema('request', request, clientSchemas.feesRequestSchema);
const httpRequestOpts = {
params: requestOpts,
payload: request,
};
const responseJson = await this._requestAsync('/order_config', HttpRequestType.Get, httpRequestOpts);
const fees = relayerResponseJsonParsers.parseOrderConfigResponseJson(responseJson);
const responseJson = await this._requestAsync('/fees', HttpRequestType.Post, httpRequestOpts);
const fees = relayerResponseJsonParsers.parseFeesResponseJson(responseJson);
return fees;
}
/**
* Retrieve the list of fee recipient addresses used by the relayer.
* @param requestOpts Options specifying page information, and network id.
* @return The resulting FeeRecipientsResponse
*/
public async getFeeRecipientsAsync(requestOpts?: RequestOpts & PagedRequestOpts): Promise<FeeRecipientsResponse> {
if (!_.isUndefined(requestOpts)) {
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.pagedRequestOptsSchema);
assert.doesConformToSchema('requestOpts', requestOpts, clientSchemas.requestOptsSchema);
}
const httpRequestOpts = {
params: requestOpts,
};
const feeRecipients = await this._requestAsync('/fee_recipients', HttpRequestType.Get, httpRequestOpts);
assert.doesConformToSchema('feeRecipients', feeRecipients, schemas.relayerApiFeeRecipientsResponseSchema);
return feeRecipients;
}
/**
* Submit a signed order to the API
* @param signedOrder A SignedOrder instance to submit
* @param requestOpts Options specifying network id.
*/
public async submitOrderAsync(signedOrder: SignedOrder, requestOpts?: RequestOpts): Promise<void> {
public async submitOrderAsync(signedOrder: SignedOrder): Promise<void> {
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
const httpRequestOpts = {
params: requestOpts,
const requestOpts = {
payload: signedOrder,
};
await this._requestAsync('/order', HttpRequestType.Post, httpRequestOpts);
await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
}
private async _requestAsync(
path: string,
@@ -197,7 +167,7 @@ export class HttpClient implements Client {
const headers = new Headers({
'content-type': 'application/json',
});
const response = await fetchAsync(url, {
const response = await fetch(url, {
method: requestType,
body: JSON.stringify(payload),
headers,

View File

@@ -1,23 +1,20 @@
export { HttpClient } from './http_client';
export { ordersChannelFactory } from './orders_channel_factory';
export { WebSocketOrderbookChannel } from './ws_orderbook_channel';
export {
Client,
OrderConfigRequest,
OrderConfigResponse,
OrdersChannel,
OrdersChannelHandler,
OrdersChannelSubscriptionOpts,
FeesRequest,
FeesResponse,
OrderbookChannel,
OrderbookChannelHandler,
OrderbookChannelSubscriptionOpts,
OrderbookRequest,
OrderbookResponse,
OrdersRequestOpts,
PagedRequestOpts,
AssetPairsRequestOpts,
RequestOpts,
AssetPairsResponse,
FeeRecipientsResponse,
APIOrder,
OrdersResponse,
PaginatedCollection,
TokenPairsItem,
TokenPairsRequestOpts,
TokenTradeInfo,
WebSocketOrderbookChannelConfig,
} from './types';
export { SignedOrder } from '@0xproject/types';
export { ECSignature, Order, SignedOrder } from '@0xproject/types';

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);

View File

@@ -0,0 +1,8 @@
import { postpublishUtils } from '@0xproject/monorepo-scripts';
import * as packageJSON from '../package.json';
import * as tsConfigJSON from '../tsconfig.json';
const cwd = `${__dirname}/..`;
// tslint:disable-next-line:no-floating-promises
postpublishUtils.publishDocsToStagingAsync(packageJSON, tsConfigJSON, cwd);

View File

@@ -1,29 +0,0 @@
import * as WebSocket from 'websocket';
import { OrdersChannel, OrdersChannelHandler } from './types';
import { assert } from './utils/assert';
import { WebSocketOrdersChannel } from './ws_orders_channel';
export const ordersChannelFactory = {
/**
* Instantiates a new WebSocketOrdersChannel instance
* @param url The relayer API base WS url you would like to interact with
* @param handler An OrdersChannelHandler instance that responds to various
* channel updates
* @return An OrdersChannel Promise
*/
async createWebSocketOrdersChannelAsync(url: string, handler: OrdersChannelHandler): Promise<OrdersChannel> {
assert.isUri('url', url);
assert.isOrdersChannelHandler('handler', handler);
return new Promise<OrdersChannel>((resolve, reject) => {
const client = new WebSocket.w3cwebsocket(url);
client.onopen = () => {
const ordersChannel = new WebSocketOrdersChannel(client, handler);
resolve(ordersChannel);
};
client.onerror = err => {
reject(err);
};
});
},
};

View File

@@ -1,8 +0,0 @@
export const assetPairsRequestOptsSchema = {
id: '/AssetPairsRequestOpts',
type: 'object',
properties: {
assetDataA: { $ref: '/hexSchema' },
assetDataB: { $ref: '/hexSchema' },
},
};

View File

@@ -0,0 +1,26 @@
export const feesRequestSchema = {
id: '/FeesRequest',
type: 'object',
properties: {
exchangeContractAddress: { $ref: '/Address' },
maker: { $ref: '/Address' },
taker: { $ref: '/Address' },
makerTokenAddress: { $ref: '/Address' },
takerTokenAddress: { $ref: '/Address' },
makerTokenAmount: { $ref: '/Number' },
takerTokenAmount: { $ref: '/Number' },
expirationUnixTimestampSec: { $ref: '/Number' },
salt: { $ref: '/Number' },
},
required: [
'exchangeContractAddress',
'maker',
'taker',
'makerTokenAddress',
'takerTokenAddress',
'makerTokenAmount',
'takerTokenAmount',
'expirationUnixTimestampSec',
'salt',
],
};

View File

@@ -1,24 +0,0 @@
export const orderConfigRequestSchema = {
id: '/OrderConfigRequest',
type: 'object',
properties: {
makerAddress: { $ref: '/addressSchema' },
takerAddress: { $ref: '/addressSchema' },
makerAssetAmount: { $ref: '/numberSchema' },
takerAssetAmount: { $ref: '/numberSchema' },
makerAssetData: { $ref: '/hexSchema' },
takerAssetData: { $ref: '/hexSchema' },
exchangeAddress: { $ref: '/addressSchema' },
expirationTimeSeconds: { $ref: '/numberSchema' },
},
required: [
'makerAddress',
'takerAddress',
'makerAssetAmount',
'takerAssetAmount',
'makerAssetData',
'takerAssetData',
'exchangeAddress',
'expirationTimeSeconds',
],
};

View File

@@ -2,8 +2,8 @@ export const orderBookRequestSchema = {
id: '/OrderBookRequest',
type: 'object',
properties: {
baseAssetData: { $ref: '/hexSchema' },
quoteAssetData: { $ref: '/hexSchema' },
baseTokenAddress: { $ref: '/Address' },
quoteTokenAddress: { $ref: '/Address' },
},
required: ['baseAssetData', 'quoteAssetData'],
required: ['baseTokenAddress', 'quoteTokenAddress'],
};

View File

@@ -2,18 +2,15 @@ export const ordersRequestOptsSchema = {
id: '/OrdersRequestOpts',
type: 'object',
properties: {
makerAssetProxyId: { $ref: '/hexSchema' },
takerAssetProxyId: { $ref: '/hexSchema' },
makerAssetAddress: { $ref: '/addressSchema' },
takerAssetAddress: { $ref: '/addressSchema' },
exchangeAddress: { $ref: '/addressSchema' },
senderAddress: { $ref: '/addressSchema' },
makerAssetData: { $ref: '/hexSchema' },
takerAssetData: { $ref: '/hexSchema' },
traderAssetData: { $ref: '/hexSchema' },
makerAddress: { $ref: '/addressSchema' },
takerAddress: { $ref: '/addressSchema' },
traderAddress: { $ref: '/addressSchema' },
feeRecipientAddress: { $ref: '/addressSchema' },
exchangeContractAddress: { $ref: '/Address' },
tokenAddress: { $ref: '/Address' },
makerTokenAddress: { $ref: '/Address' },
takerTokenAddress: { $ref: '/Address' },
tokenA: { $ref: '/Address' },
tokenB: { $ref: '/Address' },
maker: { $ref: '/Address' },
taker: { $ref: '/Address' },
trader: { $ref: '/Address' },
feeRecipient: { $ref: '/Address' },
},
};

View File

@@ -1,7 +0,0 @@
export const requestOptsSchema = {
id: '/RequestOpts',
type: 'object',
properties: {
networkId: { type: 'number' },
},
};

View File

@@ -1,15 +1,15 @@
import { assetPairsRequestOptsSchema } from './asset_pairs_request_opts_schema';
import { orderConfigRequestSchema } from './order_config_request_schema';
import { feesRequestSchema } from './fees_request_schema';
import { orderBookRequestSchema } from './orderbook_request_schema';
import { ordersRequestOptsSchema } from './orders_request_opts_schema';
import { pagedRequestOptsSchema } from './paged_request_opts_schema';
import { requestOptsSchema } from './request_opts_schema';
import { tokenPairsRequestOptsSchema } from './token_pairs_request_opts_schema';
import { webSocketOrderbookChannelConfigSchema } from './websocket_orderbook_channel_config_schema';
export const schemas = {
orderConfigRequestSchema,
feesRequestSchema,
orderBookRequestSchema,
ordersRequestOptsSchema,
pagedRequestOptsSchema,
requestOptsSchema,
assetPairsRequestOptsSchema,
tokenPairsRequestOptsSchema,
webSocketOrderbookChannelConfigSchema,
};

View File

@@ -0,0 +1,8 @@
export const tokenPairsRequestOptsSchema = {
id: '/TokenPairsRequestOpts',
type: 'object',
properties: {
tokenA: { $ref: '/Address' },
tokenB: { $ref: '/Address' },
},
};

View File

@@ -0,0 +1,10 @@
export const webSocketOrderbookChannelConfigSchema = {
id: '/WebSocketOrderbookChannelConfig',
type: 'object',
properties: {
heartbeatIntervalMs: {
type: 'number',
minimum: 10,
},
},
};

View File

@@ -1,56 +1,81 @@
import { SignedOrder } from '@0xproject/types';
import { ECSignature, Order, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
export interface Client {
getAssetPairsAsync: (
requestOpts?: AssetPairsRequestOpts & PagedRequestOpts,
) => Promise<PaginatedCollection<AssetPairsItem>>;
getOrdersAsync: (requestOpts?: OrdersRequestOpts & PagedRequestOpts) => Promise<PaginatedCollection<APIOrder>>;
getOrderAsync: (orderHash: string) => Promise<APIOrder>;
getTokenPairsAsync: (requestOpts?: TokenPairsRequestOpts & PagedRequestOpts) => Promise<TokenPairsItem[]>;
getOrdersAsync: (requestOpts?: OrdersRequestOpts & PagedRequestOpts) => Promise<SignedOrder[]>;
getOrderAsync: (orderHash: string) => Promise<SignedOrder>;
getOrderbookAsync: (request: OrderbookRequest, requestOpts?: PagedRequestOpts) => Promise<OrderbookResponse>;
getOrderConfigAsync: (request: OrderConfigRequest) => Promise<OrderConfigResponse>;
getFeeRecipientsAsync: (requestOpts?: PagedRequestOpts) => Promise<FeeRecipientsResponse>;
getFeesAsync: (request: FeesRequest) => Promise<FeesResponse>;
submitOrderAsync: (signedOrder: SignedOrder) => Promise<void>;
}
export interface OrdersChannel {
subscribe: (subscriptionOpts: OrdersChannelSubscriptionOpts) => void;
export interface OrderbookChannel {
subscribe: (subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler) => void;
close: () => void;
}
/**
* baseAssetData: The address of assetData designated as the baseToken in the currency pair calculation of price
* quoteAssetData: The address of assetData designated as the quoteToken in the currency pair calculation of price
* heartbeatIntervalMs: Interval in milliseconds that the orderbook channel should ping the underlying websocket. Default: 15000
*/
export interface WebSocketOrderbookChannelConfig {
heartbeatIntervalMs?: number;
}
/**
* baseTokenAddress: The address of token designated as the baseToken in the currency pair calculation of price
* quoteTokenAddress: The address of token designated as the quoteToken in the currency pair calculation of price
* snapshot: If true, a snapshot of the orderbook will be sent before the updates to the orderbook
* limit: Maximum number of bids and asks in orderbook snapshot
*/
export interface OrdersChannelSubscriptionOpts {
baseAssetData: string;
quoteAssetData: string;
export interface OrderbookChannelSubscriptionOpts {
baseTokenAddress: string;
quoteTokenAddress: string;
snapshot: boolean;
limit: number;
}
export interface OrdersChannelHandler {
onUpdate: (channel: OrdersChannel, subscriptionOpts: OrdersChannelSubscriptionOpts, orders: APIOrder[]) => void;
onError: (channel: OrdersChannel, err: Error, subscriptionOpts?: OrdersChannelSubscriptionOpts) => void;
onClose: (channel: OrdersChannel) => void;
export interface OrderbookChannelHandler {
onSnapshot: (
channel: OrderbookChannel,
subscriptionOpts: OrderbookChannelSubscriptionOpts,
snapshot: OrderbookResponse,
) => void;
onUpdate: (
channel: OrderbookChannel,
subscriptionOpts: OrderbookChannelSubscriptionOpts,
order: SignedOrder,
) => void;
onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
}
export type OrdersChannelMessage = UpdateOrdersChannelMessage | UnknownOrdersChannelMessage;
export type OrderbookChannelMessage =
| SnapshotOrderbookChannelMessage
| UpdateOrderbookChannelMessage
| UnknownOrderbookChannelMessage;
export enum OrdersChannelMessageTypes {
export enum OrderbookChannelMessageTypes {
Snapshot = 'snapshot',
Update = 'update',
Unknown = 'unknown',
}
export interface UpdateOrdersChannelMessage {
type: OrdersChannelMessageTypes.Update;
requestId: string;
payload: APIOrder[];
export interface SnapshotOrderbookChannelMessage {
type: OrderbookChannelMessageTypes.Snapshot;
requestId: number;
payload: OrderbookResponse;
}
export interface UnknownOrdersChannelMessage {
type: OrdersChannelMessageTypes.Unknown;
requestId: string;
export interface UpdateOrderbookChannelMessage {
type: OrderbookChannelMessageTypes.Update;
requestId: number;
payload: SignedOrder;
}
export interface UnknownOrderbookChannelMessage {
type: OrderbookChannelMessageTypes.Unknown;
requestId: number;
payload: undefined;
}
@@ -65,86 +90,60 @@ export enum WebsocketClientEventType {
ConnectFailed = 'connectFailed',
}
export type OrdersResponse = PaginatedCollection<APIOrder>;
export interface APIOrder {
order: SignedOrder;
metaData: object;
export interface TokenPairsRequestOpts {
tokenA?: string;
tokenB?: string;
}
export interface AssetPairsRequestOpts {
assetDataA?: string;
assetDataB?: string;
export interface TokenPairsItem {
tokenA: TokenTradeInfo;
tokenB: TokenTradeInfo;
}
export type AssetPairsResponse = PaginatedCollection<AssetPairsItem>;
export interface AssetPairsItem {
assetDataA: Asset;
assetDataB: Asset;
}
export interface Asset {
assetData: string;
export interface TokenTradeInfo {
address: string;
minAmount: BigNumber;
maxAmount: BigNumber;
precision: number;
}
export interface OrdersRequestOpts {
makerAssetProxyId?: string;
takerAssetProxyId?: string;
makerAssetAddress?: string;
takerAssetAddress?: string;
exchangeAddress?: string;
senderAddress?: string;
makerAssetData?: string;
takerAssetData?: string;
makerAddress?: string;
takerAddress?: string;
traderAddress?: string;
feeRecipientAddress?: string;
exchangeContractAddress?: string;
tokenAddress?: string;
makerTokenAddress?: string;
takerTokenAddress?: string;
maker?: string;
taker?: string;
trader?: string;
feeRecipient?: string;
}
export interface OrderbookRequest {
baseAssetData: string;
quoteAssetData: string;
baseTokenAddress: string;
quoteTokenAddress: string;
}
export interface OrderbookResponse {
bids: PaginatedCollection<APIOrder>;
asks: PaginatedCollection<APIOrder>;
bids: SignedOrder[];
asks: SignedOrder[];
}
export interface PaginatedCollection<T> {
total: number;
page: number;
perPage: number;
records: T[];
export interface FeesRequest {
exchangeContractAddress: string;
maker: string;
taker: string;
makerTokenAddress: string;
takerTokenAddress: string;
makerTokenAmount: BigNumber;
takerTokenAmount: BigNumber;
expirationUnixTimestampSec: BigNumber;
salt: BigNumber;
}
export interface OrderConfigRequest {
makerAddress: string;
takerAddress: string;
makerAssetAmount: BigNumber;
takerAssetAmount: BigNumber;
makerAssetData: string;
takerAssetData: string;
exchangeAddress: string;
expirationTimeSeconds: BigNumber;
}
export interface OrderConfigResponse {
export interface FeesResponse {
feeRecipient: string;
makerFee: BigNumber;
takerFee: BigNumber;
feeRecipientAddress: string;
senderAddress: string;
}
export type FeeRecipientsResponse = PaginatedCollection<string>;
export interface RequestOpts {
networkId?: number;
}
export interface PagedRequestOpts {

View File

@@ -1,25 +0,0 @@
import { assert as sharedAssert } from '@0xproject/assert';
// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here
// tslint:disable-next-line:no-unused-variable
import { Schema, schemas } from '@0xproject/json-schemas';
// tslint:disable-next-line:no-unused-variable
import { ECSignature } from '@0xproject/types';
// tslint:disable-next-line:no-unused-variable
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
export const assert = {
...sharedAssert,
isOrdersChannelSubscriptionOpts(variableName: string, subscriptionOpts: any): void {
sharedAssert.doesConformToSchema(
variableName,
subscriptionOpts,
schemas.relayerApiOrdersChannelSubscribePayload,
);
},
isOrdersChannelHandler(variableName: string, handler: any): void {
sharedAssert.isFunction(`${variableName}.onUpdate`, _.get(handler, 'onUpdate'));
sharedAssert.isFunction(`${variableName}.onError`, _.get(handler, 'onError'));
sharedAssert.isFunction(`${variableName}.onClose`, _.get(handler, 'onClose'));
},
};

View File

@@ -0,0 +1,37 @@
import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas';
import * as _ from 'lodash';
import { OrderbookChannelMessage, OrderbookChannelMessageTypes } from '../types';
import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
export const orderbookChannelMessageParser = {
parse(utf8Data: string): OrderbookChannelMessage {
const messageObj = JSON.parse(utf8Data);
const type: string = _.get(messageObj, 'type');
assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
assert.isString('type', type);
switch (type) {
case OrderbookChannelMessageTypes.Snapshot: {
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
const orderbookJson = messageObj.payload;
const orderbook = relayerResponseJsonParsers.parseOrderbookResponseJson(orderbookJson);
return _.assign(messageObj, { payload: orderbook });
}
case OrderbookChannelMessageTypes.Update: {
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
const orderJson = messageObj.payload;
const order = relayerResponseJsonParsers.parseOrderJson(orderJson);
return _.assign(messageObj, { payload: order });
}
default: {
return {
type: OrderbookChannelMessageTypes.Unknown,
requestId: 0,
payload: undefined,
};
}
}
},
};

View File

@@ -1,37 +0,0 @@
import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas';
import * as _ from 'lodash';
import { OrdersChannelMessage, OrdersChannelMessageTypes } from '../types';
import { relayerResponseJsonParsers } from './relayer_response_json_parsers';
export const ordersChannelMessageParser = {
parse(utf8Data: string): OrdersChannelMessage {
// parse the message
const messageObj = JSON.parse(utf8Data);
// ensure we have a type parameter to switch on
const type: string = _.get(messageObj, 'type');
assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
assert.isString('type', type);
// ensure we have a request id for the resulting message
const requestId: string = _.get(messageObj, 'requestId');
assert.assert(!_.isUndefined(requestId), `Message is missing a requestId parameter: ${utf8Data}`);
assert.isString('requestId', requestId);
switch (type) {
case OrdersChannelMessageTypes.Update: {
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrdersChannelUpdateSchema);
const ordersJson = messageObj.payload;
const orders = relayerResponseJsonParsers.parseAPIOrdersJson(ordersJson);
return _.assign(messageObj, { payload: orders });
}
default: {
return {
type: OrdersChannelMessageTypes.Unknown,
requestId,
payload: undefined,
};
}
}
},
};

View File

@@ -1,50 +1,38 @@
import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas';
import { orderParsingUtils } from '@0xproject/order-utils';
import { SignedOrder } from '@0xproject/types';
import * as _ from 'lodash';
import {
APIOrder,
AssetPairsItem,
AssetPairsResponse,
OrderbookResponse,
OrderConfigResponse,
OrdersResponse,
} from '../types';
import { FeesResponse, OrderbookResponse, TokenPairsItem } from '../types';
import { typeConverters } from './type_converters';
export const relayerResponseJsonParsers = {
parseAssetDataPairsJson(json: any): AssetPairsResponse {
assert.doesConformToSchema('assetDataPairsResponse', json, schemas.relayerApiAssetDataPairsResponseSchema);
return { ...json, records: relayerResponseJsonParsers.parseAssetPairsItemsJson(json.records) };
},
parseAssetPairsItemsJson(json: any): AssetPairsItem[] {
return json.map((assetDataPair: any) => {
return orderParsingUtils.convertStringsFieldsToBigNumbers(assetDataPair, [
'assetDataA.minAmount',
'assetDataA.maxAmount',
'assetDataB.minAmount',
'assetDataB.maxAmount',
parseTokenPairsJson(json: any): TokenPairsItem[] {
assert.doesConformToSchema('tokenPairs', json, schemas.relayerApiTokenPairsResponseSchema);
return json.map((tokenPair: any) => {
return typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
'tokenA.minAmount',
'tokenA.maxAmount',
'tokenB.minAmount',
'tokenB.maxAmount',
]);
});
},
parseOrdersJson(json: any): OrdersResponse {
assert.doesConformToSchema('relayerApiOrdersResponse', json, schemas.relayerApiOrdersResponseSchema);
return { ...json, records: relayerResponseJsonParsers.parseAPIOrdersJson(json.records) };
parseOrdersJson(json: any): SignedOrder[] {
assert.doesConformToSchema('orders', json, schemas.signedOrdersSchema);
return json.map((order: object) => typeConverters.convertOrderStringFieldsToBigNumber(order));
},
parseAPIOrdersJson(json: any): APIOrder[] {
return json.map(relayerResponseJsonParsers.parseAPIOrderJson.bind(relayerResponseJsonParsers));
},
parseAPIOrderJson(json: any): APIOrder {
assert.doesConformToSchema('relayerApiOrder', json, schemas.relayerApiOrderSchema);
return typeConverters.convertAPIOrderStringFieldsToBigNumber(json);
parseOrderJson(json: any): SignedOrder {
assert.doesConformToSchema('order', json, schemas.signedOrderSchema);
return typeConverters.convertOrderStringFieldsToBigNumber(json);
},
parseOrderbookResponseJson(json: any): OrderbookResponse {
assert.doesConformToSchema('orderBookResponse', json, schemas.relayerApiOrderbookResponseSchema);
assert.doesConformToSchema('orderBook', json, schemas.relayerApiOrderBookResponseSchema);
return typeConverters.convertOrderbookStringFieldsToBigNumber(json);
},
parseOrderConfigResponseJson(json: any): OrderConfigResponse {
assert.doesConformToSchema('orderConfigResponse', json, schemas.relayerApiOrderConfigResponseSchema);
return orderParsingUtils.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
parseFeesResponseJson(json: any): FeesResponse {
assert.doesConformToSchema('fees', json, schemas.relayerApiFeesResponseSchema);
return typeConverters.convertStringsFieldsToBigNumbers(json, ['makerFee', 'takerFee']);
},
};

View File

@@ -1,26 +1,30 @@
import { orderParsingUtils } from '@0xproject/order-utils';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { APIOrder } from '../types';
export const typeConverters = {
convertOrderbookStringFieldsToBigNumber(orderbook: any): any {
const bids = _.get(orderbook, 'bids', []);
const asks = _.get(orderbook, 'asks', []);
const convertedBids = {
...bids,
records: bids.records.map((order: any) => typeConverters.convertAPIOrderStringFieldsToBigNumber(order)),
};
const convertedAsks = {
...asks,
records: asks.records.map((order: any) => typeConverters.convertAPIOrderStringFieldsToBigNumber(order)),
};
return {
bids: convertedBids,
asks: convertedAsks,
bids: bids.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
asks: asks.map((order: any) => this.convertOrderStringFieldsToBigNumber(order)),
};
},
convertAPIOrderStringFieldsToBigNumber(apiOrder: any): APIOrder {
return { ...apiOrder, order: orderParsingUtils.convertOrderStringFieldsToBigNumber(apiOrder.order) };
convertOrderStringFieldsToBigNumber(order: any): any {
return this.convertStringsFieldsToBigNumbers(order, [
'makerTokenAmount',
'takerTokenAmount',
'makerFee',
'takerFee',
'expirationUnixTimestampSec',
'salt',
]);
},
convertStringsFieldsToBigNumbers(obj: any, fields: string[]): any {
const result = _.assign({}, obj);
_.each(fields, field => {
_.update(result, field, (value: string) => new BigNumber(value));
});
return result;
},
};

View File

@@ -0,0 +1,166 @@
import { assert } from '@0xproject/assert';
import { schemas } from '@0xproject/json-schemas';
import * as _ from 'lodash';
import * as WebSocket from 'websocket';
import { schemas as clientSchemas } from './schemas/schemas';
import {
OrderbookChannel,
OrderbookChannelHandler,
OrderbookChannelMessageTypes,
OrderbookChannelSubscriptionOpts,
WebsocketClientEventType,
WebsocketConnectionEventType,
WebSocketOrderbookChannelConfig,
} from './types';
import { orderbookChannelMessageParser } from './utils/orderbook_channel_message_parser';
const DEFAULT_HEARTBEAT_INTERVAL_MS = 15000;
const MINIMUM_HEARTBEAT_INTERVAL_MS = 10;
/**
* This class includes all the functionality related to interacting with a websocket endpoint
* that implements the standard relayer API v0
*/
export class WebSocketOrderbookChannel implements OrderbookChannel {
private _apiEndpointUrl: string;
private _client: WebSocket.client;
private _connectionIfExists?: WebSocket.connection;
private _heartbeatTimerIfExists?: NodeJS.Timer;
private _subscriptionCounter = 0;
private _heartbeatIntervalMs: number;
/**
* Instantiates a new WebSocketOrderbookChannel instance
* @param url The relayer API base WS url you would like to interact with
* @param config The configuration object. Look up the type for the description.
* @return An instance of WebSocketOrderbookChannel
*/
constructor(url: string, config?: WebSocketOrderbookChannelConfig) {
assert.isUri('url', url);
if (!_.isUndefined(config)) {
assert.doesConformToSchema('config', config, clientSchemas.webSocketOrderbookChannelConfigSchema);
}
this._apiEndpointUrl = url;
this._heartbeatIntervalMs =
_.isUndefined(config) || _.isUndefined(config.heartbeatIntervalMs)
? DEFAULT_HEARTBEAT_INTERVAL_MS
: config.heartbeatIntervalMs;
this._client = new WebSocket.client();
}
/**
* Subscribe to orderbook snapshots and updates from the websocket
* @param subscriptionOpts An OrderbookChannelSubscriptionOpts instance describing which
* token pair to subscribe to
* @param handler An OrderbookChannelHandler instance that responds to various
* channel updates
*/
public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
assert.doesConformToSchema(
'subscriptionOpts',
subscriptionOpts,
schemas.relayerApiOrderbookChannelSubscribePayload,
);
assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
assert.isFunction('handler.onError', _.get(handler, 'onError'));
assert.isFunction('handler.onClose', _.get(handler, 'onClose'));
this._subscriptionCounter += 1;
const subscribeMessage = {
type: 'subscribe',
channel: 'orderbook',
requestId: this._subscriptionCounter,
payload: subscriptionOpts,
};
this._getConnection((error, connection) => {
if (!_.isUndefined(error)) {
handler.onError(this, subscriptionOpts, error);
} else if (!_.isUndefined(connection) && connection.connected) {
connection.on(WebsocketConnectionEventType.Error, wsError => {
handler.onError(this, subscriptionOpts, wsError);
});
connection.on(WebsocketConnectionEventType.Close, (code: number, desc: string) => {
handler.onClose(this, subscriptionOpts);
});
connection.on(WebsocketConnectionEventType.Message, message => {
this._handleWebSocketMessage(subscribeMessage.requestId, subscriptionOpts, message, handler);
});
connection.sendUTF(JSON.stringify(subscribeMessage));
}
});
}
/**
* Close the websocket and stop receiving updates
*/
public close(): void {
if (!_.isUndefined(this._connectionIfExists)) {
this._connectionIfExists.close();
}
if (!_.isUndefined(this._heartbeatTimerIfExists)) {
clearInterval(this._heartbeatTimerIfExists);
}
}
private _getConnection(callback: (error?: Error, connection?: WebSocket.connection) => void): void {
if (!_.isUndefined(this._connectionIfExists) && this._connectionIfExists.connected) {
callback(undefined, this._connectionIfExists);
} else {
this._client.on(WebsocketClientEventType.Connect, connection => {
this._connectionIfExists = connection;
if (this._heartbeatIntervalMs >= MINIMUM_HEARTBEAT_INTERVAL_MS) {
this._heartbeatTimerIfExists = setInterval(() => {
connection.ping('');
}, this._heartbeatIntervalMs);
} else {
callback(
new Error(
`Heartbeat interval is ${
this._heartbeatIntervalMs
}ms which is less than the required minimum of ${MINIMUM_HEARTBEAT_INTERVAL_MS}ms`,
),
undefined,
);
}
callback(undefined, this._connectionIfExists);
});
this._client.on(WebsocketClientEventType.ConnectFailed, error => {
callback(error, undefined);
});
this._client.connect(this._apiEndpointUrl);
}
}
private _handleWebSocketMessage(
requestId: number,
subscriptionOpts: OrderbookChannelSubscriptionOpts,
message: WebSocket.IMessage,
handler: OrderbookChannelHandler,
): void {
if (!_.isUndefined(message.utf8Data)) {
try {
const utf8Data = message.utf8Data;
const parserResult = orderbookChannelMessageParser.parse(utf8Data);
if (parserResult.requestId === requestId) {
switch (parserResult.type) {
case OrderbookChannelMessageTypes.Snapshot: {
handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
break;
}
case OrderbookChannelMessageTypes.Update: {
handler.onUpdate(this, subscriptionOpts, parserResult.payload);
break;
}
default: {
handler.onError(
this,
subscriptionOpts,
new Error(`Message has missing a type parameter: ${utf8Data}`),
);
}
}
}
} catch (error) {
handler.onError(this, subscriptionOpts, error);
}
} else {
handler.onError(this, subscriptionOpts, new Error(`Message does not contain utf8Data`));
}
}
}

View File

@@ -1,101 +0,0 @@
import * as _ from 'lodash';
import { v4 as uuid } from 'uuid';
import * as WebSocket from 'websocket';
import { OrdersChannel, OrdersChannelHandler, OrdersChannelMessageTypes, OrdersChannelSubscriptionOpts } from './types';
import { assert } from './utils/assert';
import { ordersChannelMessageParser } from './utils/orders_channel_message_parser';
export interface OrdersChannelSubscriptionOptsMap {
[key: string]: OrdersChannelSubscriptionOpts;
}
/**
* This class includes all the functionality related to interacting with a websocket endpoint
* that implements the standard relayer API v0
*/
export class WebSocketOrdersChannel implements OrdersChannel {
private readonly _client: WebSocket.w3cwebsocket;
private readonly _handler: OrdersChannelHandler;
private readonly _subscriptionOptsMap: OrdersChannelSubscriptionOptsMap = {};
/**
* Instantiates a new WebSocketOrdersChannel instance
* @param client A WebSocket client
* @param handler An OrdersChannelHandler instance that responds to various
* channel updates
* @return An instance of WebSocketOrdersChannel
*/
constructor(client: WebSocket.w3cwebsocket, handler: OrdersChannelHandler) {
assert.isOrdersChannelHandler('handler', handler);
// set private members
this._client = client;
this._handler = handler;
// attach client callbacks
this._client.onerror = err => {
this._handler.onError(this, err);
};
this._client.onclose = () => {
this._handler.onClose(this);
};
this._client.onmessage = message => {
this._handleWebSocketMessage(message);
};
}
/**
* Subscribe to orderbook snapshots and updates from the websocket
* @param subscriptionOpts An OrdersChannelSubscriptionOpts instance describing which
* assetData pair to subscribe to
*/
public subscribe(subscriptionOpts: OrdersChannelSubscriptionOpts): void {
assert.isOrdersChannelSubscriptionOpts('subscriptionOpts', subscriptionOpts);
assert.assert(this._client.readyState === WebSocket.w3cwebsocket.OPEN, 'WebSocket connection is closed');
const requestId = uuid();
this._subscriptionOptsMap[requestId] = subscriptionOpts;
const subscribeMessage = {
type: 'subscribe',
channel: 'orders',
requestId,
payload: subscriptionOpts,
};
this._client.send(JSON.stringify(subscribeMessage));
}
/**
* Close the websocket and stop receiving updates
*/
public close(): void {
this._client.close();
}
private _handleWebSocketMessage(message: any): void {
if (_.isUndefined(message.data)) {
this._handler.onError(this, new Error(`Message does not contain data. Url: ${this._client.url}`));
return;
}
try {
const data = message.data;
const parserResult = ordersChannelMessageParser.parse(data);
const subscriptionOpts = this._subscriptionOptsMap[parserResult.requestId];
if (_.isUndefined(subscriptionOpts)) {
this._handler.onError(
this,
new Error(`Message has unknown requestId. Url: ${this._client.url} Message: ${data}`),
);
return;
}
switch (parserResult.type) {
case OrdersChannelMessageTypes.Update: {
this._handler.onUpdate(this, subscriptionOpts, parserResult.payload);
break;
}
default: {
this._handler.onError(
this,
new Error(`Message has unknown type parameter. Url: ${this._client.url} Message: ${data}`),
subscriptionOpts,
);
}
}
} catch (error) {
this._handler.onError(this, error);
}
}
}

View File

@@ -1,21 +0,0 @@
{
"total": 43,
"page": 1,
"perPage": 100,
"records": [
{
"assetDataA": {
"minAmount": "0",
"maxAmount": "10000000000000000000",
"precision": 5,
"assetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d"
},
"assetDataB": {
"minAmount": "0",
"maxAmount": "50000000000000000000",
"precision": 5,
"assetData": "0x0257179264389b814a946f3e92105513705ca6b990"
}
}
]
}

View File

@@ -1,25 +0,0 @@
import { BigNumber } from '@0xproject/utils';
import { AssetPairsResponse } from '../../../src/types';
export const assetDataPairsResponse: AssetPairsResponse = {
total: 43,
page: 1,
perPage: 100,
records: [
{
assetDataA: {
minAmount: new BigNumber('0'),
maxAmount: new BigNumber('10000000000000000000'),
precision: 5,
assetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
},
assetDataB: {
minAmount: new BigNumber('0'),
maxAmount: new BigNumber('50000000000000000000'),
precision: 5,
assetData: '0x0257179264389b814a946f3e92105513705ca6b990',
},
},
],
};

View File

@@ -1,10 +0,0 @@
{
"total": 3,
"page": 1,
"perPage": 10,
"records": [
"0x6ec92694ea172ebc430c30fa31de87620967a082",
"0x9e56625509c2f60af937f23b7b532600390e8c8b",
"0xa2b31dacf30a9c50ca473337c01d8a201ae33e32"
]
}

View File

@@ -1,12 +0,0 @@
import { FeeRecipientsResponse } from '../../../src/types';
export const feeRecipientsResponse: FeeRecipientsResponse = {
total: 3,
page: 1,
perPage: 10,
records: [
'0x6ec92694ea172ebc430c30fa31de87620967a082',
'0x9e56625509c2f60af937f23b7b532600390e8c8b',
'0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
],
};

View File

@@ -0,0 +1,5 @@
{
"feeRecipient": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
"makerFee": "10000000000000000",
"takerFee": "30000000000000000"
}

View File

@@ -0,0 +1,9 @@
import { BigNumber } from '@0xproject/utils';
import { FeesResponse } from '../../../src/types';
export const feesResponse: FeesResponse = {
feeRecipient: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
makerFee: new BigNumber('10000000000000000'),
takerFee: new BigNumber('30000000000000000'),
};

View File

@@ -1,19 +1,19 @@
{
"order": {
"makerAddress": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
"takerAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
"feeRecipientAddress": "0xb046140686d052fff581f63f8136cce132e857da",
"senderAddress": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
"makerAssetAmount": "10000000000000000",
"takerAssetAmount": "20000000000000000",
"makerFee": "100000000000000",
"takerFee": "200000000000000",
"expirationTimeSeconds": "1532560590",
"salt": "1532559225",
"makerAssetData": "0xf47261b04c32345ced77393b3530b1eed0f346429d",
"takerAssetData": "0x0257179264389b814a946f3e92105513705ca6b990",
"exchangeAddress": "0x12459c951127e0c374ff9105dda097662a027093",
"signature": "0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33"
},
"metaData": {}
"maker": "0x9e56625509c2f60af937f23b7b532600390e8c8b",
"taker": "0xa2b31dacf30a9c50ca473337c01d8a201ae33e32",
"makerFee": "100000000000000",
"takerFee": "200000000000000",
"makerTokenAmount": "10000000000000000",
"takerTokenAmount": "20000000000000000",
"makerTokenAddress": "0x323b5d4c32345ced77393b3530b1eed0f346429d",
"takerTokenAddress": "0xef7fff64389b814a946f3e92105513705ca6b990",
"salt": "256",
"feeRecipient": "0xb046140686d052fff581f63f8136cce132e857da",
"exchangeContractAddress": "0x12459c951127e0c374ff9105dda097662a027093",
"expirationUnixTimestampSec": "42",
"ecSignature": {
"v": 27,
"r": "0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33",
"s": "0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254"
}
}

View File

@@ -1,21 +1,21 @@
import { BigNumber } from '@0xproject/utils';
export const orderResponse = {
order: {
makerAddress: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
takerAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
feeRecipientAddress: '0xb046140686d052fff581f63f8136cce132e857da',
senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
makerAssetAmount: new BigNumber('10000000000000000'),
takerAssetAmount: new BigNumber('20000000000000000'),
makerFee: new BigNumber('100000000000000'),
takerFee: new BigNumber('200000000000000'),
expirationTimeSeconds: new BigNumber('1532560590'),
salt: new BigNumber('1532559225'),
makerAssetData: '0xf47261b04c32345ced77393b3530b1eed0f346429d',
takerAssetData: '0x0257179264389b814a946f3e92105513705ca6b990',
exchangeAddress: '0x12459c951127e0c374ff9105dda097662a027093',
signature: '0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
maker: '0x9e56625509c2f60af937f23b7b532600390e8c8b',
taker: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
makerFee: new BigNumber('100000000000000'),
takerFee: new BigNumber('200000000000000'),
makerTokenAmount: new BigNumber('10000000000000000'),
takerTokenAmount: new BigNumber('20000000000000000'),
makerTokenAddress: '0x323b5d4c32345ced77393b3530b1eed0f346429d',
takerTokenAddress: '0xef7fff64389b814a946f3e92105513705ca6b990',
salt: new BigNumber('256'),
feeRecipient: '0xb046140686d052fff581f63f8136cce132e857da',
exchangeContractAddress: '0x12459c951127e0c374ff9105dda097662a027093',
expirationUnixTimestampSec: new BigNumber('42'),
ecSignature: {
v: 27,
r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
},
metaData: {},
};

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