diff options
author | Bryan Stitt <bryan@stitthappens.com> | 2018-11-12 07:13:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-12 07:13:09 +0800 |
commit | 0101cd73aa87fecc72cc816c6c26af028afd569c (patch) | |
tree | 637a87a6ea98e59036cf2537367186b8b4133c9d | |
parent | 6ef628613e658e90a06cbe5e34f119082e06678e (diff) | |
parent | 397b4e289015f9bb0831c1a0ce6fee601670b487 (diff) | |
download | dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.tar dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.tar.gz dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.tar.bz2 dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.tar.lz dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.tar.xz dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.tar.zst dexon-sol-tools-0101cd73aa87fecc72cc816c6c26af028afd569c.zip |
Merge branch 'development' into patch-1
158 files changed, 2191 insertions, 930 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml index 7811b9b34..0ab512f58 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: - restore_cache: keys: - repo-{{ .Environment.CIRCLE_SHA1 }} - - run: cd packages/website && yarn build + - run: cd packages/website && yarn build:prod test-contracts-ganache: docker: - image: circleci/node:9 diff --git a/package.json b/package.json index c786e7f19..e598ac2d3 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ }, { "path": "packages/instant/public/main.bundle.js", - "maxSize": "500kB" + "maxSize": "1000kB" } ], "ci": { diff --git a/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json index a404ed481..7d9cb8312 100644 --- a/packages/0x.js/CHANGELOG.json +++ b/packages/0x.js/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "2.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "2.0.0", "changes": [ { diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index 939ada519..d312b2c9b 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.1 - _November 9, 2018_ + + * Dependencies updated + ## v2.0.0 - _October 18, 2018_ * Add support for `eth_signTypedData`. (#1102) diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index bfc29128c..38478980f 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "2.0.0", + "version": "2.0.1", "engines": { "node": ">=6.12" }, @@ -42,12 +42,12 @@ }, "license": "Apache-2.0", "devDependencies": { - "@0x/abi-gen": "^1.0.14", - "@0x/abi-gen-wrappers": "^1.0.1", - "@0x/contract-addresses": "^1.0.1", - "@0x/dev-utils": "^1.0.13", - "@0x/migrations": "^2.0.0", - "@0x/tslint-config": "^1.0.9", + "@0x/abi-gen": "^1.0.15", + "@0x/abi-gen-wrappers": "^1.0.2", + "@0x/contract-addresses": "^1.1.0", + "@0x/dev-utils": "^1.0.14", + "@0x/migrations": "^2.0.1", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", "@types/node": "*", @@ -73,18 +73,18 @@ "webpack": "^4.20.2" }, "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/base-contract": "^3.0.2", - "@0x/contract-wrappers": "^3.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/order-watcher": "^2.2.0", - "@0x/subproviders": "^2.1.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/assert": "^1.0.15", + "@0x/base-contract": "^3.0.3", + "@0x/contract-wrappers": "^3.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/order-watcher": "^2.2.1", + "@0x/subproviders": "^2.1.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/web3-provider-engine": "^14.0.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethers": "~4.0.4", "lodash": "^4.17.5", "web3-provider-engine": "14.0.6" diff --git a/packages/abi-gen-wrappers/CHANGELOG.json b/packages/abi-gen-wrappers/CHANGELOG.json index 211d79d26..c3273536b 100644 --- a/packages/abi-gen-wrappers/CHANGELOG.json +++ b/packages/abi-gen-wrappers/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.1", "changes": [ diff --git a/packages/abi-gen-wrappers/CHANGELOG.md b/packages/abi-gen-wrappers/CHANGELOG.md index df72b112c..18bd28cb8 100644 --- a/packages/abi-gen-wrappers/CHANGELOG.md +++ b/packages/abi-gen-wrappers/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.2 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.1 - _October 18, 2018_ * Dependencies updated diff --git a/packages/abi-gen-wrappers/package.json b/packages/abi-gen-wrappers/package.json index b8010a8a7..a4316449f 100644 --- a/packages/abi-gen-wrappers/package.json +++ b/packages/abi-gen-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0x/abi-gen-wrappers", - "version": "1.0.1", + "version": "1.0.2", "engines": { "node": ">=6.12" }, @@ -30,17 +30,17 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen-wrappers/README.md", "devDependencies": { - "@0x/abi-gen": "^1.0.14", - "@0x/tslint-config": "^1.0.9", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", - "ethereum-types": "^1.1.1", + "@0x/abi-gen": "^1.0.15", + "@0x/tslint-config": "^1.0.10", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", + "ethereum-types": "^1.1.2", "ethers": "~4.0.4", "lodash": "^4.17.5", "shx": "^0.2.2" }, "dependencies": { - "@0x/base-contract": "^3.0.2" + "@0x/base-contract": "^3.0.3" }, "publishConfig": { "access": "public" diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index 4bec24183..658a997f4 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.15", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.14", "changes": [ diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index 61c4d8487..21fda1656 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.15 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.14 - _October 18, 2018_ * Dependencies updated diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index c78d4f269..5367c9c29 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -1,6 +1,6 @@ { "name": "@0x/abi-gen", - "version": "1.0.14", + "version": "1.0.15", "engines": { "node": ">=6.12" }, @@ -31,10 +31,10 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md", "dependencies": { - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", "chalk": "^2.3.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "glob": "^7.1.2", "handlebars": "^4.0.11", "lodash": "^4.17.5", @@ -45,7 +45,7 @@ "yargs": "^10.0.3" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/glob": "5.0.35", "@types/handlebars": "^4.0.36", "@types/mkdirp": "^0.5.1", diff --git a/packages/assert/CHANGELOG.json b/packages/assert/CHANGELOG.json index f5a77103b..82c0938cf 100644 --- a/packages/assert/CHANGELOG.json +++ b/packages/assert/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.15", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.14", "changes": [ diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md index 78b5da851..7d0895eca 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.15 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.14 - _October 18, 2018_ * Dependencies updated diff --git a/packages/assert/package.json b/packages/assert/package.json index a96f65258..cc2fdaae9 100644 --- a/packages/assert/package.json +++ b/packages/assert/package.json @@ -1,6 +1,6 @@ { "name": "@0x/assert", - "version": "1.0.14", + "version": "1.0.15", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", "@types/valid-url": "^1.0.2", @@ -44,9 +44,9 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/json-schemas": "^2.0.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", + "@0x/json-schemas": "^2.0.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", "lodash": "^4.17.5", "valid-url": "^1.0.9" }, diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json index 2a775075f..df4531063 100644 --- a/packages/asset-buyer/CHANGELOG.json +++ b/packages/asset-buyer/CHANGELOG.json @@ -29,7 +29,8 @@ "note": "Lower default expiry buffer from 5 minutes to 2 minutes", "pr": 1217 } - ] + ], + "timestamp": 1541740904 }, { "version": "2.1.0", diff --git a/packages/asset-buyer/CHANGELOG.md b/packages/asset-buyer/CHANGELOG.md index 8845e7041..d6220767e 100644 --- a/packages/asset-buyer/CHANGELOG.md +++ b/packages/asset-buyer/CHANGELOG.md @@ -5,6 +5,15 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.2.0 - _November 9, 2018_ + + * `getAssetBuyerForProvidedOrders` factory function now takes 3 args instead of 4 (#1187) + * the `OrderProvider` now requires a new method `getAvailableMakerAssetDatasAsync` and the `StandardRelayerAPIOrderProvider` requires the network id at init. (#1203) + * No longer require that provided orders all have the same maker and taker asset data (#1197) + * Fix bug where `BuyQuoteInfo` objects could return `totalEthAmount` and `feeEthAmount` that were not whole numbers (#1207) + * Fix bug where default values for `AssetBuyer` public facing methods could get overriden by `undefined` values (#1207) + * Lower default expiry buffer from 5 minutes to 2 minutes (#1217) + ## v2.1.0 - _October 18, 2018_ * Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts` @@ -13,6 +22,7 @@ CHANGELOG * Add `gasLimit` and `gasPrice` as optional properties on `BuyQuoteExecutionOpts` (#1116) * Add `docs:json` command to package.json (#1139) * Add missing types to public interface (#1139) + * Throw `SignatureRequestDenied` and `TransactionValueTooLow` errors when executing buy (#1147) ## v2.0.0 - _October 4, 2018_ diff --git a/packages/asset-buyer/package.json b/packages/asset-buyer/package.json index dd0668632..fc2414952 100644 --- a/packages/asset-buyer/package.json +++ b/packages/asset-buyer/package.json @@ -1,6 +1,6 @@ { "name": "@0x/asset-buyer", - "version": "2.1.0", + "version": "2.2.0", "engines": { "node": ">=6.12" }, @@ -36,21 +36,21 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/asset-buyer/README.md", "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/connect": "^3.0.2", - "@0x/contract-wrappers": "^3.0.0", - "@0x/json-schemas": "^2.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/subproviders": "^2.1.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", - "ethereum-types": "^1.1.1", + "@0x/assert": "^1.0.15", + "@0x/connect": "^3.0.3", + "@0x/contract-wrappers": "^3.0.1", + "@0x/json-schemas": "^2.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/subproviders": "^2.1.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", + "ethereum-types": "^1.1.2", "lodash": "^4.17.10" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "^4.14.116", "@types/mocha": "^2.2.42", "@types/node": "*", diff --git a/packages/base-contract/CHANGELOG.json b/packages/base-contract/CHANGELOG.json index 166c04408..f8a1051d6 100644 --- a/packages/base-contract/CHANGELOG.json +++ b/packages/base-contract/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "3.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "3.0.2", "changes": [ diff --git a/packages/base-contract/CHANGELOG.md b/packages/base-contract/CHANGELOG.md index 2981b5ef8..d544f4f99 100644 --- a/packages/base-contract/CHANGELOG.md +++ b/packages/base-contract/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.0.3 - _November 9, 2018_ + + * Dependencies updated + ## v3.0.2 - _October 18, 2018_ * Dependencies updated diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json index 520dff5f9..efa4a5c81 100644 --- a/packages/base-contract/package.json +++ b/packages/base-contract/package.json @@ -1,6 +1,6 @@ { "name": "@0x/base-contract", - "version": "3.0.2", + "version": "3.0.3", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "4.14.104", "chai": "^4.0.1", "make-promises-safe": "^1.1.0", @@ -40,10 +40,10 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", - "ethereum-types": "^1.1.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", + "ethereum-types": "^1.1.2", "ethers": "~4.0.4", "lodash": "^4.17.5" }, diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json index 3412831d5..52ad9d575 100644 --- a/packages/connect/CHANGELOG.json +++ b/packages/connect/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "3.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "3.0.2", "changes": [ diff --git a/packages/connect/CHANGELOG.md b/packages/connect/CHANGELOG.md index d20b5a5f7..8e38e16de 100644 --- a/packages/connect/CHANGELOG.md +++ b/packages/connect/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.0.3 - _November 9, 2018_ + + * Dependencies updated + ## v3.0.2 - _October 18, 2018_ * Dependencies updated diff --git a/packages/connect/package.json b/packages/connect/package.json index de846e58b..527ac5bdc 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -1,6 +1,6 @@ { "name": "@0x/connect", - "version": "3.0.2", + "version": "3.0.3", "engines": { "node": ">=6.12" }, @@ -44,12 +44,12 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md", "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/json-schemas": "^2.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", + "@0x/assert": "^1.0.15", + "@0x/json-schemas": "^2.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", "lodash": "^4.17.5", "query-string": "^5.0.1", "sinon": "^4.0.0", @@ -57,7 +57,7 @@ "websocket": "^1.0.25" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/fetch-mock": "^6.0.3", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json index 2727cd42b..307d73545 100644 --- a/packages/contract-addresses/CHANGELOG.json +++ b/packages/contract-addresses/CHANGELOG.json @@ -6,7 +6,8 @@ "pr": 1192, "note": "Update Forwarder addresses" } - ] + ], + "timestamp": 1541740904 }, { "version": "1.0.1", diff --git a/packages/contract-addresses/CHANGELOG.md b/packages/contract-addresses/CHANGELOG.md index 82c22f2e4..20e52cd8b 100644 --- a/packages/contract-addresses/CHANGELOG.md +++ b/packages/contract-addresses/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.0 - _November 9, 2018_ + + * Update Forwarder addresses (#1192) + ## v1.0.1 - _October 18, 2018_ * Initial release (#1105) diff --git a/packages/contract-addresses/package.json b/packages/contract-addresses/package.json index 3136d571b..47258edef 100644 --- a/packages/contract-addresses/package.json +++ b/packages/contract-addresses/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-addresses", - "version": "1.0.1", + "version": "1.1.0", "engines": { "node": ">=6.12" }, diff --git a/packages/contract-artifacts/CHANGELOG.json b/packages/contract-artifacts/CHANGELOG.json index e6a6d02c0..8833255ed 100644 --- a/packages/contract-artifacts/CHANGELOG.json +++ b/packages/contract-artifacts/CHANGELOG.json @@ -6,7 +6,8 @@ "pr": 1192, "note": "Update Forwarder artifact" } - ] + ], + "timestamp": 1541740904 }, { "version": "1.0.1", diff --git a/packages/contract-artifacts/CHANGELOG.md b/packages/contract-artifacts/CHANGELOG.md index 82c22f2e4..b3c399985 100644 --- a/packages/contract-artifacts/CHANGELOG.md +++ b/packages/contract-artifacts/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.0 - _November 9, 2018_ + + * Update Forwarder artifact (#1192) + ## v1.0.1 - _October 18, 2018_ * Initial release (#1105) diff --git a/packages/contract-artifacts/package.json b/packages/contract-artifacts/package.json index 53f5d3c47..9c25e3ac5 100644 --- a/packages/contract-artifacts/package.json +++ b/packages/contract-artifacts/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-artifacts", - "version": "1.0.1", + "version": "1.1.0", "engines": { "node": ">=6.12" }, diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 9ff372e33..0346b79b2 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -6,7 +6,8 @@ "note": "Fix bug in `ForwarderWrapper` where `feeRecipientAddress` was not correctly normalized.", "pr": 1178 } - ] + ], + "timestamp": 1541740904 }, { "version": "3.0.0", diff --git a/packages/contract-wrappers/CHANGELOG.md b/packages/contract-wrappers/CHANGELOG.md index 6f3005831..1fe903dd9 100644 --- a/packages/contract-wrappers/CHANGELOG.md +++ b/packages/contract-wrappers/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.0.1 - _November 9, 2018_ + + * Fix bug in `ForwarderWrapper` where `feeRecipientAddress` was not correctly normalized. (#1178) + ## v3.0.0 - _October 18, 2018_ * Add optional validation to the forwarder wrapper methods @@ -15,6 +19,8 @@ CHANGELOG * Removed `setProvider` method in top-level `ContractWrapper` class and added new `unsubscribeAll` method. (#1105) * Some properties and methods have been renamed. For example, some methods that previously could throw no longer can, and so their names have been updated accordingly. (#1105) * Removed ContractNotFound errors. Checking for this error was somewhat ineffecient. Relevant methods/functions now return the default error from web3-wrapper, which we feel provides enough information. (#1105) + * Add `ForwarderWrapperError` to public interface (#1147) + * Add `ContractWrapperError.SignatureRequestDenied` to public interface (#1147) ## v2.0.2 - _October 4, 2018_ diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 178675763..cb69bbd33 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-wrappers", - "version": "3.0.0", + "version": "3.0.1", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", @@ -37,10 +37,10 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/migrations": "^2.0.0", - "@0x/subproviders": "^2.1.0", - "@0x/tslint-config": "^1.0.9", + "@0x/dev-utils": "^1.0.14", + "@0x/migrations": "^2.0.1", + "@0x/subproviders": "^2.1.1", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", "@types/node": "*", @@ -65,18 +65,18 @@ "web3-provider-engine": "14.0.6" }, "dependencies": { - "@0x/abi-gen-wrappers": "^1.0.1", - "@0x/assert": "^1.0.14", - "@0x/contract-addresses": "^1.0.1", - "@0x/contract-artifacts": "^1.0.1", - "@0x/fill-scenarios": "^1.0.8", - "@0x/json-schemas": "^2.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", - "ethereum-types": "^1.1.1", + "@0x/abi-gen-wrappers": "^1.0.2", + "@0x/assert": "^1.0.15", + "@0x/contract-addresses": "^1.1.0", + "@0x/contract-artifacts": "^1.1.0", + "@0x/fill-scenarios": "^1.0.9", + "@0x/json-schemas": "^2.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-blockstream": "6.0.0", "ethereumjs-util": "^5.1.1", "ethers": "~4.0.4", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 4f24310e8..bf9bb4826 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "contracts", - "version": "2.1.50", + "version": "2.1.51", "engines": { "node": ">=6.12" }, @@ -45,12 +45,12 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md", "devDependencies": { - "@0x/abi-gen": "^1.0.14", - "@0x/dev-utils": "^1.0.13", - "@0x/sol-compiler": "^1.1.8", - "@0x/sol-cov": "^2.1.8", - "@0x/subproviders": "^2.1.0", - "@0x/tslint-config": "^1.0.9", + "@0x/abi-gen": "^1.0.15", + "@0x/dev-utils": "^1.0.14", + "@0x/sol-compiler": "^1.1.9", + "@0x/sol-cov": "^2.1.9", + "@0x/subproviders": "^2.1.1", + "@0x/tslint-config": "^1.0.10", "@types/bn.js": "^4.11.0", "@types/ethereumjs-abi": "^0.6.0", "@types/lodash": "4.14.104", @@ -71,15 +71,15 @@ "yargs": "^10.0.3" }, "dependencies": { - "@0x/base-contract": "^3.0.2", - "@0x/order-utils": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/base-contract": "^3.0.3", + "@0x/order-utils": "^2.0.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/js-combinatorics": "^0.5.29", "bn.js": "^4.11.8", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-abi": "0.6.5", "ethereumjs-util": "^5.1.1", "ethers": "~4.0.4", diff --git a/packages/dev-tools-pages/package.json b/packages/dev-tools-pages/package.json index ca13c1cc8..b1b89ac99 100644 --- a/packages/dev-tools-pages/package.json +++ b/packages/dev-tools-pages/package.json @@ -1,6 +1,6 @@ { "name": "@0x/dev-tools-pages", - "version": "0.0.2", + "version": "0.0.3", "engines": { "node": ">=6.12" }, @@ -16,7 +16,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@0x/react-shared": "^1.0.17", + "@0x/react-shared": "^1.0.18", "basscss": "^8.0.3", "bowser": "^1.9.3", "less": "^2.7.2", diff --git a/packages/dev-utils/CHANGELOG.json b/packages/dev-utils/CHANGELOG.json index fd5a8d446..269cdc934 100644 --- a/packages/dev-utils/CHANGELOG.json +++ b/packages/dev-utils/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.14", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "1.0.13", "changes": [ { diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index a6b60884e..ee614a904 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.14 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.13 - _October 18, 2018_ * Make web3-provider-engine types a 'dependency' so it's available to users of the library (#1105) diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 7c6bfde90..e1b3201d3 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0x/dev-utils", - "version": "1.0.13", + "version": "1.0.14", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", "make-promises-safe": "^1.1.0", @@ -41,14 +41,14 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/subproviders": "^2.1.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/subproviders": "^2.1.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/web3-provider-engine": "^14.0.0", "chai": "^4.0.1", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "lodash": "^4.17.5" }, "publishConfig": { diff --git a/packages/ethereum-types/CHANGELOG.json b/packages/ethereum-types/CHANGELOG.json index b042c4588..9db75ae9f 100644 --- a/packages/ethereum-types/CHANGELOG.json +++ b/packages/ethereum-types/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.1.2", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "1.1.1", "changes": [ { diff --git a/packages/ethereum-types/CHANGELOG.md b/packages/ethereum-types/CHANGELOG.md index 73ea54204..6ad7b4cc6 100644 --- a/packages/ethereum-types/CHANGELOG.md +++ b/packages/ethereum-types/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.2 - _November 9, 2018_ + + * Dependencies updated + ## v1.1.1 - _October 18, 2018_ * Add `JSONRPCResponseError` and error field on `JSONRPCResponsePayload`. (#1102) diff --git a/packages/ethereum-types/package.json b/packages/ethereum-types/package.json index 49b093bdd..1630344db 100644 --- a/packages/ethereum-types/package.json +++ b/packages/ethereum-types/package.json @@ -1,6 +1,6 @@ { "name": "ethereum-types", - "version": "1.1.1", + "version": "1.1.2", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/ethereum-types/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "make-promises-safe": "^1.1.0", "shx": "^0.2.2", "tslint": "5.11.0", diff --git a/packages/fill-scenarios/CHANGELOG.json b/packages/fill-scenarios/CHANGELOG.json index b9840957e..8aa4e78d3 100644 --- a/packages/fill-scenarios/CHANGELOG.json +++ b/packages/fill-scenarios/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "1.0.8", "changes": [ { diff --git a/packages/fill-scenarios/CHANGELOG.md b/packages/fill-scenarios/CHANGELOG.md index 20ef1322c..4ff28f82f 100644 --- a/packages/fill-scenarios/CHANGELOG.md +++ b/packages/fill-scenarios/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.9 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.8 - _October 18, 2018_ * Updated to use new @0xproject/contract-artifacts and @0xproject/abi-gen-wrappers packages (#1105) diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json index ae7fa02ad..e9ca077fb 100644 --- a/packages/fill-scenarios/package.json +++ b/packages/fill-scenarios/package.json @@ -1,6 +1,6 @@ { "name": "@0x/fill-scenarios", - "version": "1.0.8", + "version": "1.0.9", "description": "0x order fill scenario generator", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -20,7 +20,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/fill-scenarios/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/lodash": "4.14.104", "make-promises-safe": "^1.1.0", "shx": "^0.2.2", @@ -28,15 +28,15 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/abi-gen-wrappers": "^1.0.1", - "@0x/base-contract": "^3.0.2", - "@0x/contract-artifacts": "^1.0.1", - "@0x/order-utils": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", - "ethereum-types": "^1.1.1", + "@0x/abi-gen-wrappers": "^1.0.2", + "@0x/base-contract": "^3.0.3", + "@0x/contract-artifacts": "^1.1.0", + "@0x/order-utils": "^2.0.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", + "ethereum-types": "^1.1.2", "ethers": "~4.0.4", "lodash": "^4.17.5" }, diff --git a/packages/instant/package.json b/packages/instant/package.json index f90990649..3c87743c1 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -1,6 +1,6 @@ { "name": "@0x/instant", - "version": "0.0.3", + "version": "0.0.4", "engines": { "node": ">=6.12" }, @@ -45,15 +45,17 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md", "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/asset-buyer": "^2.1.0", - "@0x/json-schemas": "^2.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", - "ethereum-types": "^1.1.1", + "@0x/assert": "^1.0.15", + "@0x/asset-buyer": "^2.2.0", + "@0x/json-schemas": "^2.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/subproviders": "^2.1.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", + "copy-to-clipboard": "^3.0.8", + "ethereum-types": "^1.1.2", "lodash": "^4.17.10", "polished": "^2.2.0", "react": "^16.5.2", @@ -65,7 +67,7 @@ "ts-optchain": "^0.1.1" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@static/discharge": "https://github.com/0xProject/discharge.git", "@types/enzyme": "^3.1.14", "@types/enzyme-adapter-react-16": "^1.0.3", diff --git a/packages/instant/public/external.css b/packages/instant/public/external.css new file mode 100644 index 000000000..cab11112a --- /dev/null +++ b/packages/instant/public/external.css @@ -0,0 +1,25 @@ +/* + CSS file meant to represent an external (integrators) stylesheet and + help ensure that instant looks consistent across environments. +*/ + +button { + font-size: 50px; + height: 200px; + background-color: red; +} + +input { + padding: 100px; + font-size: 50px; + height: 100px; +} + +div { + padding: 3px; +} + +p { + background-color: green; + margin: 10px; +} diff --git a/packages/instant/public/index.html b/packages/instant/public/index.html index 033a125a4..f6c809e33 100644 --- a/packages/instant/public/index.html +++ b/packages/instant/public/index.html @@ -5,6 +5,7 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>0x Instant Dev Environment</title> + <link rel="stylesheet" href="/external.css"> <script type="text/javascript" src="/main.bundle.js" charset="utf-8"></script> <script type="text/javascript" src="https://unpkg.com/jsuri@1.3.1/Uri.js" charset="utf-8"></script> <script type="text/javascript" src="https://unpkg.com/bignumber.js@4.1.0/bignumber.js" charset="utf-8"></script> diff --git a/packages/instant/src/components/animations/position_animation.tsx b/packages/instant/src/components/animations/position_animation.tsx index 4bb21befb..8b3b294b7 100644 --- a/packages/instant/src/components/animations/position_animation.tsx +++ b/packages/instant/src/components/animations/position_animation.tsx @@ -1,5 +1,6 @@ -import { Keyframes } from 'styled-components'; +import { InterpolationValue } from 'styled-components'; +import { media, OptionallyScreenSpecific, stylesForMedia } from '../../style/media'; import { css, keyframes, styled } from '../../style/theme'; export interface TransitionInfo { @@ -51,30 +52,59 @@ export interface PositionAnimationSettings { right?: TransitionInfo; timingFunction: string; duration?: string; + position?: string; } -export interface PositionAnimationProps extends PositionAnimationSettings { - position: string; +const generatePositionAnimationCss = (positionSettings: PositionAnimationSettings) => { + return css` + animation-name: ${slideKeyframeGenerator( + positionSettings.position || 'relative', + positionSettings.top, + positionSettings.bottom, + positionSettings.left, + positionSettings.right, + )}; + animation-duration: ${positionSettings.duration || '0.3s'}; + animation-timing-function: ${positionSettings.timingFunction}; + animation-delay: 0s; + animation-iteration-count: 1; + animation-fill-mode: forwards; + position: ${positionSettings.position || 'relative'}; + width: 100%; + `; +}; + +export interface PositionAnimationProps { + positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>; + zIndex?: OptionallyScreenSpecific<number>; + height?: string; } +const defaultAnimation = (positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>) => { + const bestDefault = 'default' in positionSettings ? positionSettings.default : positionSettings; + return generatePositionAnimationCss(bestDefault); +}; +const animationForSize = ( + positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>, + sizeKey: 'sm' | 'md' | 'lg', + mediaFn: (...args: any[]) => InterpolationValue[], +) => { + // checking default makes sure we have a PositionAnimationSettings object + // and then we check to see if we have a setting for the specific `sizeKey` + const animationSettingsForSize = 'default' in positionSettings && positionSettings[sizeKey]; + return animationSettingsForSize && mediaFn`${generatePositionAnimationCss(animationSettingsForSize)}`; +}; + export const PositionAnimation = styled.div < PositionAnimationProps > ` - animation-name: ${props => - css` - ${slideKeyframeGenerator(props.position, props.top, props.bottom, props.left, props.right)}; - `}; - animation-duration: ${props => props.duration || '0.3s'}; - animation-timing-function: ${props => props.timingFunction}; - animation-delay: 0s; - animation-iteration-count: 1; - animation-fill-mode: forwards; - position: ${props => props.position}; - height: 100%; - width: 100%; + && { + ${props => props.zIndex && stylesForMedia<number>('z-index', props.zIndex)} + ${props => defaultAnimation(props.positionSettings)} + ${props => animationForSize(props.positionSettings, 'sm', media.small)} + ${props => animationForSize(props.positionSettings, 'md', media.medium)} + ${props => animationForSize(props.positionSettings, 'lg', media.large)} + ${props => (props.height ? `height: ${props.height};` : '')} + } `; - -PositionAnimation.defaultProps = { - position: 'relative', -}; diff --git a/packages/instant/src/components/animations/slide_animation.tsx b/packages/instant/src/components/animations/slide_animation.tsx index 66a314c7f..9adb1c674 100644 --- a/packages/instant/src/components/animations/slide_animation.tsx +++ b/packages/instant/src/components/animations/slide_animation.tsx @@ -1,22 +1,25 @@ import * as React from 'react'; +import { OptionallyScreenSpecific } from '../../style/media'; + import { PositionAnimation, PositionAnimationSettings } from './position_animation'; export type SlideAnimationState = 'slidIn' | 'slidOut' | 'none'; export interface SlideAnimationProps { - position: string; animationState: SlideAnimationState; - slideInSettings: PositionAnimationSettings; - slideOutSettings: PositionAnimationSettings; + slideInSettings: OptionallyScreenSpecific<PositionAnimationSettings>; + slideOutSettings: OptionallyScreenSpecific<PositionAnimationSettings>; + zIndex?: OptionallyScreenSpecific<number>; + height?: string; } export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => { if (props.animationState === 'none') { return <React.Fragment>{props.children}</React.Fragment>; } - const propsToUse = props.animationState === 'slidIn' ? props.slideInSettings : props.slideOutSettings; + const positionSettings = props.animationState === 'slidIn' ? props.slideInSettings : props.slideOutSettings; return ( - <PositionAnimation position={props.position} {...propsToUse}> + <PositionAnimation height={props.height} positionSettings={positionSettings} zIndex={props.zIndex}> {props.children} </PositionAnimation> ); diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index e6d50de96..877ab275c 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -1,4 +1,5 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; @@ -7,17 +8,17 @@ import { oc } from 'ts-optchain'; import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; import { ColorOption } from '../style/theme'; import { AffiliateInfo, ZeroExInstantError } from '../types'; -import { getBestAddress } from '../util/address'; -import { balanceUtil } from '../util/balance'; import { gasPriceEstimator } from '../util/gas_price_estimator'; import { util } from '../util/util'; import { Button } from './ui/button'; -import { Text } from './ui/text'; export interface BuyButtonProps { + accountAddress?: string; + accountEthBalanceInWei?: BigNumber; buyQuote?: BuyQuote; - assetBuyer?: AssetBuyer; + assetBuyer: AssetBuyer; + web3Wrapper: Web3Wrapper; affiliateInfo?: AffiliateInfo; onValidationPending: (buyQuote: BuyQuote) => void; onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; @@ -34,39 +35,41 @@ export class BuyButton extends React.Component<BuyButtonProps> { onBuyFailure: util.boundNoop, }; public render(): React.ReactNode { - const shouldDisableButton = _.isUndefined(this.props.buyQuote) || _.isUndefined(this.props.assetBuyer); + const { buyQuote, accountAddress } = this.props; + const shouldDisableButton = _.isUndefined(buyQuote) || _.isUndefined(accountAddress); return ( - <Button width="100%" onClick={this._handleClick} isDisabled={shouldDisableButton}> - <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px"> - Buy - </Text> + <Button + width="100%" + onClick={this._handleClick} + isDisabled={shouldDisableButton} + fontColor={ColorOption.white} + fontSize="20px" + > + Buy </Button> ); } private readonly _handleClick = async () => { // The button is disabled when there is no buy quote anyway. - const { buyQuote, assetBuyer, affiliateInfo } = this.props; - if (_.isUndefined(buyQuote) || _.isUndefined(assetBuyer)) { + const { buyQuote, assetBuyer, affiliateInfo, accountAddress, accountEthBalanceInWei, web3Wrapper } = this.props; + if (_.isUndefined(buyQuote) || _.isUndefined(accountAddress)) { return; } - this.props.onValidationPending(buyQuote); - const web3Wrapper = new Web3Wrapper(assetBuyer.provider); - const takerAddress = await getBestAddress(web3Wrapper); - - const hasSufficientEth = await balanceUtil.hasSufficientEth(takerAddress, buyQuote, web3Wrapper); + const ethNeededForBuy = buyQuote.worstCaseQuoteInfo.totalEthAmount; + // if we don't have a balance for the user, let the transaction through, it will be handled by the wallet + const hasSufficientEth = _.isUndefined(accountEthBalanceInWei) || accountEthBalanceInWei.gte(ethNeededForBuy); if (!hasSufficientEth) { this.props.onValidationFail(buyQuote, ZeroExInstantError.InsufficientETH); return; } - let txHash: string | undefined; const gasInfo = await gasPriceEstimator.getGasInfoAsync(); const feeRecipient = oc(affiliateInfo).feeRecipient(); try { txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { feeRecipient, - takerAddress, + takerAddress: accountAddress, gasPrice: gasInfo.gasPriceInWei, }); } catch (e) { @@ -81,7 +84,6 @@ export class BuyButton extends React.Component<BuyButtonProps> { } throw e; } - const startTimeUnix = new Date().getTime(); const expectedEndTimeUnix = startTimeUnix + gasInfo.estimatedTimeMs; this.props.onBuyProcessing(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix); @@ -94,7 +96,6 @@ export class BuyButton extends React.Component<BuyButtonProps> { } throw e; } - this.props.onBuySuccess(buyQuote, txHash); }; } diff --git a/packages/instant/src/components/buy_order_progress.tsx b/packages/instant/src/components/buy_order_progress.tsx index 7fe4e77e9..bc7319423 100644 --- a/packages/instant/src/components/buy_order_progress.tsx +++ b/packages/instant/src/components/buy_order_progress.tsx @@ -14,12 +14,12 @@ export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> = const { buyOrderState } = props; if ( - buyOrderState.processState === OrderProcessState.PROCESSING || - buyOrderState.processState === OrderProcessState.SUCCESS || - buyOrderState.processState === OrderProcessState.FAILURE + buyOrderState.processState === OrderProcessState.Processing || + buyOrderState.processState === OrderProcessState.Success || + buyOrderState.processState === OrderProcessState.Failure ) { const progress = buyOrderState.progress; - const hasEnded = buyOrderState.processState !== OrderProcessState.PROCESSING; + const hasEnded = buyOrderState.processState !== OrderProcessState.Processing; const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix; return ( <Container padding="20px 20px 0px 20px" width="100%"> diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx index 0d54d3187..6041bf4f5 100644 --- a/packages/instant/src/components/buy_order_state_buttons.tsx +++ b/packages/instant/src/components/buy_order_state_buttons.tsx @@ -1,4 +1,6 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as React from 'react'; import { ColorOption } from '../style/theme'; @@ -10,12 +12,14 @@ import { SecondaryButton } from './secondary_button'; import { Button } from './ui/button'; import { Flex } from './ui/flex'; -import { Text } from './ui/text'; export interface BuyOrderStateButtonProps { + accountAddress?: string; + accountEthBalanceInWei?: BigNumber; buyQuote?: BuyQuote; buyOrderProcessingState: OrderProcessState; - assetBuyer?: AssetBuyer; + assetBuyer: AssetBuyer; + web3Wrapper: Web3Wrapper; affiliateInfo?: AffiliateInfo; onViewTransaction: () => void; onValidationPending: (buyQuote: BuyQuote) => void; @@ -28,13 +32,11 @@ export interface BuyOrderStateButtonProps { } export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonProps> = props => { - if (props.buyOrderProcessingState === OrderProcessState.FAILURE) { + if (props.buyOrderProcessingState === OrderProcessState.Failure) { return ( <Flex justify="space-between"> - <Button width="48%" onClick={props.onRetry}> - <Text fontColor={ColorOption.white} fontWeight={600} fontSize="16px"> - Back - </Text> + <Button width="48%" onClick={props.onRetry} fontColor={ColorOption.white} fontSize="16px"> + Back </Button> <SecondaryButton width="48%" onClick={props.onViewTransaction}> Details @@ -42,18 +44,21 @@ export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonP </Flex> ); } else if ( - props.buyOrderProcessingState === OrderProcessState.SUCCESS || - props.buyOrderProcessingState === OrderProcessState.PROCESSING + props.buyOrderProcessingState === OrderProcessState.Success || + props.buyOrderProcessingState === OrderProcessState.Processing ) { return <SecondaryButton onClick={props.onViewTransaction}>View Transaction</SecondaryButton>; - } else if (props.buyOrderProcessingState === OrderProcessState.VALIDATING) { + } else if (props.buyOrderProcessingState === OrderProcessState.Validating) { return <PlacingOrderButton />; } return ( <BuyButton + accountAddress={props.accountAddress} + accountEthBalanceInWei={props.accountEthBalanceInWei} buyQuote={props.buyQuote} assetBuyer={props.assetBuyer} + web3Wrapper={props.web3Wrapper} affiliateInfo={props.affiliateInfo} onValidationPending={props.onValidationPending} onValidationFail={props.onValidationFail} diff --git a/packages/instant/src/components/css_reset.tsx b/packages/instant/src/components/css_reset.tsx new file mode 100644 index 000000000..0bef85389 --- /dev/null +++ b/packages/instant/src/components/css_reset.tsx @@ -0,0 +1,32 @@ +import { INJECTED_DIV_CLASS } from '../constants'; +import { createGlobalStyle } from '../style/theme'; + +export interface CSSResetProps {} + +/* +* Derived from +* https://github.com/jtrost/Complete-CSS-Reset +*/ +export const CSSReset = createGlobalStyle` + .${INJECTED_DIV_CLASS} { + a, abbr, area, article, aside, audio, b, bdo, blockquote, body, button, + canvas, caption, cite, code, col, colgroup, command, datalist, dd, del, + details, dialog, dfn, div, dl, dt, em, embed, fieldset, figure, form, + h1, h2, h3, h4, h5, h6, head, header, hgroup, hr, html, i, iframe, img, + input, ins, keygen, kbd, label, legend, li, map, mark, menu, meter, nav, + noscript, object, ol, optgroup, option, output, p, param, pre, progress, + q, rp, rt, ruby, samp, section, select, small, span, strong, sub, sup, + table, tbody, td, textarea, tfoot, th, thead, time, tr, ul, var, video { + background: transparent; + border: 0; + font-size: 100%; + font: inherit; + margin: 0; + outline: none; + padding: 0; + text-align: left; + text-decoration: none; + vertical-align: baseline; + } + } +`; diff --git a/packages/instant/src/components/erc20_asset_amount_input.tsx b/packages/instant/src/components/erc20_asset_amount_input.tsx index f21c21b87..520ac33d5 100644 --- a/packages/instant/src/components/erc20_asset_amount_input.tsx +++ b/packages/instant/src/components/erc20_asset_amount_input.tsx @@ -113,7 +113,7 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput } return ( <Container marginLeft="5px"> - <Icon icon="chevron" width={12} onClick={this._handleSelectAssetClick} /> + <Icon icon="chevron" width={12} stroke={ColorOption.white} onClick={this._handleSelectAssetClick} /> </Container> ); }; diff --git a/packages/instant/src/components/erc20_token_selector.tsx b/packages/instant/src/components/erc20_token_selector.tsx index 41b0b44b0..3503ff31a 100644 --- a/packages/instant/src/components/erc20_token_selector.tsx +++ b/packages/instant/src/components/erc20_token_selector.tsx @@ -28,14 +28,14 @@ export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps> public render(): React.ReactNode { const { tokens, onTokenSelect } = this.props; return ( - <Container> + <Container height="100%"> <SearchInput placeholder="Search tokens..." width="100%" value={this.state.searchQuery} onChange={this._handleSearchInputChange} /> - <Container overflow="scroll" height="275px" marginTop="10px"> + <Container overflow="scroll" height="calc(100% - 80px)" marginTop="10px"> {_.map(tokens, token => { if (!this._isTokenQueryMatch(token)) { return null; @@ -85,7 +85,7 @@ class TokenSelectorRow extends React.Component<TokenSelectorRowProps> { <Container marginLeft="5px"> <Flex justify="flex-start"> <Container marginRight="10px"> - <Circle diameter={30} fillColor={token.metaData.primaryColor}> + <Circle diameter={30} rawColor={token.metaData.primaryColor}> <Flex height="100%"> <Text fontColor={ColorOption.white} fontSize="8px"> {displaySymbol} diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 6d87bc292..b07776b2c 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -77,11 +77,11 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> { private _renderIcon(): React.ReactNode { const processState = this.props.buyOrderState.processState; - if (processState === OrderProcessState.FAILURE) { + if (processState === OrderProcessState.Failure) { return <Icon icon="failed" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />; - } else if (processState === OrderProcessState.PROCESSING) { + } else if (processState === OrderProcessState.Processing) { return <Spinner widthPx={ICON_HEIGHT} heightPx={ICON_HEIGHT} />; - } else if (processState === OrderProcessState.SUCCESS) { + } else if (processState === OrderProcessState.Success) { return <Icon icon="success" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />; } return undefined; @@ -89,11 +89,11 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> { private _renderTopText(): React.ReactNode { const processState = this.props.buyOrderState.processState; - if (processState === OrderProcessState.FAILURE) { + if (processState === OrderProcessState.Failure) { return 'Order failed'; - } else if (processState === OrderProcessState.PROCESSING) { + } else if (processState === OrderProcessState.Processing) { return 'Processing Order...'; - } else if (processState === OrderProcessState.SUCCESS) { + } else if (processState === OrderProcessState.Success) { return 'Tokens received!'; } @@ -101,7 +101,7 @@ export class InstantHeading extends React.Component<InstantHeadingProps, {}> { } private _renderPlaceholderOrAmount(amountFunction: () => React.ReactNode): React.ReactNode { - if (this.props.quoteRequestState === AsyncProcessState.PENDING) { + if (this.props.quoteRequestState === AsyncProcessState.Pending) { return <AmountPlaceholder isPulsating={true} color={PLACEHOLDER_COLOR} />; } if (_.isUndefined(this.props.selectedAssetAmount)) { diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index f1029d70c..9abd7137e 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -26,7 +26,7 @@ export class OrderDetails extends React.Component<OrderDetailsProps> { const ethTokenFee = buyQuoteAccessor.feeEthAmount(); const totalEthAmount = buyQuoteAccessor.totalEthAmount(); return ( - <Container padding="20px" width="100%"> + <Container padding="20px" width="100%" flexGrow={1}> <Container marginBottom="10px"> <Text letterSpacing="1px" diff --git a/packages/instant/src/components/payment_method.tsx b/packages/instant/src/components/payment_method.tsx new file mode 100644 index 000000000..8c0b47d72 --- /dev/null +++ b/packages/instant/src/components/payment_method.tsx @@ -0,0 +1,45 @@ +import { BigNumber } from '@0x/utils'; +import * as _ from 'lodash'; +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; +import { Network } from '../types'; + +import { PaymentMethodDropdown } from './payment_method_dropdown'; +import { Circle } from './ui/circle'; +import { Container } from './ui/container'; +import { Flex } from './ui/flex'; +import { Text } from './ui/text'; + +export interface PaymentMethodProps {} + +export const PaymentMethod: React.StatelessComponent<PaymentMethodProps> = () => ( + <Container padding="20px" width="100%"> + <Container marginBottom="10px"> + <Flex justify="space-between"> + <Text + letterSpacing="1px" + fontColor={ColorOption.primaryColor} + fontWeight={600} + textTransform="uppercase" + fontSize="14px" + > + Payment Method + </Text> + <Flex> + <Circle color={ColorOption.green} diameter={8} /> + <Container marginLeft="3px"> + <Text fontColor={ColorOption.darkGrey} fontSize="12px"> + MetaMask + </Text> + </Container> + </Flex> + </Flex> + </Container> + <PaymentMethodDropdown + accountAddress="0xa1b2c3d4e5f6g7h8j9k10" + accountEthBalanceInWei={new BigNumber(10500000000000000000)} + network={Network.Mainnet} + /> + </Container> +); diff --git a/packages/instant/src/components/payment_method_dropdown.tsx b/packages/instant/src/components/payment_method_dropdown.tsx new file mode 100644 index 000000000..bdce2a49d --- /dev/null +++ b/packages/instant/src/components/payment_method_dropdown.tsx @@ -0,0 +1,44 @@ +import { BigNumber } from '@0x/utils'; +import copy from 'copy-to-clipboard'; +import * as React from 'react'; + +import { Network } from '../types'; +import { etherscanUtil } from '../util/etherscan'; +import { format } from '../util/format'; + +import { Dropdown, DropdownItemConfig } from './ui/dropdown'; + +export interface PaymentMethodDropdownProps { + accountAddress: string; + accountEthBalanceInWei?: BigNumber; + network: Network; +} + +export class PaymentMethodDropdown extends React.Component<PaymentMethodDropdownProps> { + public render(): React.ReactNode { + const { accountAddress, accountEthBalanceInWei } = this.props; + const value = format.ethAddress(accountAddress); + const label = format.ethBaseAmount(accountEthBalanceInWei, 4, '') as string; + return <Dropdown value={value} label={label} items={this._getDropdownItemConfigs()} />; + } + private readonly _getDropdownItemConfigs = (): DropdownItemConfig[] => { + const viewOnEtherscan = { + text: 'View on Etherscan', + onClick: this._handleEtherscanClick, + }; + const copyAddressToClipboard = { + text: 'Copy address to clipboard', + onClick: this._handleCopyToClipboardClick, + }; + return [viewOnEtherscan, copyAddressToClipboard]; + }; + private readonly _handleEtherscanClick = (): void => { + const { accountAddress, network } = this.props; + const etherscanUrl = etherscanUtil.getEtherScanEthAddressIfExists(accountAddress, network); + window.open(etherscanUrl, '_blank'); + }; + private readonly _handleCopyToClipboardClick = (): void => { + const { accountAddress } = this.props; + copy(accountAddress); + }; +} diff --git a/packages/instant/src/components/placing_order_button.tsx b/packages/instant/src/components/placing_order_button.tsx index 4232e6c22..d774d7d27 100644 --- a/packages/instant/src/components/placing_order_button.tsx +++ b/packages/instant/src/components/placing_order_button.tsx @@ -5,15 +5,12 @@ import { ColorOption } from '../style/theme'; import { Button } from './ui/button'; import { Container } from './ui/container'; import { Spinner } from './ui/spinner'; -import { Text } from './ui/text'; export const PlacingOrderButton: React.StatelessComponent<{}> = props => ( - <Button isDisabled={true} width="100%"> + <Button isDisabled={true} width="100%" fontColor={ColorOption.white} fontSize="20px"> <Container display="inline-block" position="relative" top="3px" marginRight="8px"> <Spinner widthPx={20} heightPx={20} /> </Container> - <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px"> - Placing Order… - </Text> + Placing Order… </Button> ); diff --git a/packages/instant/src/components/secondary_button.tsx b/packages/instant/src/components/secondary_button.tsx index 583058b5b..df0539606 100644 --- a/packages/instant/src/components/secondary_button.tsx +++ b/packages/instant/src/components/secondary_button.tsx @@ -4,7 +4,6 @@ import * as React from 'react'; import { ColorOption } from '../style/theme'; import { Button, ButtonProps } from './ui/button'; -import { Text } from './ui/text'; export interface SecondaryButtonProps extends ButtonProps {} @@ -16,11 +15,11 @@ export const SecondaryButton: React.StatelessComponent<SecondaryButtonProps> = p borderColor={ColorOption.lightGrey} width={props.width} onClick={props.onClick} + fontColor={ColorOption.primaryColor} + fontSize="16px" {...buttonProps} > - <Text fontColor={ColorOption.primaryColor} fontWeight={600} fontSize="16px"> - {props.children} - </Text> + {props.children} </Button> ); }; diff --git a/packages/instant/src/components/sliding_error.tsx b/packages/instant/src/components/sliding_error.tsx index a923b9932..a8d4e391c 100644 --- a/packages/instant/src/components/sliding_error.tsx +++ b/packages/instant/src/components/sliding_error.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; +import { ScreenSpecification } from '../style/media'; import { ColorOption } from '../style/theme'; +import { zIndex } from '../style/z_index'; import { PositionAnimationSettings } from './animations/position_animation'; import { SlideAnimation, SlideAnimationState } from './animations/slide_animation'; @@ -21,6 +23,7 @@ export const Error: React.StatelessComponent<ErrorProps> = props => ( backgroundColor={ColorOption.lightOrange} width="100%" borderRadius="6px" + marginTop="10px" marginBottom="10px" > <Flex justify="flex-start"> @@ -39,25 +42,51 @@ export interface SlidingErrorProps extends ErrorProps { } export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props => { const slideAmount = '120px'; - const slideUpSettings: PositionAnimationSettings = { + + const desktopSlideIn: PositionAnimationSettings = { timingFunction: 'ease-in', top: { from: slideAmount, to: '0px', }, + position: 'relative', }; - const slideDownSettings: PositionAnimationSettings = { + const desktopSlideOut: PositionAnimationSettings = { timingFunction: 'cubic-bezier(0.25, 0.1, 0.25, 1)', top: { from: '0px', to: slideAmount, }, + position: 'relative', + }; + + const mobileSlideIn: PositionAnimationSettings = { + duration: '0.5s', + timingFunction: 'ease-in', + top: { from: '-120px', to: '0px' }, + position: 'fixed', + }; + const moblieSlideOut: PositionAnimationSettings = { + duration: '0.5s', + timingFunction: 'ease-in', + top: { from: '0px', to: '-120px' }, + position: 'fixed', + }; + + const slideUpSettings: ScreenSpecification<PositionAnimationSettings> = { + default: desktopSlideIn, + sm: mobileSlideIn, }; + const slideOutSettings: ScreenSpecification<PositionAnimationSettings> = { + default: desktopSlideOut, + sm: moblieSlideOut, + }; + return ( <SlideAnimation - position="relative" slideInSettings={slideUpSettings} - slideOutSettings={slideDownSettings} + slideOutSettings={slideOutSettings} + zIndex={{ sm: zIndex.errorPopup, default: zIndex.errorPopBehind }} animationState={props.animationState} > <Error icon={props.icon} message={props.message} /> diff --git a/packages/instant/src/components/sliding_panel.tsx b/packages/instant/src/components/sliding_panel.tsx index 7ef28e09c..9d16f9560 100644 --- a/packages/instant/src/components/sliding_panel.tsx +++ b/packages/instant/src/components/sliding_panel.tsx @@ -30,7 +30,9 @@ export const Panel: React.StatelessComponent<PanelProps> = ({ title, children, o <Icon width={12} color={ColorOption.lightGrey} icon="closeX" onClick={onClose} /> </Container> </Flex> - <Container marginTop="10px">{children}</Container> + <Container marginTop="10px" height="100%"> + {children} + </Container> </Container> ); @@ -51,6 +53,7 @@ export const SlidingPanel: React.StatelessComponent<SlidingPanelProps> = props = from: slideAmount, to: '0px', }, + position: 'absolute', }; const slideDownSettings: PositionAnimationSettings = { duration: '0.3s', @@ -59,13 +62,14 @@ export const SlidingPanel: React.StatelessComponent<SlidingPanelProps> = props = from: '0px', to: slideAmount, }, + position: 'absolute', }; return ( <SlideAnimation - position="absolute" slideInSettings={slideUpSettings} slideOutSettings={slideDownSettings} animationState={animationState} + height="100%" > <Panel {...rest} /> </SlideAnimation> diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx index f2a6f5745..59aaa33a1 100644 --- a/packages/instant/src/components/timed_progress_bar.tsx +++ b/packages/instant/src/components/timed_progress_bar.tsx @@ -70,9 +70,11 @@ export const TimedProgress = styled.div < TimedProgressProps > ` - background-color: ${props => props.theme[ColorOption.primaryColor]}; - border-radius: 6px; - height: 6px; - animation: ${props => expandingWidthKeyframes(props.fromWidth, props.toWidth)} - ${props => props.timeMs}ms linear 1 forwards; - `; + && { + background-color: ${props => props.theme[ColorOption.primaryColor]}; + border-radius: 6px; + height: 6px; + animation: ${props => expandingWidthKeyframes(props.fromWidth, props.toWidth)} + ${props => props.timeMs}ms linear 1 forwards; + } +`; diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx index 5274d835b..b90221bf4 100644 --- a/packages/instant/src/components/ui/button.tsx +++ b/packages/instant/src/components/ui/button.tsx @@ -6,6 +6,8 @@ import { ColorOption, styled } from '../../style/theme'; export interface ButtonProps { backgroundColor?: ColorOption; borderColor?: ColorOption; + fontColor?: ColorOption; + fontSize?: string; width?: string; padding?: string; type?: string; @@ -24,29 +26,39 @@ const darkenOnHoverAmount = 0.1; const darkenOnActiveAmount = 0.2; const saturateOnFocusAmount = 0.2; export const Button = styled(PlainButton)` - cursor: ${props => (props.isDisabled ? 'default' : 'pointer')}; - transition: background-color, opacity 0.5s ease; - padding: ${props => props.padding}; - border-radius: 3px; - outline: none; - width: ${props => props.width}; - background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; - border: ${props => (props.borderColor ? `1px solid ${props.theme[props.borderColor]}` : 'none')}; - &:hover { - background-color: ${props => - !props.isDisabled - ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) - : ''} !important; - } - &:active { - background-color: ${props => - !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; - } - &:disabled { - opacity: 0.5; - } - &:focus { - background-color: ${props => saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; + && { + all: initial; + box-sizing: border-box; + font-size: ${props => props.fontSize}; + font-family: 'Inter UI', sans-serif; + font-weight: 600; + color: ${props => props.fontColor && props.theme[props.fontColor]}; + cursor: ${props => (props.isDisabled ? 'default' : 'pointer')}; + transition: background-color, opacity 0.5s ease; + padding: ${props => props.padding}; + border-radius: 3px; + text-align: center; + outline: none; + width: ${props => props.width}; + background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; + border: ${props => (props.borderColor ? `1px solid ${props.theme[props.borderColor]}` : 'none')}; + &:hover { + background-color: ${props => + !props.isDisabled + ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) + : ''} !important; + } + &:active { + background-color: ${props => + !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; + } + &:disabled { + opacity: 0.5; + } + &:focus { + background-color: ${props => + saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; + } } `; @@ -55,7 +67,8 @@ Button.defaultProps = { borderColor: ColorOption.primaryColor, width: 'auto', isDisabled: false, - padding: '1em 2.2em', + padding: '.6em 1.2em', + fontSize: '15px', }; Button.displayName = 'Button'; diff --git a/packages/instant/src/components/ui/circle.tsx b/packages/instant/src/components/ui/circle.tsx index eec2777d2..4f9f56f12 100644 --- a/packages/instant/src/components/ui/circle.tsx +++ b/packages/instant/src/components/ui/circle.tsx @@ -1,22 +1,27 @@ -import { styled } from '../../style/theme'; +import { ColorOption, styled, Theme, withTheme } from '../../style/theme'; export interface CircleProps { diameter: number; - fillColor?: string; + rawColor?: string; + color?: ColorOption; + theme: Theme; } -export const Circle = +export const Circle = withTheme( styled.div < - CircleProps > - ` - width: ${props => props.diameter}px; - height: ${props => props.diameter}px; - background-color: ${props => props.fillColor}; - border-radius: 50%; -`; + CircleProps > + ` + && { + width: ${props => props.diameter}px; + height: ${props => props.diameter}px; + background-color: ${props => (props.rawColor ? props.rawColor : props.theme[props.color || ColorOption.white])}; + border-radius: 50%; + } +`, +); Circle.displayName = 'Circle'; Circle.defaultProps = { - fillColor: 'white', + color: ColorOption.white, }; diff --git a/packages/instant/src/components/ui/container.tsx b/packages/instant/src/components/ui/container.tsx index a0a187e5f..8aa5db9e5 100644 --- a/packages/instant/src/components/ui/container.tsx +++ b/packages/instant/src/components/ui/container.tsx @@ -1,17 +1,18 @@ import { darken } from 'polished'; +import { MediaChoice, stylesForMedia } from '../../style/media'; import { ColorOption, styled } from '../../style/theme'; import { cssRuleIfExists } from '../../style/util'; export interface ContainerProps { - display?: string; + display?: MediaChoice; position?: string; top?: string; right?: string; bottom?: string; left?: string; - width?: string; - height?: string; + width?: MediaChoice; + height?: MediaChoice; maxWidth?: string; margin?: string; marginTop?: string; @@ -33,47 +34,53 @@ export interface ContainerProps { cursor?: string; overflow?: string; darkenOnHover?: boolean; + boxShadowOnHover?: boolean; + flexGrow?: string | number; } export const Container = styled.div < ContainerProps > ` - box-sizing: border-box; - ${props => cssRuleIfExists(props, 'display')} - ${props => cssRuleIfExists(props, 'position')} - ${props => cssRuleIfExists(props, 'top')} - ${props => cssRuleIfExists(props, 'right')} - ${props => cssRuleIfExists(props, 'bottom')} - ${props => cssRuleIfExists(props, 'left')} - ${props => cssRuleIfExists(props, 'width')} - ${props => cssRuleIfExists(props, 'height')} - ${props => cssRuleIfExists(props, 'max-width')} - ${props => cssRuleIfExists(props, 'margin')} - ${props => cssRuleIfExists(props, 'margin-top')} - ${props => cssRuleIfExists(props, 'margin-right')} - ${props => cssRuleIfExists(props, 'margin-bottom')} - ${props => cssRuleIfExists(props, 'margin-left')} - ${props => cssRuleIfExists(props, 'padding')} - ${props => cssRuleIfExists(props, 'border-radius')} - ${props => cssRuleIfExists(props, 'border')} - ${props => cssRuleIfExists(props, 'border-top')} - ${props => cssRuleIfExists(props, 'border-bottom')} - ${props => cssRuleIfExists(props, 'z-index')} - ${props => cssRuleIfExists(props, 'white-space')} - ${props => cssRuleIfExists(props, 'opacity')} - ${props => cssRuleIfExists(props, 'cursor')} - ${props => cssRuleIfExists(props, 'overflow')} - ${props => (props.hasBoxShadow ? `box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)` : '')}; - background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; - border-color: ${props => (props.borderColor ? props.theme[props.borderColor] : 'none')}; - &:hover { - ${props => - props.darkenOnHover - ? `background-color: ${ - props.backgroundColor ? darken(0.05, props.theme[props.backgroundColor]) : 'none' - }` - : ''}; + && { + box-sizing: border-box; + ${props => cssRuleIfExists(props, 'flex-grow')} + ${props => cssRuleIfExists(props, 'position')} + ${props => cssRuleIfExists(props, 'top')} + ${props => cssRuleIfExists(props, 'right')} + ${props => cssRuleIfExists(props, 'bottom')} + ${props => cssRuleIfExists(props, 'left')} + ${props => cssRuleIfExists(props, 'max-width')} + ${props => cssRuleIfExists(props, 'margin')} + ${props => cssRuleIfExists(props, 'margin-top')} + ${props => cssRuleIfExists(props, 'margin-right')} + ${props => cssRuleIfExists(props, 'margin-bottom')} + ${props => cssRuleIfExists(props, 'margin-left')} + ${props => cssRuleIfExists(props, 'padding')} + ${props => cssRuleIfExists(props, 'border-radius')} + ${props => cssRuleIfExists(props, 'border')} + ${props => cssRuleIfExists(props, 'border-top')} + ${props => cssRuleIfExists(props, 'border-bottom')} + ${props => cssRuleIfExists(props, 'z-index')} + ${props => cssRuleIfExists(props, 'white-space')} + ${props => cssRuleIfExists(props, 'opacity')} + ${props => cssRuleIfExists(props, 'cursor')} + ${props => cssRuleIfExists(props, 'overflow')} + ${props => (props.hasBoxShadow ? `box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)` : '')}; + ${props => props.display && stylesForMedia<string>('display', props.display)} + ${props => props.width && stylesForMedia<string>('width', props.width)} + ${props => props.height && stylesForMedia<string>('height', props.height)} + background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; + border-color: ${props => (props.borderColor ? props.theme[props.borderColor] : 'none')}; + &:hover { + ${props => + props.darkenOnHover + ? `background-color: ${ + props.backgroundColor ? darken(0.05, props.theme[props.backgroundColor]) : 'none' + }` + : ''}; + ${props => (props.boxShadowOnHover ? 'box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)' : '')}; + } } `; diff --git a/packages/instant/src/components/ui/dropdown.tsx b/packages/instant/src/components/ui/dropdown.tsx new file mode 100644 index 000000000..3a23f456d --- /dev/null +++ b/packages/instant/src/components/ui/dropdown.tsx @@ -0,0 +1,134 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { ColorOption, completelyTransparent } from '../../style/theme'; +import { zIndex } from '../../style/z_index'; + +import { Container } from './container'; +import { Flex } from './flex'; +import { Icon } from './icon'; +import { Overlay } from './overlay'; +import { Text } from './text'; + +export interface DropdownItemConfig { + text: string; + onClick?: () => void; +} + +export interface DropdownProps { + value: string; + label?: string; + items: DropdownItemConfig[]; +} + +export interface DropdownState { + isOpen: boolean; +} + +export class Dropdown extends React.Component<DropdownProps, DropdownState> { + public static defaultProps = { + items: [], + }; + public state: DropdownState = { + isOpen: false, + }; + public render(): React.ReactNode { + const { value, label, items } = this.props; + const { isOpen } = this.state; + const hasItems = !_.isEmpty(items); + const borderRadius = isOpen ? '4px 4px 0px 0px' : '4px'; + return ( + <React.Fragment> + {isOpen && ( + <Overlay + zIndex={zIndex.dropdownItems - 1} + backgroundColor={completelyTransparent} + onClick={this._closeDropdown} + /> + )} + <Container position="relative"> + <Container + cursor={hasItems ? 'pointer' : undefined} + onClick={this._handleDropdownClick} + hasBoxShadow={isOpen} + boxShadowOnHover={true} + borderRadius={borderRadius} + border="1px solid" + borderColor={ColorOption.feintGrey} + padding="0.8em" + > + <Flex justify="space-between"> + <Text fontSize="16px" fontColor={ColorOption.darkGrey}> + {value} + </Text> + <Container> + {label && ( + <Text fontSize="16px" fontColor={ColorOption.lightGrey}> + {label} + </Text> + )} + {hasItems && ( + <Container marginLeft="5px" display="inline-block" position="relative" bottom="2px"> + <Icon padding="3px" icon="chevron" width={12} stroke={ColorOption.grey} /> + </Container> + )} + </Container> + </Flex> + </Container> + {isOpen && ( + <Container + width="100%" + position="absolute" + onClick={this._closeDropdown} + backgroundColor={ColorOption.white} + hasBoxShadow={true} + zIndex={zIndex.dropdownItems} + > + {_.map(items, (item, index) => ( + <DropdownItem key={item.text} {...item} isLast={index === items.length - 1} /> + ))} + </Container> + )} + </Container> + </React.Fragment> + ); + } + private readonly _handleDropdownClick = (): void => { + if (_.isEmpty(this.props.items)) { + return; + } + this.setState({ + isOpen: !this.state.isOpen, + }); + }; + private readonly _closeDropdown = (): void => { + this.setState({ + isOpen: false, + }); + }; +} + +export interface DropdownItemProps extends DropdownItemConfig { + text: string; + onClick?: () => void; + isLast: boolean; +} + +export const DropdownItem: React.StatelessComponent<DropdownItemProps> = ({ text, onClick, isLast }) => ( + <Container + onClick={onClick} + cursor="pointer" + darkenOnHover={true} + backgroundColor={ColorOption.white} + padding="0.8em" + borderTop="0" + border="1px solid" + borderRadius={isLast ? '0px 0px 4px 4px' : undefined} + width="100%" + borderColor={ColorOption.feintGrey} + > + <Text fontSize="14px" fontColor={ColorOption.darkGrey}> + {text} + </Text> + </Container> +); diff --git a/packages/instant/src/components/ui/flex.tsx b/packages/instant/src/components/ui/flex.tsx index 29c6511bb..274c46b9e 100644 --- a/packages/instant/src/components/ui/flex.tsx +++ b/packages/instant/src/components/ui/flex.tsx @@ -1,3 +1,4 @@ +import { MediaChoice, stylesForMedia } from '../../style/media'; import { ColorOption, styled } from '../../style/theme'; import { cssRuleIfExists } from '../../style/util'; @@ -6,24 +7,28 @@ export interface FlexProps { flexWrap?: 'wrap' | 'nowrap'; justify?: 'flex-start' | 'center' | 'space-around' | 'space-between' | 'space-evenly' | 'flex-end'; align?: 'flex-start' | 'center' | 'space-around' | 'space-between' | 'space-evenly' | 'flex-end'; - width?: string; - height?: string; + width?: MediaChoice; + height?: MediaChoice; backgroundColor?: ColorOption; inline?: boolean; + flexGrow?: number | string; } export const Flex = styled.div < FlexProps > ` - display: ${props => (props.inline ? 'inline-flex' : 'flex')}; - flex-direction: ${props => props.direction}; - flex-wrap: ${props => props.flexWrap}; - justify-content: ${props => props.justify}; - align-items: ${props => props.align}; - ${props => cssRuleIfExists(props, 'width')} - ${props => cssRuleIfExists(props, 'height')} - background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; + && { + display: ${props => (props.inline ? 'inline-flex' : 'flex')}; + flex-direction: ${props => props.direction}; + flex-wrap: ${props => props.flexWrap}; + ${props => cssRuleIfExists(props, 'flexGrow')} + justify-content: ${props => props.justify}; + align-items: ${props => props.align}; + background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; + ${props => (props.width ? stylesForMedia('width', props.width) : '')} + ${props => (props.height ? stylesForMedia('height', props.height) : '')} + } `; Flex.defaultProps = { diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx index 94ea26900..a88fa87dd 100644 --- a/packages/instant/src/components/ui/icon.tsx +++ b/packages/instant/src/components/ui/icon.tsx @@ -9,7 +9,6 @@ interface IconInfo { path: string; fillRule?: svgRule; clipRule?: svgRule; - stroke?: string; strokeOpacity?: number; strokeWidth?: number; strokeLinecap?: 'butt' | 'round' | 'square' | 'inherit'; @@ -47,7 +46,6 @@ const ICONS: IconInfoMapping = { chevron: { viewBox: '0 0 12 7', path: 'M11 1L6 6L1 1', - stroke: 'white', strokeOpacity: 0.5, strokeWidth: 1.5, strokeLinecap: 'round', @@ -67,6 +65,7 @@ export interface IconProps { width: number; height?: number; color?: ColorOption; + stroke?: ColorOption; icon: keyof IconInfoMapping; onClick?: (event: React.MouseEvent<HTMLElement>) => void; padding?: string; @@ -75,6 +74,7 @@ export interface IconProps { const PlainIcon: React.StatelessComponent<IconProps> = props => { const iconInfo = ICONS[props.icon]; const colorValue = _.isUndefined(props.color) ? undefined : props.theme[props.color]; + const strokeValue = _.isUndefined(props.stroke) ? undefined : props.theme[props.stroke]; return ( <div onClick={props.onClick} className={props.className}> <svg @@ -89,7 +89,7 @@ const PlainIcon: React.StatelessComponent<IconProps> = props => { fill={colorValue} fillRule={iconInfo.fillRule || 'nonzero'} clipRule={iconInfo.clipRule || 'nonzero'} - stroke={iconInfo.stroke} + stroke={strokeValue} strokeOpacity={iconInfo.strokeOpacity} strokeWidth={iconInfo.strokeWidth} strokeLinecap={iconInfo.strokeLinecap} @@ -101,15 +101,18 @@ const PlainIcon: React.StatelessComponent<IconProps> = props => { }; export const Icon = withTheme(styled(PlainIcon)` - cursor: ${props => (!_.isUndefined(props.onClick) ? 'pointer' : 'default')}; - transition: opacity 0.5s ease; - padding: ${props => props.padding}; - opacity: ${props => (!_.isUndefined(props.onClick) ? 0.7 : 1)}; - &:hover { - opacity: 1; - } - &:active { - opacity: 1; + && { + display: inline-block; + ${props => (!_.isUndefined(props.onClick) ? 'cursor: pointer' : '')}; + transition: opacity 0.5s ease; + padding: ${props => props.padding}; + opacity: ${props => (!_.isUndefined(props.onClick) ? 0.7 : 1)}; + &:hover { + opacity: 1; + } + &:active { + opacity: 1; + } } `); diff --git a/packages/instant/src/components/ui/input.tsx b/packages/instant/src/components/ui/input.tsx index a884ff7cb..2fb408db4 100644 --- a/packages/instant/src/components/ui/input.tsx +++ b/packages/instant/src/components/ui/input.tsx @@ -16,17 +16,20 @@ export const Input = styled.input < InputProps > ` - font-size: ${props => props.fontSize}; - width: ${props => props.width}; - padding: 0.1em 0em; - font-family: 'Inter UI'; - color: ${props => props.theme[props.fontColor || 'white']}; - background: transparent; - outline: none; - border: none; - &::placeholder { + && { + all: initial; + font-size: ${props => props.fontSize}; + width: ${props => props.width}; + padding: 0.1em 0em; + font-family: 'Inter UI'; color: ${props => props.theme[props.fontColor || 'white']}; - opacity: 0.5; + background: transparent; + outline: none; + border: none; + &::placeholder { + color: ${props => props.theme[props.fontColor || 'white']}; + opacity: 0.5; + } } `; diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx index f1706c874..f67d6fb2f 100644 --- a/packages/instant/src/components/ui/overlay.tsx +++ b/packages/instant/src/components/ui/overlay.tsx @@ -1,38 +1,39 @@ import * as _ from 'lodash'; -import * as React from 'react'; -import { ColorOption, overlayBlack, styled } from '../../style/theme'; - -import { Container } from './container'; -import { Flex } from './flex'; -import { Icon } from './icon'; +import { generateMediaWrapper, ScreenWidths } from '../../style/media'; +import { generateOverlayBlack, styled } from '../../style/theme'; +import { zIndex } from '../../style/z_index'; export interface OverlayProps { - className?: string; - onClose?: () => void; zIndex?: number; + backgroundColor?: string; + width?: string; + height?: string; + showMaxWidth?: ScreenWidths; } -const PlainOverlay: React.StatelessComponent<OverlayProps> = ({ children, className, onClose }) => ( - <Flex height="100vh" className={className}> - <Container position="absolute" top="0px" right="0px"> - <Icon height={18} width={18} color={ColorOption.white} icon="closeX" onClick={onClose} padding="2em 2em" /> - </Container> - <div>{children}</div> - </Flex> -); -export const Overlay = styled(PlainOverlay)` - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: ${props => props.zIndex} - background-color: ${overlayBlack}; +export const Overlay = + styled.div < + OverlayProps > + ` + && { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: ${props => props.zIndex} + background-color: ${props => props.backgroundColor}; + ${props => props.width && `width: ${props.width};`} + ${props => props.height && `height: ${props.height};`} + display: ${props => (props.showMaxWidth ? 'none' : 'block')}; + ${props => props.showMaxWidth && generateMediaWrapper(props.showMaxWidth)`display: block;`} + } `; Overlay.defaultProps = { - zIndex: 100, + zIndex: zIndex.overlayDefault, + backgroundColor: generateOverlayBlack(0.6), }; Overlay.displayName = 'Overlay'; diff --git a/packages/instant/src/components/ui/text.tsx b/packages/instant/src/components/ui/text.tsx index cba6e7b20..4fe429d25 100644 --- a/packages/instant/src/components/ui/text.tsx +++ b/packages/instant/src/components/ui/text.tsx @@ -27,25 +27,27 @@ export const Text = styled.div < TextProps > ` - font-family: ${props => props.fontFamily}; - font-style: ${props => props.fontStyle}; - font-weight: ${props => props.fontWeight}; - font-size: ${props => props.fontSize}; - opacity: ${props => props.opacity}; - text-decoration-line: ${props => props.textDecorationLine}; - ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')}; - ${props => (props.center ? 'text-align: center' : '')}; - color: ${props => props.fontColor && props.theme[props.fontColor]}; - ${props => (props.minHeight ? `min-height: ${props.minHeight}` : '')}; - ${props => (props.onClick ? 'cursor: pointer' : '')}; - transition: color 0.5s ease; - ${props => (props.noWrap ? 'white-space: nowrap' : '')}; - ${props => (props.display ? `display: ${props.display}` : '')}; - ${props => (props.letterSpacing ? `letter-spacing: ${props.letterSpacing}` : '')}; - ${props => (props.textTransform ? `text-transform: ${props.textTransform}` : '')}; - &:hover { - ${props => - props.onClick ? `color: ${darken(darkenOnHoverAmount, props.theme[props.fontColor || 'white'])}` : ''}; + && { + font-family: 'Inter UI', sans-serif; + font-style: ${props => props.fontStyle}; + font-weight: ${props => props.fontWeight}; + font-size: ${props => props.fontSize}; + opacity: ${props => props.opacity}; + text-decoration-line: ${props => props.textDecorationLine}; + ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')}; + ${props => (props.center ? 'text-align: center' : '')}; + color: ${props => props.fontColor && props.theme[props.fontColor]}; + ${props => (props.minHeight ? `min-height: ${props.minHeight}` : '')}; + ${props => (props.onClick ? 'cursor: pointer' : '')}; + transition: color 0.5s ease; + ${props => (props.noWrap ? 'white-space: nowrap' : '')}; + ${props => (props.display ? `display: ${props.display}` : '')}; + ${props => (props.letterSpacing ? `letter-spacing: ${props.letterSpacing}` : '')}; + ${props => (props.textTransform ? `text-transform: ${props.textTransform}` : '')}; + &:hover { + ${props => + props.onClick ? `color: ${darken(darkenOnHoverAmount, props.theme[props.fontColor || 'white'])}` : ''}; + } } `; @@ -61,14 +63,3 @@ Text.defaultProps = { }; Text.displayName = 'Text'; - -export const Title: React.StatelessComponent<TextProps> = props => <Text {...props} />; - -Title.defaultProps = { - fontSize: '20px', - fontWeight: 600, - opacity: 1, - fontColor: ColorOption.primaryColor, -}; - -Title.displayName = 'Title'; diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx index 907c42e7a..b945f9908 100644 --- a/packages/instant/src/components/zero_ex_instant.tsx +++ b/packages/instant/src/components/zero_ex_instant.tsx @@ -1,5 +1,7 @@ import * as React from 'react'; +import { INJECTED_DIV_CLASS } from '../constants'; + import { ZeroExInstantContainer } from './zero_ex_instant_container'; import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider'; @@ -7,8 +9,10 @@ export type ZeroExInstantProps = ZeroExInstantProviderProps; export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = props => { return ( - <ZeroExInstantProvider {...props}> - <ZeroExInstantContainer /> - </ZeroExInstantProvider> + <div className={INJECTED_DIV_CLASS}> + <ZeroExInstantProvider {...props}> + <ZeroExInstantContainer /> + </ZeroExInstantProvider> + </div> ); }; diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 851dfa2db..5748e064e 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -3,15 +3,14 @@ import * as React from 'react'; import { AvailableERC20TokenSelector } from '../containers/available_erc20_token_selector'; import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details'; import { LatestError } from '../containers/latest_error'; +import { SelectedAssetBuyOrderProgress } from '../containers/selected_asset_buy_order_progress'; import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; - -import { SelectedAssetBuyOrderProgress } from '../containers/selected_asset_buy_order_progress'; - import { ColorOption } from '../style/theme'; import { zIndex } from '../style/z_index'; import { SlideAnimationState } from './animations/slide_animation'; +import { CSSReset } from './css_reset'; import { SlidingPanel } from './sliding_panel'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; @@ -27,35 +26,43 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain }; public render(): React.ReactNode { return ( - <Container width="350px" position="relative"> - <Container zIndex={zIndex.errorPopup} position="relative"> - <LatestError /> - </Container> + <React.Fragment> + <CSSReset /> <Container - zIndex={zIndex.mainContainer} + width={{ default: '350px', sm: '100%' }} + height={{ default: 'auto', sm: '100%' }} position="relative" - backgroundColor={ColorOption.white} - borderRadius="3px" - hasBoxShadow={true} - overflow="hidden" > - <Flex direction="column" justify="flex-start"> - <SelectedAssetInstantHeading onSelectAssetClick={this._handleSymbolClick} /> - <SelectedAssetBuyOrderProgress /> - <LatestBuyQuoteOrderDetails /> - <Container padding="20px" width="100%"> - <SelectedAssetBuyOrderStateButtons /> - </Container> - </Flex> - <SlidingPanel - title="Select Token" - animationState={this.state.tokenSelectionPanelAnimationState} - onClose={this._handlePanelClose} + <Container position="relative"> + <LatestError /> + </Container> + <Container + zIndex={zIndex.mainContainer} + position="relative" + backgroundColor={ColorOption.white} + borderRadius="3px" + hasBoxShadow={true} + overflow="hidden" + height="100%" > - <AvailableERC20TokenSelector onTokenSelect={this._handlePanelClose} /> - </SlidingPanel> + <Flex direction="column" justify="flex-start" height="100%"> + <SelectedAssetInstantHeading onSelectAssetClick={this._handleSymbolClick} /> + <SelectedAssetBuyOrderProgress /> + <LatestBuyQuoteOrderDetails /> + <Container padding="20px" width="100%"> + <SelectedAssetBuyOrderStateButtons /> + </Container> + </Flex> + <SlidingPanel + title="Select Token" + animationState={this.state.tokenSelectionPanelAnimationState} + onClose={this._handlePanelClose} + > + <AvailableERC20TokenSelector onTokenSelect={this._handlePanelClose} /> + </SlidingPanel> + </Container> </Container> - </Container> + </React.Fragment> ); } private readonly _handleSymbolClick = (): void => { diff --git a/packages/instant/src/components/zero_ex_instant_overlay.tsx b/packages/instant/src/components/zero_ex_instant_overlay.tsx index 3461600e1..10438ab7a 100644 --- a/packages/instant/src/components/zero_ex_instant_overlay.tsx +++ b/packages/instant/src/components/zero_ex_instant_overlay.tsx @@ -1,5 +1,10 @@ import * as React from 'react'; +import { ColorOption } from '../style/theme'; + +import { Container } from './ui/container'; +import { Flex } from './ui/flex'; +import { Icon } from './ui/icon'; import { Overlay } from './ui/overlay'; import { ZeroExInstantContainer } from './zero_ex_instant_container'; import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider'; @@ -13,8 +18,22 @@ export const ZeroExInstantOverlay: React.StatelessComponent<ZeroExInstantOverlay const { onClose, zIndex, ...rest } = props; return ( <ZeroExInstantProvider {...rest}> - <Overlay onClose={onClose} zIndex={zIndex}> - <ZeroExInstantContainer /> + <Overlay zIndex={zIndex}> + <Flex height="100vh"> + <Container position="absolute" top="0px" right="0px" display={{ default: 'initial', sm: 'none' }}> + <Icon + height={18} + width={18} + color={ColorOption.white} + icon="closeX" + onClick={onClose} + padding="2em 2em" + /> + </Container> + <Container width={{ default: 'auto', sm: '100%' }} height={{ default: 'auto', sm: '100%' }}> + <ZeroExInstantContainer /> + </Container> + </Flex> </Overlay> </ZeroExInstantProvider> ); diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 0b9408329..411f118cc 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -1,23 +1,23 @@ -import { AssetBuyer } from '@0x/asset-buyer'; -import { ObjectMap, SignedOrder } from '@0x/types'; +import { ObjectMap } from '@0x/types'; import { BigNumber } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; import * as React from 'react'; import { Provider as ReduxProvider } from 'react-redux'; -import { oc } from 'ts-optchain'; +import { ACCOUNT_UPDATE_INTERVAL_TIME_MS, BUY_QUOTE_UPDATE_INTERVAL_TIME_MS } from '../constants'; import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider'; import { asyncData } from '../redux/async_data'; -import { INITIAL_STATE, State } from '../redux/reducer'; +import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer'; import { store, Store } from '../redux/store'; import { fonts } from '../style/fonts'; -import { AffiliateInfo, AssetMetaData, Network } from '../types'; +import { AccountState, AffiliateInfo, AssetMetaData, Network, OrderSource } from '../types'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; import { gasPriceEstimator } from '../util/gas_price_estimator'; -import { getInjectedProvider } from '../util/injected_provider'; +import { Heartbeater } from '../util/heartbeater'; +import { generateAccountHeartbeater, generateBuyQuoteHeartbeater } from '../util/heartbeater_factory'; +import { providerStateFactory } from '../util/provider_state_factory'; fonts.include(); @@ -25,7 +25,7 @@ export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps & Partial<ZeroExInstantProviderOptionalProps>; export interface ZeroExInstantProviderRequiredProps { - orderSource: string | SignedOrder[]; + orderSource: OrderSource; } export interface ZeroExInstantProviderOptionalProps { @@ -40,31 +40,31 @@ export interface ZeroExInstantProviderOptionalProps { export class ZeroExInstantProvider extends React.Component<ZeroExInstantProviderProps> { private readonly _store: Store; + private _accountUpdateHeartbeat?: Heartbeater; + private _buyQuoteHeartbeat?: Heartbeater; + // TODO(fragosti): Write tests for this beast once we inject a provider. - private static _mergeInitialStateWithProps(props: ZeroExInstantProviderProps, state: State = INITIAL_STATE): State { - const networkId = props.networkId || state.network; - // TODO: Proper wallet connect flow - const provider = props.provider || getInjectedProvider(); - const assetBuyerOptions = { + private static _mergeDefaultStateWithProps( + props: ZeroExInstantProviderProps, + defaultState: DefaultState = DEFAULT_STATE, + ): State { + // use the networkId passed in with the props, otherwise default to that of the default state (1, mainnet) + const networkId = props.networkId || defaultState.network; + // construct the ProviderState + const providerState = providerStateFactory.getInitialProviderState( + props.orderSource, networkId, - }; - let assetBuyer; - if (_.isString(props.orderSource)) { - assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl( - provider, - props.orderSource, - assetBuyerOptions, - ); - } else { - assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.orderSource, assetBuyerOptions); - } + props.provider, + ); + // merge the additional additionalAssetMetaDataMap with our default map const completeAssetMetaDataMap = { ...props.additionalAssetMetaDataMap, - ...state.assetMetaDataMap, + ...defaultState.assetMetaDataMap, }; + // construct the final state const storeStateFromProps: State = { - ...state, - assetBuyer, + ...defaultState, + providerState, network: networkId, selectedAsset: _.isUndefined(props.defaultSelectedAssetData) ? undefined @@ -74,7 +74,7 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider networkId, ), selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount) - ? state.selectedAssetAmount + ? undefined : new BigNumber(props.defaultAssetBuyAmount), availableAssets: _.isUndefined(props.availableAssetDatas) ? undefined @@ -86,10 +86,9 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider } constructor(props: ZeroExInstantProviderProps) { super(props); - const initialAppState = ZeroExInstantProvider._mergeInitialStateWithProps(this.props, INITIAL_STATE); + const initialAppState = ZeroExInstantProvider._mergeDefaultStateWithProps(this.props); this._store = store.create(initialAppState); } - public componentDidMount(): void { const state = this._store.getState(); // tslint:disable-next-line:no-floating-promises @@ -99,16 +98,36 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider // tslint:disable-next-line:no-floating-promises asyncData.fetchAvailableAssetDatasAndDispatchToStore(this._store); } + if (state.providerState.account.state !== AccountState.None) { + this._accountUpdateHeartbeat = generateAccountHeartbeater({ + store: this._store, + shouldPerformImmediatelyOnStart: true, + }); + this._accountUpdateHeartbeat.start(ACCOUNT_UPDATE_INTERVAL_TIME_MS); + } + this._buyQuoteHeartbeat = generateBuyQuoteHeartbeater({ + store: this._store, + shouldPerformImmediatelyOnStart: false, + }); + this._buyQuoteHeartbeat.start(BUY_QUOTE_UPDATE_INTERVAL_TIME_MS); + // tslint:disable-next-line:no-floating-promises + asyncData.fetchCurrentBuyQuoteAndDispatchToStore({ store: this._store, shouldSetPending: true }); // warm up the gas price estimator cache just in case we can't // grab the gas price estimate when submitting the transaction // tslint:disable-next-line:no-floating-promises gasPriceEstimator.getGasInfoAsync(); - // tslint:disable-next-line:no-floating-promises this._flashErrorIfWrongNetwork(); } - + public componentWillUnmount(): void { + if (this._accountUpdateHeartbeat) { + this._accountUpdateHeartbeat.stop(); + } + if (this._buyQuoteHeartbeat) { + this._buyQuoteHeartbeat.stop(); + } + } public render(): React.ReactNode { return ( <ReduxProvider store={this._store}> @@ -116,19 +135,15 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider </ReduxProvider> ); } - private readonly _flashErrorIfWrongNetwork = async (): Promise<void> => { const msToShowError = 30000; // 30 seconds - const network = this._store.getState().network; - const assetBuyerIfExists = this._store.getState().assetBuyer; - const providerIfExists = oc(assetBuyerIfExists).provider(); - if (!_.isUndefined(providerIfExists)) { - const web3Wrapper = new Web3Wrapper(providerIfExists); - const networkOfProvider = await web3Wrapper.getNetworkIdAsync(); - if (network !== networkOfProvider) { - const errorMessage = `Wrong network detected. Try switching to ${Network[network]}.`; - errorFlasher.flashNewErrorMessage(this._store.dispatch, errorMessage, msToShowError); - } + const state = this._store.getState(); + const network = state.network; + const web3Wrapper = state.providerState.web3Wrapper; + const networkOfProvider = await web3Wrapper.getNetworkIdAsync(); + if (network !== networkOfProvider) { + const errorMessage = `Wrong network detected. Try switching to ${Network[network]}.`; + errorFlasher.flashNewErrorMessage(this._store.dispatch, errorMessage, msToShowError); } }; } diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 15105b65c..110a8248a 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -1,15 +1,35 @@ import { BigNumber } from '@0x/utils'; + +import { AccountNotReady, AccountState, Network } from './types'; + export const BIG_NUMBER_ZERO = new BigNumber(0); export const ETH_DECIMALS = 18; export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer'; +export const INJECTED_DIV_CLASS = 'zeroExInstantResetRoot'; export const INJECTED_DIV_ID = 'zeroExInstant'; export const WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX = 'Transaction failed'; export const GWEI_IN_WEI = new BigNumber(1000000000); export const ONE_SECOND_MS = 1000; export const ONE_MINUTE_MS = ONE_SECOND_MS * 60; +export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5; +export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6); export const DEFAULT_ESTIMATED_TRANSACTION_TIME_MS = ONE_MINUTE_MS * 2; export const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info'; export const COINBASE_API_BASE_URL = 'https://api.coinbase.com/v2'; export const PROGRESS_STALL_AT_WIDTH = '95%'; export const PROGRESS_FINISH_ANIMATION_TIME_MS = 200; +export const ETHEREUM_NODE_URL_BY_NETWORK = { + [Network.Mainnet]: 'https://mainnet.infura.io/', + [Network.Kovan]: 'https://kovan.infura.io/', +}; +export const BLOCK_POLLING_INTERVAL_MS = 10000; // 10s +export const NO_ACCOUNT: AccountNotReady = { + state: AccountState.None, +}; +export const LOADING_ACCOUNT: AccountNotReady = { + state: AccountState.Loading, +}; +export const LOCKED_ACCOUNT: AccountNotReady = { + state: AccountState.Locked, +}; diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts index 092aaaf20..2b59ed3ae 100644 --- a/packages/instant/src/containers/latest_buy_quote_order_details.ts +++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts @@ -22,7 +22,7 @@ const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProp // use the worst case quote info buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(), ethUsdPrice: state.ethUsdPrice, - isLoading: state.quoteRequestState === AsyncProcessState.PENDING, + isLoading: state.quoteRequestState === AsyncProcessState.Pending, }); export const LatestBuyQuoteOrderDetails: React.ComponentClass<LatestBuyQuoteOrderDetailsProps> = connect( diff --git a/packages/instant/src/containers/latest_error.tsx b/packages/instant/src/containers/latest_error.tsx index 99e55a6c4..c0da181f1 100644 --- a/packages/instant/src/containers/latest_error.tsx +++ b/packages/instant/src/containers/latest_error.tsx @@ -1,35 +1,60 @@ import * as React from 'react'; import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; import { SlideAnimationState } from '../components/animations/slide_animation'; import { SlidingError } from '../components/sliding_error'; +import { Overlay } from '../components/ui/overlay'; +import { Action } from '../redux/actions'; import { State } from '../redux/reducer'; -import { Asset, DisplayStatus } from '../types'; +import { ScreenWidths } from '../style/media'; +import { generateOverlayBlack } from '../style/theme'; +import { zIndex } from '../style/z_index'; +import { Asset, DisplayStatus, Omit } from '../types'; +import { errorFlasher } from '../util/error_flasher'; export interface LatestErrorComponentProps { asset?: Asset; latestErrorMessage?: string; animationState: SlideAnimationState; + shouldRenderOverlay: boolean; + onOverlayClick: () => void; } export const LatestErrorComponent: React.StatelessComponent<LatestErrorComponentProps> = props => { if (!props.latestErrorMessage) { return <div />; } - return <SlidingError animationState={props.animationState} icon="😢" message={props.latestErrorMessage} />; + return ( + <React.Fragment> + <SlidingError animationState={props.animationState} icon="😢" message={props.latestErrorMessage} /> + {props.shouldRenderOverlay && ( + <Overlay + onClick={props.onOverlayClick} + zIndex={zIndex.containerOverlay} + showMaxWidth={ScreenWidths.Sm} + backgroundColor={generateOverlayBlack(0.4)} + /> + )} + </React.Fragment> + ); }; -interface ConnectedState { - asset?: Asset; - latestErrorMessage?: string; - animationState: SlideAnimationState; -} export interface LatestErrorProps {} +interface ConnectedState extends Omit<LatestErrorComponentProps, 'onOverlayClick'> {} const mapStateToProps = (state: State, _ownProps: LatestErrorProps): ConnectedState => ({ asset: state.selectedAsset, latestErrorMessage: state.latestErrorMessage, animationState: state.latestErrorDisplayStatus === DisplayStatus.Present ? 'slidIn' : 'slidOut', + shouldRenderOverlay: state.latestErrorDisplayStatus === DisplayStatus.Present, +}); + +type ConnectedDispatch = Pick<LatestErrorComponentProps, 'onOverlayClick'>; +const mapDispatchToProps = (dispatch: Dispatch<Action>, _ownProps: LatestErrorProps): ConnectedDispatch => ({ + onOverlayClick: () => { + errorFlasher.clearError(dispatch); + }, }); -export const LatestError = connect(mapStateToProps)(LatestErrorComponent); +export const LatestError = connect(mapStateToProps, mapDispatchToProps)(LatestErrorComponent); diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index 72d99f844..610335243 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -1,4 +1,6 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; @@ -7,14 +9,17 @@ import { Dispatch } from 'redux'; import { BuyOrderStateButtons } from '../components/buy_order_state_buttons'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; -import { AffiliateInfo, OrderProcessState, ZeroExInstantError } from '../types'; +import { AccountState, AffiliateInfo, OrderProcessState, ZeroExInstantError } from '../types'; import { errorFlasher } from '../util/error_flasher'; import { etherscanUtil } from '../util/etherscan'; interface ConnectedState { + accountAddress?: string; + accountEthBalanceInWei?: BigNumber; buyQuote?: BuyQuote; buyOrderProcessingState: OrderProcessState; - assetBuyer?: AssetBuyer; + assetBuyer: AssetBuyer; + web3Wrapper: Web3Wrapper; affiliateInfo?: AffiliateInfo; onViewTransaction: () => void; } @@ -29,29 +34,38 @@ interface ConnectedDispatch { onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void; } export interface SelectedAssetBuyOrderStateButtons {} -const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => ({ - buyOrderProcessingState: state.buyOrderState.processState, - assetBuyer: state.assetBuyer, - buyQuote: state.latestBuyQuote, - affiliateInfo: state.affiliateInfo, - onViewTransaction: () => { - if ( - state.assetBuyer && - (state.buyOrderState.processState === OrderProcessState.PROCESSING || - state.buyOrderState.processState === OrderProcessState.SUCCESS || - state.buyOrderState.processState === OrderProcessState.FAILURE) - ) { - const etherscanUrl = etherscanUtil.getEtherScanTxnAddressIfExists( - state.buyOrderState.txHash, - state.assetBuyer.networkId, - ); - if (etherscanUrl) { - window.open(etherscanUrl, '_blank'); - return; +const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyOrderStateButtons): ConnectedState => { + const assetBuyer = state.providerState.assetBuyer; + const web3Wrapper = state.providerState.web3Wrapper; + const account = state.providerState.account; + const accountAddress = account.state === AccountState.Ready ? account.address : undefined; + const accountEthBalanceInWei = account.state === AccountState.Ready ? account.ethBalanceInWei : undefined; + return { + accountAddress, + accountEthBalanceInWei, + buyOrderProcessingState: state.buyOrderState.processState, + assetBuyer, + web3Wrapper, + buyQuote: state.latestBuyQuote, + affiliateInfo: state.affiliateInfo, + onViewTransaction: () => { + if ( + state.buyOrderState.processState === OrderProcessState.Processing || + state.buyOrderState.processState === OrderProcessState.Success || + state.buyOrderState.processState === OrderProcessState.Failure + ) { + const etherscanUrl = etherscanUtil.getEtherScanTxnAddressIfExists( + state.buyOrderState.txHash, + assetBuyer.networkId, + ); + if (etherscanUrl) { + window.open(etherscanUrl, '_blank'); + return; + } } - } - }, -}); + }, + }; +}; const mapDispatchToProps = ( dispatch: Dispatch<Action>, diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index f7d56c564..93ff3db70 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -1,20 +1,17 @@ -import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { AssetBuyer } from '@0x/asset-buyer'; import { AssetProxyId } from '@0x/types'; import { BigNumber } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; -import { oc } from 'ts-optchain'; import { ERC20AssetAmountInput } from '../components/erc20_asset_amount_input'; import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; import { AffiliateInfo, ERC20Asset, OrderProcessState } from '../types'; -import { assetUtils } from '../util/asset'; -import { errorFlasher } from '../util/error_flasher'; +import { buyQuoteUpdater } from '../util/buy_quote_updater'; export interface SelectedERC20AssetAmountInputProps { fontColor?: ColorOption; @@ -23,7 +20,7 @@ export interface SelectedERC20AssetAmountInputProps { } interface ConnectedState { - assetBuyer?: AssetBuyer; + assetBuyer: AssetBuyer; value?: BigNumber; asset?: ERC20Asset; isDisabled: boolean; @@ -33,7 +30,7 @@ interface ConnectedState { interface ConnectedDispatch { updateBuyQuote: ( - assetBuyer?: AssetBuyer, + assetBuyer: AssetBuyer, value?: BigNumber, asset?: ERC20Asset, affiliateInfo?: AffiliateInfo, @@ -52,15 +49,16 @@ type FinalProps = ConnectedProps & SelectedERC20AssetAmountInputProps; const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputProps): ConnectedState => { const processState = state.buyOrderState.processState; - const isEnabled = processState === OrderProcessState.NONE || processState === OrderProcessState.FAILURE; + const isEnabled = processState === OrderProcessState.None || processState === OrderProcessState.Failure; const isDisabled = !isEnabled; const selectedAsset = !_.isUndefined(state.selectedAsset) && state.selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20 ? (state.selectedAsset as ERC20Asset) : undefined; const numberOfAssetsAvailable = _.isUndefined(state.availableAssets) ? undefined : state.availableAssets.length; + const assetBuyer = state.providerState.assetBuyer; return { - assetBuyer: state.assetBuyer, + assetBuyer, value: state.selectedAssetAmount, asset: selectedAsset, isDisabled, @@ -69,52 +67,9 @@ const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputP }; }; -const updateBuyQuoteAsync = async ( - assetBuyer: AssetBuyer, - dispatch: Dispatch<Action>, - asset: ERC20Asset, - assetAmount: BigNumber, - affiliateInfo?: AffiliateInfo, -): Promise<void> => { - // get a new buy quote. - const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, asset.metaData.decimals); - - // mark quote as pending - dispatch(actions.setQuoteRequestStatePending()); - - const feePercentage = oc(affiliateInfo).feePercentage(); - let newBuyQuote: BuyQuote | undefined; - try { - newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage }); - } catch (error) { - dispatch(actions.setQuoteRequestStateFailure()); - let errorMessage; - if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { - const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); - errorMessage = `Not enough ${assetName} available`; - } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { - errorMessage = 'Not enough ZRX available'; - } else if ( - error.message === AssetBuyerError.StandardRelayerApiError || - error.message.startsWith(AssetBuyerError.AssetUnavailable) - ) { - const assetName = assetUtils.bestNameForAsset(asset, 'This asset'); - errorMessage = `${assetName} is currently unavailable`; - } - if (!_.isUndefined(errorMessage)) { - errorFlasher.flashNewErrorMessage(dispatch, errorMessage); - } else { - throw error; - } - return; - } - // We have a successful new buy quote - errorFlasher.clearError(dispatch); - // invalidate the last buy quote. - dispatch(actions.updateLatestBuyQuote(newBuyQuote)); -}; - -const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true }); +const debouncedUpdateBuyQuoteAsync = _.debounce(buyQuoteUpdater.updateBuyQuoteAsync.bind(buyQuoteUpdater), 200, { + trailing: true, +}) as typeof buyQuoteUpdater.updateBuyQuoteAsync; const mapDispatchToProps = ( dispatch: Dispatch<Action>, @@ -128,11 +83,11 @@ const mapDispatchToProps = ( // reset our buy state dispatch(actions.setBuyOrderStateNone()); - if (!_.isUndefined(value) && value.greaterThan(0) && !_.isUndefined(asset) && !_.isUndefined(assetBuyer)) { + if (!_.isUndefined(value) && value.greaterThan(0) && !_.isUndefined(asset)) { // even if it's debounced, give them the illusion it's loading dispatch(actions.setQuoteRequestStatePending()); // tslint:disable-next-line:no-floating-promises - debouncedUpdateBuyQuoteAsync(assetBuyer, dispatch, asset, value, affiliateInfo); + debouncedUpdateBuyQuoteAsync(assetBuyer, dispatch, asset, value, true, affiliateInfo); } }, }); diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts index 59d1e646f..0274db30c 100644 --- a/packages/instant/src/index.umd.ts +++ b/packages/instant/src/index.umd.ts @@ -2,7 +2,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR, INJECTED_DIV_ID } from './constants'; +import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR, INJECTED_DIV_CLASS, INJECTED_DIV_ID } from './constants'; import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index'; import { assert } from './util/assert'; @@ -41,6 +41,7 @@ export const render = (props: ZeroExInstantOverlayProps, selector: string = DEFA const appendTo = appendToIfExists as Element; const injectedDiv = document.createElement('div'); injectedDiv.setAttribute('id', INJECTED_DIV_ID); + injectedDiv.setAttribute('class', INJECTED_DIV_CLASS); appendTo.appendChild(injectedDiv); const instantOverlayProps = { ...props, diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index c41c5054b..8947c6c97 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -2,7 +2,7 @@ import { BuyQuote } from '@0x/asset-buyer'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; -import { ActionsUnion, Asset } from '../types'; +import { ActionsUnion, AddressAndEthBalanceInWei, Asset } from '../types'; export interface PlainAction<T extends string> { type: T; @@ -21,6 +21,10 @@ function createAction<T extends string, P>(type: T, data?: P): PlainAction<T> | } export enum ActionTypes { + SET_ACCOUNT_STATE_LOADING = 'SET_ACCOUNT_STATE_LOADING', + SET_ACCOUNT_STATE_LOCKED = 'SET_ACCOUNT_STATE_LOCKED', + SET_ACCOUNT_STATE_READY = 'SET_ACCOUNT_STATE_READY', + UPDATE_ACCOUNT_ETH_BALANCE = 'UPDATE_ACCOUNT_ETH_BALANCE', UPDATE_ETH_USD_PRICE = 'UPDATE_ETH_USD_PRICE', UPDATE_SELECTED_ASSET_AMOUNT = 'UPDATE_SELECTED_ASSET_AMOUNT', SET_BUY_ORDER_STATE_NONE = 'SET_BUY_ORDER_STATE_NONE', @@ -40,6 +44,11 @@ export enum ActionTypes { } export const actions = { + setAccountStateLoading: () => createAction(ActionTypes.SET_ACCOUNT_STATE_LOADING), + setAccountStateLocked: () => createAction(ActionTypes.SET_ACCOUNT_STATE_LOCKED), + setAccountStateReady: (address: string) => createAction(ActionTypes.SET_ACCOUNT_STATE_READY, address), + updateAccountEthBalance: (addressAndBalance: AddressAndEthBalanceInWei) => + createAction(ActionTypes.UPDATE_ACCOUNT_ETH_BALANCE, addressAndBalance), updateEthUsdPrice: (price?: BigNumber) => createAction(ActionTypes.UPDATE_ETH_USD_PRICE, price), updateSelectedAssetAmount: (amount?: BigNumber) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount), setBuyOrderStateNone: () => createAction(ActionTypes.SET_BUY_ORDER_STATE_NONE), diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts index 0e05c13da..b920ac914 100644 --- a/packages/instant/src/redux/async_data.ts +++ b/packages/instant/src/redux/async_data.ts @@ -1,7 +1,10 @@ +import { AssetProxyId } from '@0x/types'; import * as _ from 'lodash'; import { BIG_NUMBER_ZERO } from '../constants'; +import { AccountState, ERC20Asset, OrderProcessState } from '../types'; import { assetUtils } from '../util/asset'; +import { buyQuoteUpdater } from '../util/buy_quote_updater'; import { coinbaseApi } from '../util/coinbase_api'; import { errorFlasher } from '../util/error_flasher'; @@ -20,18 +23,81 @@ export const asyncData = { } }, fetchAvailableAssetDatasAndDispatchToStore: async (store: Store) => { - const { assetBuyer, assetMetaDataMap, network } = store.getState(); - if (!_.isUndefined(assetBuyer)) { - try { - const assetDatas = await assetBuyer.getAvailableAssetDatasAsync(); - const assets = assetUtils.createAssetsFromAssetDatas(assetDatas, assetMetaDataMap, network); - store.dispatch(actions.setAvailableAssets(assets)); - } catch (e) { - const errorMessage = 'Could not find any assets'; - errorFlasher.flashNewErrorMessage(store.dispatch, errorMessage); - // On error, just specify that none are available - store.dispatch(actions.setAvailableAssets([])); - } + const { providerState, assetMetaDataMap, network } = store.getState(); + const assetBuyer = providerState.assetBuyer; + try { + const assetDatas = await assetBuyer.getAvailableAssetDatasAsync(); + const assets = assetUtils.createAssetsFromAssetDatas(assetDatas, assetMetaDataMap, network); + store.dispatch(actions.setAvailableAssets(assets)); + } catch (e) { + const errorMessage = 'Could not find any assets'; + errorFlasher.flashNewErrorMessage(store.dispatch, errorMessage); + // On error, just specify that none are available + store.dispatch(actions.setAvailableAssets([])); + } + }, + fetchAccountInfoAndDispatchToStore: async (options: { store: Store; shouldSetToLoading: boolean }) => { + const { store, shouldSetToLoading } = options; + const { providerState } = store.getState(); + const web3Wrapper = providerState.web3Wrapper; + const provider = providerState.provider; + if (shouldSetToLoading && providerState.account.state !== AccountState.Loading) { + store.dispatch(actions.setAccountStateLoading()); + } + let availableAddresses: string[]; + try { + // TODO(bmillman): Add support at the web3Wrapper level for calling `eth_requestAccounts` instead of calling enable here + const isPrivacyModeEnabled = !_.isUndefined((provider as any).enable); + availableAddresses = isPrivacyModeEnabled + ? await (provider as any).enable() + : await web3Wrapper.getAvailableAddressesAsync(); + } catch (e) { + store.dispatch(actions.setAccountStateLocked()); + return; + } + if (!_.isEmpty(availableAddresses)) { + const activeAddress = availableAddresses[0]; + store.dispatch(actions.setAccountStateReady(activeAddress)); + // tslint:disable-next-line:no-floating-promises + asyncData.fetchAccountBalanceAndDispatchToStore(store); + } else { + store.dispatch(actions.setAccountStateLocked()); + } + }, + fetchAccountBalanceAndDispatchToStore: async (store: Store) => { + const { providerState } = store.getState(); + const web3Wrapper = providerState.web3Wrapper; + const account = providerState.account; + if (account.state !== AccountState.Ready) { + return; + } + try { + const address = account.address; + const ethBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(address); + store.dispatch(actions.updateAccountEthBalance({ address, ethBalanceInWei })); + } catch (e) { + // leave balance as is + return; + } + }, + fetchCurrentBuyQuoteAndDispatchToStore: async (options: { store: Store; shouldSetPending: boolean }) => { + const { store, shouldSetPending } = options; + const { buyOrderState, providerState, selectedAsset, selectedAssetAmount, affiliateInfo } = store.getState(); + const assetBuyer = providerState.assetBuyer; + if ( + !_.isUndefined(selectedAssetAmount) && + !_.isUndefined(selectedAsset) && + buyOrderState.processState === OrderProcessState.None && + selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20 + ) { + await buyQuoteUpdater.updateBuyQuoteAsync( + assetBuyer, + store.dispatch, + selectedAsset as ERC20Asset, + selectedAssetAmount, + shouldSetPending, + affiliateInfo, + ); } }, }; diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index bc435d069..ef46fdd9d 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -1,11 +1,15 @@ -import { AssetBuyer, BuyQuote } from '@0x/asset-buyer'; +import { BuyQuote } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; +import { LOADING_ACCOUNT, LOCKED_ACCOUNT } from '../constants'; import { assetMetaDataMap } from '../data/asset_meta_data_map'; import { + Account, + AccountReady, + AccountState, AffiliateInfo, Asset, AssetMetaData, @@ -14,172 +18,216 @@ import { Network, OrderProcessState, OrderState, + ProviderState, } from '../types'; import { Action, ActionTypes } from './actions'; -export interface State { +// State that is required and we have defaults for, before props are passed in +export interface DefaultState { network: Network; - assetBuyer?: AssetBuyer; assetMetaDataMap: ObjectMap<AssetMetaData>; - selectedAsset?: Asset; - availableAssets?: Asset[]; - selectedAssetAmount?: BigNumber; buyOrderState: OrderState; - ethUsdPrice?: BigNumber; - latestBuyQuote?: BuyQuote; - quoteRequestState: AsyncProcessState; - latestErrorMessage?: string; latestErrorDisplayStatus: DisplayStatus; - affiliateInfo?: AffiliateInfo; + quoteRequestState: AsyncProcessState; } -export const INITIAL_STATE: State = { +// State that is required but needs to be derived from the props +interface PropsDerivedState { + providerState: ProviderState; +} + +// State that is optional +interface OptionalState { + selectedAsset: Asset; + availableAssets: Asset[]; + selectedAssetAmount: BigNumber; + ethUsdPrice: BigNumber; + latestBuyQuote: BuyQuote; + latestErrorMessage: string; + affiliateInfo: AffiliateInfo; +} + +export type State = DefaultState & PropsDerivedState & Partial<OptionalState>; + +export const DEFAULT_STATE: DefaultState = { network: Network.Mainnet, - selectedAssetAmount: undefined, - availableAssets: undefined, assetMetaDataMap, - buyOrderState: { processState: OrderProcessState.NONE }, - ethUsdPrice: undefined, - latestBuyQuote: undefined, - latestErrorMessage: undefined, + buyOrderState: { processState: OrderProcessState.None }, latestErrorDisplayStatus: DisplayStatus.Hidden, - quoteRequestState: AsyncProcessState.NONE, - affiliateInfo: undefined, + quoteRequestState: AsyncProcessState.None, }; -export const reducer = (state: State = INITIAL_STATE, action: Action): State => { - switch (action.type) { - case ActionTypes.UPDATE_ETH_USD_PRICE: - return { - ...state, - ethUsdPrice: action.data, - }; - case ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT: - return { - ...state, - selectedAssetAmount: action.data, - }; - case ActionTypes.UPDATE_LATEST_BUY_QUOTE: - const newBuyQuoteIfExists = action.data; - const shouldUpdate = - _.isUndefined(newBuyQuoteIfExists) || doesBuyQuoteMatchState(newBuyQuoteIfExists, state); - if (shouldUpdate) { - return { - ...state, - latestBuyQuote: newBuyQuoteIfExists, - quoteRequestState: AsyncProcessState.SUCCESS, +export const createReducer = (initialState: State) => { + const reducer = (state: State = initialState, action: Action): State => { + switch (action.type) { + case ActionTypes.SET_ACCOUNT_STATE_LOADING: + return reduceStateWithAccount(state, LOADING_ACCOUNT); + case ActionTypes.SET_ACCOUNT_STATE_LOCKED: + return reduceStateWithAccount(state, LOCKED_ACCOUNT); + case ActionTypes.SET_ACCOUNT_STATE_READY: { + const account: AccountReady = { + state: AccountState.Ready, + address: action.data, }; - } else { - return state; + return reduceStateWithAccount(state, account); } - - case ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING: - return { - ...state, - latestBuyQuote: undefined, - quoteRequestState: AsyncProcessState.PENDING, - }; - case ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE: - return { - ...state, - latestBuyQuote: undefined, - quoteRequestState: AsyncProcessState.FAILURE, - }; - case ActionTypes.SET_BUY_ORDER_STATE_NONE: - return { - ...state, - buyOrderState: { processState: OrderProcessState.NONE }, - }; - case ActionTypes.SET_BUY_ORDER_STATE_VALIDATING: - return { - ...state, - buyOrderState: { processState: OrderProcessState.VALIDATING }, - }; - case ActionTypes.SET_BUY_ORDER_STATE_PROCESSING: - const processingData = action.data; - const { startTimeUnix, expectedEndTimeUnix } = processingData; - return { - ...state, - buyOrderState: { - processState: OrderProcessState.PROCESSING, - txHash: processingData.txHash, - progress: { - startTimeUnix, - expectedEndTimeUnix, - }, - }, - }; - case ActionTypes.SET_BUY_ORDER_STATE_FAILURE: - const failureTxHash = action.data; - if ('txHash' in state.buyOrderState) { - if (state.buyOrderState.txHash === failureTxHash) { - const { txHash, progress } = state.buyOrderState; - return { - ...state, - buyOrderState: { - processState: OrderProcessState.FAILURE, - txHash, - progress, - }, + case ActionTypes.UPDATE_ACCOUNT_ETH_BALANCE: { + const { address, ethBalanceInWei } = action.data; + const currentAccount = state.providerState.account; + if (currentAccount.state !== AccountState.Ready || currentAccount.address !== address) { + return state; + } else { + const newAccount: AccountReady = { + ...currentAccount, + ethBalanceInWei, }; + return reduceStateWithAccount(state, newAccount); } } - return state; - case ActionTypes.SET_BUY_ORDER_STATE_SUCCESS: - const successTxHash = action.data; - if ('txHash' in state.buyOrderState) { - if (state.buyOrderState.txHash === successTxHash) { - const { txHash, progress } = state.buyOrderState; + case ActionTypes.UPDATE_ETH_USD_PRICE: + return { + ...state, + ethUsdPrice: action.data, + }; + case ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT: + return { + ...state, + selectedAssetAmount: action.data, + }; + case ActionTypes.UPDATE_LATEST_BUY_QUOTE: + const newBuyQuoteIfExists = action.data; + const shouldUpdate = + _.isUndefined(newBuyQuoteIfExists) || doesBuyQuoteMatchState(newBuyQuoteIfExists, state); + if (shouldUpdate) { return { ...state, - buyOrderState: { - processState: OrderProcessState.SUCCESS, - txHash, - progress, - }, + latestBuyQuote: newBuyQuoteIfExists, + quoteRequestState: AsyncProcessState.Success, }; + } else { + return state; } - } - return state; - case ActionTypes.SET_ERROR_MESSAGE: - return { - ...state, - latestErrorMessage: action.data, - latestErrorDisplayStatus: DisplayStatus.Present, - }; - case ActionTypes.HIDE_ERROR: - return { - ...state, - latestErrorDisplayStatus: DisplayStatus.Hidden, - }; - case ActionTypes.CLEAR_ERROR: - return { - ...state, - latestErrorMessage: undefined, - latestErrorDisplayStatus: DisplayStatus.Hidden, - }; - case ActionTypes.UPDATE_SELECTED_ASSET: - return { - ...state, - selectedAsset: action.data, - }; - case ActionTypes.RESET_AMOUNT: - return { - ...state, - latestBuyQuote: undefined, - quoteRequestState: AsyncProcessState.NONE, - buyOrderState: { processState: OrderProcessState.NONE }, - selectedAssetAmount: undefined, - }; - case ActionTypes.SET_AVAILABLE_ASSETS: - return { - ...state, - availableAssets: action.data, - }; - default: - return state; - } + case ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING: + return { + ...state, + latestBuyQuote: undefined, + quoteRequestState: AsyncProcessState.Pending, + }; + case ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE: + return { + ...state, + latestBuyQuote: undefined, + quoteRequestState: AsyncProcessState.Failure, + }; + case ActionTypes.SET_BUY_ORDER_STATE_NONE: + return { + ...state, + buyOrderState: { processState: OrderProcessState.None }, + }; + case ActionTypes.SET_BUY_ORDER_STATE_VALIDATING: + return { + ...state, + buyOrderState: { processState: OrderProcessState.Validating }, + }; + case ActionTypes.SET_BUY_ORDER_STATE_PROCESSING: + const processingData = action.data; + const { startTimeUnix, expectedEndTimeUnix } = processingData; + return { + ...state, + buyOrderState: { + processState: OrderProcessState.Processing, + txHash: processingData.txHash, + progress: { + startTimeUnix, + expectedEndTimeUnix, + }, + }, + }; + case ActionTypes.SET_BUY_ORDER_STATE_FAILURE: + const failureTxHash = action.data; + if ('txHash' in state.buyOrderState) { + if (state.buyOrderState.txHash === failureTxHash) { + const { txHash, progress } = state.buyOrderState; + return { + ...state, + buyOrderState: { + processState: OrderProcessState.Failure, + txHash, + progress, + }, + }; + } + } + return state; + case ActionTypes.SET_BUY_ORDER_STATE_SUCCESS: + const successTxHash = action.data; + if ('txHash' in state.buyOrderState) { + if (state.buyOrderState.txHash === successTxHash) { + const { txHash, progress } = state.buyOrderState; + return { + ...state, + buyOrderState: { + processState: OrderProcessState.Success, + txHash, + progress, + }, + }; + } + } + return state; + case ActionTypes.SET_ERROR_MESSAGE: + return { + ...state, + latestErrorMessage: action.data, + latestErrorDisplayStatus: DisplayStatus.Present, + }; + case ActionTypes.HIDE_ERROR: + return { + ...state, + latestErrorDisplayStatus: DisplayStatus.Hidden, + }; + case ActionTypes.CLEAR_ERROR: + return { + ...state, + latestErrorMessage: undefined, + latestErrorDisplayStatus: DisplayStatus.Hidden, + }; + case ActionTypes.UPDATE_SELECTED_ASSET: + return { + ...state, + selectedAsset: action.data, + }; + case ActionTypes.RESET_AMOUNT: + return { + ...state, + latestBuyQuote: undefined, + quoteRequestState: AsyncProcessState.None, + buyOrderState: { processState: OrderProcessState.None }, + selectedAssetAmount: undefined, + }; + case ActionTypes.SET_AVAILABLE_ASSETS: + return { + ...state, + availableAssets: action.data, + }; + default: + return state; + } + }; + return reducer; +}; + +const reduceStateWithAccount = (state: State, account: Account) => { + const oldProviderState = state.providerState; + const newProviderState: ProviderState = { + ...oldProviderState, + account, + }; + return { + ...state, + providerState: newProviderState, + }; }; const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => { diff --git a/packages/instant/src/redux/store.ts b/packages/instant/src/redux/store.ts index 01deb8690..20710765d 100644 --- a/packages/instant/src/redux/store.ts +++ b/packages/instant/src/redux/store.ts @@ -2,12 +2,13 @@ import * as _ from 'lodash'; import { createStore, Store as ReduxStore } from 'redux'; import { devToolsEnhancer } from 'redux-devtools-extension/developmentOnly'; -import { reducer, State } from './reducer'; +import { createReducer, State } from './reducer'; export type Store = ReduxStore<State>; export const store = { - create: (state: State): Store => { - return createStore(reducer, state, devToolsEnhancer({})); + create: (initialState: State): Store => { + const reducer = createReducer(initialState); + return createStore(reducer, initialState, devToolsEnhancer({})); }, }; diff --git a/packages/instant/src/style/media.ts b/packages/instant/src/style/media.ts new file mode 100644 index 000000000..bbf376694 --- /dev/null +++ b/packages/instant/src/style/media.ts @@ -0,0 +1,51 @@ +import { InterpolationValue } from 'styled-components'; + +import { css } from './theme'; + +export enum ScreenWidths { + Sm = 40, + Md = 52, + Lg = 64, +} + +export const generateMediaWrapper = (screenWidth: ScreenWidths) => (...args: any[]) => css` + @media (max-width: ${screenWidth}em) { + ${css.apply(css, args)}; + } +`; + +export const media = { + small: generateMediaWrapper(ScreenWidths.Sm), + medium: generateMediaWrapper(ScreenWidths.Md), + large: generateMediaWrapper(ScreenWidths.Lg), +}; + +export interface ScreenSpecification<T> { + default: T; + sm?: T; + md?: T; + lg?: T; +} +export type OptionallyScreenSpecific<T> = T | ScreenSpecification<T>; +export type MediaChoice = OptionallyScreenSpecific<string>; +/** + * Given a css property name and a OptionallyScreenSpecific value, + * generates css properties with screen-specific viewport styling + */ +export function stylesForMedia<T extends string | number>( + cssPropertyName: string, + choice: OptionallyScreenSpecific<T>, +): InterpolationValue[] { + if (typeof choice === 'object') { + return css` + ${cssPropertyName}: ${choice.default}; + ${choice.lg && media.large`${cssPropertyName}: ${choice.lg}`} + ${choice.md && media.medium`${cssPropertyName}: ${choice.md}`} + ${choice.sm && media.small`${cssPropertyName}: ${choice.sm}`} + `; + } else { + return css` + ${cssPropertyName}: ${choice}; + `; + } +} diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts index d10c9b72c..1e9f55e00 100644 --- a/packages/instant/src/style/theme.ts +++ b/packages/instant/src/style/theme.ts @@ -1,6 +1,6 @@ import * as styledComponents from 'styled-components'; -const { default: styled, css, keyframes, withTheme, ThemeProvider } = styledComponents; +const { default: styled, css, keyframes, withTheme, createGlobalStyle, ThemeProvider } = styledComponents; export type Theme = { [key in ColorOption]: string }; @@ -15,6 +15,8 @@ export enum ColorOption { white = 'white', lightOrange = 'lightOrange', darkOrange = 'darkOrange', + green = 'green', + red = 'red', } export const theme: Theme = { @@ -28,9 +30,15 @@ export const theme: Theme = { white: 'white', lightOrange: '#F9F2ED', darkOrange: '#F2994C', + green: '#3CB34F', + red: '#D00000', }; export const transparentWhite = 'rgba(255,255,255,0.3)'; -export const overlayBlack = 'rgba(0, 0, 0, 0.6)'; +export const completelyTransparent = 'rga(0, 0, 0, 0)'; -export { styled, css, keyframes, withTheme, ThemeProvider }; +export const generateOverlayBlack = (opacity = 0.6) => { + return `rgba(0, 0, 0, ${opacity})`; +}; + +export { styled, css, keyframes, withTheme, createGlobalStyle, ThemeProvider }; diff --git a/packages/instant/src/style/z_index.ts b/packages/instant/src/style/z_index.ts index 727a5189d..ba2d27a17 100644 --- a/packages/instant/src/style/z_index.ts +++ b/packages/instant/src/style/z_index.ts @@ -1,5 +1,9 @@ export const zIndex = { - errorPopup: 1, - mainContainer: 2, - panel: 3, + errorPopBehind: 10, + mainContainer: 20, + dropdownItems: 30, + panel: 40, + containerOverlay: 45, + errorPopup: 50, + overlayDefault: 100, }; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 449bc0f31..b43a82d46 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -1,20 +1,24 @@ -import { AssetProxyId, ObjectMap } from '@0x/types'; +import { AssetBuyer, BigNumber } from '@0x/asset-buyer'; +import { AssetProxyId, ObjectMap, SignedOrder } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { Provider } from 'ethereum-types'; // Reusable +export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; export type Maybe<T> = T | undefined; export enum AsyncProcessState { - NONE = 'None', - PENDING = 'Pending', - SUCCESS = 'Success', - FAILURE = 'Failure', + None = 'NONE', + Pending = 'PENDING', + Success = 'SUCCESS', + Failure = 'FAILURE', } export enum OrderProcessState { - NONE = 'None', - VALIDATING = 'Validating', - PROCESSING = 'Processing', - SUCCESS = 'Success', - FAILURE = 'Failure', + None = 'NONE', + Validating = 'VALIDATING', + Processing = 'PROCESSING', + Success = 'SUCCESS', + Failure = 'FAILURE', } export interface SimulatedProgress { @@ -23,10 +27,10 @@ export interface SimulatedProgress { } interface OrderStatePreTx { - processState: OrderProcessState.NONE | OrderProcessState.VALIDATING; + processState: OrderProcessState.None | OrderProcessState.Validating; } interface OrderStatePostTx { - processState: OrderProcessState.PROCESSING | OrderProcessState.SUCCESS | OrderProcessState.FAILURE; + processState: OrderProcessState.Processing | OrderProcessState.Success | OrderProcessState.Failure; txHash: string; progress: SimulatedProgress; } @@ -89,3 +93,35 @@ export interface AffiliateInfo { feeRecipient: string; feePercentage: number; } + +export interface ProviderState { + provider: Provider; + assetBuyer: AssetBuyer; + web3Wrapper: Web3Wrapper; + account: Account; +} + +export enum AccountState { + None = 'NONE,', + Loading = 'LOADING', + Ready = 'READY', + Locked = 'LOCKED', +} + +export interface AccountReady { + state: AccountState.Ready; + address: string; + ethBalanceInWei?: BigNumber; +} +export interface AccountNotReady { + state: AccountState.None | AccountState.Loading | AccountState.Locked; +} + +export type Account = AccountReady | AccountNotReady; + +export type OrderSource = string | SignedOrder[]; + +export interface AddressAndEthBalanceInWei { + address: string; + ethBalanceInWei: BigNumber; +} diff --git a/packages/instant/src/util/asset_buyer_factory.ts b/packages/instant/src/util/asset_buyer_factory.ts new file mode 100644 index 000000000..5ba46223c --- /dev/null +++ b/packages/instant/src/util/asset_buyer_factory.ts @@ -0,0 +1,17 @@ +import { AssetBuyer, AssetBuyerOpts } from '@0x/asset-buyer'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { Network, OrderSource } from '../types'; + +export const assetBuyerFactory = { + getAssetBuyer: (provider: Provider, orderSource: OrderSource, network: Network): AssetBuyer => { + const assetBuyerOptions: Partial<AssetBuyerOpts> = { + networkId: network, + }; + const assetBuyer = _.isString(orderSource) + ? AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(provider, orderSource, assetBuyerOptions) + : AssetBuyer.getAssetBuyerForProvidedOrders(provider, orderSource, assetBuyerOptions); + return assetBuyer; + }, +}; diff --git a/packages/instant/src/util/balance.ts b/packages/instant/src/util/balance.ts deleted file mode 100644 index f2271495b..000000000 --- a/packages/instant/src/util/balance.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BuyQuote } from '@0x/asset-buyer'; -import { Web3Wrapper } from '@0x/web3-wrapper'; -import * as _ from 'lodash'; - -export const balanceUtil = { - hasSufficientEth: async (takerAddress: string | undefined, buyQuote: BuyQuote, web3Wrapper: Web3Wrapper) => { - if (_.isUndefined(takerAddress)) { - return false; - } - const balanceWei = await web3Wrapper.getBalanceInWeiAsync(takerAddress); - return balanceWei.gte(buyQuote.worstCaseQuoteInfo.totalEthAmount); - }, -}; diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts new file mode 100644 index 000000000..c33e28f1c --- /dev/null +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -0,0 +1,59 @@ +import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import * as _ from 'lodash'; +import { Dispatch } from 'redux'; +import { oc } from 'ts-optchain'; + +import { Action, actions } from '../redux/actions'; +import { AffiliateInfo, ERC20Asset } from '../types'; +import { assetUtils } from '../util/asset'; +import { errorFlasher } from '../util/error_flasher'; + +export const buyQuoteUpdater = { + updateBuyQuoteAsync: async ( + assetBuyer: AssetBuyer, + dispatch: Dispatch<Action>, + asset: ERC20Asset, + assetAmount: BigNumber, + setPending = true, + affiliateInfo?: AffiliateInfo, + ): Promise<void> => { + // get a new buy quote. + const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, asset.metaData.decimals); + if (setPending) { + // mark quote as pending + dispatch(actions.setQuoteRequestStatePending()); + } + const feePercentage = oc(affiliateInfo).feePercentage(); + let newBuyQuote: BuyQuote | undefined; + try { + newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage }); + } catch (error) { + dispatch(actions.setQuoteRequestStateFailure()); + let errorMessage; + if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { + const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); + errorMessage = `Not enough ${assetName} available`; + } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { + errorMessage = 'Not enough ZRX available'; + } else if ( + error.message === AssetBuyerError.StandardRelayerApiError || + error.message.startsWith(AssetBuyerError.AssetUnavailable) + ) { + const assetName = assetUtils.bestNameForAsset(asset, 'This asset'); + errorMessage = `${assetName} is currently unavailable`; + } + if (!_.isUndefined(errorMessage)) { + errorFlasher.flashNewErrorMessage(dispatch, errorMessage); + } else { + throw error; + } + return; + } + // We have a successful new buy quote + errorFlasher.clearError(dispatch); + // invalidate the last buy quote. + dispatch(actions.updateLatestBuyQuote(newBuyQuote)); + }, +}; diff --git a/packages/instant/src/util/etherscan.ts b/packages/instant/src/util/etherscan.ts index cfc2578a3..4d62c4d9f 100644 --- a/packages/instant/src/util/etherscan.ts +++ b/packages/instant/src/util/etherscan.ts @@ -21,4 +21,11 @@ export const etherscanUtil = { } return `https://${prefix}etherscan.io/tx/${txHash}`; }, + getEtherScanEthAddressIfExists: (ethAddress: string, networkId: number) => { + const prefix = etherscanPrefix(networkId); + if (_.isUndefined(prefix)) { + return; + } + return `https://${prefix}etherscan.io/address/${ethAddress}`; + }, }; diff --git a/packages/instant/src/util/format.ts b/packages/instant/src/util/format.ts index 4a48dec9d..44661d697 100644 --- a/packages/instant/src/util/format.ts +++ b/packages/instant/src/util/format.ts @@ -50,4 +50,7 @@ export const format = { } return `$${ethUnitAmount.mul(ethUsdPrice).toFixed(decimalPlaces)}`; }, + ethAddress: (address: string): string => { + return `0x${address.slice(2, 7)}…${address.slice(-5)}`; + }, }; diff --git a/packages/instant/src/util/heartbeater.ts b/packages/instant/src/util/heartbeater.ts new file mode 100644 index 000000000..e700d489e --- /dev/null +++ b/packages/instant/src/util/heartbeater.ts @@ -0,0 +1,35 @@ +import { intervalUtils } from '@0x/utils'; +import * as _ from 'lodash'; + +type HeartbeatableFunction = () => Promise<void>; +export class Heartbeater { + private _intervalId?: NodeJS.Timer; + private readonly _performImmediatelyOnStart: boolean; + private readonly _performFunction: HeartbeatableFunction; + + public constructor(performingFunctionAsync: HeartbeatableFunction, performImmediatelyOnStart: boolean) { + this._performFunction = performingFunctionAsync; + this._performImmediatelyOnStart = performImmediatelyOnStart; + } + + public start(intervalTimeMs: number): void { + if (!_.isUndefined(this._intervalId)) { + throw new Error('Heartbeat is running, please stop before restarting'); + } + + if (this._performImmediatelyOnStart) { + // tslint:disable-next-line:no-floating-promises + this._performFunction(); + } + + // tslint:disable-next-line:no-unbound-method + this._intervalId = intervalUtils.setAsyncExcludingInterval(this._performFunction, intervalTimeMs, _.noop); + } + + public stop(): void { + if (this._intervalId) { + intervalUtils.clearInterval(this._intervalId); + } + this._intervalId = undefined; + } +} diff --git a/packages/instant/src/util/heartbeater_factory.ts b/packages/instant/src/util/heartbeater_factory.ts new file mode 100644 index 000000000..96a8ac4e6 --- /dev/null +++ b/packages/instant/src/util/heartbeater_factory.ts @@ -0,0 +1,22 @@ +import { asyncData } from '../redux/async_data'; +import { Store } from '../redux/store'; + +import { Heartbeater } from './heartbeater'; + +export interface HeartbeatFactoryOptions { + store: Store; + shouldPerformImmediatelyOnStart: boolean; +} +export const generateAccountHeartbeater = (options: HeartbeatFactoryOptions): Heartbeater => { + const { store, shouldPerformImmediatelyOnStart } = options; + return new Heartbeater(async () => { + await asyncData.fetchAccountInfoAndDispatchToStore({ store, shouldSetToLoading: false }); + }, shouldPerformImmediatelyOnStart); +}; + +export const generateBuyQuoteHeartbeater = (options: HeartbeatFactoryOptions): Heartbeater => { + const { store, shouldPerformImmediatelyOnStart } = options; + return new Heartbeater(async () => { + await asyncData.fetchCurrentBuyQuoteAndDispatchToStore({ store, shouldSetPending: false }); + }, shouldPerformImmediatelyOnStart); +}; diff --git a/packages/instant/src/util/injected_provider.ts b/packages/instant/src/util/injected_provider.ts deleted file mode 100644 index 40f9e2da5..000000000 --- a/packages/instant/src/util/injected_provider.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Provider } from 'ethereum-types'; -import * as _ from 'lodash'; - -export const getInjectedProvider = (): Provider => { - const injectedProviderIfExists = (window as any).ethereum; - if (!_.isUndefined(injectedProviderIfExists)) { - // TODO: call enable here when implementing wallet connection flow - return injectedProviderIfExists; - } - const injectedWeb3IfExists = (window as any).web3; - if (!_.isUndefined(injectedWeb3IfExists.currentProvider)) { - return injectedWeb3IfExists.currentProvider; - } else { - throw new Error(`No injected web3 found`); - } -}; diff --git a/packages/instant/src/util/provider_factory.ts b/packages/instant/src/util/provider_factory.ts new file mode 100644 index 000000000..603f7674d --- /dev/null +++ b/packages/instant/src/util/provider_factory.ts @@ -0,0 +1,34 @@ +import { EmptyWalletSubprovider, RPCSubprovider, Web3ProviderEngine } from '@0x/subproviders'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { BLOCK_POLLING_INTERVAL_MS, ETHEREUM_NODE_URL_BY_NETWORK } from '../constants'; +import { Maybe, Network } from '../types'; + +export const providerFactory = { + getInjectedProviderIfExists: (): Maybe<Provider> => { + const injectedProviderIfExists = (window as any).ethereum; + if (!_.isUndefined(injectedProviderIfExists)) { + return injectedProviderIfExists; + } + const injectedWeb3IfExists = (window as any).web3; + if (!_.isUndefined(injectedWeb3IfExists) && !_.isUndefined(injectedWeb3IfExists.currentProvider)) { + return injectedWeb3IfExists.currentProvider; + } + return undefined; + }, + getFallbackNoSigningProvider: (network: Network): Provider => { + const providerEngine = new Web3ProviderEngine({ + pollingInterval: BLOCK_POLLING_INTERVAL_MS, + }); + // Intercept calls to `eth_accounts` and always return empty + providerEngine.addProvider(new EmptyWalletSubprovider()); + // Construct an RPC subprovider, all data based requests will be sent via the RPCSubprovider + // TODO(bmillman): make this more resilient to infura failures + const rpcUrl = ETHEREUM_NODE_URL_BY_NETWORK[network]; + providerEngine.addProvider(new RPCSubprovider(rpcUrl)); + // // Start the Provider Engine + providerEngine.start(); + return providerEngine; + }, +}; diff --git a/packages/instant/src/util/provider_state_factory.ts b/packages/instant/src/util/provider_state_factory.ts new file mode 100644 index 000000000..3281f6bfb --- /dev/null +++ b/packages/instant/src/util/provider_state_factory.ts @@ -0,0 +1,63 @@ +import { Web3Wrapper } from '@0x/web3-wrapper'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { LOADING_ACCOUNT, NO_ACCOUNT } from '../constants'; +import { Maybe, Network, OrderSource, ProviderState } from '../types'; + +import { assetBuyerFactory } from './asset_buyer_factory'; +import { providerFactory } from './provider_factory'; + +export const providerStateFactory = { + getInitialProviderState: (orderSource: OrderSource, network: Network, provider?: Provider): ProviderState => { + if (!_.isUndefined(provider)) { + return providerStateFactory.getInitialProviderStateFromProvider(orderSource, network, provider); + } + const providerStateFromWindowIfExits = providerStateFactory.getInitialProviderStateFromWindowIfExists( + orderSource, + network, + ); + if (providerStateFromWindowIfExits) { + return providerStateFromWindowIfExits; + } else { + return providerStateFactory.getInitialProviderStateFallback(orderSource, network); + } + }, + getInitialProviderStateFromProvider: ( + orderSource: OrderSource, + network: Network, + provider: Provider, + ): ProviderState => { + const providerState: ProviderState = { + provider, + web3Wrapper: new Web3Wrapper(provider), + assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network), + account: LOADING_ACCOUNT, + }; + return providerState; + }, + getInitialProviderStateFromWindowIfExists: (orderSource: OrderSource, network: Network): Maybe<ProviderState> => { + const injectedProviderIfExists = providerFactory.getInjectedProviderIfExists(); + if (!_.isUndefined(injectedProviderIfExists)) { + const providerState: ProviderState = { + provider: injectedProviderIfExists, + web3Wrapper: new Web3Wrapper(injectedProviderIfExists), + assetBuyer: assetBuyerFactory.getAssetBuyer(injectedProviderIfExists, orderSource, network), + account: LOADING_ACCOUNT, + }; + return providerState; + } else { + return undefined; + } + }, + getInitialProviderStateFallback: (orderSource: OrderSource, network: Network): ProviderState => { + const provider = providerFactory.getFallbackNoSigningProvider(network); + const providerState: ProviderState = { + provider, + web3Wrapper: new Web3Wrapper(provider), + assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network), + account: NO_ACCOUNT, + }; + return providerState; + }, +}; diff --git a/packages/json-schemas/CHANGELOG.json b/packages/json-schemas/CHANGELOG.json index 3bd6552e3..f25a487b8 100644 --- a/packages/json-schemas/CHANGELOG.json +++ b/packages/json-schemas/CHANGELOG.json @@ -7,7 +7,8 @@ "Improve schemas by enforcing that amounts that must be whole numbers (e.g Order asset amounts) no longer allow decimal amounts", "pr": 1173 } - ] + ], + "timestamp": 1541740904 }, { "version": "2.0.0", diff --git a/packages/json-schemas/CHANGELOG.md b/packages/json-schemas/CHANGELOG.md index 21efe1be0..a1c784640 100644 --- a/packages/json-schemas/CHANGELOG.md +++ b/packages/json-schemas/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.1 - _November 9, 2018_ + + * Improve schemas by enforcing that amounts that must be whole numbers (e.g Order asset amounts) no longer allow decimal amounts (#1173) + ## v2.0.0 - _October 18, 2018_ * Convert all schemas to JSON files so that they can be used with `json-schema` implemenations in other programming languages. (#1145) diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json index 57715c601..c87cbb65a 100644 --- a/packages/json-schemas/package.json +++ b/packages/json-schemas/package.json @@ -1,6 +1,6 @@ { "name": "@0x/json-schemas", - "version": "2.0.0", + "version": "2.0.1", "engines": { "node": ">=6.12" }, @@ -39,14 +39,14 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/json-schemas/README.md", "dependencies": { - "@0x/typescript-typings": "^3.0.3", + "@0x/typescript-typings": "^3.0.4", "@types/node": "*", "jsonschema": "^1.2.0", "lodash.values": "^4.3.0" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", - "@0x/utils": "^2.0.3", + "@0x/tslint-config": "^1.0.10", + "@0x/utils": "^2.0.4", "@types/lodash.foreach": "^4.5.3", "@types/lodash.values": "^4.3.3", "@types/mocha": "^2.2.42", diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index e3432c010..35a0834f2 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -1,6 +1,6 @@ { "name": "@0x/metacoin", - "version": "0.0.24", + "version": "0.0.25", "engines": { "node": ">=6.12" }, @@ -29,25 +29,25 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@0x/abi-gen": "^1.0.14", - "@0x/base-contract": "^3.0.2", - "@0x/sol-cov": "^2.1.8", - "@0x/subproviders": "^2.1.0", - "@0x/tslint-config": "^1.0.9", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/abi-gen": "^1.0.15", + "@0x/base-contract": "^3.0.3", + "@0x/sol-cov": "^2.1.9", + "@0x/subproviders": "^2.1.1", + "@0x/tslint-config": "^1.0.10", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/mocha": "^5.2.2", "copyfiles": "^2.0.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethers": "~4.0.4", "lodash": "^4.17.5", "run-s": "^0.0.0" }, "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/sol-compiler": "^1.1.8", + "@0x/dev-utils": "^1.0.14", + "@0x/sol-compiler": "^1.1.9", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", diff --git a/packages/migrations/CHANGELOG.json b/packages/migrations/CHANGELOG.json index 6d93feb1e..b7128f8e1 100644 --- a/packages/migrations/CHANGELOG.json +++ b/packages/migrations/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "2.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "2.0.0", "changes": [ { diff --git a/packages/migrations/CHANGELOG.md b/packages/migrations/CHANGELOG.md index 8d3346972..387ae0abb 100644 --- a/packages/migrations/CHANGELOG.md +++ b/packages/migrations/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.1 - _November 9, 2018_ + + * Dependencies updated + ## v2.0.0 - _October 18, 2018_ * Contract artifacts have been moved to the new @0xproject/contract-artifacts package. v1 migrations have been removed. `runMigrationsAsync` returns the addresses of the contracts that were deployed. (#1105) diff --git a/packages/migrations/package.json b/packages/migrations/package.json index b610d3c6a..d8c5fb6c2 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -1,6 +1,6 @@ { "name": "@0x/migrations", - "version": "2.0.0", + "version": "2.0.1", "engines": { "node": ">=6.12" }, @@ -17,9 +17,9 @@ }, "license": "Apache-2.0", "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/tslint-config": "^1.0.9", - "@0x/types": "^1.2.0", + "@0x/dev-utils": "^1.0.14", + "@0x/tslint-config": "^1.0.10", + "@0x/types": "^1.2.1", "@types/yargs": "^10.0.0", "make-promises-safe": "^1.1.0", "npm-run-all": "^4.1.2", @@ -29,18 +29,18 @@ "yargs": "^10.0.3" }, "dependencies": { - "@0x/abi-gen-wrappers": "^1.0.1", - "@0x/base-contract": "^3.0.2", - "@0x/contract-addresses": "^1.0.1", - "@0x/contract-artifacts": "^1.0.1", - "@0x/order-utils": "^2.0.0", - "@0x/sol-compiler": "^1.1.8", - "@0x/subproviders": "^2.1.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/abi-gen-wrappers": "^1.0.2", + "@0x/base-contract": "^3.0.3", + "@0x/contract-addresses": "^1.1.0", + "@0x/contract-artifacts": "^1.1.0", + "@0x/order-utils": "^2.0.1", + "@0x/sol-compiler": "^1.1.9", + "@0x/subproviders": "^2.1.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@ledgerhq/hw-app-eth": "^4.3.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethers": "~4.0.4", "lodash": "^4.17.5" }, diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index a83f90516..a31085014 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0x/monorepo-scripts", - "version": "1.0.12", + "version": "1.0.13", "engines": { "node": ">=6.12" }, diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index 22af2412b..abcf3d392 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "2.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "2.0.0", "changes": [ { diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md index afd5c4adc..31bd02595 100644 --- a/packages/order-utils/CHANGELOG.md +++ b/packages/order-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.1 - _November 9, 2018_ + + * Dependencies updated + ## v2.0.0 - _October 18, 2018_ * Added `ecSignOrderAsync` to first sign an order using `eth_signTypedData` and fallback to `eth_sign`. (#1102) diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index a6a84b940..d6fb9892e 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0x/order-utils", - "version": "2.0.0", + "version": "2.0.1", "engines": { "node": ">=6.12" }, @@ -35,8 +35,8 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md", "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/tslint-config": "^1.0.9", + "@0x/dev-utils": "^1.0.14", + "@0x/tslint-config": "^1.0.10", "@types/bn.js": "^4.11.0", "@types/lodash": "4.14.104", "chai": "^4.0.1", @@ -53,18 +53,18 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/abi-gen-wrappers": "^1.0.1", - "@0x/assert": "^1.0.14", - "@0x/base-contract": "^3.0.2", - "@0x/contract-artifacts": "^1.0.1", - "@0x/json-schemas": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/abi-gen-wrappers": "^1.0.2", + "@0x/assert": "^1.0.15", + "@0x/base-contract": "^3.0.3", + "@0x/contract-artifacts": "^1.1.0", + "@0x/json-schemas": "^2.0.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/node": "*", "bn.js": "^4.11.8", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-abi": "0.6.5", "ethereumjs-util": "^5.1.1", "ethers": "~4.0.4", diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index f93eda527..38d308b74 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -1,6 +1,6 @@ [ { - "version: "2.2.1", + "version: "2.2.2", "changes": [ { "note": "start jsonRpcRequestId at 1, not 0", @@ -10,6 +10,15 @@ "timestamp": 1541977777 }, { + "version": "2.2.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "2.2.0", "changes": [ { diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md index 299af5437..b271956c7 100644 --- a/packages/order-watcher/CHANGELOG.md +++ b/packages/order-watcher/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.2.1 - _November 9, 2018_ + + * Dependencies updated + ## v2.2.0 - _October 18, 2018_ * Added getStats function and returns a Stats object (#1118) diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 42e3f572c..174e0a3a6 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -1,6 +1,6 @@ { "name": "@0x/order-watcher", - "version": "2.2.0", + "version": "2.2.1", "description": "An order watcher daemon that watches for order validity", "keywords": [ "0x", @@ -33,9 +33,9 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/migrations": "^2.0.0", - "@0x/tslint-config": "^1.0.9", + "@0x/dev-utils": "^1.0.14", + "@0x/migrations": "^2.0.1", + "@0x/tslint-config": "^1.0.10", "@types/bintrees": "^1.0.2", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", @@ -57,21 +57,21 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/abi-gen-wrappers": "^1.0.1", - "@0x/assert": "^1.0.14", - "@0x/base-contract": "^3.0.2", - "@0x/contract-addresses": "^1.0.1", - "@0x/contract-artifacts": "^1.0.1", - "@0x/contract-wrappers": "^3.0.0", - "@0x/fill-scenarios": "^1.0.8", - "@0x/json-schemas": "^2.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/abi-gen-wrappers": "^1.0.2", + "@0x/assert": "^1.0.15", + "@0x/base-contract": "^3.0.3", + "@0x/contract-addresses": "^1.1.0", + "@0x/contract-artifacts": "^1.1.0", + "@0x/contract-wrappers": "^3.0.1", + "@0x/fill-scenarios": "^1.0.9", + "@0x/json-schemas": "^2.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "bintrees": "^1.0.2", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-blockstream": "6.0.0", "ethers": "~4.0.4", "lodash": "^4.17.5" diff --git a/packages/react-docs/CHANGELOG.json b/packages/react-docs/CHANGELOG.json index 97485be96..228dfab4f 100644 --- a/packages/react-docs/CHANGELOG.json +++ b/packages/react-docs/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.15", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.14", "changes": [ diff --git a/packages/react-docs/CHANGELOG.md b/packages/react-docs/CHANGELOG.md index 096bd8460..991b3a490 100644 --- a/packages/react-docs/CHANGELOG.md +++ b/packages/react-docs/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.15 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.14 - _October 18, 2018_ * Dependencies updated diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index e234b0479..827a54fdb 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -1,6 +1,6 @@ { "name": "@0x/react-docs", - "version": "1.0.14", + "version": "1.0.15", "engines": { "node": ">=6.12" }, @@ -24,8 +24,8 @@ "url": "https://github.com/0xProject/0x-monorepo.git" }, "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/tslint-config": "^1.0.9", + "@0x/dev-utils": "^1.0.14", + "@0x/tslint-config": "^1.0.10", "@types/compare-versions": "^3.0.0", "@types/styled-components": "^4.0.0", "make-promises-safe": "^1.1.0", @@ -34,9 +34,9 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/react-shared": "^1.0.17", - "@0x/types": "^1.2.0", - "@0x/utils": "^2.0.3", + "@0x/react-shared": "^1.0.18", + "@0x/types": "^1.2.1", + "@0x/utils": "^2.0.4", "@types/lodash": "4.14.104", "@types/material-ui": "^0.20.0", "@types/node": "*", diff --git a/packages/react-shared/CHANGELOG.json b/packages/react-shared/CHANGELOG.json index 8578b4603..4dd11398b 100644 --- a/packages/react-shared/CHANGELOG.json +++ b/packages/react-shared/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.18", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "1.0.17", "changes": [ { diff --git a/packages/react-shared/CHANGELOG.md b/packages/react-shared/CHANGELOG.md index fc3f7e32c..54ca77b16 100644 --- a/packages/react-shared/CHANGELOG.md +++ b/packages/react-shared/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.18 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.17 - _October 18, 2018_ * Dependencies updated diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 45220e2d2..35a69f105 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -1,6 +1,6 @@ { "name": "@0x/react-shared", - "version": "1.0.17", + "version": "1.0.18", "engines": { "node": ">=6.12" }, @@ -25,15 +25,15 @@ "url": "https://github.com/0xProject/0x-monorepo.git" }, "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/tslint-config": "^1.0.9", + "@0x/dev-utils": "^1.0.14", + "@0x/tslint-config": "^1.0.10", "make-promises-safe": "^1.1.0", "shx": "^0.2.2", "tslint": "^5.9.1", "typescript": "3.0.1" }, "dependencies": { - "@0x/types": "^1.2.0", + "@0x/types": "^1.2.1", "@material-ui/core": "^3.0.1", "@types/is-mobile": "0.3.0", "@types/lodash": "4.14.104", diff --git a/packages/sol-compiler/CHANGELOG.json b/packages/sol-compiler/CHANGELOG.json index d945c305b..724e68a68 100644 --- a/packages/sol-compiler/CHANGELOG.json +++ b/packages/sol-compiler/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.1.9", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.1.8", "changes": [ diff --git a/packages/sol-compiler/CHANGELOG.md b/packages/sol-compiler/CHANGELOG.md index 1a86d097d..322313f9e 100644 --- a/packages/sol-compiler/CHANGELOG.md +++ b/packages/sol-compiler/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.9 - _November 9, 2018_ + + * Dependencies updated + ## v1.1.8 - _October 18, 2018_ * Dependencies updated diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 17ccb50b8..766c789df 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-compiler", - "version": "1.1.8", + "version": "1.1.9", "engines": { "node": ">=6.12" }, @@ -42,8 +42,8 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-compiler/README.md", "devDependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/tslint-config": "^1.0.9", + "@0x/dev-utils": "^1.0.14", + "@0x/tslint-config": "^1.0.10", "@types/mkdirp": "^0.5.2", "@types/require-from-string": "^1.2.0", "@types/semver": "^5.5.0", @@ -65,16 +65,16 @@ "zeppelin-solidity": "1.8.0" }, "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/json-schemas": "^2.0.0", - "@0x/sol-resolver": "^1.0.15", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/assert": "^1.0.15", + "@0x/json-schemas": "^2.0.1", + "@0x/sol-resolver": "^1.0.16", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/yargs": "^11.0.0", "chalk": "^2.3.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-util": "^5.1.1", "lodash": "^4.17.5", "mkdirp": "^0.5.1", diff --git a/packages/sol-cov/CHANGELOG.json b/packages/sol-cov/CHANGELOG.json index cbee0233b..e331d608f 100644 --- a/packages/sol-cov/CHANGELOG.json +++ b/packages/sol-cov/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "2.1.9", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "2.1.8", "changes": [ { diff --git a/packages/sol-cov/CHANGELOG.md b/packages/sol-cov/CHANGELOG.md index 11ed486e2..e9d9d6952 100644 --- a/packages/sol-cov/CHANGELOG.md +++ b/packages/sol-cov/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.1.9 - _November 9, 2018_ + + * Dependencies updated + ## v2.1.8 - _October 18, 2018_ * Make @types/solidity-parser-antlr a 'dependency' so it's available to users of the library (#1105) diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json index 09119321d..34e7a8559 100644 --- a/packages/sol-cov/package.json +++ b/packages/sol-cov/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-cov", - "version": "2.1.8", + "version": "2.1.9", "engines": { "node": ">=6.12" }, @@ -42,14 +42,14 @@ }, "homepage": "https://github.com/0xProject/0x.js/packages/sol-cov/README.md", "dependencies": { - "@0x/dev-utils": "^1.0.13", - "@0x/sol-compiler": "^1.1.8", - "@0x/subproviders": "^2.1.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/dev-utils": "^1.0.14", + "@0x/sol-compiler": "^1.1.9", + "@0x/subproviders": "^2.1.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@types/solidity-parser-antlr": "^0.2.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-util": "^5.1.1", "glob": "^7.1.2", "istanbul": "^0.4.5", @@ -61,7 +61,7 @@ "solidity-parser-antlr": "^0.2.12" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/istanbul": "^0.4.30", "@types/loglevel": "^1.5.3", "@types/mkdirp": "^0.5.1", diff --git a/packages/sol-doc/CHANGELOG.json b/packages/sol-doc/CHANGELOG.json index e117ff291..d54569a4d 100644 --- a/packages/sol-doc/CHANGELOG.json +++ b/packages/sol-doc/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.3", "changes": [ diff --git a/packages/sol-doc/CHANGELOG.md b/packages/sol-doc/CHANGELOG.md index 9adc02b19..d44af5d7f 100644 --- a/packages/sol-doc/CHANGELOG.md +++ b/packages/sol-doc/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.4 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.3 - _October 18, 2018_ * Dependencies updated diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json index b1e887fa5..0eb5d6fd5 100644 --- a/packages/sol-doc/package.json +++ b/packages/sol-doc/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-doc", - "version": "1.0.3", + "version": "1.0.4", "description": "Solidity documentation generator", "main": "lib/src/index.js", "types": "lib/src/index.d.js", @@ -25,16 +25,16 @@ "author": "F. Eugene Aumson", "license": "Apache-2.0", "dependencies": { - "@0x/sol-compiler": "^1.1.8", - "@0x/types": "^1.2.0", - "@0x/utils": "^2.0.3", - "ethereum-types": "^1.1.1", + "@0x/sol-compiler": "^1.1.9", + "@0x/types": "^1.2.1", + "@0x/utils": "^2.0.4", + "ethereum-types": "^1.1.2", "ethereumjs-util": "^5.1.1", "lodash": "^4.17.10", "yargs": "^12.0.2" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "chai": "^4.1.2", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.2", diff --git a/packages/sol-resolver/CHANGELOG.json b/packages/sol-resolver/CHANGELOG.json index a72ca6d63..a6ff84237 100644 --- a/packages/sol-resolver/CHANGELOG.json +++ b/packages/sol-resolver/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.16", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.15", "changes": [ diff --git a/packages/sol-resolver/CHANGELOG.md b/packages/sol-resolver/CHANGELOG.md index 671d3ea84..f8c5a7692 100644 --- a/packages/sol-resolver/CHANGELOG.md +++ b/packages/sol-resolver/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.16 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.15 - _October 18, 2018_ * Dependencies updated diff --git a/packages/sol-resolver/package.json b/packages/sol-resolver/package.json index 4d4d0be0e..7572072c4 100644 --- a/packages/sol-resolver/package.json +++ b/packages/sol-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-resolver", - "version": "1.0.15", + "version": "1.0.16", "engines": { "node": ">=6.12" }, @@ -23,15 +23,15 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/resolver/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "make-promises-safe": "^1.1.0", "shx": "^0.2.2", "tslint": "5.11.0", "typescript": "3.0.1" }, "dependencies": { - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", "lodash": "^4.17.5" }, "publishConfig": { diff --git a/packages/sra-spec/CHANGELOG.json b/packages/sra-spec/CHANGELOG.json index a068df3fb..e053b3163 100644 --- a/packages/sra-spec/CHANGELOG.json +++ b/packages/sra-spec/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.8", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "1.0.7", "changes": [ { diff --git a/packages/sra-spec/CHANGELOG.md b/packages/sra-spec/CHANGELOG.md index ba4cddec2..02d22431f 100644 --- a/packages/sra-spec/CHANGELOG.md +++ b/packages/sra-spec/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.8 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.7 - _October 18, 2018_ * Make @loopback/openapi-v3-types a 'dependency' so it's available to users of the library (#1105) diff --git a/packages/sra-spec/package.json b/packages/sra-spec/package.json index 2d3e7decd..e3b6ad979 100644 --- a/packages/sra-spec/package.json +++ b/packages/sra-spec/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sra-spec", - "version": "1.0.7", + "version": "1.0.8", "engines": { "node": ">=6.12" }, @@ -35,11 +35,11 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sra-spec/README.md", "dependencies": { - "@0x/json-schemas": "^2.0.0", + "@0x/json-schemas": "^2.0.1", "@loopback/openapi-v3-types": "^0.8.2" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/mocha": "^2.2.42", "@types/node": "^10.5.3", "chai": "^4.0.1", diff --git a/packages/sra-spec/src/json-schemas.ts b/packages/sra-spec/src/json-schemas.ts index 9eb32de59..f9342ca9e 100644 --- a/packages/sra-spec/src/json-schemas.ts +++ b/packages/sra-spec/src/json-schemas.ts @@ -2,6 +2,7 @@ import { schemas as jsonSchemas } from '@0x/json-schemas'; // Only include schemas we actually need const { + wholeNumberSchema, numberSchema, addressSchema, hexSchema, @@ -28,6 +29,7 @@ const { } = jsonSchemas; const usedSchemas = { + wholeNumberSchema, numberSchema, addressSchema, hexSchema, diff --git a/packages/subproviders/CHANGELOG.json b/packages/subproviders/CHANGELOG.json index b145bbbe5..816c776a5 100644 --- a/packages/subproviders/CHANGELOG.json +++ b/packages/subproviders/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "2.1.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "2.1.0", "changes": [ { diff --git a/packages/subproviders/CHANGELOG.md b/packages/subproviders/CHANGELOG.md index f9e3e63a6..72ac9d1f7 100644 --- a/packages/subproviders/CHANGELOG.md +++ b/packages/subproviders/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.1.1 - _November 9, 2018_ + + * Dependencies updated + ## v2.1.0 - _October 18, 2018_ * Add `MetamaskSubprovider` to handle inconsistent JSON RPC behaviour (#1102) diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 32e2bae24..1a25b5e32 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -1,6 +1,6 @@ { "name": "@0x/subproviders", - "version": "2.1.0", + "version": "2.1.1", "engines": { "node": ">=6.12" }, @@ -29,13 +29,13 @@ } }, "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/assert": "^1.0.15", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "@ledgerhq/hw-app-eth": "^4.3.0", - "@ledgerhq/hw-transport-u2f": "^4.3.0", + "@ledgerhq/hw-transport-u2f": "4.24.0", "@types/eth-lightwallet": "^3.0.0", "@types/ganache-core": "^2.1.0", "@types/hdkey": "^0.7.0", @@ -43,7 +43,7 @@ "bip39": "^2.5.0", "bn.js": "^4.11.8", "eth-lightwallet": "^3.0.1", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-tx": "^1.3.5", "ethereumjs-util": "^5.1.1", "ganache-core": "^2.2.1", @@ -54,7 +54,7 @@ "web3-provider-engine": "14.0.6" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/bip39": "^2.4.0", "@types/bn.js": "^4.11.0", "@types/ethereumjs-tx": "^1.0.0", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 53f1b95df..c46f5465a 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0x/testnet-faucets", - "version": "1.0.52", + "version": "1.0.53", "engines": { "node": ">=6.12" }, @@ -18,13 +18,13 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^2.0.0", - "@0x/subproviders": "^2.1.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "0x.js": "^2.0.1", + "@0x/subproviders": "^2.1.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "body-parser": "^1.17.1", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-tx": "^1.3.5", "ethereumjs-util": "^5.1.1", "express": "^4.15.2", @@ -32,7 +32,7 @@ "rollbar": "^0.6.5" }, "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/body-parser": "^1.16.1", "@types/express": "^4.0.35", "@types/lodash": "4.14.104", diff --git a/packages/tslint-config/CHANGELOG.json b/packages/tslint-config/CHANGELOG.json index 99fbc7989..9f504216c 100644 --- a/packages/tslint-config/CHANGELOG.json +++ b/packages/tslint-config/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "1.0.9", "changes": [ diff --git a/packages/tslint-config/CHANGELOG.md b/packages/tslint-config/CHANGELOG.md index f0b429d29..f5cacb5d1 100644 --- a/packages/tslint-config/CHANGELOG.md +++ b/packages/tslint-config/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _November 9, 2018_ + + * Dependencies updated + ## v1.0.9 - _October 18, 2018_ * Dependencies updated diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json index a235532fb..2914f31e2 100644 --- a/packages/tslint-config/package.json +++ b/packages/tslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@0x/tslint-config", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 84a06faa8..6d9f83c57 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "1.2.1", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "version": "1.2.0", "changes": [ { diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index d1b8ea79c..556bf1799 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.2.1 - _November 9, 2018_ + + * Dependencies updated + ## v1.2.0 - _October 18, 2018_ * Added `EIP712Parameter` `EIP712Types` `EIP712TypedData` for EIP712 signing (#1102) diff --git a/packages/types/package.json b/packages/types/package.json index 9b3ae6701..c32e9a6f7 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@0x/types", - "version": "1.2.0", + "version": "1.2.1", "engines": { "node": ">=6.12" }, @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/types/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "make-promises-safe": "^1.1.0", "shx": "^0.2.2", "tslint": "5.11.0", @@ -32,7 +32,7 @@ "dependencies": { "@types/node": "*", "bignumber.js": "~4.1.0", - "ethereum-types": "^1.1.1" + "ethereum-types": "^1.1.2" }, "publishConfig": { "access": "public" diff --git a/packages/typescript-typings/CHANGELOG.json b/packages/typescript-typings/CHANGELOG.json index e21e788b5..5653b397d 100644 --- a/packages/typescript-typings/CHANGELOG.json +++ b/packages/typescript-typings/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "3.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "3.0.3", "changes": [ diff --git a/packages/typescript-typings/CHANGELOG.md b/packages/typescript-typings/CHANGELOG.md index df58bfc57..62e6665be 100644 --- a/packages/typescript-typings/CHANGELOG.md +++ b/packages/typescript-typings/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.0.4 - _November 9, 2018_ + + * Dependencies updated + ## v3.0.3 - _October 18, 2018_ * Dependencies updated diff --git a/packages/typescript-typings/package.json b/packages/typescript-typings/package.json index 6b9e67602..9dbbe1370 100644 --- a/packages/typescript-typings/package.json +++ b/packages/typescript-typings/package.json @@ -1,6 +1,6 @@ { "name": "@0x/typescript-typings", - "version": "3.0.3", + "version": "3.0.4", "engines": { "node": ">=6.12" }, @@ -27,7 +27,7 @@ "@types/bn.js": "^4.11.0", "@types/react": "*", "bignumber.js": "~4.1.0", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "popper.js": "1.14.3" }, "devDependencies": { diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index 7594581d4..6c9da5f37 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "2.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1541740904 + }, + { "timestamp": 1539871071, "version": "2.0.3", "changes": [ diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 45b2cd0c2..4fdd13d9c 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.4 - _November 9, 2018_ + + * Dependencies updated + ## v2.0.3 - _October 18, 2018_ * Dependencies updated diff --git a/packages/utils/package.json b/packages/utils/package.json index 4e0df9275..24c2496b0 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0x/utils", - "version": "2.0.3", + "version": "2.0.4", "engines": { "node": ">=6.12" }, @@ -28,7 +28,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/utils/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/detect-node": "2.0.0", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", @@ -41,13 +41,13 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", "@types/node": "*", "abortcontroller-polyfill": "^1.1.9", "bignumber.js": "~4.1.0", "detect-node": "2.0.3", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-util": "^5.1.1", "ethers": "~4.0.4", "isomorphic-fetch": "^2.2.1", diff --git a/packages/utils/src/configured_bignumber.ts b/packages/utils/src/configured_bignumber.ts index 2b22b6938..34b57d303 100644 --- a/packages/utils/src/configured_bignumber.ts +++ b/packages/utils/src/configured_bignumber.ts @@ -11,4 +11,27 @@ BigNumber.config({ DECIMAL_PLACES: 78, }); +// Set a debug print function for NodeJS +// Upstream issue: https://github.com/MikeMcl/bignumber.js/issues/188 +import isNode = require('detect-node'); +if (isNode) { + // Dynamically load a NodeJS specific module. + // Typescript requires all imports to be global, so we need to use + // `const` here and disable the tslint warning. + // tslint:disable-next-line: no-var-requires + const util = require('util'); + + // Set a custom util.inspect function + // HACK: We add a function to the BigNumber class by assigning to the + // prototype. The function name is a symbol provided by Node. + (BigNumber.prototype as any)[util.inspect.custom] = function(): string { + // HACK: When executed, `this` will refer to the BigNumber instance. + // This is also why we need a function expression instead of an + // arrow function, as the latter does not have a `this`. + // Return the readable string representation + // tslint:disable-next-line: no-invalid-this + return this.toString(); + }; +} + export { BigNumber }; diff --git a/packages/web3-wrapper/CHANGELOG.json b/packages/web3-wrapper/CHANGELOG.json index 6b554110f..7b21da73a 100644 --- a/packages/web3-wrapper/CHANGELOG.json +++ b/packages/web3-wrapper/CHANGELOG.json @@ -7,7 +7,8 @@ "Fix bug in `getTransactionByHashAsync` which was causing the return value to have the wrong type (raw fields instead of unmarshalled fields).", "pr": 1177 } - ] + ], + "timestamp": 1541740904 }, { "version": "3.1.0", diff --git a/packages/web3-wrapper/CHANGELOG.md b/packages/web3-wrapper/CHANGELOG.md index 90d62953a..ebbef2c48 100644 --- a/packages/web3-wrapper/CHANGELOG.md +++ b/packages/web3-wrapper/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.1.1 - _November 9, 2018_ + + * Fix bug in `getTransactionByHashAsync` which was causing the return value to have the wrong type (raw fields instead of unmarshalled fields). (#1177) + ## v3.1.0 - _October 18, 2018_ * Add `signTypedData` to perform EIP712 `eth_signTypedData`. (#1102) diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index e95245df8..2b87cc92a 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@0x/web3-wrapper", - "version": "3.1.0", + "version": "3.1.1", "engines": { "node": ">=6.12" }, @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/web3-wrapper/README.md", "devDependencies": { - "@0x/tslint-config": "^1.0.9", + "@0x/tslint-config": "^1.0.10", "@types/ganache-core": "^2.1.0", "@types/lodash": "4.14.104", "chai": "^4.0.1", @@ -53,11 +53,11 @@ "typescript": "3.0.1" }, "dependencies": { - "@0x/assert": "^1.0.14", - "@0x/json-schemas": "^2.0.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "ethereum-types": "^1.1.1", + "@0x/assert": "^1.0.15", + "@0x/json-schemas": "^2.0.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "ethereum-types": "^1.1.2", "ethereumjs-util": "^5.1.1", "ethers": "~4.0.4", "lodash": "^4.17.5" diff --git a/packages/website/package.json b/packages/website/package.json index efb97d309..fd671d85d 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,40 +1,41 @@ { "name": "@0x/website", - "version": "0.0.55", + "version": "0.0.56", "engines": { "node": ">=6.12" }, "private": true, "description": "Website and 0x portal dapp", "scripts": { - "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production", + "build": "yarn build:dev", + "build:prod": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production", "build:dev": "../../node_modules/.bin/webpack --mode development", "clean": "shx rm -f public/bundle*", "lint": "tslint --format stylish --project . 'ts/**/*.ts' 'ts/**/*.tsx'", "dev": "webpack-dev-server --mode development --content-base public --https", - "deploy_dogfood": "npm run build; aws s3 sync ./public/. s3://dogfood.0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", - "deploy_staging": "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", - "deploy_live": "DEPLOY_ROLLBAR_SOURCEMAPS=true npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js" + "deploy_dogfood": "npm run build:prod; aws s3 sync ./public/. s3://dogfood.0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", + "deploy_staging": "npm run build:prod; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers", + "deploy_live": "DEPLOY_ROLLBAR_SOURCEMAPS=true npm run build:prod; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js" }, "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "@0x/contract-wrappers": "^3.0.0", - "@0x/json-schemas": "^2.0.0", - "@0x/order-utils": "^2.0.0", - "@0x/react-docs": "^1.0.14", - "@0x/react-shared": "^1.0.17", - "@0x/subproviders": "^2.1.0", - "@0x/types": "^1.2.0", - "@0x/typescript-typings": "^3.0.3", - "@0x/utils": "^2.0.3", - "@0x/web3-wrapper": "^3.1.0", + "@0x/contract-wrappers": "^3.0.1", + "@0x/json-schemas": "^2.0.1", + "@0x/order-utils": "^2.0.1", + "@0x/react-docs": "^1.0.15", + "@0x/react-shared": "^1.0.18", + "@0x/subproviders": "^2.1.1", + "@0x/types": "^1.2.1", + "@0x/typescript-typings": "^3.0.4", + "@0x/utils": "^2.0.4", + "@0x/web3-wrapper": "^3.1.1", "accounting": "^0.4.1", "basscss": "^8.0.3", "blockies": "^0.0.2", "bowser": "^1.9.3", "deep-equal": "^1.0.1", - "ethereum-types": "^1.1.1", + "ethereum-types": "^1.1.2", "ethereumjs-util": "^5.1.1", "find-versions": "^2.0.0", "jsonschema": "^1.2.0", @@ -541,13 +541,19 @@ "@ledgerhq/hw-transport" "^4.7.3" node-hid "^0.7.2" -"@ledgerhq/hw-transport-u2f@^4.3.0": - version "4.7.3" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-4.7.3.tgz#32be84bd2829f0ad0745604355f73a169dceb5e5" +"@ledgerhq/hw-transport-u2f@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-4.24.0.tgz#d67cfc4abf6d9a900ed45f2e2df7fe06dfdff5c7" dependencies: - "@ledgerhq/hw-transport" "^4.7.3" + "@ledgerhq/hw-transport" "^4.24.0" u2f-api "0.2.7" +"@ledgerhq/hw-transport@^4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-4.24.0.tgz#8def925d8c2e1f73d15128d9e27ead729870be58" + dependencies: + events "^3.0.0" + "@ledgerhq/hw-transport@^4.7.3": version "4.7.3" resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-4.7.3.tgz#e89cd90d30aaf008adf9fdfa4af317a48fe798ca" @@ -1902,7 +1908,7 @@ aes-js@^0.2.3: aes-js@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: version "4.2.1" @@ -3366,7 +3372,7 @@ bs58check@^1.0.8: bs58check@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" dependencies: bs58 "^4.0.0" create-hash "^1.1.0" @@ -4401,9 +4407,9 @@ copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" -copy-to-clipboard@^3: +copy-to-clipboard@^3, copy-to-clipboard@^3.0.8: version "3.0.8" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz#f4e82f4a8830dce4666b7eb8ded0c9bcc313aba9" + resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz#f4e82f4a8830dce4666b7eb8ded0c9bcc313aba9" dependencies: toggle-selection "^1.0.3" @@ -5961,7 +5967,7 @@ ethereumjs-wallet@0.6.0: ethereumjs-wallet@~0.6.0: version "0.6.2" - resolved "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" dependencies: aes-js "^3.1.1" bs58check "^2.1.2" @@ -6049,6 +6055,10 @@ events@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/events/-/events-2.0.0.tgz#cbbb56bf3ab1ac18d71c43bb32c86255062769f2" +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + eventsource@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" @@ -7503,7 +7513,7 @@ hdkey@^0.7.0, hdkey@^0.7.1: hdkey@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" + resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" dependencies: coinstring "^2.0.0" safe-buffer "^5.1.1" @@ -15597,7 +15607,7 @@ utf8@^2.1.1: utf8@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" util-deprecate@~1.0.1: version "1.0.2" |