diff --git a/contracts/examples/CHANGELOG.json b/contracts/examples/CHANGELOG.json index 022b0f5dfa..724ab1e4a5 100644 --- a/contracts/examples/CHANGELOG.json +++ b/contracts/examples/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.5", diff --git a/contracts/examples/CHANGELOG.md b/contracts/examples/CHANGELOG.md index 6d53a0b9cb..59d0804da4 100644 --- a/contracts/examples/CHANGELOG.md +++ b/contracts/examples/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.5 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/examples/package.json b/contracts/examples/package.json index 562908126d..845ea06362 100644 --- a/contracts/examples/package.json +++ b/contracts/examples/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-examples", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -34,7 +34,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/examples/README.md", "devDependencies": { "@0x/abi-gen": "^1.0.22", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contracts-test-utils": "^2.0.1", "@0x/dev-utils": "^1.0.24", "@0x/sol-compiler": "^2.0.2", "@0x/subproviders": "^2.1.11", @@ -59,11 +59,11 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-interfaces": "^1.0.5", - "@0x/contracts-libs": "^1.0.5", - "@0x/contracts-multisig": "^1.0.5", - "@0x/contracts-tokens": "^1.0.5", - "@0x/contracts-utils": "^1.0.5", + "@0x/contracts-interfaces": "^1.0.6", + "@0x/contracts-libs": "^1.0.6", + "@0x/contracts-multisig": "^1.0.6", + "@0x/contracts-tokens": "^1.0.6", + "@0x/contracts-utils": "^1.0.6", "@0x/order-utils": "^3.1.2", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/contracts/extensions/CHANGELOG.json b/contracts/extensions/CHANGELOG.json index 0b5d905b19..920fef05a0 100644 --- a/contracts/extensions/CHANGELOG.json +++ b/contracts/extensions/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.2.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.2.2", diff --git a/contracts/extensions/CHANGELOG.md b/contracts/extensions/CHANGELOG.md index c6d447129f..94ffdfb67b 100644 --- a/contracts/extensions/CHANGELOG.md +++ b/contracts/extensions/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.2.3 - _January 17, 2019_ + + * Dependencies updated + ## v1.2.2 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/extensions/package.json b/contracts/extensions/package.json index ae5426def4..14492af8fb 100644 --- a/contracts/extensions/package.json +++ b/contracts/extensions/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-extensions", - "version": "1.2.2", + "version": "1.2.3", "engines": { "node": ">=6.12" }, @@ -45,8 +45,8 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", "devDependencies": { "@0x/abi-gen": "^1.0.22", - "@0x/contract-wrappers": "^5.0.0", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contract-wrappers": "^5.0.1", + "@0x/contracts-test-utils": "^2.0.1", "@0x/dev-utils": "^1.0.24", "@0x/sol-compiler": "^2.0.2", "@0x/subproviders": "^2.1.11", @@ -71,11 +71,11 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-interfaces": "^1.0.5", - "@0x/contracts-libs": "^1.0.5", - "@0x/contracts-protocol": "^2.2.2", - "@0x/contracts-tokens": "^1.0.5", - "@0x/contracts-utils": "^1.0.5", + "@0x/contracts-interfaces": "^1.0.6", + "@0x/contracts-libs": "^1.0.6", + "@0x/contracts-protocol": "^2.2.3", + "@0x/contracts-tokens": "^1.0.6", + "@0x/contracts-utils": "^1.0.6", "@0x/order-utils": "^3.1.2", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/contracts/interfaces/CHANGELOG.json b/contracts/interfaces/CHANGELOG.json index 022b0f5dfa..724ab1e4a5 100644 --- a/contracts/interfaces/CHANGELOG.json +++ b/contracts/interfaces/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.5", diff --git a/contracts/interfaces/CHANGELOG.md b/contracts/interfaces/CHANGELOG.md index 6d53a0b9cb..59d0804da4 100644 --- a/contracts/interfaces/CHANGELOG.md +++ b/contracts/interfaces/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.5 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/interfaces/package.json b/contracts/interfaces/package.json index 3550487da6..c67c25df39 100644 --- a/contracts/interfaces/package.json +++ b/contracts/interfaces/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-interfaces", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -42,8 +42,8 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-libs": "^1.0.5", - "@0x/contracts-utils": "^1.0.5", + "@0x/contracts-libs": "^1.0.6", + "@0x/contracts-utils": "^1.0.6", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", "@0x/utils": "^3.0.1", diff --git a/contracts/libs/CHANGELOG.json b/contracts/libs/CHANGELOG.json index 022b0f5dfa..724ab1e4a5 100644 --- a/contracts/libs/CHANGELOG.json +++ b/contracts/libs/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.5", diff --git a/contracts/libs/CHANGELOG.md b/contracts/libs/CHANGELOG.md index 6d53a0b9cb..59d0804da4 100644 --- a/contracts/libs/CHANGELOG.md +++ b/contracts/libs/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.5 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/libs/package.json b/contracts/libs/package.json index 75905b573b..b28ec37742 100644 --- a/contracts/libs/package.json +++ b/contracts/libs/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-libs", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -45,7 +45,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/libs/README.md", "devDependencies": { "@0x/abi-gen": "^1.0.22", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contracts-test-utils": "^2.0.1", "@0x/dev-utils": "^1.0.24", "@0x/sol-compiler": "^2.0.2", "@0x/subproviders": "^2.1.11", @@ -70,8 +70,8 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-multisig": "^1.0.5", - "@0x/contracts-utils": "^1.0.5", + "@0x/contracts-multisig": "^1.0.6", + "@0x/contracts-utils": "^1.0.6", "@0x/order-utils": "^3.1.2", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/contracts/multisig/CHANGELOG.json b/contracts/multisig/CHANGELOG.json index 022b0f5dfa..724ab1e4a5 100644 --- a/contracts/multisig/CHANGELOG.json +++ b/contracts/multisig/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.5", diff --git a/contracts/multisig/CHANGELOG.md b/contracts/multisig/CHANGELOG.md index 6d53a0b9cb..59d0804da4 100644 --- a/contracts/multisig/CHANGELOG.md +++ b/contracts/multisig/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.5 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/multisig/package.json b/contracts/multisig/package.json index b3860536bb..1c3911cbcc 100644 --- a/contracts/multisig/package.json +++ b/contracts/multisig/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-multisig", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -45,7 +45,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/multisig/README.md", "devDependencies": { "@0x/abi-gen": "^1.0.22", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contracts-test-utils": "^2.0.1", "@0x/dev-utils": "^1.0.24", "@0x/sol-compiler": "^2.0.2", "@0x/subproviders": "^2.1.11", diff --git a/contracts/protocol/CHANGELOG.json b/contracts/protocol/CHANGELOG.json index 2f6b691449..0d513cc176 100644 --- a/contracts/protocol/CHANGELOG.json +++ b/contracts/protocol/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "2.2.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "2.2.2", diff --git a/contracts/protocol/CHANGELOG.md b/contracts/protocol/CHANGELOG.md index 05d2ae6e2b..779eb68a71 100644 --- a/contracts/protocol/CHANGELOG.md +++ b/contracts/protocol/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.2.3 - _January 17, 2019_ + + * Dependencies updated + ## v2.2.2 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/protocol/package.json b/contracts/protocol/package.json index e696d64cda..d1ef70a707 100644 --- a/contracts/protocol/package.json +++ b/contracts/protocol/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-protocol", - "version": "2.2.2", + "version": "2.2.3", "engines": { "node": ">=6.12" }, @@ -69,13 +69,13 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-examples": "^1.0.5", - "@0x/contracts-interfaces": "^1.0.5", - "@0x/contracts-libs": "^1.0.5", - "@0x/contracts-multisig": "^1.0.5", - "@0x/contracts-test-utils": "^2.0.0", - "@0x/contracts-tokens": "^1.0.5", - "@0x/contracts-utils": "^1.0.5", + "@0x/contracts-examples": "^1.0.6", + "@0x/contracts-interfaces": "^1.0.6", + "@0x/contracts-libs": "^1.0.6", + "@0x/contracts-multisig": "^1.0.6", + "@0x/contracts-test-utils": "^2.0.1", + "@0x/contracts-tokens": "^1.0.6", + "@0x/contracts-utils": "^1.0.6", "@0x/order-utils": "^3.1.2", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/contracts/test-utils/CHANGELOG.json b/contracts/test-utils/CHANGELOG.json index aa1321cf32..ae1575e430 100644 --- a/contracts/test-utils/CHANGELOG.json +++ b/contracts/test-utils/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "2.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "2.0.0", "changes": [ diff --git a/contracts/test-utils/CHANGELOG.md b/contracts/test-utils/CHANGELOG.md index 63baf7fafc..2ed0524a62 100644 --- a/contracts/test-utils/CHANGELOG.md +++ b/contracts/test-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.1 - _January 17, 2019_ + + * Dependencies updated + ## v2.0.0 - _January 15, 2019_ * Renamed OrderStatus enum members to PascalCase to conform with tslint enum-naming rule (#1474) diff --git a/contracts/test-utils/package.json b/contracts/test-utils/package.json index 2adfd491b8..b0f4713afe 100644 --- a/contracts/test-utils/package.json +++ b/contracts/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-test-utils", - "version": "2.0.0", + "version": "2.0.1", "engines": { "node": ">=6.12" }, @@ -44,9 +44,9 @@ "@0x/dev-utils": "^1.0.24", "@0x/order-utils": "^3.1.2", "@0x/sol-compiler": "^2.0.2", - "@0x/sol-coverage": "^1.0.2", - "@0x/sol-profiler": "^1.0.2", - "@0x/sol-trace": "^1.0.2", + "@0x/sol-coverage": "^1.0.3", + "@0x/sol-profiler": "^1.0.3", + "@0x/sol-trace": "^1.0.3", "@0x/subproviders": "^2.1.11", "@0x/tslint-config": "^2.0.2", "@0x/types": "^1.5.2", diff --git a/contracts/tokens/CHANGELOG.json b/contracts/tokens/CHANGELOG.json index 022b0f5dfa..724ab1e4a5 100644 --- a/contracts/tokens/CHANGELOG.json +++ b/contracts/tokens/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.5", diff --git a/contracts/tokens/CHANGELOG.md b/contracts/tokens/CHANGELOG.md index 6d53a0b9cb..59d0804da4 100644 --- a/contracts/tokens/CHANGELOG.md +++ b/contracts/tokens/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.5 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/tokens/package.json b/contracts/tokens/package.json index 310cc8c717..bd03169191 100644 --- a/contracts/tokens/package.json +++ b/contracts/tokens/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-tokens", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -45,7 +45,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", "devDependencies": { "@0x/abi-gen": "^1.0.22", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contracts-test-utils": "^2.0.1", "@0x/dev-utils": "^1.0.24", "@0x/sol-compiler": "^2.0.2", "@0x/subproviders": "^2.1.11", @@ -70,10 +70,10 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-interfaces": "^1.0.5", - "@0x/contracts-libs": "^1.0.5", - "@0x/contracts-multisig": "^1.0.5", - "@0x/contracts-utils": "^1.0.5", + "@0x/contracts-interfaces": "^1.0.6", + "@0x/contracts-libs": "^1.0.6", + "@0x/contracts-multisig": "^1.0.6", + "@0x/contracts-utils": "^1.0.6", "@0x/order-utils": "^3.1.2", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/contracts/utils/CHANGELOG.json b/contracts/utils/CHANGELOG.json index 022b0f5dfa..724ab1e4a5 100644 --- a/contracts/utils/CHANGELOG.json +++ b/contracts/utils/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.5", diff --git a/contracts/utils/CHANGELOG.md b/contracts/utils/CHANGELOG.md index 6d53a0b9cb..59d0804da4 100644 --- a/contracts/utils/CHANGELOG.md +++ b/contracts/utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.5 - _January 15, 2019_ * Dependencies updated diff --git a/contracts/utils/package.json b/contracts/utils/package.json index c6a143b863..4e45169fd3 100644 --- a/contracts/utils/package.json +++ b/contracts/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contracts-utils", - "version": "1.0.5", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -45,7 +45,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/utils/README.md", "devDependencies": { "@0x/abi-gen": "^1.0.22", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contracts-test-utils": "^2.0.1", "@0x/dev-utils": "^1.0.24", "@0x/sol-compiler": "^2.0.2", "@0x/subproviders": "^2.1.11", @@ -71,7 +71,7 @@ }, "dependencies": { "@0x/base-contract": "^3.0.13", - "@0x/contracts-multisig": "^1.0.5", + "@0x/contracts-multisig": "^1.0.6", "@0x/order-utils": "^3.1.2", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json index c9c120fed9..20778f8bbb 100644 --- a/packages/0x.js/CHANGELOG.json +++ b/packages/0x.js/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "3.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "3.0.2", diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index c389c0e00b..b0279f0971 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 +## v3.0.3 - _January 17, 2019_ + + * Dependencies updated + ## v3.0.2 - _January 15, 2019_ * Dependencies updated diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 2fd28e91ef..64054d2882 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "3.0.2", + "version": "3.0.3", "engines": { "node": ">=6.12" }, @@ -74,9 +74,9 @@ "dependencies": { "@0x/assert": "^1.0.23", "@0x/base-contract": "^3.0.13", - "@0x/contract-wrappers": "^5.0.0", + "@0x/contract-wrappers": "^5.0.1", "@0x/order-utils": "^3.1.2", - "@0x/order-watcher": "^2.4.2", + "@0x/order-watcher": "^2.4.3", "@0x/subproviders": "^2.1.11", "@0x/types": "^1.5.2", "@0x/typescript-typings": "^3.0.8", diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json index 4e670b642c..2de603de07 100644 --- a/packages/asset-buyer/CHANGELOG.json +++ b/packages/asset-buyer/CHANGELOG.json @@ -8,6 +8,24 @@ } ] }, + { + "version": "4.1.0", + "changes": [ + { + "note": "Adds new public method getLiquidityForAssetDataAsync, and exposes getOrdersAndFillableAmountsAsync as public method", + "pr": 1512 + } + ] + }, + { + "timestamp": 1547747677, + "version": "4.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "4.0.1", diff --git a/packages/asset-buyer/CHANGELOG.md b/packages/asset-buyer/CHANGELOG.md index 85c02479a8..f2a3d2236d 100644 --- a/packages/asset-buyer/CHANGELOG.md +++ b/packages/asset-buyer/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v4.0.2 - _January 17, 2019_ + + * Dependencies updated + ## v4.0.1 - _January 15, 2019_ * Dependencies updated diff --git a/packages/asset-buyer/package.json b/packages/asset-buyer/package.json index c9ed9d02fb..0f79ac06a2 100644 --- a/packages/asset-buyer/package.json +++ b/packages/asset-buyer/package.json @@ -1,6 +1,6 @@ { "name": "@0x/asset-buyer", - "version": "4.0.1", + "version": "4.0.2", "engines": { "node": ">=6.12" }, @@ -38,7 +38,7 @@ "dependencies": { "@0x/assert": "^1.0.23", "@0x/connect": "^3.0.13", - "@0x/contract-wrappers": "^5.0.0", + "@0x/contract-wrappers": "^5.0.1", "@0x/json-schemas": "^2.1.7", "@0x/order-utils": "^3.1.2", "@0x/subproviders": "^2.1.11", @@ -65,6 +65,7 @@ "shx": "^0.2.2", "tslint": "5.11.0", "typedoc": "0.13.0", + "typemoq": "^2.1.0", "typescript": "3.0.1" }, "publishConfig": { diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts index 934410c55a..ad4b3bb606 100644 --- a/packages/asset-buyer/src/asset_buyer.ts +++ b/packages/asset-buyer/src/asset_buyer.ts @@ -16,14 +16,16 @@ import { BuyQuote, BuyQuoteExecutionOpts, BuyQuoteRequestOpts, + LiquidityForAssetData, + LiquidityRequestOpts, OrderProvider, - OrderProviderResponse, OrdersAndFillableAmounts, } from './types'; import { assert } from './utils/assert'; import { assetDataUtils } from './utils/asset_data_utils'; import { buyQuoteCalculator } from './utils/buy_quote_calculator'; +import { calculateLiquidity } from './utils/calculate_liquidity'; import { orderProviderResponseProcessor } from './utils/order_provider_response_processor'; interface OrdersEntry { @@ -138,10 +140,10 @@ export class AssetBuyer { // get the relevant orders for the makerAsset and fees // if the requested assetData is ZRX, don't get the fee info const [ordersAndFillableAmounts, feeOrdersAndFillableAmounts] = await Promise.all([ - this._getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh), + this.getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh), isMakerAssetZrxToken ? Promise.resolve(constants.EMPTY_ORDERS_AND_FILLABLE_AMOUNTS) - : this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh), + : this.getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh), shouldForceOrderRefresh, ]); if (ordersAndFillableAmounts.orders.length === 0) { @@ -177,6 +179,40 @@ export class AssetBuyer { const buyQuote = this.getBuyQuoteAsync(assetData, assetBuyAmount, options); return buyQuote; } + /** + * Returns information about available liquidity for an asset + * Does not factor in slippage or fees + * @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md). + * @param options Options for the request. See type definition for more information. + * + * @return An object that conforms to LiquidityForAssetData that satisfies the request. See type definition for more information. + */ + public async getLiquidityForAssetDataAsync( + assetData: string, + options: Partial = {}, + ): Promise { + const shouldForceOrderRefresh = + options.shouldForceOrderRefresh !== undefined ? options.shouldForceOrderRefresh : false; + assetDataUtils.decodeAssetDataOrThrow(assetData); + assert.isBoolean('options.shouldForceOrderRefresh', shouldForceOrderRefresh); + + const assetPairs = await this.orderProvider.getAvailableMakerAssetDatasAsync(assetData); + const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow(); + if (!assetPairs.includes(etherTokenAssetData)) { + return { + tokensAvailableInBaseUnits: new BigNumber(0), + ethValueAvailableInWei: new BigNumber(0), + }; + } + + const ordersAndFillableAmounts = await this.getOrdersAndFillableAmountsAsync( + assetData, + shouldForceOrderRefresh, + ); + + return calculateLiquidity(ordersAndFillableAmounts); + } + /** * Given a BuyQuote and desired rate, attempt to execute the buy. * @param buyQuote An object that conforms to BuyQuote. See type definition for more information. @@ -260,8 +296,10 @@ export class AssetBuyer { } /** * Grab orders from the map, if there is a miss or it is time to refresh, fetch and process the orders + * @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md). + * @param shouldForceOrderRefresh If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs. */ - private async _getOrdersAndFillableAmountsAsync( + public async getOrdersAndFillableAmountsAsync( assetData: string, shouldForceOrderRefresh: boolean, ): Promise { diff --git a/packages/asset-buyer/src/index.ts b/packages/asset-buyer/src/index.ts index a42d7e272e..f69cfad69c 100644 --- a/packages/asset-buyer/src/index.ts +++ b/packages/asset-buyer/src/index.ts @@ -19,6 +19,9 @@ export { BuyQuoteExecutionOpts, BuyQuoteInfo, BuyQuoteRequestOpts, + LiquidityForAssetData, + LiquidityRequestOpts, + OrdersAndFillableAmounts, OrderProvider, OrderProviderRequest, OrderProviderResponse, diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts index d5d6be6954..46a2338cea 100644 --- a/packages/asset-buyer/src/types.ts +++ b/packages/asset-buyer/src/types.ts @@ -75,6 +75,13 @@ export interface BuyQuoteRequestOpts { slippagePercentage: number; } +/* + * Options for checking liquidity + * + * shouldForceOrderRefresh: If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs. Defaults to false. + */ +export type LiquidityRequestOpts = Pick; + /** * ethAmount: The desired amount of eth to spend. Defaults to buyQuote.worstCaseQuoteInfo.totalEthAmount. * takerAddress: The address to perform the buy. Defaults to the first available address from the provider. @@ -117,7 +124,19 @@ export enum AssetBuyerError { TransactionValueTooLow = 'TRANSACTION_VALUE_TOO_LOW', } +/** + * orders: An array of signed orders + * remainingFillableMakerAssetAmounts: A list of fillable amounts for the signed orders. The index of an item in the array associates the amount with the corresponding order. + */ export interface OrdersAndFillableAmounts { orders: SignedOrder[]; remainingFillableMakerAssetAmounts: BigNumber[]; } + +/** + * Represents available liquidity for a given assetData + */ +export interface LiquidityForAssetData { + tokensAvailableInBaseUnits: BigNumber; + ethValueAvailableInWei: BigNumber; +} diff --git a/packages/asset-buyer/src/utils/calculate_liquidity.ts b/packages/asset-buyer/src/utils/calculate_liquidity.ts new file mode 100644 index 0000000000..a8d165b4b9 --- /dev/null +++ b/packages/asset-buyer/src/utils/calculate_liquidity.ts @@ -0,0 +1,34 @@ +import { BigNumber } from '@0x/utils'; + +import { LiquidityForAssetData, OrdersAndFillableAmounts } from '../types'; + +import { orderUtils } from './order_utils'; + +export const calculateLiquidity = (ordersAndFillableAmounts: OrdersAndFillableAmounts): LiquidityForAssetData => { + const { orders, remainingFillableMakerAssetAmounts } = ordersAndFillableAmounts; + const liquidityInBigNumbers = orders.reduce( + (acc, order, curIndex) => { + const availableMakerAssetAmount = remainingFillableMakerAssetAmounts[curIndex]; + if (availableMakerAssetAmount === undefined) { + throw new Error(`No corresponding fillableMakerAssetAmounts at index ${curIndex}`); + } + + const tokensAvailableForCurrentOrder = availableMakerAssetAmount; + const ethValueAvailableForCurrentOrder = orderUtils.getTakerFillAmount(order, availableMakerAssetAmount); + return { + tokensAvailableInBaseUnits: acc.tokensAvailableInBaseUnits.plus(tokensAvailableForCurrentOrder), + ethValueAvailableInWei: acc.ethValueAvailableInWei.plus(ethValueAvailableForCurrentOrder), + }; + }, + { + tokensAvailableInBaseUnits: new BigNumber(0), + ethValueAvailableInWei: new BigNumber(0), + }, + ); + + // Turn into regular numbers + return { + tokensAvailableInBaseUnits: liquidityInBigNumbers.tokensAvailableInBaseUnits, + ethValueAvailableInWei: liquidityInBigNumbers.ethValueAvailableInWei, + }; +}; diff --git a/packages/asset-buyer/test/asset_buyer_test.ts b/packages/asset-buyer/test/asset_buyer_test.ts new file mode 100644 index 0000000000..f117b4d7ad --- /dev/null +++ b/packages/asset-buyer/test/asset_buyer_test.ts @@ -0,0 +1,212 @@ +import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; +import { Web3ProviderEngine } from '@0x/subproviders'; +import { SignedOrder } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; +import * as chai from 'chai'; +import 'mocha'; +import * as TypeMoq from 'typemoq'; + +import { AssetBuyer } from '../src'; +import { constants } from '../src/constants'; +import { LiquidityForAssetData, OrderProvider, OrdersAndFillableAmounts } from '../src/types'; + +import { chaiSetup } from './utils/chai_setup'; +import { + mockAvailableAssetDatas, + mockedAssetBuyerWithOrdersAndFillableAmounts, + orderProviderMock, +} from './utils/mocks'; + +chaiSetup.configure(); +const expect = chai.expect; + +const FAKE_SRA_URL = 'https://fakeurl.com'; +const FAKE_ASSET_DATA = '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48'; +const TOKEN_DECIMALS = 18; +const DAI_ASSET_DATA = '0xf47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359"'; +const WETH_ASSET_DATA = '0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const WETH_DECIMALS = constants.ETHER_TOKEN_DECIMALS; + +const baseUnitAmount = (unitAmount: number, decimals = TOKEN_DECIMALS): BigNumber => { + return Web3Wrapper.toBaseUnitAmount(new BigNumber(unitAmount), decimals); +}; + +const expectLiquidityResult = async ( + web3Provider: Web3ProviderEngine, + orderProvider: OrderProvider, + ordersAndFillableAmounts: OrdersAndFillableAmounts, + expectedLiquidityResult: LiquidityForAssetData, +) => { + const mockedAssetBuyer = mockedAssetBuyerWithOrdersAndFillableAmounts( + web3Provider, + orderProvider, + FAKE_ASSET_DATA, + ordersAndFillableAmounts, + ); + const liquidityResult = await mockedAssetBuyer.object.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA); + expect(liquidityResult).to.deep.equal(expectedLiquidityResult); +}; + +// tslint:disable:custom-no-magic-numbers +describe('AssetBuyer', () => { + describe('getLiquidityForAssetDataAsync', () => { + const mockWeb3Provider = TypeMoq.Mock.ofType(Web3ProviderEngine); + const mockOrderProvider = orderProviderMock(); + + beforeEach(() => { + mockWeb3Provider.reset(); + mockOrderProvider.reset(); + }); + + afterEach(() => { + mockWeb3Provider.verifyAll(); + mockOrderProvider.verifyAll(); + }); + + describe('validation', () => { + it('should ensure assetData is a string', async () => { + const assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl( + mockWeb3Provider.object, + FAKE_SRA_URL, + ); + + expect(assetBuyer.getLiquidityForAssetDataAsync(false as any)).to.be.rejectedWith( + 'Expected assetData to be of type string, encountered: false', + ); + }); + }); + + describe('asset pair not supported', () => { + it('should return 0s when no asset pair not supported', async () => { + mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, []); + + const assetBuyer = new AssetBuyer(mockWeb3Provider.object, mockOrderProvider.object); + const liquidityResult = await assetBuyer.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA); + expect(liquidityResult).to.deep.equal({ + tokensAvailableInBaseUnits: new BigNumber(0), + ethValueAvailableInWei: new BigNumber(0), + }); + }); + it('should return 0s when only other asset pair supported', async () => { + mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, [DAI_ASSET_DATA]); + + const assetBuyer = new AssetBuyer(mockWeb3Provider.object, mockOrderProvider.object); + const liquidityResult = await assetBuyer.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA); + expect(liquidityResult).to.deep.equal({ + tokensAvailableInBaseUnits: new BigNumber(0), + ethValueAvailableInWei: new BigNumber(0), + }); + }); + }); + + describe('assetData is supported', () => { + // orders + const sellTwoTokensFor1Weth: SignedOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: baseUnitAmount(2), + takerAssetAmount: baseUnitAmount(1, WETH_DECIMALS), + }); + const sellTenTokensFor10Weth: SignedOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: baseUnitAmount(10), + takerAssetAmount: baseUnitAmount(10, WETH_DECIMALS), + }); + + beforeEach(() => { + mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, [WETH_ASSET_DATA]); + }); + + it('should return 0s when no orders available', async () => { + const ordersAndFillableAmounts: OrdersAndFillableAmounts = { + orders: [], + remainingFillableMakerAssetAmounts: [], + }; + const expectedResult = { + tokensAvailableInBaseUnits: new BigNumber(0), + ethValueAvailableInWei: new BigNumber(0), + }; + await expectLiquidityResult( + mockWeb3Provider.object, + mockOrderProvider.object, + ordersAndFillableAmounts, + expectedResult, + ); + }); + + it('should return correct computed value when orders provided with full fillableAmounts', async () => { + const orders: SignedOrder[] = [sellTwoTokensFor1Weth, sellTenTokensFor10Weth]; + const ordersAndFillableAmounts = { + orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth], + remainingFillableMakerAssetAmounts: orders.map(o => o.makerAssetAmount), + }; + + const expectedTokensAvailable = orders[0].makerAssetAmount.plus(orders[1].makerAssetAmount); + const expectedEthValueAvailable = orders[0].takerAssetAmount.plus(orders[1].takerAssetAmount); + const expectedResult = { + tokensAvailableInBaseUnits: expectedTokensAvailable, + ethValueAvailableInWei: expectedEthValueAvailable, + }; + + await expectLiquidityResult( + mockWeb3Provider.object, + mockOrderProvider.object, + ordersAndFillableAmounts, + expectedResult, + ); + }); + + it('should return correct computed value with one partial fillableAmounts', async () => { + const ordersAndFillableAmounts = { + orders: [sellTwoTokensFor1Weth], + remainingFillableMakerAssetAmounts: [baseUnitAmount(1)], + }; + const expectedResult = { + tokensAvailableInBaseUnits: baseUnitAmount(1), + ethValueAvailableInWei: baseUnitAmount(0.5, WETH_DECIMALS), + }; + + await expectLiquidityResult( + mockWeb3Provider.object, + mockOrderProvider.object, + ordersAndFillableAmounts, + expectedResult, + ); + }); + + it('should return correct computed value with multiple orders and fillable amounts', async () => { + const ordersAndFillableAmounts = { + orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth], + remainingFillableMakerAssetAmounts: [baseUnitAmount(1), baseUnitAmount(3)], + }; + const expectedResult = { + tokensAvailableInBaseUnits: baseUnitAmount(4), + ethValueAvailableInWei: baseUnitAmount(3.5, WETH_DECIMALS), + }; + + await expectLiquidityResult( + mockWeb3Provider.object, + mockOrderProvider.object, + ordersAndFillableAmounts, + expectedResult, + ); + }); + + it('should return 0s when no amounts fillable', async () => { + const ordersAndFillableAmounts = { + orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth], + remainingFillableMakerAssetAmounts: [baseUnitAmount(0), baseUnitAmount(0)], + }; + const expectedResult = { + tokensAvailableInBaseUnits: baseUnitAmount(0), + ethValueAvailableInWei: baseUnitAmount(0, WETH_DECIMALS), + }; + + await expectLiquidityResult( + mockWeb3Provider.object, + mockOrderProvider.object, + ordersAndFillableAmounts, + expectedResult, + ); + }); + }); + }); +}); diff --git a/packages/asset-buyer/test/buy_quote_calculator_test.ts b/packages/asset-buyer/test/buy_quote_calculator_test.ts index cf443bef36..177fd8fe60 100644 --- a/packages/asset-buyer/test/buy_quote_calculator_test.ts +++ b/packages/asset-buyer/test/buy_quote_calculator_test.ts @@ -168,7 +168,7 @@ describe('buyQuoteCalculator', () => { }; testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(1)); }); - it('should throw without amount available to fill if amount rounds to 0', () => { + it('should throw with 0 available to fill if amount rounds to 0', () => { const smallOrder = orderFactory.createSignedOrderFromPartial({ makerAssetAmount: new BigNumber(1), takerAssetAmount: new BigNumber(1), @@ -184,7 +184,7 @@ describe('buyQuoteCalculator', () => { false, ); }; - testHelpers.expectInsufficientLiquidityError(expect, errorFunction, undefined); + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(0)); }); }); it('should not throw if order is fillable', () => { diff --git a/packages/asset-buyer/test/utils/mocks.ts b/packages/asset-buyer/test/utils/mocks.ts new file mode 100644 index 0000000000..d3e1c09c44 --- /dev/null +++ b/packages/asset-buyer/test/utils/mocks.ts @@ -0,0 +1,68 @@ +import { Web3ProviderEngine } from '@0x/subproviders'; +import * as TypeMoq from 'typemoq'; + +import { AssetBuyer } from '../../src/asset_buyer'; +import { OrderProvider, OrderProviderResponse, OrdersAndFillableAmounts } from '../../src/types'; + +// tslint:disable:promise-function-async + +// Implementing dummy class for using in mocks, see https://github.com/florinn/typemoq/issues/3 +class OrderProviderClass implements OrderProvider { + // tslint:disable-next-line:prefer-function-over-method + public async getOrdersAsync(): Promise { + return Promise.resolve({ orders: [] }); + } + // tslint:disable-next-line:prefer-function-over-method + public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise { + return Promise.resolve([]); + } +} + +export const orderProviderMock = () => { + return TypeMoq.Mock.ofType(OrderProviderClass, TypeMoq.MockBehavior.Strict); +}; + +export const mockAvailableAssetDatas = ( + mockOrderProvider: TypeMoq.IMock, + assetData: string, + availableAssetDatas: string[], +) => { + mockOrderProvider + .setup(op => op.getAvailableMakerAssetDatasAsync(TypeMoq.It.isValue(assetData))) + .returns(() => { + return Promise.resolve(availableAssetDatas); + }) + .verifiable(TypeMoq.Times.once()); +}; + +const partiallyMockedAssetBuyer = ( + provider: Web3ProviderEngine, + orderProvider: OrderProvider, +): TypeMoq.IMock => { + const rawAssetBuyer = new AssetBuyer(provider, orderProvider); + const mockedAssetBuyer = TypeMoq.Mock.ofInstance(rawAssetBuyer, TypeMoq.MockBehavior.Loose, false); + mockedAssetBuyer.callBase = true; + return mockedAssetBuyer; +}; + +const mockGetOrdersAndAvailableAmounts = ( + mockedAssetBuyer: TypeMoq.IMock, + assetData: string, + ordersAndFillableAmounts: OrdersAndFillableAmounts, +): void => { + mockedAssetBuyer + .setup(a => a.getOrdersAndFillableAmountsAsync(assetData, false)) + .returns(() => Promise.resolve(ordersAndFillableAmounts)) + .verifiable(TypeMoq.Times.once()); +}; + +export const mockedAssetBuyerWithOrdersAndFillableAmounts = ( + provider: Web3ProviderEngine, + orderProvider: OrderProvider, + assetData: string, + ordersAndFillableAmounts: OrdersAndFillableAmounts, +): TypeMoq.IMock => { + const mockedAssetBuyer = partiallyMockedAssetBuyer(provider, orderProvider); + mockGetOrdersAndAvailableAmounts(mockedAssetBuyer, assetData, ordersAndFillableAmounts); + return mockedAssetBuyer; +}; diff --git a/packages/asset-buyer/test/utils/test_helpers.ts b/packages/asset-buyer/test/utils/test_helpers.ts index 9c7c244af0..04a58d2c8e 100644 --- a/packages/asset-buyer/test/utils/test_helpers.ts +++ b/packages/asset-buyer/test/utils/test_helpers.ts @@ -6,7 +6,7 @@ export const testHelpers = { expectInsufficientLiquidityError: ( expect: Chai.ExpectStatic, functionWhichTriggersError: () => void, - expectedAmountAvailableToFill?: BigNumber, + expectedAmountAvailableToFill: BigNumber, ): void => { let wasErrorThrown = false; try { diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index 09c585cc5f..30199ae1d0 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "5.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "5.0.0", "changes": [ diff --git a/packages/contract-wrappers/CHANGELOG.md b/packages/contract-wrappers/CHANGELOG.md index 8281f5050e..28cbf2ec65 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 +## v5.0.1 - _January 17, 2019_ + + * Dependencies updated + ## v5.0.0 - _January 15, 2019_ * Renamed OrderStatus enum members to PascalCase to conform with tslint enum-naming rule (#1474) diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 8fefbd95c2..cc7dc1a3e1 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0x/contract-wrappers", - "version": "5.0.0", + "version": "5.0.1", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", @@ -69,7 +69,7 @@ "@0x/assert": "^1.0.23", "@0x/contract-addresses": "^2.2.0", "@0x/contract-artifacts": "^1.3.0", - "@0x/contracts-test-utils": "^2.0.0", + "@0x/contracts-test-utils": "^2.0.1", "@0x/fill-scenarios": "^1.1.2", "@0x/json-schemas": "^2.1.7", "@0x/order-utils": "^3.1.2", diff --git a/packages/dev-tools-pages/.gitignore b/packages/dev-tools-pages/.gitignore index 557b82311b..d70ebaa1da 100644 --- a/packages/dev-tools-pages/.gitignore +++ b/packages/dev-tools-pages/.gitignore @@ -1,3 +1 @@ -public -assets/fonts/*.woff -assets/fonts/*.woff2 \ No newline at end of file +public \ No newline at end of file diff --git a/packages/dev-tools-pages/assets/crawl.html b/packages/dev-tools-pages/assets/crawl.html index 9135c3edec..352300d733 100644 --- a/packages/dev-tools-pages/assets/crawl.html +++ b/packages/dev-tools-pages/assets/crawl.html @@ -1,20 +1,17 @@ - - - - - Document - - - - - - - \ No newline at end of file + + + + + Test + + + + + diff --git a/packages/dev-tools-pages/assets/fonts/.gitkeep b/packages/dev-tools-pages/assets/fonts/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/dev-tools-pages/assets/fonts/MaisonNeue-Bold-subset.woff2 b/packages/dev-tools-pages/assets/fonts/MaisonNeue-Bold-subset.woff2 new file mode 100644 index 0000000000..54424f6fcb Binary files /dev/null and b/packages/dev-tools-pages/assets/fonts/MaisonNeue-Bold-subset.woff2 differ diff --git a/packages/dev-tools-pages/assets/fonts/MaisonNeue-Book-subset.woff2 b/packages/dev-tools-pages/assets/fonts/MaisonNeue-Book-subset.woff2 new file mode 100644 index 0000000000..8c2dea7efd Binary files /dev/null and b/packages/dev-tools-pages/assets/fonts/MaisonNeue-Book-subset.woff2 differ diff --git a/packages/dev-tools-pages/package.json b/packages/dev-tools-pages/package.json index 79d4a840ff..feab72856f 100644 --- a/packages/dev-tools-pages/package.json +++ b/packages/dev-tools-pages/package.json @@ -1,18 +1,28 @@ { "name": "@0x/dev-tools-pages", - "version": "0.0.13", + "version": "0.0.14", "engines": { "node": ">=6.12" }, "private": true, "description": "0x Dev tools pages", "scripts": { - "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production && react-snap", + "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production", "build:ci": "yarn build", "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" + "dev": "webpack-dev-server --mode development --content-base public", + "deploy:all": "npm run build; npm run deploy:compiler; npm run deploy:compiler:index; npm run deploy:coverage; npm run deploy:coverage:index; npm run deploy:profiler; npm run deploy:profiler:index; npm run deploy:trace; npm run deploy:trace:index;", + "deploy:compiler": "DIR_NAME=./public/. BUCKET=s3://sol-compiler.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-trace*' --exclude 'bundle-profiler*'", + "deploy:coverage": "DIR_NAME=./public/. BUCKET=s3://sol-coverage.com yarn s3:sync --exclude 'bundle-compiler*' --exclude 'bundle-trace*' --exclude 'bundle-profiler*'", + "deploy:profiler": "DIR_NAME=./public/. BUCKET=s3://sol-profiler.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-trace*' --exclude 'bundle-compiler*'", + "deploy:trace": "DIR_NAME=./public/. BUCKET=s3://sol-trace.com yarn s3:sync --exclude 'bundle-cov*' --exclude 'bundle-compiler*' --exclude 'bundle-profiler*'", + "deploy:compiler:index": "DIR_NAME=./public/compiler/. BUCKET=s3://sol-compiler.com yarn s3:sync", + "deploy:coverage:index": "DIR_NAME=./public/coverage/. BUCKET=s3://sol-coverage.com yarn s3:sync", + "deploy:profiler:index": "DIR_NAME=./public/profiler/. BUCKET=s3://sol-profiler.com yarn s3:sync", + "deploy:trace:index": "DIR_NAME=./public/trace/. BUCKET=s3://sol-trace.com yarn s3:sync", + "s3:sync": "aws s3 sync $DIR_NAME $BUCKET --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js --exclude 'profiler/*' --exclude 'trace/*' --exclude 'coverage/*' --exclude 'compiler/*'" }, "license": "Apache-2.0", "dependencies": { @@ -51,7 +61,6 @@ "less-loader": "^4.1.0", "make-promises-safe": "^1.1.0", "raw-loader": "^0.5.1", - "react-snap": "^1.19.0", "react-svg-loader": "^2.1.0", "shx": "^0.2.2", "source-map-loader": "^0.2.4", @@ -65,12 +74,5 @@ "webpack-bundle-analyzer": "^3.0.3", "webpack-cli": "3.1.2", "webpack-dev-server": "^3.1.9" - }, - "reactSnap": { - "source": "public", - "puppeteerArgs": [ - "--no-sandbox", - "--disable-setuid-sandbox" - ] } } diff --git a/packages/dev-tools-pages/pages.js b/packages/dev-tools-pages/pages.js index 7609a07e91..488c2ecd78 100644 --- a/packages/dev-tools-pages/pages.js +++ b/packages/dev-tools-pages/pages.js @@ -11,26 +11,26 @@ const pages = [ 'og-title': { property: 'og:title', content: 'sol-compiler' }, 'og-description': { property: 'og:description', content: 'Solidity compilation that just works' }, 'og-type': { property: 'og:type', content: 'website' }, - 'og-image': { property: 'og:image', content: '/images/og-compiler' }, + 'og-image': { property: 'og:image', content: '/images/og-compiler.png' }, 'twitter:site': '@0xproject', - 'twitter:image': '/images/og-compiler', + 'twitter:image': '/images/og-compiler.png', }, }, { - title: 'sol-cov', - filename: 'cov/index.html', + title: 'sol-coverage', + filename: 'coverage/index.html', template: 'assets/index.html', - chunks: ['cov'], + chunks: ['coverage'], favicon: 'assets/favicons/cov.ico', minify: true, meta: { description: 'Solidity code coverage', - 'og-title': { property: 'og:title', content: 'sol-cov' }, + 'og-title': { property: 'og:title', content: 'sol-coverage' }, 'og-description': { property: 'og:description', content: 'Solidity code coverage' }, 'og-type': { property: 'og:type', content: 'website' }, - 'og-image': { property: 'og:image', content: '/images/og-cov' }, + 'og-image': { property: 'og:image', content: '/images/og-cov.png' }, 'twitter:site': '@0xproject', - 'twitter:image': '/images/og-cov', + 'twitter:image': '/images/og-cov.png', }, }, { @@ -45,9 +45,9 @@ const pages = [ 'og-title': { property: 'og:title', content: 'sol-profiler' }, 'og-description': { property: 'og:description', content: 'Gas profiling for Solidity' }, 'og-type': { property: 'og:type', content: 'website' }, - 'og-image': { property: 'og:image', content: '/images/og-profiler' }, + 'og-image': { property: 'og:image', content: '/images/og-profiler.png' }, 'twitter:site': '@0xproject', - 'twitter:image': '/images/og-profiler', + 'twitter:image': '/images/og-profiler.png', }, }, { @@ -62,9 +62,9 @@ const pages = [ 'og-title': { property: 'og:title', content: 'sol-trace' }, 'og-description': { property: 'og:description', content: 'Human-readable stack traces' }, 'og-type': { property: 'og:type', content: 'website' }, - 'og-image': { property: 'og:image', content: '/images/og-trace' }, + 'og-image': { property: 'og:image', content: '/images/og-trace.png' }, 'twitter:site': '@0xproject', - 'twitter:image': '/images/og-trace', + 'twitter:image': '/images/og-trace.png', }, }, ]; diff --git a/packages/dev-tools-pages/ts/components/call_to_action.tsx b/packages/dev-tools-pages/ts/components/call_to_action.tsx new file mode 100644 index 0000000000..3805a7c8c1 --- /dev/null +++ b/packages/dev-tools-pages/ts/components/call_to_action.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; +import styled from 'styled-components'; + +import { ContextInterface, ThemeContext } from 'ts/context'; + +import { Button } from './button'; + +const CallToAction: React.StatelessComponent = ({ children }) => ( + + {({ docLink }: ContextInterface) => ( + + + + + {children} + + )} + +); + +const StyledCallToAction = styled.section` + text-align: center; + padding-top: 0; + padding-bottom: 1rem; + padding-left: 2.5rem; + padding-right: 2.5rem; + min-height: min-content; + max-height: 37.5rem; + height: 20vh; + position: relative; +`; + +const CallToActionContainer = styled.div` + margin: 0 auto; + max-width: 590px; +`; + +export { CallToAction }; diff --git a/packages/dev-tools-pages/ts/components/code.tsx b/packages/dev-tools-pages/ts/components/code.tsx index c4f9cee248..0f7d6a0cd6 100644 --- a/packages/dev-tools-pages/ts/components/code.tsx +++ b/packages/dev-tools-pages/ts/components/code.tsx @@ -139,7 +139,6 @@ class Code extends React.Component { public render(): React.ReactNode { const { language, isLight, isDiff, children, gutterLength, canCopy } = this.props; const { hlCode } = this.state; - return ( @@ -157,7 +156,7 @@ class Code extends React.Component { diff --git a/packages/dev-tools-pages/ts/components/compiler.tsx b/packages/dev-tools-pages/ts/components/compiler.tsx index 694a535dd3..c00e3a2b99 100644 --- a/packages/dev-tools-pages/ts/components/compiler.tsx +++ b/packages/dev-tools-pages/ts/components/compiler.tsx @@ -45,7 +45,7 @@ const Dd = styled.dd` const cards = [ { - title: 'A Project-centric', + title: 'Project-centric', body: ( Compiles an entire project instead of only individual .sol files. @@ -54,7 +54,7 @@ const cards = [ }, { title: 'Incremental builds', - body: 'Recompiles your smart contracts after they have changed', + body: 'Only recompiles smart contracts that have been modified.', }, { title: 'Customizable artifacts', @@ -63,12 +63,16 @@ const cards = [ }, { title: 'Seamless', - body: 'Fetches and caches the required compiler binaries.', + body: 'Fetches and caches the required compiler binaries for the Solidity versions you use.', }, { title: 'Versioning', body: - 'Compiles each contract with the version specified at the top of its file (sol-compiler even supports version ranges!).', + 'Compiles each contract with the Solidity version specified at the top of its file (it even supports version ranges!).', + }, + { + title: 'Watch mode', + body: 'Have your contracts instantly recompile on file save.', }, ]; diff --git a/packages/dev-tools-pages/ts/components/footer.tsx b/packages/dev-tools-pages/ts/components/footer.tsx index 04fd9b88e9..7e44bf128d 100644 --- a/packages/dev-tools-pages/ts/components/footer.tsx +++ b/packages/dev-tools-pages/ts/components/footer.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import styled from 'styled-components'; import { context as compiler } from 'ts/context/compiler'; -import { context as cov } from 'ts/context/cov'; +import { context as coverage } from 'ts/context/coverage'; import { context as profiler } from 'ts/context/profiler'; import { context as trace } from 'ts/context/trace'; import MainIcon from 'ts/icons/logos/0x.svg'; @@ -12,7 +12,7 @@ import { media } from 'ts/variables'; import { Container } from './container'; import { Alpha, Beta } from './typography'; -const tools = [trace, cov, compiler, profiler]; +const tools = [trace, coverage, compiler, profiler]; const Footer: React.StatelessComponent<{}> = () => ( @@ -20,9 +20,9 @@ const Footer: React.StatelessComponent<{}> = () => ( Other tools by 0x - {_.map(tools, ({ title, subtitle, icon }) => ( + {_.map(tools, ({ title, subtitle, icon, name }) => ( - +
{title} @@ -37,6 +37,10 @@ const Footer: React.StatelessComponent<{}> = () => ( 0x is an open, permissionless protocol allowing for tokens to be traded on the Ethereum blockchain. + Interested in joining our team?{' '} + + We're hiring + diff --git a/packages/dev-tools-pages/ts/components/header.tsx b/packages/dev-tools-pages/ts/components/header.tsx index 2787692c11..4d3a8685c3 100644 --- a/packages/dev-tools-pages/ts/components/header.tsx +++ b/packages/dev-tools-pages/ts/components/header.tsx @@ -17,7 +17,7 @@ const Header: React.StatelessComponent<{}> = () => ( {title} - + Built by 0x diff --git a/packages/dev-tools-pages/ts/components/hero.tsx b/packages/dev-tools-pages/ts/components/hero.tsx index cdcad69820..e2977f3f2b 100644 --- a/packages/dev-tools-pages/ts/components/hero.tsx +++ b/packages/dev-tools-pages/ts/components/hero.tsx @@ -9,16 +9,16 @@ import { Beta } from './typography'; const Hero: React.StatelessComponent = ({ children }) => ( - {({ subtitle, tagline }: ContextInterface) => ( + {({ subtitle, tagline, docLink }: ContextInterface) => ( {subtitle} {tagline} - - {navigator.userAgent !== 'ReactSnap' ? children : null} + {children} )} diff --git a/packages/dev-tools-pages/ts/components/trace.tsx b/packages/dev-tools-pages/ts/components/trace.tsx index f41dac9b71..81f6db0aba 100644 --- a/packages/dev-tools-pages/ts/components/trace.tsx +++ b/packages/dev-tools-pages/ts/components/trace.tsx @@ -25,7 +25,7 @@ const Trace: React.StatelessComponent<{}> = () => ( troublemaking line of code. The only hint you'll get is a generic error. - Error: VM Exception while processing transaction: rever + Error: VM Exception while processing transaction: revert @@ -44,8 +44,8 @@ const Trace: React.StatelessComponent<{}> = () => ( Time-consuming

- Working with a large code-base that contains hundreds of smart contracts, - finding the failing line of code quickly becomes a daunting task. + Working within a large code-base that contains many smart contracts, finding the + failing line of code quickly becomes a daunting task.

@@ -78,8 +78,8 @@ const Trace: React.StatelessComponent<{}> = () => ( Exact location

- It shows you the exact location of the specific code linen and where it was - called from. + It shows you the exact location of the offending line and where it was called + from.

@@ -90,8 +90,7 @@ const Trace: React.StatelessComponent<{}> = () => ( Time-saving

Turning "Your code failed somewhere, good luck debugging it" into "Your code - failed on line X of contract Y", it drastically improves the developer - experience. + failed on line X of contract Y", drastically improves the developer experience.

diff --git a/packages/dev-tools-pages/ts/context/compiler.tsx b/packages/dev-tools-pages/ts/context/compiler.tsx index 177e265e58..e4642c826d 100644 --- a/packages/dev-tools-pages/ts/context/compiler.tsx +++ b/packages/dev-tools-pages/ts/context/compiler.tsx @@ -5,6 +5,7 @@ import { ContextInterface } from './index'; export const context: ContextInterface = { title: 'sol-compiler', name: 'compiler', + docLink: 'https://0x.org/docs/sol-compiler', subtitle: 'Solidity compilation that just works', tagline: 'Seamlessly compile an entire solidity project and generate customisable artifacts', icon: Icon, diff --git a/packages/dev-tools-pages/ts/context/cov.tsx b/packages/dev-tools-pages/ts/context/coverage.tsx similarity index 81% rename from packages/dev-tools-pages/ts/context/cov.tsx rename to packages/dev-tools-pages/ts/context/coverage.tsx index 1ade45e9d6..3e44b6ec23 100644 --- a/packages/dev-tools-pages/ts/context/cov.tsx +++ b/packages/dev-tools-pages/ts/context/coverage.tsx @@ -3,9 +3,10 @@ import Icon from 'ts/icons/logos/cov.svg'; import { ContextInterface } from './index'; export const context: ContextInterface = { - title: 'sol-cov', - name: 'cov', + title: 'sol-coverage', + name: 'coverage', subtitle: 'Solidity code coverage', + docLink: 'https://0x.org/docs/sol-coverage', tagline: 'Measure Solidity code coverage', icon: Icon, colors: { diff --git a/packages/dev-tools-pages/ts/context/index.tsx b/packages/dev-tools-pages/ts/context/index.tsx index 35c647ad68..97ccf5c162 100644 --- a/packages/dev-tools-pages/ts/context/index.tsx +++ b/packages/dev-tools-pages/ts/context/index.tsx @@ -3,6 +3,7 @@ import { createContext } from 'react'; interface ContextInterface { title?: string; name?: string; + docLink?: string; subtitle?: string; tagline?: string; icon?: React.ReactNode; diff --git a/packages/dev-tools-pages/ts/context/profiler.tsx b/packages/dev-tools-pages/ts/context/profiler.tsx index 5ccfa5b4ca..e2ddcb2309 100644 --- a/packages/dev-tools-pages/ts/context/profiler.tsx +++ b/packages/dev-tools-pages/ts/context/profiler.tsx @@ -5,6 +5,7 @@ import { ContextInterface } from './index'; export const context: ContextInterface = { title: 'sol-profiler', name: 'profiler', + docLink: 'https://0x.org/docs/sol-profiler', subtitle: 'Gas profiling for Solidity', tagline: "Implement data-guided optimizations by profiling your contract's gas usage", icon: Icon, diff --git a/packages/dev-tools-pages/ts/context/trace.tsx b/packages/dev-tools-pages/ts/context/trace.tsx index 9627cc0a4f..3c19661f2f 100644 --- a/packages/dev-tools-pages/ts/context/trace.tsx +++ b/packages/dev-tools-pages/ts/context/trace.tsx @@ -6,6 +6,7 @@ export const context: ContextInterface = { title: 'sol-trace', name: 'trace', subtitle: 'Human-readable stack traces', + docLink: 'https://0x.org/docs/sol-trace', tagline: 'Immediately locate Solidity errors and rapidly debug failed transactions', icon: Icon, colors: { diff --git a/packages/dev-tools-pages/ts/pages/compiler.tsx b/packages/dev-tools-pages/ts/pages/compiler.tsx index 93a667562e..407646add2 100644 --- a/packages/dev-tools-pages/ts/pages/compiler.tsx +++ b/packages/dev-tools-pages/ts/pages/compiler.tsx @@ -6,6 +6,7 @@ import { context } from 'ts/context/compiler'; import { Base } from 'ts/components/base'; import { Breakout } from 'ts/components/breakout'; +import { CallToAction } from 'ts/components/call_to_action'; import { Code } from 'ts/components/code'; import { Compiler as CompilerComponent } from 'ts/components/compiler'; import { Content } from 'ts/components/content'; @@ -24,6 +25,9 @@ const Animation = Loadable({ }, }); +const SOLIDITY_INPUT_FORMAT_DOCS = + 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#compiler-input-and-output-json-description'; + const Compiler: React.StatelessComponent<{}> = () => ( @@ -40,7 +44,7 @@ const Compiler: React.StatelessComponent<{}> = () => ( - cd /your_project_dir && sol-compiler + cd /your_project_dir && sol-compiler @@ -49,11 +53,11 @@ const Compiler: React.StatelessComponent<{}> = () => ( Configure via a compiler.json file.

- mkdir compiler.json + mkdir compiler.json

Example of settings:

- + {`{ "contractsDir": "contracts", "artifactsDir": "artifacts", @@ -74,15 +78,19 @@ const Compiler: React.StatelessComponent<{}> = () => ( - Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define - which parts of the artifact you need. + Sol compiler uses{' '} + + Solidity standard JSON input format + {' '} + to specify what to include in the generated artifacts. This way, you have complete flexibility on + what is included.

- Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define - which parts of the artifact you need. + In production, you want to optimize for a small bundle size, so your compiler.json config would + instruct sol-compiler to only output the contract ABI.

@@ -109,8 +117,9 @@ const Compiler: React.StatelessComponent<{}> = () => (

- Sometimes you need to use some debuggers or other dev tools and you’ll need more info in the - artifact. + In development, you need to use profiler and other dev tools that require more information from the + artifact. To do this, you can specify that the artifact also contain the bytecode, deployed bytecode + and source maps.

@@ -158,6 +167,9 @@ const Compiler: React.StatelessComponent<{}> = () => (
+
+ +
); diff --git a/packages/dev-tools-pages/ts/pages/cov.tsx b/packages/dev-tools-pages/ts/pages/coverage.tsx similarity index 56% rename from packages/dev-tools-pages/ts/pages/cov.tsx rename to packages/dev-tools-pages/ts/pages/coverage.tsx index 85487248ab..575891f3b3 100644 --- a/packages/dev-tools-pages/ts/pages/cov.tsx +++ b/packages/dev-tools-pages/ts/pages/coverage.tsx @@ -2,10 +2,11 @@ import * as React from 'react'; import { hydrate, render } from 'react-dom'; import * as Loadable from 'react-loadable'; -import { context } from 'ts/context/cov'; +import { context } from 'ts/context/coverage'; import { Base } from 'ts/components/base'; import { Breakout } from 'ts/components/breakout'; +import { CallToAction } from 'ts/components/call_to_action'; import { Code } from 'ts/components/code'; import { Content } from 'ts/components/content'; import { ContentBlock } from 'ts/components/content-block'; @@ -25,7 +26,7 @@ const Animation = Loadable({ }, }); -const Cov: React.StatelessComponent<{}> = () => ( +const Coverage: React.StatelessComponent<{}> = () => ( @@ -33,9 +34,9 @@ const Cov: React.StatelessComponent<{}> = () => (

- When it comes to writing smart contracts, testing is one of the most important steps of the process. - In order to quantify the robustness of your Solidity testing suite, you need to measure its code - coverage. + When it comes to writing secure smart contracts, testing is one of the most important steps in the + process. In order to quantify the robustness of your Solidity testing suite, you need to measure its + code coverage.

@@ -69,29 +70,57 @@ const Cov: React.StatelessComponent<{}> = () => ( - Use ganache-cli as a backing node. + Use{' '} + + Geth + {' '} + as a backing node. We recommend using our{' '} + + Devnet Docker container + {' '} + which sets up a Geth node for testing purposes.{' '} + + Ganache support is a work in progress. + - Understand and use web3-provider-engine. + Understand and use{' '} + + web3-provider-engine + + . - npm install @0x/sol-coverage --save + npm install @0x/sol-coverage --save

- Sol-cov is a subprovider that needs to be prepended to your provider engine. - Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-cov ships with - the SolCompilerArtifactAdapter for use with Sol-compiler{' '} + Sol-coverage is a subprovider that needs to be prepended to your{' '} + + provider engine + + . Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-coverage + ships with the SolCompilerArtifactAdapter for use with{' '} + + Sol-compiler + {' '} and TruffleArtifactAdapter for use with the{' '} - Truffle framework. You can also write your own and support any artifact format. + + Truffle framework + {' '} + (Also see our{' '} + + Truffle example project + {' '} + for a complete walk-through). You can also write your own and support any artifact format.

- + {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace'; // Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in @@ -99,16 +128,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi - + {`import { TruffleArtifactAdapter } from '@0x/sol-trace'; const projectRoot = '.'; -const solcVersion = '0.4.24'; +const solcVersion = '0.5.0'; const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`} - + {`import { AbstractArtifactAdapter } from '@0x/sol-trace'; class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...}; @@ -118,32 +147,33 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}

Now that we have an artifactAdapter, we can create a{' '} - RevertTraceSubprovider and append it to our provider engine. + CoverageSubprovider and append it to our provider engine.

- + {`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine'; -import { RevertTraceSubprovider } from '@0x/sol-coverage'; +import { CoverageSubprovider } from '@0x/sol-coverage'; const defaultFromAddress = "..."; // Some ethereum address with test funds -const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress); +const coverageSubprovider = new CoverageSubprovider(artifactAdapter, defaultFromAddress); const providerEngine = new ProviderEngine(); -providerEngine.addProvider(revertTraceSubprovider); +providerEngine.addProvider(coverageSubprovider); providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'})); providerEngine.start();`}
+ ); const root = document.getElementById('app'); if (root.hasChildNodes()) { - hydrate(, root); + hydrate(, root); } else { - render(, root); + render(, root); } diff --git a/packages/dev-tools-pages/ts/pages/profiler.tsx b/packages/dev-tools-pages/ts/pages/profiler.tsx index 16ac9088e5..0bc4efa456 100644 --- a/packages/dev-tools-pages/ts/pages/profiler.tsx +++ b/packages/dev-tools-pages/ts/pages/profiler.tsx @@ -6,6 +6,7 @@ import { context } from 'ts/context/profiler'; import { Base } from 'ts/components/base'; import { Breakout } from 'ts/components/breakout'; +import { CallToAction } from 'ts/components/call_to_action'; import { Code } from 'ts/components/code'; import { Content } from 'ts/components/content'; import { ContentBlock } from 'ts/components/content-block'; @@ -66,29 +67,57 @@ const Profiler: React.StatelessComponent<{}> = () => ( - Use ganache-cli as a backing node. + Use{' '} + + Geth + {' '} + as a backing node. We recommend using our{' '} + + Devnet Docker container + {' '} + which sets up a Geth node for testing purposes.{' '} + + Ganache support is a work in progress. + - Understand and use web3-provider-engine. + Understand and use{' '} + + web3-provider-engine + + . - npm install @0x/sol-trace --save + npm install @0x/sol-trace --save

- Sol-trace is a subprovider that needs to be prepended to your provider engine. - Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships + Sol-trace is a subprovider that needs to be prepended to your{' '} + + provider engine + + . Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships with the SolCompilerArtifactAdapter for use with{' '} - Sol-compiler and TruffleArtifactAdapter for use with the{' '} - Truffle framework. You can also write your own and support any artifact format. + + Sol-compiler + {' '} + and TruffleArtifactAdapter for use with the{' '} + + Truffle framework + {' '} + (Also see our{' '} + + Truffle example project + {' '} + for a complete walk-through). You can also write your own and support any artifact format.

- + {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace'; // Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in @@ -96,16 +125,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi - + {`import { TruffleArtifactAdapter } from '@0x/sol-trace'; const projectRoot = '.'; -const solcVersion = '0.4.24'; +const solcVersion = '0.5.0'; const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`} - + {`import { AbstractArtifactAdapter } from '@0x/sol-trace'; class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...}; @@ -115,25 +144,26 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}

Now that we have an artifactAdapter, we can create a{' '} - RevertTraceSubprovider and append it to our provider engine. + ProfilerSubprovider and append it to our provider engine.

- + {`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine'; -import { RevertTraceSubprovider } from '@0x/sol-coverage'; +import { ProfilerSubprovider } from '@0x/sol-profiler'; const defaultFromAddress = "..."; // Some ethereum address with test funds -const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress); +const profilerSubprovider = new ProfilerSubprovider(artifactAdapter, defaultFromAddress); const providerEngine = new ProviderEngine(); -providerEngine.addProvider(revertTraceSubprovider); +providerEngine.addProvider(profilerSubprovider); providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'})); providerEngine.start();`}
+ ); diff --git a/packages/dev-tools-pages/ts/pages/trace.tsx b/packages/dev-tools-pages/ts/pages/trace.tsx index cc34e0fbe7..cd6180fb94 100644 --- a/packages/dev-tools-pages/ts/pages/trace.tsx +++ b/packages/dev-tools-pages/ts/pages/trace.tsx @@ -6,6 +6,7 @@ import { context } from 'ts/context/trace'; import { Base } from 'ts/components/base'; import { Breakout } from 'ts/components/breakout'; +import { CallToAction } from 'ts/components/call_to_action'; import { Code } from 'ts/components/code'; import { Content } from 'ts/components/content'; import { ContentBlock } from 'ts/components/content-block'; @@ -36,29 +37,57 @@ const Trace: React.StatelessComponent<{}> = () => ( - Use ganache-cli as a backing node. + Use{' '} + + Geth + {' '} + as a backing node. We recommend using our{' '} + + Devnet Docker container + {' '} + which sets up a Geth node for testing purposes.{' '} + + Ganache support is a work in progress. + - Understand and use web3-provider-engine. + Understand and use{' '} + + web3-provider-engine + + . - npm install @0x/sol-trace --save + npm install @0x/sol-trace --save

- Sol-trace is a subprovider that needs to be prepended to your provider engine. - Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships + Sol-trace is a subprovider that needs to be prepended to your{' '} + + provider engine + + . Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships with the SolCompilerArtifactAdapter for use with{' '} - Sol-compiler and TruffleArtifactAdapter for use with the{' '} - Truffle framework. You can also write your own and support any artifact format. + + Sol-compiler + {' '} + and TruffleArtifactAdapter for use with the{' '} + + Truffle framework + {' '} + (Also see our{' '} + + Truffle example project + {' '} + for a complete walk-through). You can also write your own and support any artifact format.

- + {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace'; // Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in @@ -66,16 +95,16 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi - + {`import { TruffleArtifactAdapter } from '@0x/sol-trace'; const projectRoot = '.'; -const solcVersion = '0.4.24'; +const solcVersion = '0.5.0'; const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`} - + {`import { AbstractArtifactAdapter } from '@0x/sol-trace'; class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...}; @@ -85,13 +114,13 @@ const artifactAdapter = new YourCustomArtifactsAdapter(...);`}

Now that we have an artifactAdapter, we can create a{' '} - RevertTraceSubprovider and append it to our provider engine. + revertTraceSubprovider and append it to our provider engine.

- + {`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine'; -import { RevertTraceSubprovider } from '@0x/sol-coverage'; +import { RevertTraceSubprovider } from '@0x/sol-trace'; const defaultFromAddress = "..."; // Some ethereum address with test funds const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress); @@ -102,8 +131,10 @@ providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}) providerEngine.start();`} +

Stack traces will now be printed whenever your contracts revert!

+ ); diff --git a/packages/dev-tools-pages/webpack.config.js b/packages/dev-tools-pages/webpack.config.js index 640297770e..ef2f98cf20 100644 --- a/packages/dev-tools-pages/webpack.config.js +++ b/packages/dev-tools-pages/webpack.config.js @@ -3,7 +3,6 @@ const webpack = require('webpack'); const TerserPlugin = require('terser-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const HtmlWebpackPlugin = require('html-webpack-plugin'); -const childProcess = require('child_process'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); @@ -12,7 +11,7 @@ const pages = require('./pages'); const config = { entry: { compiler: './ts/pages/compiler.tsx', - cov: './ts/pages/cov.tsx', + coverage: './ts/pages/coverage.tsx', profiler: './ts/pages/profiler.tsx', trace: './ts/pages/trace.tsx', }, diff --git a/packages/devnet/genesis.json b/packages/devnet/genesis.json index 03dc5d6231..073672dd95 100644 --- a/packages/devnet/genesis.json +++ b/packages/devnet/genesis.json @@ -8,7 +8,7 @@ "eip158Block": 3, "byzantiumBlock": 4, "clique": { - "period": 1, + "period": 0, "epoch": 30000 } }, diff --git a/packages/instant/package.json b/packages/instant/package.json index 36409ef3d1..86fac9afe1 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -1,6 +1,6 @@ { "name": "@0x/instant", - "version": "1.0.7", + "version": "1.0.8", "engines": { "node": ">=6.12" }, @@ -42,7 +42,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md", "dependencies": { "@0x/assert": "^1.0.23", - "@0x/asset-buyer": "^4.0.1", + "@0x/asset-buyer": "^4.0.2", "@0x/json-schemas": "^2.1.7", "@0x/order-utils": "^3.1.2", "@0x/subproviders": "^2.1.11", diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts index d172f41457..0acf3f2ad1 100644 --- a/packages/instant/src/index.umd.ts +++ b/packages/instant/src/index.umd.ts @@ -1,3 +1,6 @@ +import { AssetBuyer, BigNumber } from '@0x/asset-buyer'; +import { assetDataUtils } from '@0x/order-utils'; +import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; @@ -9,9 +12,12 @@ import { INJECTED_DIV_ID, NPM_PACKAGE_VERSION, } from './constants'; +import { assetMetaDataMap } from './data/asset_meta_data_map'; import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index'; +import { Network, OrderSource } from './types'; import { analytics } from './util/analytics'; import { assert } from './util/assert'; +import { providerFactory } from './util/provider_factory'; import { util } from './util/util'; const isInstantRendered = (): boolean => !!document.getElementById(INJECTED_DIV_ID); @@ -122,6 +128,42 @@ export const render = (config: ZeroExInstantConfig, selector: string = DEFAULT_Z window.onpopstate = onPopStateHandler; }; +export const assetDataForERC20TokenAddress = (tokenAddress: string): string => { + assert.isETHAddressHex('tokenAddress', tokenAddress); + return assetDataUtils.encodeERC20AssetData(tokenAddress); +}; + +export const hasMetaDataForAssetData = (assetData: string): boolean => { + assert.isHexString('assetData', assetData); + return assetMetaDataMap[assetData] !== undefined; +}; + +export const hasLiquidityForAssetDataAsync = async ( + assetData: string, + orderSource: OrderSource, + networkId: Network = Network.Mainnet, + provider?: Provider, +): Promise => { + assert.isHexString('assetData', assetData); + assert.isValidOrderSource('orderSource', orderSource); + assert.isNumber('networkId', networkId); + + if (provider !== undefined) { + assert.isWeb3Provider('provider', provider); + } + + const bestProvider: Provider = provider || providerFactory.getFallbackNoSigningProvider(networkId); + + const assetBuyerOptions = { networkId }; + + const assetBuyer = _.isString(orderSource) + ? AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(bestProvider, orderSource, assetBuyerOptions) + : AssetBuyer.getAssetBuyerForProvidedOrders(bestProvider, orderSource, assetBuyerOptions); + + const liquidity = await assetBuyer.getLiquidityForAssetDataAsync(assetData); + return liquidity.ethValueAvailableInWei.gt(new BigNumber(0)); +}; + // Write version info to the exported object for debugging export const GIT_SHA = GIT_SHA_FROM_CONSTANT; export const NPM_VERSION = NPM_PACKAGE_VERSION; diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index bd665632f6..3b082f075e 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -1,6 +1,6 @@ { "name": "@0x/metacoin", - "version": "0.0.35", + "version": "0.0.36", "engines": { "node": ">=6.12" }, @@ -32,9 +32,9 @@ "@0x/abi-gen": "^1.0.22", "@0x/abi-gen-templates": "^1.0.2", "@0x/base-contract": "^3.0.13", - "@0x/sol-coverage": "^1.0.2", - "@0x/sol-profiler": "^1.0.2", - "@0x/sol-trace": "^1.0.2", + "@0x/sol-coverage": "^1.0.3", + "@0x/sol-profiler": "^1.0.3", + "@0x/sol-trace": "^1.0.3", "@0x/subproviders": "^2.1.11", "@0x/tslint-config": "^2.0.2", "@0x/types": "^1.5.2", diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index e18aa1d2ff..187a80c933 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.18", + "version": "1.0.19", "engines": { "node": ">=6.12" }, diff --git a/packages/monorepo-scripts/src/prepublish_checks.ts b/packages/monorepo-scripts/src/prepublish_checks.ts index 82eaf5cf9b..021e572266 100644 --- a/packages/monorepo-scripts/src/prepublish_checks.ts +++ b/packages/monorepo-scripts/src/prepublish_checks.ts @@ -6,6 +6,8 @@ import semverSort = require('semver-sort'); import { constants } from './constants'; import { Package } from './types'; import { changelogUtils } from './utils/changelog_utils'; +import { configs } from './utils/configs'; +import { dockerHubUtils } from './utils/docker_hub_utils'; import { npmUtils } from './utils/npm_utils'; import { utils } from './utils/utils'; @@ -17,6 +19,12 @@ async function prepublishChecksAsync(): Promise { await checkChangelogFormatAsync(updatedPublicPackages); await checkGitTagsForNextVersionAndDeleteIfExistAsync(updatedPublicPackages); await checkPublishRequiredSetupAsync(); + await checkDockerHubSetupAsync(); +} + +async function checkDockerHubSetupAsync(): Promise { + await dockerHubUtils.checkUserAddedToOrganizationOrThrowAsync(configs.DOCKER_HUB_ORG); + await dockerHubUtils.loginUserToDockerCommandlineOrThrowAsync(); } async function checkGitTagsForNextVersionAndDeleteIfExistAsync(updatedPublicPackages: Package[]): Promise { diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index e0602a74f8..105d87dcd0 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -1,11 +1,12 @@ #!/usr/bin/env node +import { logUtils } from '@0x/utils'; import * as promisify from 'es6-promisify'; import * as fs from 'fs'; import * as _ from 'lodash'; import * as moment from 'moment'; import opn = require('opn'); -import { exec as execAsync } from 'promisify-child-process'; +import { exec as execAsync, spawn as spawnAsync } from 'promisify-child-process'; import * as prompt from 'prompt'; import semver = require('semver'); import semverSort = require('semver-sort'); @@ -79,12 +80,16 @@ async function confirmAsync(message: string): Promise { }); utils.log(`Calling 'lerna publish'...`); await lernaPublishAsync(packageToNextVersion); - if (!configs.IS_LOCAL_PUBLISH) { + + const isDryRun = configs.IS_LOCAL_PUBLISH; + if (!isDryRun) { + // Publish docker images to DockerHub + await publishImagesToDockerHubAsync(allPackagesToPublish); + const isStaging = false; const shouldUploadDocs = true; await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs); } - const isDryRun = configs.IS_LOCAL_PUBLISH; const releaseNotes = await publishReleaseNotesAsync(updatedPublicPackages, isDryRun); utils.log('Published release notes'); @@ -95,11 +100,45 @@ async function confirmAsync(message: string): Promise { utils.log("Publish successful, but couldn't auto-alert discord (", e.message, '), Please alert manually.'); } } + process.exit(0); })().catch(err => { utils.log(err); process.exit(1); }); +async function publishImagesToDockerHubAsync(allUpdatedPackages: Package[]): Promise { + for (const pkg of allUpdatedPackages) { + const packageJSON = pkg.packageJson; + const shouldPublishDockerImage = + !_.isUndefined(packageJSON.config) && + !_.isUndefined(packageJSON.config.postpublish) && + !_.isUndefined(packageJSON.config.postpublish.dockerHubRepo); + if (!shouldPublishDockerImage) { + continue; + } + const dockerHubRepo = _.get(packageJSON, 'config.postpublish.dockerHubRepo'); + const pkgName = pkg.packageJson.name; + const packageDirName = _.startsWith(pkgName, '@0x/') ? pkgName.split('/')[1] : pkgName; + + // Build the Docker image + logUtils.log(`Building '${dockerHubRepo}' docker image...`); + await spawnAsync('docker', ['build', '-t', dockerHubRepo, '.'], { + cwd: `${constants.monorepoRootPath}/packages/${packageDirName}`, + }); + + // Tag the docker image with the latest version + const version = pkg.packageJson.version; + logUtils.log(`Tagging '${dockerHubRepo}' docker image with version ${version}...`); + await execAsync(`docker tag ${dockerHubRepo} ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:${version}`); + await execAsync(`docker tag ${dockerHubRepo} ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:latest`); + + // Publish to DockerHub + logUtils.log(`Pushing '${dockerHubRepo}' docker image to DockerHub...`); + await execAsync(`docker push ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:${version}`); + await execAsync(`docker push ${configs.DOCKER_HUB_ORG}/${dockerHubRepo}:latest`); + } +} + function getPackagesWithDocs(allUpdatedPackages: Package[]): Package[] { const rootPackageJsonPath = `${constants.monorepoRootPath}/package.json`; const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath).toString()); diff --git a/packages/monorepo-scripts/src/types.ts b/packages/monorepo-scripts/src/types.ts index 3c2ec50695..4af4fd257e 100644 --- a/packages/monorepo-scripts/src/types.ts +++ b/packages/monorepo-scripts/src/types.ts @@ -41,7 +41,11 @@ export interface PackageJSON { main?: string; scripts?: { [command: string]: string }; config?: { - additionalTsTypings?: string[]; + postpublish?: { + assets?: string[]; + docOmitExports?: string[]; + dockerHubRepo?: string; + }; }; } diff --git a/packages/monorepo-scripts/src/utils/configs.ts b/packages/monorepo-scripts/src/utils/configs.ts index e579bdb7c3..b6b6e2c5ee 100644 --- a/packages/monorepo-scripts/src/utils/configs.ts +++ b/packages/monorepo-scripts/src/utils/configs.ts @@ -5,4 +5,5 @@ const REMOTE_NPM_REGISTRY_URL = 'https://registry.npmjs.org'; export const configs = { IS_LOCAL_PUBLISH, NPM_REGISTRY_URL: IS_LOCAL_PUBLISH ? LOCAL_NPM_REGISTRY_URL : REMOTE_NPM_REGISTRY_URL, + DOCKER_HUB_ORG: '0xorg', }; diff --git a/packages/monorepo-scripts/src/utils/docker_hub_utils.ts b/packages/monorepo-scripts/src/utils/docker_hub_utils.ts new file mode 100644 index 0000000000..62215a5797 --- /dev/null +++ b/packages/monorepo-scripts/src/utils/docker_hub_utils.ts @@ -0,0 +1,65 @@ +import { fetchAsync } from '@0x/utils'; +import { exec as execAsync } from 'promisify-child-process'; + +import { utils } from './utils'; + +const API_ENDPOINT = 'https://hub.docker.com/v2'; +const HTTP_OK_STATUS = 200; + +export const dockerHubUtils = { + async getTokenAsync(): Promise { + const payload = { + username: process.env.DOCKER_USERNAME, + password: process.env.DOCKER_PASS, + }; + const response = await fetchAsync(`${API_ENDPOINT}/users/login`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + }); + if (response.status !== HTTP_OK_STATUS) { + throw new Error( + `DockerHub user login failed (status code: ${ + response.status + }). Make sure you have environment variables 'DOCKER_USERNAME; and 'DOCKER_PASS' set`, + ); + } + const respPayload = await response.json(); + const token = respPayload.token; + return token; + }, + async checkUserAddedToOrganizationOrThrowAsync(organization: string): Promise { + utils.log('Checking that the user was added to the 0xorg DockerHub organization...'); + const token = await dockerHubUtils.getTokenAsync(); + const response = await fetchAsync(`${API_ENDPOINT}/repositories/${organization}/?page_size=10`, { + method: 'GET', + headers: { + Accept: 'application/json', + Authorization: `JWT ${token}`, + }, + }); + const respPayload = await response.json(); + if (response.status !== HTTP_OK_STATUS || respPayload.count === 0) { + throw new Error( + `Failed to fetch org: ${organization}'s list of repos (status code: ${ + response.status + }). Make sure your account has been added to the '${organization}' org on DockerHub`, + ); + } + }, + async loginUserToDockerCommandlineOrThrowAsync(): Promise { + try { + utils.log('Checking that the user is logged in to docker command...'); + await execAsync(`echo "$DOCKER_PASS" | docker login -u $DOCKER_USERNAME --password-stdin`); + } catch (err) { + throw new Error( + `Failed to log you into the 'docker' commandline tool. Make sure you have the 'docker' commandline tool installed. Full error: ${ + err.message + }`, + ); + } + }, +}; diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 95b187cc27..28c5658f3d 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -106,8 +106,10 @@ export const utils = { return nextVersionIfValid; }, async getRemoteGitTagsAsync(): Promise { + const TEN_MEGA_BYTES = 1024 * 1024 * 10; // tslint:disable-line custom-no-magic-numbers const result = await execAsync(`git ls-remote --tags`, { cwd: constants.monorepoRootPath, + maxBuffer: TEN_MEGA_BYTES, }); const tagsString = result.stdout; const tagOutputs: string[] = tagsString.split('\n'); diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index 4f96487ed0..585bb48e68 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "2.4.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "2.4.2", diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md index e5f4833cd8..df065866c6 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.4.3 - _January 17, 2019_ + + * Dependencies updated + ## v2.4.2 - _January 15, 2019_ * Dependencies updated diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index ab95289113..895c648135 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -1,6 +1,6 @@ { "name": "@0x/order-watcher", - "version": "2.4.2", + "version": "2.4.3", "description": "An order watcher daemon that watches for order validity", "keywords": [ "0x", @@ -24,6 +24,11 @@ "run_mocha": "mocha --require source-map-support/register --require make-promises-safe lib/test/**/*_test.js lib/test/global_hooks.js --timeout 10000 --bail --exit", "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" }, + "config": { + "postpublish": { + "dockerHubRepo": "order-watcher" + } + }, "repository": { "type": "git", "url": "https://github.com/0xProject/0x-monorepo" @@ -63,7 +68,7 @@ "@0x/base-contract": "^3.0.13", "@0x/contract-addresses": "^2.2.0", "@0x/contract-artifacts": "^1.3.0", - "@0x/contract-wrappers": "^5.0.0", + "@0x/contract-wrappers": "^5.0.1", "@0x/fill-scenarios": "^1.1.2", "@0x/json-schemas": "^2.1.7", "@0x/order-utils": "^3.1.2", diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 47d36ca667..4be4742b02 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -52,7 +52,7 @@ "material-ui": "^0.20.0", "react": "^16.5.2", "react-dom": "^16.5.2", - "react-highlight": "0xproject/react-highlight#699ac4d9529e33520bff4b9bd9c624d21efbba75", + "react-highlight": "0xproject/react-highlight#fix/react-version", "react-markdown": "^3.2.2", "react-router-dom": "^4.1.1", "react-scroll": "0xproject/react-scroll#pr-330-and-replace-state", diff --git a/packages/sol-coverage/CHANGELOG.json b/packages/sol-coverage/CHANGELOG.json index 1b7aef0f3b..550ca2feb9 100644 --- a/packages/sol-coverage/CHANGELOG.json +++ b/packages/sol-coverage/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.2", diff --git a/packages/sol-coverage/CHANGELOG.md b/packages/sol-coverage/CHANGELOG.md index ac09a1bbf0..18c1719bf7 100644 --- a/packages/sol-coverage/CHANGELOG.md +++ b/packages/sol-coverage/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.3 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.2 - _January 15, 2019_ * Dependencies updated diff --git a/packages/sol-coverage/package.json b/packages/sol-coverage/package.json index efe91cf2bb..805e2e6703 100644 --- a/packages/sol-coverage/package.json +++ b/packages/sol-coverage/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-coverage", - "version": "1.0.2", + "version": "1.0.3", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-coverage/README.md", "dependencies": { - "@0x/sol-tracing-utils": "^4.0.0", + "@0x/sol-tracing-utils": "^4.0.1", "@0x/subproviders": "^2.1.11", "@0x/typescript-typings": "^3.0.8", "ethereum-types": "^1.1.6", diff --git a/packages/sol-profiler/CHANGELOG.json b/packages/sol-profiler/CHANGELOG.json index 1b7aef0f3b..550ca2feb9 100644 --- a/packages/sol-profiler/CHANGELOG.json +++ b/packages/sol-profiler/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.2", diff --git a/packages/sol-profiler/CHANGELOG.md b/packages/sol-profiler/CHANGELOG.md index ac09a1bbf0..18c1719bf7 100644 --- a/packages/sol-profiler/CHANGELOG.md +++ b/packages/sol-profiler/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.3 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.2 - _January 15, 2019_ * Dependencies updated diff --git a/packages/sol-profiler/package.json b/packages/sol-profiler/package.json index 1a89e0a6bf..4fe2928c7a 100644 --- a/packages/sol-profiler/package.json +++ b/packages/sol-profiler/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-profiler", - "version": "1.0.2", + "version": "1.0.3", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-profiler/README.md", "dependencies": { - "@0x/sol-tracing-utils": "^4.0.0", + "@0x/sol-tracing-utils": "^4.0.1", "@0x/subproviders": "^2.1.11", "@0x/typescript-typings": "^3.0.8", "ethereum-types": "^1.1.6", diff --git a/packages/sol-trace/CHANGELOG.json b/packages/sol-trace/CHANGELOG.json index 1b7aef0f3b..550ca2feb9 100644 --- a/packages/sol-trace/CHANGELOG.json +++ b/packages/sol-trace/CHANGELOG.json @@ -8,6 +8,15 @@ } ] }, + { + "timestamp": 1547747677, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1547561734, "version": "1.0.2", diff --git a/packages/sol-trace/CHANGELOG.md b/packages/sol-trace/CHANGELOG.md index ac09a1bbf0..18c1719bf7 100644 --- a/packages/sol-trace/CHANGELOG.md +++ b/packages/sol-trace/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.3 - _January 17, 2019_ + + * Dependencies updated + ## v1.0.2 - _January 15, 2019_ * Dependencies updated diff --git a/packages/sol-trace/package.json b/packages/sol-trace/package.json index acae60303f..2aedf7ebc8 100644 --- a/packages/sol-trace/package.json +++ b/packages/sol-trace/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-trace", - "version": "1.0.2", + "version": "1.0.3", "engines": { "node": ">=6.12" }, @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-trace/README.md", "dependencies": { - "@0x/sol-tracing-utils": "^4.0.0", + "@0x/sol-tracing-utils": "^4.0.1", "@0x/subproviders": "^2.1.11", "@0x/typescript-typings": "^3.0.8", "ethereum-types": "^1.1.6", diff --git a/packages/sol-trace/src/revert_trace_subprovider.ts b/packages/sol-trace/src/revert_trace_subprovider.ts index fa065cfcb1..046dad8124 100644 --- a/packages/sol-trace/src/revert_trace_subprovider.ts +++ b/packages/sol-trace/src/revert_trace_subprovider.ts @@ -109,9 +109,7 @@ export class RevertTraceSubprovider extends TraceCollectionSubprovider { const fileNameToFileIndex = _.invert(contractData.sources); const fileIndex = _.parseInt(fileNameToFileIndex[sourceRange.fileName]); const sourceSnippet = getSourceRangeSnippet(sourceRange, contractData.sourceCodes[fileIndex]); - if (sourceSnippet !== null) { - sourceSnippets.push(sourceSnippet); - } + sourceSnippets.push(sourceSnippet); } const filteredSnippets = filterSnippets(sourceSnippets); if (filteredSnippets.length > 0) { @@ -135,9 +133,7 @@ function filterSnippets(sourceSnippets: SourceSnippet[]): SourceSnippet[] { const results: SourceSnippet[] = [sourceSnippets[0]]; let prev = sourceSnippets[0]; for (const sourceSnippet of sourceSnippets) { - if (sourceSnippet.type === 'IfStatement') { - continue; - } else if (sourceSnippet.source === prev.source) { + if (sourceSnippet.source === prev.source) { prev = sourceSnippet; continue; } @@ -157,12 +153,5 @@ function getStackTraceString(sourceSnippet: SourceSnippet): string { } function getSourceSnippetString(sourceSnippet: SourceSnippet): string { - switch (sourceSnippet.type) { - case 'ContractDefinition': - return `contract ${sourceSnippet.name}`; - case 'FunctionDefinition': - return `function ${sourceSnippet.name}`; - default: - return `${sourceSnippet.source}`; - } + return `${sourceSnippet.source}`; } diff --git a/packages/sol-tracing-utils/CHANGELOG.json b/packages/sol-tracing-utils/CHANGELOG.json index f47baf65aa..ef96dc69b0 100644 --- a/packages/sol-tracing-utils/CHANGELOG.json +++ b/packages/sol-tracing-utils/CHANGELOG.json @@ -8,6 +8,24 @@ } ] }, + { + "version": "4.0.1", + "changes": [ + { + "note": "Fix a bug where a custom `Geth` tracer didn't return stack entries for `DELEGATECALL`", + "pr": 1521 + }, + { + "note": "Fix a bug where `TraceCollectionSubprovider` was hanging on the fake `Geth` snapshot transaction", + "pr": 1521 + }, + { + "note": "Fix/simplify handling of revert trace snippets", + "pr": 1521 + } + ], + "timestamp": 1547747677 + }, { "version": "4.0.0", "changes": [ diff --git a/packages/sol-tracing-utils/CHANGELOG.md b/packages/sol-tracing-utils/CHANGELOG.md index 00d36844ce..9bffb2a6d9 100644 --- a/packages/sol-tracing-utils/CHANGELOG.md +++ b/packages/sol-tracing-utils/CHANGELOG.md @@ -5,6 +5,12 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v4.0.1 - _January 17, 2019_ + + * Fix a bug where a custom `Geth` tracer didn't return stack entries for `DELEGATECALL` (#1521) + * Fix a bug where `TraceCollectionSubprovider` was hanging on the fake `Geth` snapshot transaction (#1521) + * Fix/simplify handling of revert trace snippets (#1521) + ## v4.0.0 - _January 15, 2019_ * Fix a bug with incorrect parsing of `sourceMaps` due to sources being in an array instead of a map (#1498) diff --git a/packages/sol-tracing-utils/package.json b/packages/sol-tracing-utils/package.json index e3e52f42c8..cabb752d28 100644 --- a/packages/sol-tracing-utils/package.json +++ b/packages/sol-tracing-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0x/sol-tracing-utils", - "version": "4.0.0", + "version": "4.0.1", "engines": { "node": ">=6.12" }, diff --git a/packages/sol-tracing-utils/src/get_source_range_snippet.ts b/packages/sol-tracing-utils/src/get_source_range_snippet.ts index 7aef00fee8..c1f6e3a4e9 100644 --- a/packages/sol-tracing-utils/src/get_source_range_snippet.ts +++ b/packages/sol-tracing-utils/src/get_source_range_snippet.ts @@ -1,185 +1,16 @@ -import * as ethUtil from 'ethereumjs-util'; -import * as _ from 'lodash'; -import * as Parser from 'solidity-parser-antlr'; - -import { SingleFileSourceRange, SourceRange, SourceSnippet } from './types'; +import { SourceRange, SourceSnippet } from './types'; import { utils } from './utils'; -interface ASTInfo { - type: string; - node: Parser.ASTNode; - name: string | null; - range?: SingleFileSourceRange; -} - -// Parsing source code for each transaction/code is slow and therefore we cache it -const hashToParsedSource: { [sourceHash: string]: Parser.ASTNode } = {}; - /** * Gets the source range snippet by source range to be used by revert trace. * @param sourceRange source range * @param sourceCode source code */ -export function getSourceRangeSnippet(sourceRange: SourceRange, sourceCode: string): SourceSnippet | null { - const sourceHash = ethUtil.sha3(sourceCode).toString('hex'); - if (_.isUndefined(hashToParsedSource[sourceHash])) { - hashToParsedSource[sourceHash] = Parser.parse(sourceCode, { loc: true }); - } - const astNode = hashToParsedSource[sourceHash]; - const visitor = new ASTInfoVisitor(); - Parser.visit(astNode, visitor); - const astInfo = visitor.getASTInfoForRange(sourceRange); - if (astInfo === null) { - return null; - } +export function getSourceRangeSnippet(sourceRange: SourceRange, sourceCode: string): SourceSnippet { const sourceCodeInRange = utils.getRange(sourceCode, sourceRange.location); return { - ...astInfo, - range: astInfo.range as SingleFileSourceRange, + range: sourceRange.location, source: sourceCodeInRange, fileName: sourceRange.fileName, }; } - -// A visitor which collects ASTInfo for most nodes in the AST. -class ASTInfoVisitor { - private readonly _astInfos: ASTInfo[] = []; - public getASTInfoForRange(sourceRange: SourceRange): ASTInfo | null { - // HACK(albrow): Sometimes the source range doesn't exactly match that - // of astInfo. To work around that we try with a +/-1 offset on - // end.column. If nothing matches even with the offset, we return null. - const offset = { - start: { - line: 0, - column: 0, - }, - end: { - line: 0, - column: 0, - }, - }; - let astInfo = this._getASTInfoForRange(sourceRange, offset); - if (astInfo !== null) { - return astInfo; - } - offset.end.column += 1; - astInfo = this._getASTInfoForRange(sourceRange, offset); - if (astInfo !== null) { - return astInfo; - } - offset.end.column -= 2; - astInfo = this._getASTInfoForRange(sourceRange, offset); - if (astInfo !== null) { - return astInfo; - } - return null; - } - public ContractDefinition(ast: Parser.ContractDefinition): void { - this._visitContractDefinition(ast); - } - public IfStatement(ast: Parser.IfStatement): void { - this._visitStatement(ast); - } - public FunctionDefinition(ast: Parser.FunctionDefinition): void { - this._visitFunctionLikeDefinition(ast); - } - public ModifierDefinition(ast: Parser.ModifierDefinition): void { - this._visitFunctionLikeDefinition(ast); - } - public ForStatement(ast: Parser.ForStatement): void { - this._visitStatement(ast); - } - public ReturnStatement(ast: Parser.ReturnStatement): void { - this._visitStatement(ast); - } - public BreakStatement(ast: Parser.BreakStatement): void { - this._visitStatement(ast); - } - public ContinueStatement(ast: Parser.ContinueStatement): void { - this._visitStatement(ast); - } - public EmitStatement(ast: any /* TODO: Parser.EmitStatement */): void { - this._visitStatement(ast); - } - public VariableDeclarationStatement(ast: Parser.VariableDeclarationStatement): void { - this._visitStatement(ast); - } - public Statement(ast: Parser.Statement): void { - this._visitStatement(ast); - } - public WhileStatement(ast: Parser.WhileStatement): void { - this._visitStatement(ast); - } - public SimpleStatement(ast: Parser.SimpleStatement): void { - this._visitStatement(ast); - } - public ThrowStatement(ast: Parser.ThrowStatement): void { - this._visitStatement(ast); - } - public DoWhileStatement(ast: Parser.DoWhileStatement): void { - this._visitStatement(ast); - } - public ExpressionStatement(ast: Parser.ExpressionStatement): void { - this._visitStatement(ast.expression); - } - public InlineAssemblyStatement(ast: Parser.InlineAssemblyStatement): void { - this._visitStatement(ast); - } - public ModifierInvocation(ast: Parser.ModifierInvocation): void { - const BUILTIN_MODIFIERS = ['public', 'view', 'payable', 'external', 'internal', 'pure', 'constant']; - if (!_.includes(BUILTIN_MODIFIERS, ast.name)) { - this._visitStatement(ast); - } - } - private _visitStatement(ast: Parser.ASTNode): void { - this._astInfos.push({ - type: ast.type, - node: ast, - name: null, - range: ast.loc, - }); - } - private _visitFunctionLikeDefinition(ast: Parser.ModifierDefinition | Parser.FunctionDefinition): void { - this._astInfos.push({ - type: ast.type, - node: ast, - name: ast.name, - range: ast.loc, - }); - } - private _visitContractDefinition(ast: Parser.ContractDefinition): void { - this._astInfos.push({ - type: ast.type, - node: ast, - name: ast.name, - range: ast.loc, - }); - } - private _getASTInfoForRange(sourceRange: SourceRange, offset: SingleFileSourceRange): ASTInfo | null { - const offsetSourceRange = { - ...sourceRange, - location: { - start: { - line: sourceRange.location.start.line + offset.start.line, - column: sourceRange.location.start.column + offset.start.column, - }, - end: { - line: sourceRange.location.end.line + offset.end.line, - column: sourceRange.location.end.column + offset.end.column, - }, - }, - }; - for (const astInfo of this._astInfos) { - const astInfoRange = astInfo.range as SingleFileSourceRange; - if ( - astInfoRange.start.column === offsetSourceRange.location.start.column && - astInfoRange.start.line === offsetSourceRange.location.start.line && - astInfoRange.end.column === offsetSourceRange.location.end.column && - astInfoRange.end.line === offsetSourceRange.location.end.line - ) { - return astInfo; - } - } - return null; - } -} diff --git a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index 323e1523c6..5118921faf 100644 --- a/packages/sol-tracing-utils/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts @@ -144,7 +144,7 @@ export abstract class TraceCollectionSubprovider extends Subprovider { txHash: string | undefined, cb: Callback, ): Promise { - if (!txData.isFakeTransaction) { + if (!(txData.isFakeTransaction || txData.from === txData.to)) { // This transaction is a usual transaction. Not a call executed as one. // And we don't want it to be executed within a snapshotting period await this._lock.acquire(); diff --git a/packages/sol-tracing-utils/src/trace_info_subprovider.ts b/packages/sol-tracing-utils/src/trace_info_subprovider.ts index b75fc7bf7e..de42e1862f 100644 --- a/packages/sol-tracing-utils/src/trace_info_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_info_subprovider.ts @@ -31,7 +31,7 @@ export abstract class TraceInfoSubprovider extends TraceCollectionSubprovider { const depth = 0 | log.getDepth(); const gasCost = 0 | log.getCost(); const gas = 0 | log.getGas(); - const isCall = opn == 0xf1 || opn == 0xf2 || opn == 0xf4 || opn == 0xf5; + const isCall = opn == 0xf1 || opn == 0xf2 || opn == 0xf4 || opn == 0xf5 || opn == 0xfa; const stack = isCall ? ['0x'+log.stack.peek(1).toString(16), null] : null; this.data.push({ pc, gasCost, depth, op, stack, gas }); }, diff --git a/packages/sol-tracing-utils/src/types.ts b/packages/sol-tracing-utils/src/types.ts index 27568ae035..97b5e6b370 100644 --- a/packages/sol-tracing-utils/src/types.ts +++ b/packages/sol-tracing-utils/src/types.ts @@ -1,5 +1,4 @@ import { StructLog } from 'ethereum-types'; -import * as Parser from 'solidity-parser-antlr'; export interface LineColumn { line: number; @@ -126,8 +125,5 @@ export type EvmCallStack = EvmCallStackEntry[]; export interface SourceSnippet { source: string; fileName: string; - type: string; - node: Parser.ASTNode; - name: string | null; range: SingleFileSourceRange; } diff --git a/packages/sol-tracing-utils/src/utils.ts b/packages/sol-tracing-utils/src/utils.ts index 644321f325..89c158ee71 100644 --- a/packages/sol-tracing-utils/src/utils.ts +++ b/packages/sol-tracing-utils/src/utils.ts @@ -8,6 +8,7 @@ import { ContractData, LineColumn, SingleFileSourceRange } from './types'; // This is the minimum length of valid contract bytecode. The Solidity compiler // metadata is 86 bytes. If you add the '0x' prefix, we get 88. const MIN_CONTRACT_BYTECODE_LENGTH = 88; +const STATICCALL_GAS_COST = 40; export const utils = { compareLineColumn(lhs: LineColumn, rhs: LineColumn): number { @@ -76,10 +77,17 @@ export const utils = { normalizeStructLogs(structLogs: StructLog[]): StructLog[] { if (structLogs[0].depth === 1) { // Geth uses 1-indexed depth counter whilst ganache starts from 0 - const newStructLogs = _.map(structLogs, structLog => ({ - ...structLog, - depth: structLog.depth - 1, - })); + const newStructLogs = _.map(structLogs, structLog => { + const newStructLog = { + ...structLog, + depth: structLog.depth - 1, + }; + if (newStructLog.op === 'STATICCALL') { + // HACK(leo): Geth traces sometimes returns those gas costs incorrectly as very big numbers so we manually fix them. + newStructLog.gasCost = STATICCALL_GAS_COST; + } + return newStructLog; + }); return newStructLogs; } return structLogs; diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index b6e84698db..da7477be4c 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.63", + "version": "1.0.64", "engines": { "node": ">=6.12" }, @@ -18,7 +18,7 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^3.0.2", + "0x.js": "^3.0.3", "@0x/subproviders": "^2.1.11", "@0x/typescript-typings": "^3.0.8", "@0x/utils": "^3.0.1", diff --git a/packages/utils/src/abi_encoder/evm_data_types/int.ts b/packages/utils/src/abi_encoder/evm_data_types/int.ts index b7e0d9f4e5..f8be1f7788 100644 --- a/packages/utils/src/abi_encoder/evm_data_types/int.ts +++ b/packages/utils/src/abi_encoder/evm_data_types/int.ts @@ -10,7 +10,7 @@ import * as EncoderMath from '../utils/math'; export class IntDataType extends AbstractBlobDataType { private static readonly _MATCHER = RegExp( - '^int(8|16|24|32|40|48|56|64|72|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256){0,1}$', + '^int(8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256){0,1}$', ); private static readonly _SIZE_KNOWN_AT_COMPILE_TIME: boolean = true; private static readonly _MAX_WIDTH: number = 256; diff --git a/packages/website/md/docs/sol_coverage/installation.md b/packages/website/md/docs/sol_coverage/installation.md index c7aaf07e91..7c9840ab84 100644 --- a/packages/website/md/docs/sol_coverage/installation.md +++ b/packages/website/md/docs/sol_coverage/installation.md @@ -1,7 +1,7 @@ **Install** ```bash -yarn add @0x/sol-coverage +yarn add -D @0x/sol-coverage ``` **Import** diff --git a/packages/website/md/docs/sol_coverage/introduction.md b/packages/website/md/docs/sol_coverage/introduction.md index 3214e93a97..f21f8ecbee 100644 --- a/packages/website/md/docs/sol_coverage/introduction.md +++ b/packages/website/md/docs/sol_coverage/introduction.md @@ -1 +1 @@ -Welcome to the [sol-coverage](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-coverage) documentation! Sol-coverage is a Solidity coverage tool for your smart contract tests. +Welcome to the [sol-coverage](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-coverage) documentation! Sol-coverage is a Solidity coverage tool. diff --git a/packages/website/md/docs/sol_coverage/usage.md b/packages/website/md/docs/sol_coverage/usage.md index dd3cdf5978..d194f8abd4 100644 --- a/packages/website/md/docs/sol_coverage/usage.md +++ b/packages/website/md/docs/sol_coverage/usage.md @@ -1,4 +1,4 @@ -Sol-coverage uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `CoverageSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with ProviderEngine, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article. +Sol-coverage uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `CoverageSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with `ProviderEngine`, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article. The CoverageSubprovider eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot. @@ -12,9 +12,8 @@ If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs ```typescript import { SolCompilerArtifactsAdapter } from '@0x/sol-coverage'; -const artifactsPath = 'src/artifacts'; -const contractsPath = 'src/contracts'; -const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath); +// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in +const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir); ``` ### Truffle @@ -23,8 +22,9 @@ If your project is using [Truffle](https://truffleframework.com/), we've written ```typescript import { TruffleArtifactAdapter } from '@0x/sol-coverage'; -const contractsPath = 'src/contracts'; -const artifactAdapter = new TruffleArtifactAdapter(contractsDir); +const projectRoot = '.'; +const solcVersion = '0.5.0'; +const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion); ``` Because truffle artifacts don't have all the data we need - we actually will recompile your contracts under the hood. That's why you don't need to pass an `artifactsPath`. @@ -32,7 +32,13 @@ Because truffle artifacts don't have all the data we need - we actually will rec ### Other framework/toolset You'll need to write your own artifacts adapter. It should extend `AbstractArtifactsAdapter`. -Look at the code of the two adapters above for examples. + +```typescript +import { AbstractArtifactAdapter } from '@0x/sol-trace'; + +class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...}; +const artifactAdapter = new YourCustomArtifactsAdapter(...); +``` ### Usage @@ -41,16 +47,14 @@ import { CoverageSubprovider } from '@0x/sol-coverage'; import ProviderEngine = require('web3-provider-engine'); const provider = new ProviderEngine(); - -const artifactsPath = 'src/artifacts'; -const contractsPath = 'src/contracts'; -const networkId = 50; // Some calls might not have `from` address specified. Nevertheless - transactions need to be submitted from an address with at least some funds. defaultFromAddress is the address that will be used to submit those calls as transactions from. const defaultFromAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; const isVerbose = true; const coverageSubprovider = new CoverageSubprovider(artifactsAdapter, defaultFromAddress, isVerbose); provider.addProvider(coverageSubprovider); +// Add all your other providers +provider.start(); ``` After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call: @@ -60,3 +64,11 @@ await coverageSubprovider.writeCoverageAsync(); ``` This will create a `coverage.json` file in a `coverage` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/coverage.json.md) - so you can use it with any of the existing Istanbul reporters. + +```bash +yarn add -D istanbul +istanbul report html +open coverage/index.html +``` + +Use [Geth](https://github.com/ethereum/go-ethereum) as a backing node. We recommend using our [Devnet Docker container](https://hub.docker.com/r/0xorg/devnet) which sets up a Geth node for testing purposes. Ganache support is a [work in progress](https://github.com/0xProject/0x-monorepo/issues/1520). diff --git a/packages/website/md/docs/sol_profiler/installation.md b/packages/website/md/docs/sol_profiler/installation.md index be9a365f5e..e29ac5ae74 100644 --- a/packages/website/md/docs/sol_profiler/installation.md +++ b/packages/website/md/docs/sol_profiler/installation.md @@ -1,7 +1,7 @@ **Install** ```bash -yarn add @0x/sol-profiler +yarn add -D @0x/sol-profiler ``` **Import** diff --git a/packages/website/md/docs/sol_profiler/usage.md b/packages/website/md/docs/sol_profiler/usage.md index 35ea140dae..0fbc31bc10 100644 --- a/packages/website/md/docs/sol_profiler/usage.md +++ b/packages/website/md/docs/sol_profiler/usage.md @@ -1,4 +1,4 @@ -Sol-profiler uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `ProfilerSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with ProviderEngine, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article. +Sol-profiler uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `ProfilerSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with `ProviderEngine`, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article. The ProfilerSubprovider eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot. @@ -12,9 +12,8 @@ If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs ```typescript import { SolCompilerArtifactsAdapter } from '@0x/sol-profiler'; -const artifactsPath = 'src/artifacts'; -const contractsPath = 'src/contracts'; -const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath); +// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in +const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir); ``` ### Truffle @@ -23,8 +22,9 @@ If your project is using [Truffle](https://truffleframework.com/), we've written ```typescript import { TruffleArtifactAdapter } from '@0x/sol-profiler'; -const contractsPath = 'src/contracts'; -const artifactAdapter = new TruffleArtifactAdapter(contractsDir); +const projectRoot = '.'; +const solcVersion = '0.5.0'; +const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion); ``` Because truffle artifacts don't have all the data we need - we actually will recompile your contracts under the hood. That's why you don't need to pass an `artifactsPath`. @@ -32,7 +32,13 @@ Because truffle artifacts don't have all the data we need - we actually will rec ### Other framework/toolset You'll need to write your own artifacts adapter. It should extend `AbstractArtifactsAdapter`. -Look at the code of the two adapters above for examples. + +```typescript +import { AbstractArtifactAdapter } from '@0x/sol-trace'; + +class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...}; +const artifactAdapter = new YourCustomArtifactsAdapter(...); +``` ### Usage @@ -41,22 +47,28 @@ import { ProfilerSubprovider } from '@0x/sol-profiler'; import ProviderEngine = require('web3-provider-engine'); const provider = new ProviderEngine(); - -const artifactsPath = 'src/artifacts'; -const contractsPath = 'src/contracts'; -const networkId = 50; // Some calls might not have `from` address specified. Nevertheless - transactions need to be submitted from an address with at least some funds. defaultFromAddress is the address that will be used to submit those calls as transactions from. const defaultFromAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; const isVerbose = true; const profilerSubprovider = new ProfilerSubprovider(artifactsAdapter, defaultFromAddress, isVerbose); provider.addProvider(profilerSubprovider); +// Add all your other providers +provider.start(); ``` After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call: ```typescript -await profilerSubprovider.writeProfilerAsync(); +await profilerSubprovider.writeProfilerOutputAsync(); ``` -This will create a `profiler.json` file in a `profiler` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/profiler.json.md) - so you can use it with any of the existing Istanbul reporters. +This will create a `coverage.json` file in a `coverage` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/profiler.json.md) - so you can use it with any of the existing Istanbul reporters. + +```bash +yarn add -D istanbul +istanbul report html +open coverage/index.html +``` + +Use [Geth](https://github.com/ethereum/go-ethereum) as a backing node. We recommend using our [Devnet Docker container](https://hub.docker.com/r/0xorg/devnet) which sets up a Geth node for testing purposes. Ganache support is a [work in progress](https://github.com/0xProject/0x-monorepo/issues/1520). diff --git a/packages/website/md/docs/sol_trace/installation.md b/packages/website/md/docs/sol_trace/installation.md index 2f794b2f8f..eb7bf08b83 100644 --- a/packages/website/md/docs/sol_trace/installation.md +++ b/packages/website/md/docs/sol_trace/installation.md @@ -1,17 +1,17 @@ **Install** ```bash -yarn add @0x/sol-trace +yarn add -D @0x/sol-trace ``` **Import** ```javascript -import { TraceSubprovider } from '@0x/sol-trace'; +import { RevertTraceSubprovider } from '@0x/sol-trace'; ``` or ```javascript -var TraceSubprovider = require('@0x/sol-trace').TraceSubprovider; +var RevertTraceSubprovider = require('@0x/sol-trace').RevertTraceSubprovider; ``` diff --git a/packages/website/md/docs/sol_trace/introduction.md b/packages/website/md/docs/sol_trace/introduction.md index 21fea764e4..73f5c2bcd7 100644 --- a/packages/website/md/docs/sol_trace/introduction.md +++ b/packages/website/md/docs/sol_trace/introduction.md @@ -1 +1 @@ -Welcome to the [sol-trace](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-trace) documentation! Sol-trace is a Solidity trace tool for your smart contract tests. +Welcome to the [sol-trace](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-trace) documentation! Sol-trace gives you a human-readable error stack trace when a revert happens in your Solidity code. diff --git a/packages/website/md/docs/sol_trace/usage.md b/packages/website/md/docs/sol_trace/usage.md index f3aa6fc35a..d117a0faf1 100644 --- a/packages/website/md/docs/sol_trace/usage.md +++ b/packages/website/md/docs/sol_trace/usage.md @@ -1,10 +1,10 @@ -Sol-trace uses transaction traces in order to figure out which lines of Solidity source code have been covered by your tests. In order for it to gather these traces, you must add the `TraceSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with ProviderEngine, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article. +Sol-trace uses transaction traces to reconstruct the stack trace when reverts happen in Solidity. In order for it to gather these traces, you must add the `RevertTraceSubprovider` to the [ProviderEngine](https://github.com/MetaMask/provider-engine) instance you use when running your Solidity tests. If you're unfamiliar with `ProviderEngine`, please read the [Web3 Provider explained](https://0x.org/wiki#Web3-Provider-Explained) wiki article. -The TraceSubprovider eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot. +The `RevertTraceSubprovider` eavesdrops on the `eth_sendTransaction` and `eth_call` RPC calls and collects traces after each call using `debug_traceTransaction`. `eth_call`'s' don't generate traces - so we take a snapshot, re-submit it as a transaction, get the trace and then revert the snapshot. Trace subprovider needs some info about your contracts (`srcMap`, `bytecode`). It gets that info from your project's artifacts. Some frameworks have their own artifact format. Some artifact formats don't actually contain all the neccessary data. -In order to use `TraceSubprovider` with your favorite framework you need to pass an `artifactsAdapter` to it. +In order to use `RevertTraceSubprovider` with your favorite framework you need to pass an `artifactsAdapter` to it. ### Sol-compiler @@ -12,9 +12,8 @@ If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs ```typescript import { SolCompilerArtifactsAdapter } from '@0x/sol-trace'; -const artifactsPath = 'src/artifacts'; -const contractsPath = 'src/contracts'; -const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath); +// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in +const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir); ``` ### Truffle @@ -23,8 +22,9 @@ If your project is using [Truffle](https://truffleframework.com/), we've written ```typescript import { TruffleArtifactAdapter } from '@0x/sol-trace'; -const contractsPath = 'src/contracts'; -const artifactAdapter = new TruffleArtifactAdapter(contractsDir); +const projectRoot = '.'; +const solcVersion = '0.5.0'; +const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion); ``` Because truffle artifacts don't have all the data we need - we actually will recompile your contracts under the hood. That's why you don't need to pass an `artifactsPath`. @@ -32,31 +32,31 @@ Because truffle artifacts don't have all the data we need - we actually will rec ### Other framework/toolset You'll need to write your own artifacts adapter. It should extend `AbstractArtifactsAdapter`. -Look at the code of the two adapters above for examples. + +```typescript +import { AbstractArtifactAdapter } from '@0x/sol-trace'; + +class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...}; +const artifactAdapter = new YourCustomArtifactsAdapter(...); +``` ### Usage ```typescript -import { TraceSubprovider } from '@0x/sol-trace'; +import { RevertTraceSubprovider } from '@0x/sol-trace'; import ProviderEngine = require('web3-provider-engine'); const provider = new ProviderEngine(); - -const artifactsPath = 'src/artifacts'; -const contractsPath = 'src/contracts'; -const networkId = 50; // Some calls might not have `from` address specified. Nevertheless - transactions need to be submitted from an address with at least some funds. defaultFromAddress is the address that will be used to submit those calls as transactions from. const defaultFromAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631'; const isVerbose = true; -const traceSubprovider = new TraceSubprovider(artifactsAdapter, defaultFromAddress, isVerbose); +const revertTraceSubprovider = new RevertTraceSubprovider(artifactsAdapter, defaultFromAddress, isVerbose); -provider.addProvider(traceSubprovider); +provider.addProvider(revertTraceSubprovider); +// Add all your other providers +provider.start(); ``` -After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call: +Now when you run your tests, it should print out stack traces when encountering an error. -```typescript -await traceSubprovider.writeTraceAsync(); -``` - -This will create a `trace.json` file in a `trace` directory. This file has an [Istanbul format](https://github.com/gotwarlost/istanbul/blob/master/trace.json.md) - so you can use it with any of the existing Istanbul reporters. +Use [Geth](https://github.com/ethereum/go-ethereum) as a backing node. We recommend using our [Devnet Docker container](https://hub.docker.com/r/0xorg/devnet) which sets up a Geth node for testing purposes. Ganache support is a [work in progress](https://github.com/0xProject/0x-monorepo/issues/1520). diff --git a/packages/website/package.json b/packages/website/package.json index 0d2773a2c7..ce7ed395f4 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "@0x/website", - "version": "0.0.66", + "version": "0.0.67", "engines": { "node": ">=6.12" }, @@ -20,9 +20,9 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "@0x/asset-buyer": "^4.0.1", + "@0x/asset-buyer": "^4.0.2", "@0x/contract-addresses": "^2.2.0", - "@0x/contract-wrappers": "^5.0.0", + "@0x/contract-wrappers": "^5.0.1", "@0x/json-schemas": "^2.1.7", "@0x/order-utils": "^3.1.2", "@0x/react-docs": "^1.0.25", diff --git a/packages/website/public/images/team/oshirob.png b/packages/website/public/images/team/oshirob.png new file mode 100644 index 0000000000..094bab79b6 Binary files /dev/null and b/packages/website/public/images/team/oshirob.png differ diff --git a/packages/website/ts/pages/about/team.tsx b/packages/website/ts/pages/about/team.tsx index 41d6c2cf8b..466ba9f43b 100644 --- a/packages/website/ts/pages/about/team.tsx +++ b/packages/website/ts/pages/about/team.tsx @@ -30,7 +30,7 @@ const team: TeamMember[] = [ { imageUrl: '/images/team/fabiob.jpg', name: 'Fabio Berger', - title: 'senior engineer', + title: 'engineering manager', }, { imageUrl: '/images/team/alexv.jpg', @@ -55,7 +55,7 @@ const team: TeamMember[] = [ { imageUrl: '/images/team/toms.jpg', name: 'Tom Schmidt', - title: 'product manager', + title: 'product lead', }, { imageUrl: '/images/team/jacobe.jpg', @@ -147,6 +147,11 @@ const team: TeamMember[] = [ name: 'Xianny Ng', title: 'engineer', }, + { + imageUrl: '/images/team/oshirob.png', + name: 'Brent Oshiro', + title: 'community engagement lead', + }, ]; const advisors: TeamMember[] = [ diff --git a/yarn.lock b/yarn.lock index e0b4b2f7b3..a7c126151e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7957,7 +7957,7 @@ got@^6.7.1: graceful-fs@4.1.15, graceful-fs@^3.0.0, graceful-fs@^4.0.0, graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@~1.2.0: version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" "graceful-readlink@>= 1.0.0": version "1.0.1" @@ -12932,6 +12932,10 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +postinstall-build@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7" + prebuild-install@^2.2.2: version "2.5.3" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-2.5.3.tgz#9f65f242782d370296353710e9bc843490c19f69" @@ -13604,7 +13608,7 @@ react-helmet@^5.2.0: prop-types "^15.5.4" react-side-effect "^1.1.0" -react-highlight@0xproject/react-highlight#699ac4d9529e33520bff4b9bd9c624d21efbba75: +react-highlight@0xproject/react-highlight#fix/react-version: version "1.0.0" resolved "https://codeload.github.com/0xproject/react-highlight/tar.gz/699ac4d9529e33520bff4b9bd9c624d21efbba75" dependencies: @@ -16693,6 +16697,14 @@ typedoc@0.13.0: typedoc-default-themes "^0.5.0" typescript "3.1.x" +typemoq@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/typemoq/-/typemoq-2.1.0.tgz#4452ce360d92cf2a1a180f0c29de2803f87af1e8" + dependencies: + circular-json "^0.3.1" + lodash "^4.17.4" + postinstall-build "^5.0.1" + typeorm@^0.2.7: version "0.2.11" resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.11.tgz#d81a295ed822e05043f2920cd539f52a963896b0"