diff options
author | Fabio Berger <me@fabioberger.com> | 2019-01-11 07:47:57 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2019-01-11 07:47:57 +0800 |
commit | 583e690b7a028c85809a8be2c7afe3b65264adbe (patch) | |
tree | bc7ba2fe96833633455daaebf44d7382d0e20b7d | |
parent | a516b00a0397a567fd233bd955206d46321cc178 (diff) | |
parent | a5b7a351609a5e6689bb97990216153f64302462 (diff) | |
download | dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.tar dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.tar.gz dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.tar.bz2 dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.tar.lz dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.tar.xz dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.tar.zst dexon-sol-tools-583e690b7a028c85809a8be2c7afe3b65264adbe.zip |
Merge branch 'development' into fix/dev-tools-pages/finalTouches
* development: (49 commits)
upgrade to ddex api v3 (#1507)
Add new deployment related instructions to pipeline README (#1499)
feature: implement logging and friendly wallet name for Opera
Fix prettier
Add missing dependencies
Remove second yarn call
Add .gitkeep
Rename sol-trace-based-tools-common to sol-tracing-utils
Update packages/sol-trace/README.md
Update packages/sol-trace/CHANGELOG.json
Update packages/sol-trace-based-tools-common/src/source_maps.ts
Update packages/sol-trace-based-tools-common/CHANGELOG.json
Update packages/sol-profiler/CHANGELOG.json
Update packages/sol-coverage/CHANGELOG.json
Update packages/monorepo-scripts/src/test_installation.ts
chore: changelog update
fix: account for undefined errors in promisify, not only null
Clean up docs before publish
In README's, don't mention non-existent tests (#1497)
fix: use getBackendBaseUrl instead of hardcoded string
...
167 files changed, 1631 insertions, 722 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml index 4e82b8286..f64017b56 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ jobs: command: sudo npm install --global yarn@1.9.4 - run: name: yarn - command: yarn --frozen-lockfile --ignore-engines install || yarn --frozen-lockfile --ignore-engines install + command: yarn --frozen-lockfile --ignore-engines install - run: yarn build:ci:no_website - run: yarn build:ts - save_cache: @@ -118,7 +118,7 @@ jobs: - run: yarn wsrun test:circleci @0x/order-utils - run: yarn wsrun test:circleci @0x/order-watcher - run: yarn wsrun test:circleci @0x/sol-compiler - - run: yarn wsrun test:circleci @0x/sol-cov + - run: yarn wsrun test:circleci @0x/sol-tracing-utils - run: yarn wsrun test:circleci @0x/sol-doc - run: yarn wsrun test:circleci @0x/subproviders - run: yarn wsrun test:circleci @0x/web3-wrapper @@ -169,9 +169,9 @@ jobs: paths: - ~/repo/packages/sol-compiler/coverage/lcov.info - save_cache: - key: coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }} + key: coverage-sol-tracing-utils-{{ .Environment.CIRCLE_SHA1 }} paths: - - ~/repo/packages/sol-cov/coverage/lcov.info + - ~/repo/packages/sol-tracing-utils/coverage/lcov.info - save_cache: key: coverage-sol-doc-{{ .Environment.CIRCLE_SHA1 }} paths: @@ -335,7 +335,7 @@ jobs: - coverage-sol-compiler-{{ .Environment.CIRCLE_SHA1 }} - restore_cache: keys: - - coverage-sol-cov-{{ .Environment.CIRCLE_SHA1 }} + - coverage-sol-tracing-utils-{{ .Environment.CIRCLE_SHA1 }} - restore_cache: keys: - coverage-sol-doc-{{ .Environment.CIRCLE_SHA1 }} diff --git a/.github/autolabeler.yml b/.github/autolabeler.yml index 8284293d5..321ec18a4 100644 --- a/.github/autolabeler.yml +++ b/.github/autolabeler.yml @@ -13,7 +13,10 @@ instant: ['packages/instant'] abi-gen-templates: ['packages/abi-gen-templates'] abi-gen: ['packages/abi-gen'] website: ['packages/website'] -sol-cov: ['packages/sol-cov'] +sol-coverage: ['packages/sol-coverage'] +sol-profiler: ['packages/sol-profiler'] +sol-trace: ['packages/sol-trace'] +sol-tracing-utils: ['packages/sol-tracing-utils'] utils: ['packages/utils'] tslint-config: ['packages/tslint-config'] asset-buyer: ['packages/asset-buyer'] diff --git a/.gitignore b/.gitignore index 1d4410e25..0210edc4f 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,7 @@ contracts/interfaces/generated-artifacts/ contracts/tokens/generated-artifacts/ contracts/examples/generated-artifacts/ contracts/extensions/generated-artifacts/ -packages/sol-cov/test/fixtures/artifacts/ +packages/sol-tracing-utils/test/fixtures/artifacts/ packages/metacoin/artifacts/ # generated contract wrappers diff --git a/.prettierignore b/.prettierignore index a5912fafd..a49091816 100644 --- a/.prettierignore +++ b/.prettierignore @@ -27,7 +27,7 @@ lib /packages/dev-tools-pages/ts/**/data.json package.json scripts/postpublish_utils.js -packages/sol-cov/test/fixtures/artifacts +packages/sol-coverage/test/fixtures/artifacts .pytest_cache .mypy_cache .tox diff --git a/CODEOWNERS b/CODEOWNERS index ca98ec19b..c73a206df 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -24,7 +24,10 @@ packages/metacoin/ @LogvinovLeon packages/monorepo-scripts/ @fabioberger packages/order-utils/ @fabioberger @LogvinovLeon packages/sol-compiler/ @LogvinovLeon -packages/sol-cov/ @LogvinovLeon +packages/sol-coverage/ @LogvinovLeon +packages/sol-profiler/ @LogvinovLeon +packages/sol-trace/ @LogvinovLeon +packages/sol-tracing-utils/ @LogvinovLeon packages/sol-resolver/ @LogvinovLeon packages/subproviders/ @fabioberger @dekz packages/verdaccio/ @albrow @@ -57,7 +57,9 @@ Visit our [developer portal](https://0xproject.com/docs/order-utils) for a compr | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [`@0x/web3-wrapper`](/packages/web3-wrapper) | [![npm](https://img.shields.io/npm/v/@0x/web3-wrapper.svg)](https://www.npmjs.com/package/@0x/web3-wrapper) | An Ethereum JSON RPC client | | [`@0x/sol-compiler`](/packages/sol-compiler) | [![npm](https://img.shields.io/npm/v/@0x/sol-compiler.svg)](https://www.npmjs.com/package/@0x/sol-compiler) | A wrapper around solc-js that adds smart re-compilation, ability to compile an entire project, Solidity version specific compilation, standard input description support and much more. | -| [`@0x/sol-cov`](/packages/sol-cov) | [![npm](https://img.shields.io/npm/v/@0x/sol-cov.svg)](https://www.npmjs.com/package/@0x/sol-cov) | A solidity test coverage tool | +| [`@0x/sol-coverage`](/packages/sol-coverage) | [![npm](https://img.shields.io/npm/v/@0x/sol-coverage.svg)](https://www.npmjs.com/package/@0x/sol-coverage) | A solidity test coverage tool | +| [`@0x/sol-profiler`](/packages/sol-profiler) | [![npm](https://img.shields.io/npm/v/@0x/sol-profiler.svg)](https://www.npmjs.com/package/@0x/sol-profiler) | A solidity gas cost profiler | +| [`@0x/sol-trace`](/packages/sol-trace) | [![npm](https://img.shields.io/npm/v/@0x/sol-trace.svg)](https://www.npmjs.com/package/@0x/sol-trace) | A solidity stack trace tool | | [`@0x/sol-resolver`](/packages/sol-resolver) | [![npm](https://img.shields.io/npm/v/@0x/sol-resolver.svg)](https://www.npmjs.com/package/@0x/sol-resolver) | Import resolver for smart contracts dependencies | | [`@0x/subproviders`](/packages/subproviders) | [![npm](https://img.shields.io/npm/v/@0x/subproviders.svg)](https://www.npmjs.com/package/@0x/subproviders) | Web3 provider middlewares (e.g. LedgerSubprovider) | | [`@0x/sol-doc`](/packages/sol-doc) | [![npm](https://img.shields.io/npm/v/@0x/sol-doc.svg)](https://www.npmjs.com/package/@0x/sol-doc) | Solidity documentation generator | diff --git a/contracts/TESTING.md b/contracts/TESTING.md index 750b3c62c..3e6888c04 100644 --- a/contracts/TESTING.md +++ b/contracts/TESTING.md @@ -20,7 +20,7 @@ TEST_PROVIDER=geth yarn test ## Code coverage -In order to see the Solidity code coverage output generated by `@0x/sol-cov`, run: +In order to see the Solidity code coverage output generated by `@0x/sol-coverage`, run: ``` yarn test:coverage diff --git a/contracts/examples/package.json b/contracts/examples/package.json index b556d72d8..d04b5fc44 100644 --- a/contracts/examples/package.json +++ b/contracts/examples/package.json @@ -37,7 +37,6 @@ "@0x/contracts-test-utils": "^1.0.3", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/contracts/extensions/package.json b/contracts/extensions/package.json index 05c066fc8..99b5b35a8 100644 --- a/contracts/extensions/package.json +++ b/contracts/extensions/package.json @@ -49,7 +49,6 @@ "@0x/contracts-test-utils": "^1.0.3", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/contracts/libs/package.json b/contracts/libs/package.json index ed9d408ff..9d28cc038 100644 --- a/contracts/libs/package.json +++ b/contracts/libs/package.json @@ -48,7 +48,6 @@ "@0x/contracts-test-utils": "^1.0.3", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/contracts/multisig/package.json b/contracts/multisig/package.json index 63b6de6f2..e0bbc001d 100644 --- a/contracts/multisig/package.json +++ b/contracts/multisig/package.json @@ -48,7 +48,6 @@ "@0x/contracts-test-utils": "^1.0.3", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/contracts/protocol/package.json b/contracts/protocol/package.json index 02e1934d7..7d49dfbe8 100644 --- a/contracts/protocol/package.json +++ b/contracts/protocol/package.json @@ -47,7 +47,6 @@ "@0x/abi-gen": "^1.0.20", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/contracts/test-utils/package.json b/contracts/test-utils/package.json index 852985636..2653fc0e4 100644 --- a/contracts/test-utils/package.json +++ b/contracts/test-utils/package.json @@ -40,11 +40,13 @@ "typescript": "3.0.1" }, "dependencies": { + "@0x/sol-coverage": "^1.0.0", + "@0x/sol-profiler": "^1.0.0", + "@0x/sol-trace": "^1.0.0", "@0x/abi-gen": "^1.0.20", "@0x/dev-utils": "^1.0.22", "@0x/order-utils": "^3.1.0", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@0x/types": "^1.5.0", diff --git a/contracts/test-utils/src/coverage.ts b/contracts/test-utils/src/coverage.ts index 5becfa1b6..f82288eec 100644 --- a/contracts/test-utils/src/coverage.ts +++ b/contracts/test-utils/src/coverage.ts @@ -1,5 +1,5 @@ import { devConstants } from '@0x/dev-utils'; -import { CoverageSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-cov'; +import { CoverageSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-coverage'; import * as _ from 'lodash'; let coverageSubprovider: CoverageSubprovider; diff --git a/contracts/test-utils/src/profiler.ts b/contracts/test-utils/src/profiler.ts index 2c7c1d66c..7f51c384f 100644 --- a/contracts/test-utils/src/profiler.ts +++ b/contracts/test-utils/src/profiler.ts @@ -1,5 +1,5 @@ import { devConstants } from '@0x/dev-utils'; -import { ProfilerSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-cov'; +import { ProfilerSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-profiler'; import * as _ from 'lodash'; let profilerSubprovider: ProfilerSubprovider; diff --git a/contracts/test-utils/src/revert_trace.ts b/contracts/test-utils/src/revert_trace.ts index 3f74fd28b..3a5778859 100644 --- a/contracts/test-utils/src/revert_trace.ts +++ b/contracts/test-utils/src/revert_trace.ts @@ -1,5 +1,5 @@ import { devConstants } from '@0x/dev-utils'; -import { RevertTraceSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-cov'; +import { RevertTraceSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-trace'; import * as _ from 'lodash'; let revertTraceSubprovider: RevertTraceSubprovider; diff --git a/contracts/tokens/package.json b/contracts/tokens/package.json index 2fc5013a0..31bf8f7cc 100644 --- a/contracts/tokens/package.json +++ b/contracts/tokens/package.json @@ -48,7 +48,6 @@ "@0x/contracts-test-utils": "^1.0.3", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/contracts/utils/package.json b/contracts/utils/package.json index 58a7b3a71..732556f34 100644 --- a/contracts/utils/package.json +++ b/contracts/utils/package.json @@ -48,7 +48,6 @@ "@0x/contracts-test-utils": "^1.0.3", "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", - "@0x/sol-cov": "^2.1.17", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@types/bn.js": "^4.11.0", diff --git a/package.json b/package.json index 16b7a10f9..9395dbaa2 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ }, "config": { "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic", - "packagesWithDocPages": "0x.js connect json-schemas subproviders web3-wrapper contract-wrappers order-utils order-watcher sol-compiler sol-cov ethereum-types asset-buyer migrations" + "packagesWithDocPages": "0x.js connect json-schemas subproviders web3-wrapper contract-wrappers order-utils order-watcher sol-compiler sol-coverage sol-profiler sol-trace ethereum-types asset-buyer migrations" }, "bundlewatch": { "files": [ diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json index fcdb655fc..a7f8d3418 100644 --- a/packages/asset-buyer/CHANGELOG.json +++ b/packages/asset-buyer/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "4.0.0", + "changes": [ + { + "note": "Raise custom InsufficientAssetLiquidityError error with amountAvailableToFill attribute", + "pr": 1437 + } + ] + }, + { "timestamp": 1547040760, "version": "3.0.5", "changes": [ diff --git a/packages/asset-buyer/src/errors.ts b/packages/asset-buyer/src/errors.ts new file mode 100644 index 000000000..ec5fe548c --- /dev/null +++ b/packages/asset-buyer/src/errors.ts @@ -0,0 +1,22 @@ +import { BigNumber } from '@0x/utils'; + +import { AssetBuyerError } from './types'; + +/** + * Error class representing insufficient asset liquidity + */ +export class InsufficientAssetLiquidityError extends Error { + /** + * The amount availabe to fill (in base units) factoring in slippage. + */ + public amountAvailableToFill: BigNumber; + /** + * @param amountAvailableToFill The amount availabe to fill (in base units) factoring in slippage + */ + constructor(amountAvailableToFill: BigNumber) { + super(AssetBuyerError.InsufficientAssetLiquidity); + this.amountAvailableToFill = amountAvailableToFill; + // Setting prototype so instanceof works. See https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + Object.setPrototypeOf(this, InsufficientAssetLiquidityError.prototype); + } +} diff --git a/packages/asset-buyer/src/index.ts b/packages/asset-buyer/src/index.ts index 8418edb42..a42d7e272 100644 --- a/packages/asset-buyer/src/index.ts +++ b/packages/asset-buyer/src/index.ts @@ -9,6 +9,7 @@ export { SignedOrder } from '@0x/types'; export { BigNumber } from '@0x/utils'; export { AssetBuyer } from './asset_buyer'; +export { InsufficientAssetLiquidityError } from './errors'; export { BasicOrderProvider } from './order_providers/basic_order_provider'; export { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider'; export { diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts index 3b573edca..d5d6be695 100644 --- a/packages/asset-buyer/src/types.ts +++ b/packages/asset-buyer/src/types.ts @@ -102,7 +102,7 @@ export interface AssetBuyerOpts { } /** - * Possible errors thrown by an AssetBuyer instance or associated static methods. + * Possible error messages thrown by an AssetBuyer instance or associated static methods. */ export enum AssetBuyerError { NoEtherTokenContractFound = 'NO_ETHER_TOKEN_CONTRACT_FOUND', diff --git a/packages/asset-buyer/src/utils/buy_quote_calculator.ts b/packages/asset-buyer/src/utils/buy_quote_calculator.ts index b15b880c2..fcded6ab1 100644 --- a/packages/asset-buyer/src/utils/buy_quote_calculator.ts +++ b/packages/asset-buyer/src/utils/buy_quote_calculator.ts @@ -3,6 +3,7 @@ import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import { constants } from '../constants'; +import { InsufficientAssetLiquidityError } from '../errors'; import { AssetBuyerError, BuyQuote, BuyQuoteInfo, OrdersAndFillableAmounts } from '../types'; import { orderUtils } from './order_utils'; @@ -33,7 +34,18 @@ export const buyQuoteCalculator = { }); // if we do not have enough orders to cover the desired assetBuyAmount, throw if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) { - throw new Error(AssetBuyerError.InsufficientAssetLiquidity); + // We needed the amount they requested to buy, plus the amount for slippage + const totalAmountRequested = assetBuyAmount.plus(slippageBufferAmount); + const amountAbleToFill = totalAmountRequested.minus(remainingFillAmount); + // multiplierNeededWithSlippage represents what we need to multiply the assetBuyAmount by + // in order to get the total amount needed considering slippage + // i.e. if slippagePercent was 0.2 (20%), multiplierNeededWithSlippage would be 1.2 + const multiplierNeededWithSlippage = new BigNumber(1).plus(slippagePercentage); + // Given amountAvailableToFillConsideringSlippage * multiplierNeededWithSlippage = amountAbleToFill + // We divide amountUnableToFill by multiplierNeededWithSlippage to determine amountAvailableToFillConsideringSlippage + const amountAvailableToFillConsideringSlippage = amountAbleToFill.div(multiplierNeededWithSlippage).floor(); + + throw new InsufficientAssetLiquidityError(amountAvailableToFillConsideringSlippage); } // if we are not buying ZRX: // given the orders calculated above, find the fee-orders that cover the desired assetBuyAmount (with slippage) diff --git a/packages/asset-buyer/test/buy_quote_calculator_test.ts b/packages/asset-buyer/test/buy_quote_calculator_test.ts index a30017b72..fdc17ef25 100644 --- a/packages/asset-buyer/test/buy_quote_calculator_test.ts +++ b/packages/asset-buyer/test/buy_quote_calculator_test.ts @@ -1,4 +1,5 @@ import { orderFactory } from '@0x/order-utils/lib/src/order_factory'; +import { SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; import * as _ from 'lodash'; @@ -8,6 +9,7 @@ import { AssetBuyerError, OrdersAndFillableAmounts } from '../src/types'; import { buyQuoteCalculator } from '../src/utils/buy_quote_calculator'; import { chaiSetup } from './utils/chai_setup'; +import { testHelpers } from './utils/test_helpers'; chaiSetup.configure(); const expect = chai.expect; @@ -15,6 +17,10 @@ const expect = chai.expect; // tslint:disable:custom-no-magic-numbers describe('buyQuoteCalculator', () => { describe('#calculate', () => { + let firstOrder: SignedOrder; + let firstRemainingFillAmount: BigNumber; + let secondOrder: SignedOrder; + let secondRemainingFillAmount: BigNumber; let ordersAndFillableAmounts: OrdersAndFillableAmounts; let smallFeeOrderAndFillableAmount: OrdersAndFillableAmounts; let allFeeOrdersAndFillableAmounts: OrdersAndFillableAmounts; @@ -24,18 +30,18 @@ describe('buyQuoteCalculator', () => { // the second order has a rate of 2 makerAsset / WETH with a takerFee of 100 ZRX and has 200 / 200 makerAsset units left to fill (completely fillable) // generate one order for fees // the fee order has a rate of 1 ZRX / WETH with no taker fee and has 100 ZRX left to fill (completely fillable) - const firstOrder = orderFactory.createSignedOrderFromPartial({ + firstOrder = orderFactory.createSignedOrderFromPartial({ makerAssetAmount: new BigNumber(400), takerAssetAmount: new BigNumber(100), takerFee: new BigNumber(200), }); - const firstRemainingFillAmount = new BigNumber(200); - const secondOrder = orderFactory.createSignedOrderFromPartial({ + firstRemainingFillAmount = new BigNumber(200); + secondOrder = orderFactory.createSignedOrderFromPartial({ makerAssetAmount: new BigNumber(200), takerAssetAmount: new BigNumber(100), takerFee: new BigNumber(100), }); - const secondRemainingFillAmount = secondOrder.makerAssetAmount; + secondRemainingFillAmount = secondOrder.makerAssetAmount; ordersAndFillableAmounts = { orders: [firstOrder, secondOrder], remainingFillableMakerAssetAmounts: [firstRemainingFillAmount, secondRemainingFillAmount], @@ -61,18 +67,137 @@ describe('buyQuoteCalculator', () => { ], }; }); - it('should throw if not enough maker asset liquidity', () => { - // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units + describe('InsufficientLiquidityError', () => { + it('should throw if not enough maker asset liquidity (multiple orders)', () => { + // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units + const errorFunction = () => { + buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + smallFeeOrderAndFillableAmount, + new BigNumber(500), + 0, + 0, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(400)); + }); + it('should throw if not enough maker asset liquidity (multiple orders with 20% slippage)', () => { + // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units + const errorFunction = () => { + buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + smallFeeOrderAndFillableAmount, + new BigNumber(500), + 0, + 0.2, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(333)); + }); + it('should throw if not enough maker asset liquidity (multiple orders with 5% slippage)', () => { + // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units + const errorFunction = () => { + buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + smallFeeOrderAndFillableAmount, + new BigNumber(600), + 0, + 0.05, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(380)); + }); + it('should throw if not enough maker asset liquidity (partially filled order)', () => { + const firstOrderAndFillableAmount: OrdersAndFillableAmounts = { + orders: [firstOrder], + remainingFillableMakerAssetAmounts: [firstRemainingFillAmount], + }; + + const errorFunction = () => { + buyQuoteCalculator.calculate( + firstOrderAndFillableAmount, + smallFeeOrderAndFillableAmount, + new BigNumber(201), + 0, + 0, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(200)); + }); + it('should throw if not enough maker asset liquidity (completely fillable order)', () => { + const completelyFillableOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(123), + takerAssetAmount: new BigNumber(100), + takerFee: new BigNumber(200), + }); + const completelyFillableOrdersAndFillableAmount: OrdersAndFillableAmounts = { + orders: [completelyFillableOrder], + remainingFillableMakerAssetAmounts: [completelyFillableOrder.makerAssetAmount], + }; + const errorFunction = () => { + buyQuoteCalculator.calculate( + completelyFillableOrdersAndFillableAmount, + smallFeeOrderAndFillableAmount, + new BigNumber(124), + 0, + 0, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(123)); + }); + it('should throw with 1 amount available if no slippage', () => { + const smallOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(1), + takerAssetAmount: new BigNumber(1), + takerFee: new BigNumber(0), + }); + const errorFunction = () => { + buyQuoteCalculator.calculate( + { orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] }, + smallFeeOrderAndFillableAmount, + new BigNumber(600), + 0, + 0, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(1)); + }); + it('should throw without amount available to fill if amount rounds to 0', () => { + const smallOrder = orderFactory.createSignedOrderFromPartial({ + makerAssetAmount: new BigNumber(1), + takerAssetAmount: new BigNumber(1), + takerFee: new BigNumber(0), + }); + const errorFunction = () => { + buyQuoteCalculator.calculate( + { orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] }, + smallFeeOrderAndFillableAmount, + new BigNumber(600), + 0, + 0.2, + false, + ); + }; + testHelpers.expectInsufficientLiquidityError(expect, errorFunction, undefined); + }); + }); + it('should not throw if order is fillable', () => { expect(() => buyQuoteCalculator.calculate( ordersAndFillableAmounts, - smallFeeOrderAndFillableAmount, - new BigNumber(500), + allFeeOrdersAndFillableAmounts, + new BigNumber(300), 0, 0, false, ), - ).to.throw(AssetBuyerError.InsufficientAssetLiquidity); + ).to.not.throw(); }); it('should throw if not enough ZRX liquidity', () => { // we request 300 makerAsset units but the ZRX order is only enough to fill the first order, which only has 200 makerAssetUnits available diff --git a/packages/asset-buyer/test/utils/test_helpers.ts b/packages/asset-buyer/test/utils/test_helpers.ts new file mode 100644 index 000000000..9c7c244af --- /dev/null +++ b/packages/asset-buyer/test/utils/test_helpers.ts @@ -0,0 +1,26 @@ +import { BigNumber } from '@0x/utils'; + +import { InsufficientAssetLiquidityError } from '../../src/errors'; + +export const testHelpers = { + expectInsufficientLiquidityError: ( + expect: Chai.ExpectStatic, + functionWhichTriggersError: () => void, + expectedAmountAvailableToFill?: BigNumber, + ): void => { + let wasErrorThrown = false; + try { + functionWhichTriggersError(); + } catch (e) { + wasErrorThrown = true; + expect(e).to.be.instanceOf(InsufficientAssetLiquidityError); + if (expectedAmountAvailableToFill) { + expect(e.amountAvailableToFill).to.be.bignumber.equal(expectedAmountAvailableToFill); + } else { + expect(e.amountAvailableToFill).to.be.undefined(); + } + } + + expect(wasErrorThrown).to.be.true(); + }, +}; diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 22f0cb6a4..bfd9e9098 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -16,6 +16,7 @@ export const ONE_SECOND_MS = 1000; export const ONE_MINUTE_MS = ONE_SECOND_MS * 60; export const GIT_SHA = process.env.GIT_SHA; export const NODE_ENV = process.env.NODE_ENV; +export const SLIPPAGE_PERCENTAGE = 0.2; export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION; export const DEFAULT_UNKOWN_ASSET_NAME = '???'; export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5; @@ -73,5 +74,6 @@ export const PROVIDER_TYPE_TO_NAME: { [key in ProviderType]: string } = { [ProviderType.CoinbaseWallet]: 'Coinbase Wallet', [ProviderType.Parity]: 'Parity', [ProviderType.TrustWallet]: 'Trust Wallet', + [ProviderType.Opera]: 'Opera Wallet', [ProviderType.Fallback]: 'Fallback', }; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index ae672c919..f07a407da 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -183,6 +183,7 @@ export enum ProviderType { CoinbaseWallet = 'COINBASE_WALLET', Cipher = 'CIPHER', TrustWallet = 'TRUST_WALLET', + Opera = 'OPERA', Fallback = 'FALLBACK', } diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index faaeb7c22..b009a327f 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -1,8 +1,10 @@ -import { AssetBuyerError } from '@0x/asset-buyer'; +import { AssetBuyerError, InsufficientAssetLiquidityError } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; -import { DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; +import { BIG_NUMBER_ZERO, DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; import { assetDataNetworkMapping } from '../data/asset_data_network_mapping'; import { Asset, AssetMetaData, ERC20Asset, Network, ZeroExInstantError } from '../types'; @@ -111,6 +113,21 @@ export const assetUtils = { assetBuyerErrorMessage: (asset: ERC20Asset, error: Error): string | undefined => { if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); + if ( + error instanceof InsufficientAssetLiquidityError && + error.amountAvailableToFill.greaterThan(BIG_NUMBER_ZERO) + ) { + const unitAmountAvailableToFill = Web3Wrapper.toUnitAmount( + error.amountAvailableToFill, + asset.metaData.decimals, + ); + const roundedUnitAmountAvailableToFill = unitAmountAvailableToFill.round(2, BigNumber.ROUND_DOWN); + + if (roundedUnitAmountAvailableToFill.greaterThan(BIG_NUMBER_ZERO)) { + return `There are only ${roundedUnitAmountAvailableToFill} ${assetName} available to buy`; + } + } + return `Not enough ${assetName} available`; } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { return 'Not enough ZRX available'; diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index 6191c92e3..37974e71c 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -5,6 +5,7 @@ import * as _ from 'lodash'; import { Dispatch } from 'redux'; import { oc } from 'ts-optchain'; +import { SLIPPAGE_PERCENTAGE } from '../constants'; import { Action, actions } from '../redux/actions'; import { AffiliateInfo, ERC20Asset, QuoteFetchOrigin } from '../types'; import { analytics } from '../util/analytics'; @@ -33,8 +34,12 @@ export const buyQuoteUpdater = { } const feePercentage = oc(options.affiliateInfo).feePercentage(); let newBuyQuote: BuyQuote | undefined; + const slippagePercentage = SLIPPAGE_PERCENTAGE; try { - newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage }); + newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { + feePercentage, + slippagePercentage, + }); } catch (error) { const errorMessage = assetUtils.assetBuyerErrorMessage(asset, error); diff --git a/packages/instant/src/util/env.ts b/packages/instant/src/util/env.ts index aedf4f5d6..7d4f836ff 100644 --- a/packages/instant/src/util/env.ts +++ b/packages/instant/src/util/env.ts @@ -42,18 +42,21 @@ export const envUtil = { } }, getProviderType(provider: Provider): ProviderType | undefined { + const anyProvider = provider as any; if (provider.constructor.name === 'EthereumProvider') { return ProviderType.Mist; - } else if ((provider as any).isTrust) { + } else if (anyProvider.isTrust) { return ProviderType.TrustWallet; - } else if ((provider as any).isParity) { + } else if (anyProvider.isParity) { return ProviderType.Parity; - } else if ((provider as any).isMetaMask) { + } else if (anyProvider.isMetaMask) { return ProviderType.MetaMask; } else if (!_.isUndefined(_.get(window, 'SOFA'))) { return ProviderType.CoinbaseWallet; } else if (!_.isUndefined(_.get(window, '__CIPHER__'))) { return ProviderType.Cipher; + } else if (envUtil.getBrowser() === Browser.Opera && !anyProvider.isMetaMask) { + return ProviderType.Opera; } return; }, diff --git a/packages/instant/test/util/asset.test.ts b/packages/instant/test/util/asset.test.ts index fc4e4e2e4..402a556d5 100644 --- a/packages/instant/test/util/asset.test.ts +++ b/packages/instant/test/util/asset.test.ts @@ -1,5 +1,6 @@ -import { AssetBuyerError } from '@0x/asset-buyer'; +import { AssetBuyerError, BigNumber, InsufficientAssetLiquidityError } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import { Asset, AssetMetaData, ERC20Asset, ERC20AssetMetaData, Network, ZeroExInstantError } from '../../src/types'; import { assetUtils } from '../../src/util/asset'; @@ -19,6 +20,16 @@ const ZRX_ASSET: ERC20Asset = { const META_DATA_MAP: ObjectMap<AssetMetaData> = { [ZRX_ASSET_DATA]: ZRX_META_DATA, }; +const WAX_ASSET: ERC20Asset = { + assetData: '0xf47261b000000000000000000000000039bb259f66e1c59d5abef88375979b4d20d98022', + metaData: { + assetProxyId: AssetProxyId.ERC20, + decimals: 8, + primaryColor: '#EDB740', + symbol: 'wax', + name: 'WAX', + }, +}; describe('assetDataUtil', () => { describe('bestNameForAsset', () => { @@ -47,13 +58,39 @@ describe('assetDataUtil', () => { }); }); describe('assetBuyerErrorMessage', () => { - it('should return message for InsufficientAssetLiquidity', () => { + it('should return message for generic InsufficientAssetLiquidity error', () => { const insufficientAssetError = new Error(AssetBuyerError.InsufficientAssetLiquidity); expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, insufficientAssetError)).toEqual( 'Not enough ZRX available', ); }); - it('should return message for InsufficientAssetLiquidity', () => { + describe('InsufficientAssetLiquidityError', () => { + it('should return custom message for token w/ 18 decimals', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(20.059), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 20.05 ZRX available to buy'); + }); + it('should return custom message for token w/ 18 decimals and small amount available', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.01), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 0.01 ZRX available to buy'); + }); + it('should return custom message for token w/ 8 decimals', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), 8); + expect( + assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('There are only 3 WAX available to buy'); + }); + it('should return generic message when amount available rounds to zero', () => { + const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18); + expect( + assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)), + ).toEqual('Not enough ZRX available'); + }); + }); + it('should return message for InsufficientZrxLiquidity', () => { const insufficientZrxError = new Error(AssetBuyerError.InsufficientZrxLiquidity); expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, insufficientZrxError)).toEqual( 'Not enough ZRX available', diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index 65232639b..6812ff823 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -32,7 +32,9 @@ "@0x/abi-gen": "^1.0.20", "@0x/abi-gen-templates": "^1.0.1", "@0x/base-contract": "^3.0.11", - "@0x/sol-cov": "^2.1.17", + "@0x/sol-coverage": "^1.0.0", + "@0x/sol-profiler": "^1.0.0", + "@0x/sol-trace": "^1.0.0", "@0x/subproviders": "^2.1.9", "@0x/tslint-config": "^2.0.0", "@0x/types": "^1.5.0", diff --git a/packages/metacoin/test/utils/coverage.ts b/packages/metacoin/test/utils/coverage.ts index 31275a163..1a06d8c3c 100644 --- a/packages/metacoin/test/utils/coverage.ts +++ b/packages/metacoin/test/utils/coverage.ts @@ -1,5 +1,5 @@ import { devConstants } from '@0x/dev-utils'; -import { CoverageSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-cov'; +import { CoverageSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-coverage'; import * as _ from 'lodash'; import { config } from './config'; diff --git a/packages/metacoin/test/utils/profiler.ts b/packages/metacoin/test/utils/profiler.ts index e7c373d20..6e6fc309f 100644 --- a/packages/metacoin/test/utils/profiler.ts +++ b/packages/metacoin/test/utils/profiler.ts @@ -1,5 +1,5 @@ import { devConstants } from '@0x/dev-utils'; -import { ProfilerSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-cov'; +import { ProfilerSubprovider, SolCompilerArtifactAdapter } from '@0x/sol-profiler'; import * as _ from 'lodash'; import { config } from './config'; diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index e337ec336..3286b8412 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -47,6 +47,7 @@ "typescript": "3.0.1" }, "dependencies": { + "@0x/utils": "^2.0.8", "@lerna/batch-packages": "^3.0.0-beta.18", "@types/depcheck": "^0.6.0", "async-child-process": "^1.1.1", diff --git a/packages/monorepo-scripts/src/constants.ts b/packages/monorepo-scripts/src/constants.ts index acb4b211e..c15bcabf4 100644 --- a/packages/monorepo-scripts/src/constants.ts +++ b/packages/monorepo-scripts/src/constants.ts @@ -5,5 +5,7 @@ export const constants = { stagingWebsite: 'http://staging-0xproject.s3-website-us-east-1.amazonaws.com', lernaExecutable: path.join('node_modules', '@0x-lerna-fork', 'lerna', 'cli.js'), githubPersonalAccessToken: process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS, + discordAlertWebhookUrl: process.env.DISCORD_GITHUB_RELEASE_WEBHOOK_URL, + releasesUrl: 'https://github.com/0xProject/0x-monorepo/releases', dependenciesUpdatedMessage: 'Dependencies updated', }; diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts index dfbe98028..7a4e6bb2c 100644 --- a/packages/monorepo-scripts/src/doc_gen_configs.ts +++ b/packages/monorepo-scripts/src/doc_gen_configs.ts @@ -9,6 +9,7 @@ export const docGenConfigs: DocGenConfigs = { Array: 'https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Array', BigNumber: 'http://mikemcl.github.io/bignumber.js', Error: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error', + ErrorConstructor: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error', Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262', 'solc.StandardContractOutput': 'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description', diff --git a/packages/monorepo-scripts/src/prepublish_checks.ts b/packages/monorepo-scripts/src/prepublish_checks.ts index 36e61714b..82eaf5cf9 100644 --- a/packages/monorepo-scripts/src/prepublish_checks.ts +++ b/packages/monorepo-scripts/src/prepublish_checks.ts @@ -140,6 +140,13 @@ async function checkPublishRequiredSetupAsync(): Promise<void> { ); } + // Check to see if discord URL is set up + if (_.isUndefined(constants.discordAlertWebhookUrl)) { + throw new Error( + 'You must have a discord webhook URL set to an envVar named `DISCORD_GITHUB_RELEASE_WEBHOOK_URL`. Add it then try again.', + ); + } + // Check Yarn version is 1.X utils.log('Checking the yarn version...'); const result = await execAsync(`yarn --version`); diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts index 854a72b86..e0602a74f 100644 --- a/packages/monorepo-scripts/src/publish.ts +++ b/packages/monorepo-scripts/src/publish.ts @@ -14,6 +14,7 @@ import { constants } from './constants'; import { Package, PackageToNextVersion, VersionChangelog } from './types'; import { changelogUtils } from './utils/changelog_utils'; import { configs } from './utils/configs'; +import { alertDiscordAsync } from './utils/discord'; import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils'; import { publishReleaseNotesAsync } from './utils/github_release_utils'; import { utils } from './utils/utils'; @@ -84,7 +85,16 @@ async function confirmAsync(message: string): Promise<void> { await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs); } const isDryRun = configs.IS_LOCAL_PUBLISH; - await publishReleaseNotesAsync(updatedPublicPackages, isDryRun); + const releaseNotes = await publishReleaseNotesAsync(updatedPublicPackages, isDryRun); + utils.log('Published release notes'); + + if (!isDryRun && releaseNotes) { + try { + await alertDiscordAsync(releaseNotes); + } catch (e) { + utils.log("Publish successful, but couldn't auto-alert discord (", e.message, '), Please alert manually.'); + } + } })().catch(err => { utils.log(err); process.exit(1); diff --git a/packages/monorepo-scripts/src/test_installation.ts b/packages/monorepo-scripts/src/test_installation.ts index 5ae13b198..822f48967 100644 --- a/packages/monorepo-scripts/src/test_installation.ts +++ b/packages/monorepo-scripts/src/test_installation.ts @@ -45,45 +45,50 @@ function logIfDefined(x: any): void { const IS_LOCAL_PUBLISH = process.env.IS_LOCAL_PUBLISH === 'true'; const registry = IS_LOCAL_PUBLISH ? 'http://localhost:4873/' : 'https://registry.npmjs.org/'; const monorepoRootPath = path.join(__dirname, '../../..'); - const packages = utils.getPackages(monorepoRootPath); + // We sort error messages according to package topology so that we can see + // them in a more intuitive order. E.g. if package A has an error and + // package B imports it, the tests for both package A and package B will + // fail. But package B only fails because of an error in package A. + // Since the error in package A is the root cause, we log it first. + const packages = utils.getTopologicallySortedPackages(monorepoRootPath); const installablePackages = _.filter( packages, pkg => !pkg.packageJson.private && !_.isUndefined(pkg.packageJson.main) && pkg.packageJson.main.endsWith('.js'), ); - utils.log('Testing packages:'); - _.map(installablePackages, pkg => utils.log(`* ${pkg.packageJson.name}`)); - // Run all package tests asynchronously and push promises into an array so - // we can wait for all of them to resolve. - const promises: Array<Promise<void>> = []; - const errors: PackageErr[] = []; - for (const installablePackage of installablePackages) { - const packagePromise = testInstallPackageAsync(monorepoRootPath, registry, installablePackage).catch(error => { - errors.push({ packageName: installablePackage.packageJson.name, error }); - }); - promises.push(packagePromise); - } - await Promise.all(promises); - if (errors.length > 0) { - // We sort error messages according to package topology so that we can - // them in a more intuitive order. E.g. if package A has an error and - // package B imports it, the tests for both package A and package B will - // fail. But package B only fails because of an error in package A. - // Since the error in package A is the root cause, we log it first. - const topologicallySortedPackages = utils.getTopologicallySortedPackages(monorepoRootPath); - const topologicallySortedErrors = _.sortBy(errors, packageErr => - findPackageIndex(topologicallySortedPackages, packageErr.packageName), - ); - _.forEach(topologicallySortedErrors, packageError => { - utils.log(`ERROR in package ${packageError.packageName}:`); - logIfDefined(packageError.error.message); - logIfDefined(packageError.error.stderr); - logIfDefined(packageError.error.stdout); - logIfDefined(packageError.error.stack); - }); - process.exit(1); - } else { - process.exit(0); + const CHUNK_SIZE = 15; + const chunkedInstallablePackages = _.chunk(installablePackages, CHUNK_SIZE); + utils.log(`Testing all packages in ${chunkedInstallablePackages.length} chunks`); + for (const installablePackagesChunk of chunkedInstallablePackages) { + utils.log('Testing packages:'); + _.map(installablePackagesChunk, pkg => utils.log(`* ${pkg.packageJson.name}`)); + // Run all package tests within that chunk asynchronously and push promises into an array so + // we can wait for all of them to resolve. + const promises: Array<Promise<void>> = []; + const errors: PackageErr[] = []; + for (const installablePackage of installablePackagesChunk) { + const packagePromise = testInstallPackageAsync(monorepoRootPath, registry, installablePackage).catch( + error => { + errors.push({ packageName: installablePackage.packageJson.name, error }); + }, + ); + promises.push(packagePromise); + } + await Promise.all(promises); + if (errors.length > 0) { + const topologicallySortedErrors = _.sortBy(errors, packageErr => + findPackageIndex(packages, packageErr.packageName), + ); + _.forEach(topologicallySortedErrors, packageError => { + utils.log(`ERROR in package ${packageError.packageName}:`); + logIfDefined(packageError.error.message); + logIfDefined(packageError.error.stderr); + logIfDefined(packageError.error.stdout); + logIfDefined(packageError.error.stack); + }); + process.exit(1); + } } + process.exit(0); })().catch(err => { utils.log(`Unexpected error: ${err.message}`); process.exit(1); diff --git a/packages/monorepo-scripts/src/utils/discord.ts b/packages/monorepo-scripts/src/utils/discord.ts new file mode 100644 index 000000000..3a0458769 --- /dev/null +++ b/packages/monorepo-scripts/src/utils/discord.ts @@ -0,0 +1,26 @@ +import { fetchAsync } from '@0x/utils'; + +import { constants } from '../constants'; + +import { utils } from './utils'; + +export const alertDiscordAsync = async (releaseNotes: string): Promise<void> => { + const webhookUrl = constants.discordAlertWebhookUrl; + if (webhookUrl === undefined) { + throw new Error("No discord webhook url, can't alert"); + } + + utils.log('Alerting discord...'); + const payload = { + content: `New monorepo package released! View at ${constants.releasesUrl} \n\n ${releaseNotes}`, + }; + await fetchAsync(webhookUrl, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + }); + return; +}; diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts index e63244b46..48704f3aa 100644 --- a/packages/monorepo-scripts/src/utils/github_release_utils.ts +++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts @@ -12,7 +12,10 @@ import { utils } from './utils'; const publishReleaseAsync = promisify(publishRelease); // tslint:disable-next-line:completed-docs -export async function publishReleaseNotesAsync(packagesToPublish: Package[], isDryRun: boolean): Promise<void> { +export async function publishReleaseNotesAsync( + packagesToPublish: Package[], + isDryRun: boolean, +): Promise<string | undefined> { // Git push a tag representing this publish (publish-{commit-hash}) (truncate hash) const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath }); const latestGitCommit = result.stdout; @@ -75,6 +78,8 @@ export async function publishReleaseNotesAsync(packagesToPublish: Package[], isD utils.log('Publishing release notes ', releaseName, '...'); await publishReleaseAsync(publishReleaseConfigs); + + return aggregateNotes; } // Asset paths should described from the monorepo root. This method prefixes diff --git a/packages/pipeline/README.md b/packages/pipeline/README.md index 794488cac..40a64cdd1 100644 --- a/packages/pipeline/README.md +++ b/packages/pipeline/README.md @@ -147,6 +147,20 @@ set the`ZEROEX_DATA_PIPELINE_DB_URL` environment variable to a valid starting from that block number. 7. Run the migrations and then run your new script locally and verify it works as expected. +8. After all tests pass and you can run the script locally, open a new PR to + the monorepo. Don't merge this yet! +9. If you added any new scripts or dependencies between scripts, you will need + to make changes to https://github.com/0xProject/0x-pipeline-orchestration + and make a separate PR there. Don't merge this yet! +10. After your PR passes code review, ask @feuGeneA or @xianny to deploy your + changes to the QA environment. Check the [QA Airflow dashboard](http://airflow-qa.0x.org:8080) + to make sure everything works correctly in the QA environment. +11. Merge your PR to 0x-monorepo (and + https://github.com/0xProject/0x-pipeline-orchestration if needed). Then ask + @feuGeneA or @xianny to deploy to production. +12. Monitor the [production Airflow dashboard](http://airflow.0x.org:8080) to + make sure everything still works. +13. Celebrate! :tada: #### Additional guidelines and tips: @@ -164,3 +178,6 @@ set the`ZEROEX_DATA_PIPELINE_DB_URL` environment variable to a valid floating point numbers. * [TypeORM documentation](http://typeorm.io/#/) is pretty robust and can be a helpful resource. +* Scripts/parsers should perform minimum data transformation/normalization. + The idea here is to have a raw data feed that will be cleaned up and + synthesized in a separate step. diff --git a/packages/pipeline/migrations/1547153875669-UpdateDDexAPIToV3.ts b/packages/pipeline/migrations/1547153875669-UpdateDDexAPIToV3.ts new file mode 100644 index 000000000..957af4941 --- /dev/null +++ b/packages/pipeline/migrations/1547153875669-UpdateDDexAPIToV3.ts @@ -0,0 +1,21 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class UpdateDDexAPIToV31547153875669 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise<any> { + await queryRunner.query(` + UPDATE raw.token_orderbook_snapshots + SET quote_asset_symbol='WETH' + WHERE quote_asset_symbol='ETH' AND + source='ddex'; + `); + } + + public async down(queryRunner: QueryRunner): Promise<any> { + await queryRunner.query(` + UPDATE raw.token_orderbook_snapshots + SET quote_asset_symbol='ETH' + WHERE quote_asset_symbol='WETH' AND + source='ddex'; + `); + } +} diff --git a/packages/pipeline/src/data_sources/ddex/index.ts b/packages/pipeline/src/data_sources/ddex/index.ts index 2bbd8c29b..7ef92b90f 100644 --- a/packages/pipeline/src/data_sources/ddex/index.ts +++ b/packages/pipeline/src/data_sources/ddex/index.ts @@ -1,6 +1,6 @@ import { fetchAsync, logUtils } from '@0x/utils'; -const DDEX_BASE_URL = 'https://api.ddex.io/v2'; +const DDEX_BASE_URL = 'https://api.ddex.io/v3'; const ACTIVE_MARKETS_URL = `${DDEX_BASE_URL}/markets`; const NO_AGGREGATION_LEVEL = 3; // See https://docs.ddex.io/#get-orderbook const ORDERBOOK_ENDPOINT = `/orderbook?level=${NO_AGGREGATION_LEVEL}`; @@ -23,7 +23,6 @@ export interface DdexMarket { baseTokenDecimals: number; baseTokenAddress: string; minOrderSize: string; - maxOrderSize: string; pricePrecision: number; priceDecimals: number; amountDecimals: number; diff --git a/packages/pipeline/src/parsers/ddex_orders/index.ts b/packages/pipeline/src/parsers/ddex_orders/index.ts index eeb9c9d5b..562f894ab 100644 --- a/packages/pipeline/src/parsers/ddex_orders/index.ts +++ b/packages/pipeline/src/parsers/ddex_orders/index.ts @@ -58,14 +58,12 @@ export function parseDdexOrder( tokenOrder.orderType = orderType; tokenOrder.price = price; - // ddex currently confuses quote and base assets. - // We switch them here to maintain our internal consistency. - tokenOrder.baseAssetSymbol = ddexMarket.quoteToken; - tokenOrder.baseAssetAddress = ddexMarket.quoteTokenAddress; + tokenOrder.baseAssetSymbol = ddexMarket.baseToken; + tokenOrder.baseAssetAddress = ddexMarket.baseTokenAddress; tokenOrder.baseVolume = amount; - tokenOrder.quoteAssetSymbol = ddexMarket.baseToken; - tokenOrder.quoteAssetAddress = ddexMarket.baseTokenAddress; + tokenOrder.quoteAssetSymbol = ddexMarket.quoteToken; + tokenOrder.quoteAssetAddress = ddexMarket.quoteTokenAddress; tokenOrder.quoteVolume = price.times(amount); return tokenOrder; } diff --git a/packages/pipeline/test/parsers/ddex_orders/index_test.ts b/packages/pipeline/test/parsers/ddex_orders/index_test.ts index f30e86b02..d6f69e090 100644 --- a/packages/pipeline/test/parsers/ddex_orders/index_test.ts +++ b/packages/pipeline/test/parsers/ddex_orders/index_test.ts @@ -25,7 +25,6 @@ describe('ddex_orders', () => { baseTokenDecimals: 2, baseTokenAddress: '0xb45df06e38540a675fdb5b598abf2c0dbe9d6b81', minOrderSize: '0.1', - maxOrderSize: '1000', pricePrecision: 1, priceDecimals: 1, amountDecimals: 0, @@ -39,14 +38,12 @@ describe('ddex_orders', () => { expected.observedTimestamp = observedTimestamp; expected.orderType = OrderType.Bid; expected.price = new BigNumber(0.5); - // ddex currently confuses base and quote assets. - // Switch them to maintain our internal consistency. - expected.baseAssetSymbol = 'ABC'; - expected.baseAssetAddress = '0x0000000000000000000000000000000000000000'; - expected.baseVolume = new BigNumber(10); - expected.quoteAssetSymbol = 'DEF'; - expected.quoteAssetAddress = '0xb45df06e38540a675fdb5b598abf2c0dbe9d6b81'; + expected.quoteAssetSymbol = 'ABC'; + expected.quoteAssetAddress = '0x0000000000000000000000000000000000000000'; expected.quoteVolume = new BigNumber(5); + expected.baseAssetSymbol = 'DEF'; + expected.baseAssetAddress = '0xb45df06e38540a675fdb5b598abf2c0dbe9d6b81'; + expected.baseVolume = new BigNumber(10); const actual = parseDdexOrder(ddexMarket, observedTimestamp, orderType, source, ddexOrder); expect(actual).deep.equal(expected); diff --git a/packages/sol-cov/tslint.json b/packages/sol-cov/tslint.json deleted file mode 100644 index 631f46bca..000000000 --- a/packages/sol-cov/tslint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": ["@0x/tslint-config"], - "rules": { - "completed-docs": false - } -} diff --git a/packages/sol-cov/.npmignore b/packages/sol-coverage/.npmignore index 037786e46..037786e46 100644 --- a/packages/sol-cov/.npmignore +++ b/packages/sol-coverage/.npmignore diff --git a/packages/sol-coverage/CHANGELOG.json b/packages/sol-coverage/CHANGELOG.json new file mode 100644 index 000000000..223400eae --- /dev/null +++ b/packages/sol-coverage/CHANGELOG.json @@ -0,0 +1,11 @@ +[ + { + "version": "1.0.0", + "changes": [ + { + "note": "Initial release as a separate package. For historical entries see @0x/sol-tracing-utils", + "pr": 1492 + } + ] + } +] diff --git a/packages/sol-cov/README.md b/packages/sol-coverage/README.md index 31d73dc63..f8cc62eb8 100644 --- a/packages/sol-cov/README.md +++ b/packages/sol-coverage/README.md @@ -1,25 +1,25 @@ -## @0x/sol-cov +## @0x/sol-coverage A Solidity code coverage tool. -### Read the [Documentation](https://0xproject.com/docs/sol-cov). +### Read the [Documentation](https://0xproject.com/docs/sol-coverage). ## Installation ```bash -yarn add @0x/sol-cov +yarn add @0x/sol-coverage ``` **Import** ```javascript -import { CoverageSubprovider } from '@0x/sol-cov'; +import { CoverageSubprovider } from '@0x/sol-coverage'; ``` or ```javascript -var CoverageSubprovider = require('@0x/sol-cov').CoverageSubprovider; +var CoverageSubprovider = require('@0x/sol-coverage').CoverageSubprovider; ``` ## Contributing @@ -47,13 +47,13 @@ yarn install To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: ```bash -PKG=@0x/sol-cov yarn build +PKG=@0x/sol-coverage yarn build ``` Or continuously rebuild on change: ```bash -PKG=@0x/sol-cov yarn watch +PKG=@0x/sol-coverage yarn watch ``` ### Clean diff --git a/packages/sol-coverage/package.json b/packages/sol-coverage/package.json new file mode 100644 index 000000000..7dc764efd --- /dev/null +++ b/packages/sol-coverage/package.json @@ -0,0 +1,52 @@ +{ + "name": "@0x/sol-coverage", + "version": "1.0.0", + "engines": { + "node": ">=6.12" + }, + "description": "Generate coverage reports for Solidity code", + "main": "lib/src/index.js", + "types": "lib/src/index.d.ts", + "scripts": { + "build": "tsc -b", + "build:ci": "yarn build", + "lint": "tslint --format stylish --project .", + "clean": "shx rm -rf lib src/artifacts generated_docs", + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" + }, + "config": { + "postpublish": { + "assets": [] + } + }, + "repository": { + "type": "git", + "url": "https://github.com/0xProject/0x-monorepo.git" + }, + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/0xProject/0x-monorepo/issues" + }, + "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-coverage/README.md", + "dependencies": { + "@0x/subproviders": "^2.1.8", + "@0x/sol-tracing-utils": "^2.1.16", + "@0x/typescript-typings": "^3.0.6", + "ethereum-types": "^1.1.4", + "lodash": "^4.17.5" + }, + "devDependencies": { + "@0x/tslint-config": "^2.0.0", + "@types/node": "*", + "npm-run-all": "^4.1.2", + "nyc": "^11.0.1", + "shx": "^0.2.2", + "sinon": "^4.0.0", + "tslint": "5.11.0", + "typedoc": "0.13.0", + "typescript": "3.0.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/sol-cov/src/coverage_subprovider.ts b/packages/sol-coverage/src/coverage_subprovider.ts index 9667e891c..e6b546c4a 100644 --- a/packages/sol-cov/src/coverage_subprovider.ts +++ b/packages/sol-coverage/src/coverage_subprovider.ts @@ -1,22 +1,22 @@ -import * as _ from 'lodash'; - -import { AbstractArtifactAdapter } from './artifact_adapters/abstract_artifact_adapter'; -import { collectCoverageEntries } from './collect_coverage_entries'; -import { SingleFileSubtraceHandler, TraceCollector } from './trace_collector'; -import { TraceInfoSubprovider } from './trace_info_subprovider'; import { + AbstractArtifactAdapter, BranchCoverage, + collectCoverageEntries, ContractData, Coverage, FunctionCoverage, FunctionDescription, + SingleFileSubtraceHandler, SourceRange, StatementCoverage, StatementDescription, Subtrace, + TraceCollector, TraceInfo, -} from './types'; -import { utils } from './utils'; + TraceInfoSubprovider, + utils, +} from '@0x/sol-tracing-utils'; +import * as _ from 'lodash'; /** * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface. diff --git a/packages/sol-cov/src/globals.d.ts b/packages/sol-coverage/src/globals.d.ts index e799b3529..e799b3529 100644 --- a/packages/sol-cov/src/globals.d.ts +++ b/packages/sol-coverage/src/globals.d.ts diff --git a/packages/sol-coverage/src/index.ts b/packages/sol-coverage/src/index.ts new file mode 100644 index 000000000..97b4ecee6 --- /dev/null +++ b/packages/sol-coverage/src/index.ts @@ -0,0 +1,23 @@ +export { CoverageSubprovider } from './coverage_subprovider'; +export { + SolCompilerArtifactAdapter, + TruffleArtifactAdapter, + AbstractArtifactAdapter, + ContractData, +} from '@0x/sol-tracing-utils'; + +export { + JSONRPCRequestPayload, + Provider, + JSONRPCErrorCallback, + JSONRPCResponsePayload, + JSONRPCResponseError, +} from 'ethereum-types'; + +export { + JSONRPCRequestPayloadWithMethod, + NextCallback, + ErrorCallback, + OnNextCompleted, + Callback, +} from '@0x/subproviders'; diff --git a/packages/sol-coverage/tsconfig.json b/packages/sol-coverage/tsconfig.json new file mode 100644 index 000000000..233008d61 --- /dev/null +++ b/packages/sol-coverage/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "lib", + "rootDir": "." + }, + "include": ["./src/**/*"] +} diff --git a/packages/sol-coverage/tslint.json b/packages/sol-coverage/tslint.json new file mode 100644 index 000000000..dd9053357 --- /dev/null +++ b/packages/sol-coverage/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["@0x/tslint-config"] +} diff --git a/packages/sol-cov/typedoc-tsconfig.json b/packages/sol-coverage/typedoc-tsconfig.json index c9b0af1ae..c9b0af1ae 100644 --- a/packages/sol-cov/typedoc-tsconfig.json +++ b/packages/sol-coverage/typedoc-tsconfig.json diff --git a/packages/sol-profiler/.npmignore b/packages/sol-profiler/.npmignore new file mode 100644 index 000000000..037786e46 --- /dev/null +++ b/packages/sol-profiler/.npmignore @@ -0,0 +1,6 @@ +.* +yarn-error.log +/src/ +/scripts/ +tsconfig.json +/lib/src/monorepo_scripts/ diff --git a/packages/sol-profiler/CHANGELOG.json b/packages/sol-profiler/CHANGELOG.json new file mode 100644 index 000000000..223400eae --- /dev/null +++ b/packages/sol-profiler/CHANGELOG.json @@ -0,0 +1,11 @@ +[ + { + "version": "1.0.0", + "changes": [ + { + "note": "Initial release as a separate package. For historical entries see @0x/sol-tracing-utils", + "pr": 1492 + } + ] + } +] diff --git a/packages/sol-profiler/README.md b/packages/sol-profiler/README.md new file mode 100644 index 000000000..44fa29e3f --- /dev/null +++ b/packages/sol-profiler/README.md @@ -0,0 +1,75 @@ +## @0x/sol-profiler + +Solidity line-by-line gas profiler. + +### Read the [Documentation](https://0xproject.com/docs/sol-profiler). + +## Installation + +```bash +yarn add @0x/sol-profiler +``` + +**Import** + +```javascript +import { ProfilerSubprovider } from '@0x/sol-profiler'; +``` + +or + +```javascript +var ProfilerSubprovider = require('@0x/sol-profiler').ProfilerSubprovider; +``` + +## Contributing + +We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository. + +Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. + +### Install dependencies + +If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: + +```bash +yarn config set workspaces-experimental true +``` + +Then install dependencies + +```bash +yarn install +``` + +### Build + +To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: + +```bash +PKG=@0x/sol-profiler yarn build +``` + +Or continuously rebuild on change: + +```bash +PKG=@0x/sol-profiler yarn watch +``` + +### Clean + +```bash +yarn clean +``` + +### Lint + +```bash +yarn lint +``` + +### Run Tests + +```bash +yarn test +``` diff --git a/packages/sol-profiler/package.json b/packages/sol-profiler/package.json new file mode 100644 index 000000000..b85c82ed2 --- /dev/null +++ b/packages/sol-profiler/package.json @@ -0,0 +1,50 @@ +{ + "name": "@0x/sol-profiler", + "version": "1.0.0", + "engines": { + "node": ">=6.12" + }, + "description": "Generate profiler reports for Solidity code", + "main": "lib/src/index.js", + "types": "lib/src/index.d.ts", + "scripts": { + "build": "tsc -b", + "build:ci": "yarn build", + "lint": "tslint --format stylish --project .", + "clean": "shx rm -rf lib src/artifacts generated_docs", + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" + }, + "config": { + "postpublish": { + "assets": [] + } + }, + "repository": { + "type": "git", + "url": "https://github.com/0xProject/0x-monorepo.git" + }, + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/0xProject/0x-monorepo/issues" + }, + "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-profiler/README.md", + "dependencies": { + "@0x/subproviders": "^2.1.8", + "@0x/typescript-typings": "^3.0.6", + "@0x/sol-tracing-utils": "^2.1.16", + "ethereum-types": "^1.1.4", + "lodash": "^4.17.5" + }, + "devDependencies": { + "@0x/tslint-config": "^2.0.0", + "@types/node": "*", + "npm-run-all": "^4.1.2", + "shx": "^0.2.2", + "tslint": "5.11.0", + "typedoc": "0.13.0", + "typescript": "3.0.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/sol-profiler/src/globals.d.ts b/packages/sol-profiler/src/globals.d.ts new file mode 100644 index 000000000..e799b3529 --- /dev/null +++ b/packages/sol-profiler/src/globals.d.ts @@ -0,0 +1,7 @@ +// tslint:disable:completed-docs +declare module '*.json' { + const json: any; + /* tslint:disable */ + export default json; + /* tslint:enable */ +} diff --git a/packages/sol-cov/src/index.ts b/packages/sol-profiler/src/index.ts index 348e0fc9b..5d4806be4 100644 --- a/packages/sol-cov/src/index.ts +++ b/packages/sol-profiler/src/index.ts @@ -1,13 +1,13 @@ -export { CoverageSubprovider } from './coverage_subprovider'; -export { SolCompilerArtifactAdapter } from './artifact_adapters/sol_compiler_artifact_adapter'; -export { TruffleArtifactAdapter } from './artifact_adapters/truffle_artifact_adapter'; -export { AbstractArtifactAdapter } from './artifact_adapters/abstract_artifact_adapter'; +export { + AbstractArtifactAdapter, + SolCompilerArtifactAdapter, + TruffleArtifactAdapter, + ContractData, +} from '@0x/sol-tracing-utils'; // HACK: ProfilerSubprovider is a hacky way to do profiling using coverage tools. Not production ready export { ProfilerSubprovider } from './profiler_subprovider'; -export { RevertTraceSubprovider } from './revert_trace_subprovider'; -export { ContractData } from './types'; export { JSONRPCRequestPayload, Provider, diff --git a/packages/sol-cov/src/profiler_subprovider.ts b/packages/sol-profiler/src/profiler_subprovider.ts index ae9351f17..c3ed13ea5 100644 --- a/packages/sol-cov/src/profiler_subprovider.ts +++ b/packages/sol-profiler/src/profiler_subprovider.ts @@ -1,11 +1,18 @@ import * as _ from 'lodash'; -import { AbstractArtifactAdapter } from './artifact_adapters/abstract_artifact_adapter'; -import { collectCoverageEntries } from './collect_coverage_entries'; -import { SingleFileSubtraceHandler, TraceCollector } from './trace_collector'; -import { TraceInfoSubprovider } from './trace_info_subprovider'; -import { ContractData, Coverage, SourceRange, Subtrace, TraceInfo } from './types'; -import { utils } from './utils'; +import { + AbstractArtifactAdapter, + collectCoverageEntries, + ContractData, + Coverage, + SingleFileSubtraceHandler, + SourceRange, + Subtrace, + TraceCollector, + TraceInfo, + TraceInfoSubprovider, + utils, +} from '@0x/sol-tracing-utils'; /** * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface. diff --git a/packages/sol-profiler/tsconfig.json b/packages/sol-profiler/tsconfig.json new file mode 100644 index 000000000..233008d61 --- /dev/null +++ b/packages/sol-profiler/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "lib", + "rootDir": "." + }, + "include": ["./src/**/*"] +} diff --git a/packages/sol-profiler/tslint.json b/packages/sol-profiler/tslint.json new file mode 100644 index 000000000..dd9053357 --- /dev/null +++ b/packages/sol-profiler/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["@0x/tslint-config"] +} diff --git a/packages/sol-profiler/typedoc-tsconfig.json b/packages/sol-profiler/typedoc-tsconfig.json new file mode 100644 index 000000000..a4c669cb6 --- /dev/null +++ b/packages/sol-profiler/typedoc-tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../typedoc-tsconfig", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["./src/**/*"] +} diff --git a/packages/sol-trace/.npmignore b/packages/sol-trace/.npmignore new file mode 100644 index 000000000..037786e46 --- /dev/null +++ b/packages/sol-trace/.npmignore @@ -0,0 +1,6 @@ +.* +yarn-error.log +/src/ +/scripts/ +tsconfig.json +/lib/src/monorepo_scripts/ diff --git a/packages/sol-trace/CHANGELOG.json b/packages/sol-trace/CHANGELOG.json new file mode 100644 index 000000000..223400eae --- /dev/null +++ b/packages/sol-trace/CHANGELOG.json @@ -0,0 +1,11 @@ +[ + { + "version": "1.0.0", + "changes": [ + { + "note": "Initial release as a separate package. For historical entries see @0x/sol-tracing-utils", + "pr": 1492 + } + ] + } +] diff --git a/packages/sol-trace/README.md b/packages/sol-trace/README.md new file mode 100644 index 000000000..86ca2cbd6 --- /dev/null +++ b/packages/sol-trace/README.md @@ -0,0 +1,75 @@ +## @0x/sol-trace + +Prints a stack trace when a revert is encountered. + +### Read the [Documentation](https://0xproject.com/docs/sol-trace). + +## Installation + +```bash +yarn add @0x/sol-trace +``` + +**Import** + +```javascript +import { RevertTraceSubprovider } from '@0x/sol-trace'; +``` + +or + +```javascript +var RevertTraceSubprovider = require('@0x/sol-trace').RevertTraceSubprovider; +``` + +## Contributing + +We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository. + +Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. + +### Install dependencies + +If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: + +```bash +yarn config set workspaces-experimental true +``` + +Then install dependencies + +```bash +yarn install +``` + +### Build + +To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: + +```bash +PKG=@0x/sol-trace yarn build +``` + +Or continuously rebuild on change: + +```bash +PKG=@0x/sol-trace yarn watch +``` + +### Clean + +```bash +yarn clean +``` + +### Lint + +```bash +yarn lint +``` + +### Run Tests + +```bash +yarn test +``` diff --git a/packages/sol-trace/package.json b/packages/sol-trace/package.json new file mode 100644 index 000000000..3013be6f9 --- /dev/null +++ b/packages/sol-trace/package.json @@ -0,0 +1,52 @@ +{ + "name": "@0x/sol-trace", + "version": "1.0.0", + "engines": { + "node": ">=6.12" + }, + "description": "Prints stack trace on Solidity revert", + "main": "lib/src/index.js", + "types": "lib/src/index.d.ts", + "scripts": { + "build": "tsc -b", + "build:ci": "yarn build", + "lint": "tslint --format stylish --project .", + "clean": "shx rm -rf lib src/artifacts generated_docs", + "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" + }, + "config": { + "postpublish": { + "assets": [] + } + }, + "repository": { + "type": "git", + "url": "https://github.com/0xProject/0x-monorepo.git" + }, + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/0xProject/0x-monorepo/issues" + }, + "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-trace/README.md", + "dependencies": { + "@0x/subproviders": "^2.1.8", + "@0x/typescript-typings": "^3.0.6", + "@0x/sol-tracing-utils": "^2.1.16", + "ethereum-types": "^1.1.4", + "ethereumjs-util": "^5.1.1", + "lodash": "^4.17.5", + "loglevel": "^1.6.1" + }, + "devDependencies": { + "@0x/tslint-config": "^2.0.0", + "@types/loglevel": "^1.5.3", + "@types/node": "*", + "npm-run-all": "^4.1.2", + "shx": "^0.2.2", + "tslint": "5.11.0", + "typescript": "3.0.1" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/sol-trace/src/globals.d.ts b/packages/sol-trace/src/globals.d.ts new file mode 100644 index 000000000..e799b3529 --- /dev/null +++ b/packages/sol-trace/src/globals.d.ts @@ -0,0 +1,7 @@ +// tslint:disable:completed-docs +declare module '*.json' { + const json: any; + /* tslint:disable */ + export default json; + /* tslint:enable */ +} diff --git a/packages/sol-trace/src/index.ts b/packages/sol-trace/src/index.ts new file mode 100644 index 000000000..120c0d0a9 --- /dev/null +++ b/packages/sol-trace/src/index.ts @@ -0,0 +1,24 @@ +export { + AbstractArtifactAdapter, + TruffleArtifactAdapter, + SolCompilerArtifactAdapter, + ContractData, +} from '@0x/sol-tracing-utils'; + +export { RevertTraceSubprovider } from './revert_trace_subprovider'; + +export { + JSONRPCRequestPayload, + Provider, + JSONRPCErrorCallback, + JSONRPCResponsePayload, + JSONRPCResponseError, +} from 'ethereum-types'; + +export { + JSONRPCRequestPayloadWithMethod, + NextCallback, + ErrorCallback, + OnNextCompleted, + Callback, +} from '@0x/subproviders'; diff --git a/packages/sol-cov/src/revert_trace_subprovider.ts b/packages/sol-trace/src/revert_trace_subprovider.ts index 6ccf59653..31067a402 100644 --- a/packages/sol-cov/src/revert_trace_subprovider.ts +++ b/packages/sol-trace/src/revert_trace_subprovider.ts @@ -1,16 +1,20 @@ +import { + AbstractArtifactAdapter, + constants, + ContractData, + EvmCallStack, + getRevertTrace, + getSourceRangeSnippet, + parseSourceMap, + SourceRange, + SourceSnippet, + TraceCollectionSubprovider, + utils, +} from '@0x/sol-tracing-utils'; import { stripHexPrefix } from 'ethereumjs-util'; import * as _ from 'lodash'; import { getLogger, levels, Logger } from 'loglevel'; -import { AbstractArtifactAdapter } from './artifact_adapters/abstract_artifact_adapter'; -import { constants } from './constants'; -import { getSourceRangeSnippet } from './get_source_range_snippet'; -import { getRevertTrace } from './revert_trace'; -import { parseSourceMap } from './source_maps'; -import { TraceCollectionSubprovider } from './trace_collection_subprovider'; -import { ContractData, EvmCallStack, SourceRange, SourceSnippet } from './types'; -import { utils } from './utils'; - /** * This class implements the [web3-provider-engine](https://github.com/MetaMask/provider-engine) subprovider interface. * It is used to report call stack traces whenever a revert occurs. @@ -35,7 +39,7 @@ export class RevertTraceSubprovider extends TraceCollectionSubprovider { }; super(defaultFromAddress, traceCollectionSubproviderConfig); this._artifactAdapter = artifactAdapter; - this._logger = getLogger('sol-cov'); + this._logger = getLogger('sol-trace'); this._logger.setLevel(isVerbose ? levels.TRACE : levels.ERROR); } // tslint:disable-next-line:no-unused-variable diff --git a/packages/sol-trace/tsconfig.json b/packages/sol-trace/tsconfig.json new file mode 100644 index 000000000..233008d61 --- /dev/null +++ b/packages/sol-trace/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "lib", + "rootDir": "." + }, + "include": ["./src/**/*"] +} diff --git a/packages/sol-trace/tslint.json b/packages/sol-trace/tslint.json new file mode 100644 index 000000000..dd9053357 --- /dev/null +++ b/packages/sol-trace/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["@0x/tslint-config"] +} diff --git a/packages/sol-trace/typedoc-tsconfig.json b/packages/sol-trace/typedoc-tsconfig.json new file mode 100644 index 000000000..a4c669cb6 --- /dev/null +++ b/packages/sol-trace/typedoc-tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../typedoc-tsconfig", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["./src/**/*"] +} diff --git a/packages/sol-tracing-utils/.npmignore b/packages/sol-tracing-utils/.npmignore new file mode 100644 index 000000000..037786e46 --- /dev/null +++ b/packages/sol-tracing-utils/.npmignore @@ -0,0 +1,6 @@ +.* +yarn-error.log +/src/ +/scripts/ +tsconfig.json +/lib/src/monorepo_scripts/ diff --git a/packages/sol-cov/CHANGELOG.json b/packages/sol-tracing-utils/CHANGELOG.json index 3781dd39e..c39753ea1 100644 --- a/packages/sol-cov/CHANGELOG.json +++ b/packages/sol-tracing-utils/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "3.0.0", + "changes": [ + { + "note": "Move out specific tools and leave just the shared parts of the codebase", + "pr": 1492 + } + ] + }, + { "timestamp": 1547040760, "version": "2.1.17", "changes": [ diff --git a/packages/sol-cov/CHANGELOG.md b/packages/sol-tracing-utils/CHANGELOG.md index c2bc3cd01..c2bc3cd01 100644 --- a/packages/sol-cov/CHANGELOG.md +++ b/packages/sol-tracing-utils/CHANGELOG.md diff --git a/packages/sol-tracing-utils/README.md b/packages/sol-tracing-utils/README.md new file mode 100644 index 000000000..0a4749b8e --- /dev/null +++ b/packages/sol-tracing-utils/README.md @@ -0,0 +1,61 @@ +## @0x/sol-tracing-utils + +Common code for all solidity trace-based tools (sol-coverage, sol-profiler, sol-trace). + +## Installation + +```bash +yarn add @0x/sol-sol-tracing-utils +``` + +## Contributing + +We welcome improvements and fixes from the wider community! To report bugs within this package, please create an issue in this repository. + +Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting started. + +### Install dependencies + +If you don't have yarn workspaces enabled (Yarn < v1.0) - enable them: + +```bash +yarn config set workspaces-experimental true +``` + +Then install dependencies + +```bash +yarn install +``` + +### Build + +To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory: + +```bash +PKG=@0x/sol-tracing-utils yarn build +``` + +Or continuously rebuild on change: + +```bash +PKG=@0x/sol-tracing-utils yarn watch +``` + +### Clean + +```bash +yarn clean +``` + +### Lint + +```bash +yarn lint +``` + +### Run Tests + +```bash +yarn test +``` diff --git a/packages/sol-cov/compiler.json b/packages/sol-tracing-utils/compiler.json index a6a0c6d3a..a6a0c6d3a 100644 --- a/packages/sol-cov/compiler.json +++ b/packages/sol-tracing-utils/compiler.json diff --git a/packages/sol-cov/coverage/.gitkeep b/packages/sol-tracing-utils/coverage/.gitkeep index e69de29bb..e69de29bb 100644 --- a/packages/sol-cov/coverage/.gitkeep +++ b/packages/sol-tracing-utils/coverage/.gitkeep diff --git a/packages/sol-cov/package.json b/packages/sol-tracing-utils/package.json index 8542948b1..9486ab541 100644 --- a/packages/sol-cov/package.json +++ b/packages/sol-tracing-utils/package.json @@ -1,10 +1,10 @@ { - "name": "@0x/sol-cov", + "name": "@0x/sol-tracing-utils", "version": "2.1.17", "engines": { "node": ">=6.12" }, - "description": "Generate coverage reports for Solidity code", + "description": "Common part of trace based solidity tools (sol-coverage, sol-trace, sol-profiler)", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "scripts": { @@ -34,13 +34,13 @@ }, "repository": { "type": "git", - "url": "https://github.com/0xProject/0x.js.git" + "url": "https://github.com/0xProject/0x-monorepo.git" }, "license": "Apache-2.0", "bugs": { - "url": "https://github.com/0xProject/0x.js/issues" + "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x.js/packages/sol-cov/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-tracing-utils/README.md", "dependencies": { "@0x/dev-utils": "^1.0.22", "@0x/sol-compiler": "^2.0.0", diff --git a/packages/sol-cov/src/artifact_adapters/abstract_artifact_adapter.ts b/packages/sol-tracing-utils/src/artifact_adapters/abstract_artifact_adapter.ts index fcc6562ad..fcc6562ad 100644 --- a/packages/sol-cov/src/artifact_adapters/abstract_artifact_adapter.ts +++ b/packages/sol-tracing-utils/src/artifact_adapters/abstract_artifact_adapter.ts diff --git a/packages/sol-cov/src/artifact_adapters/sol_compiler_artifact_adapter.ts b/packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts index 57391abbe..57391abbe 100644 --- a/packages/sol-cov/src/artifact_adapters/sol_compiler_artifact_adapter.ts +++ b/packages/sol-tracing-utils/src/artifact_adapters/sol_compiler_artifact_adapter.ts diff --git a/packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts b/packages/sol-tracing-utils/src/artifact_adapters/truffle_artifact_adapter.ts index f064911d3..bb2b15153 100644 --- a/packages/sol-cov/src/artifact_adapters/truffle_artifact_adapter.ts +++ b/packages/sol-tracing-utils/src/artifact_adapters/truffle_artifact_adapter.ts @@ -80,7 +80,7 @@ export class TruffleArtifactAdapter extends AbstractArtifactAdapter { throw new Error( `${artifact.contractName} was compiled with solidity ${compilerVersion} but specified version is ${ this._solcVersion - } making it impossible for sol-cov to process traces`, + } making it impossible to process traces`, ); } } diff --git a/packages/sol-cov/src/ast_visitor.ts b/packages/sol-tracing-utils/src/ast_visitor.ts index e55cdf6ec..e55cdf6ec 100644 --- a/packages/sol-cov/src/ast_visitor.ts +++ b/packages/sol-tracing-utils/src/ast_visitor.ts diff --git a/packages/sol-cov/src/collect_coverage_entries.ts b/packages/sol-tracing-utils/src/collect_coverage_entries.ts index bdbcd613e..bdbcd613e 100644 --- a/packages/sol-cov/src/collect_coverage_entries.ts +++ b/packages/sol-tracing-utils/src/collect_coverage_entries.ts diff --git a/packages/sol-cov/src/constants.ts b/packages/sol-tracing-utils/src/constants.ts index 34d62b537..34d62b537 100644 --- a/packages/sol-cov/src/constants.ts +++ b/packages/sol-tracing-utils/src/constants.ts diff --git a/packages/sol-cov/src/get_source_range_snippet.ts b/packages/sol-tracing-utils/src/get_source_range_snippet.ts index bea17beae..f578675d3 100644 --- a/packages/sol-cov/src/get_source_range_snippet.ts +++ b/packages/sol-tracing-utils/src/get_source_range_snippet.ts @@ -15,6 +15,11 @@ interface ASTInfo { // Parsing source code for each transaction/code is slow and therefore we cache it const parsedSourceByHash: { [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(parsedSourceByHash[sourceHash])) { diff --git a/packages/sol-tracing-utils/src/globals.d.ts b/packages/sol-tracing-utils/src/globals.d.ts new file mode 100644 index 000000000..e799b3529 --- /dev/null +++ b/packages/sol-tracing-utils/src/globals.d.ts @@ -0,0 +1,7 @@ +// tslint:disable:completed-docs +declare module '*.json' { + const json: any; + /* tslint:disable */ + export default json; + /* tslint:enable */ +} diff --git a/packages/sol-tracing-utils/src/index.ts b/packages/sol-tracing-utils/src/index.ts new file mode 100644 index 000000000..413e5305e --- /dev/null +++ b/packages/sol-tracing-utils/src/index.ts @@ -0,0 +1,39 @@ +export { SolCompilerArtifactAdapter } from './artifact_adapters/sol_compiler_artifact_adapter'; +export { TruffleArtifactAdapter } from './artifact_adapters/truffle_artifact_adapter'; +export { AbstractArtifactAdapter } from './artifact_adapters/abstract_artifact_adapter'; + +export { + ContractData, + EvmCallStack, + SourceRange, + SourceSnippet, + StatementCoverage, + StatementDescription, + BranchCoverage, + BranchDescription, + Subtrace, + TraceInfo, + Coverage, + LineColumn, + LineCoverage, + FunctionCoverage, + FunctionDescription, + SingleFileSourceRange, + BranchMap, + EvmCallStackEntry, + FnMap, + LocationByOffset, + StatementMap, + TraceInfoBase, + TraceInfoExistingContract, + TraceInfoNewContract, +} from './types'; +export { collectCoverageEntries } from './collect_coverage_entries'; +export { TraceCollector, SingleFileSubtraceHandler } from './trace_collector'; +export { TraceInfoSubprovider } from './trace_info_subprovider'; +export { utils } from './utils'; +export { constants } from './constants'; +export { parseSourceMap } from './source_maps'; +export { getSourceRangeSnippet } from './get_source_range_snippet'; +export { getRevertTrace } from './revert_trace'; +export { TraceCollectionSubprovider } from './trace_collection_subprovider'; diff --git a/packages/sol-cov/src/instructions.ts b/packages/sol-tracing-utils/src/instructions.ts index 40987dbe5..40987dbe5 100644 --- a/packages/sol-cov/src/instructions.ts +++ b/packages/sol-tracing-utils/src/instructions.ts diff --git a/packages/sol-cov/src/revert_trace.ts b/packages/sol-tracing-utils/src/revert_trace.ts index d60c6e7d9..4d474120c 100644 --- a/packages/sol-cov/src/revert_trace.ts +++ b/packages/sol-tracing-utils/src/revert_trace.ts @@ -6,6 +6,11 @@ import * as _ from 'lodash'; import { EvmCallStack } from './types'; import { utils } from './utils'; +/** + * Converts linear trace to a call stack by following calls and returns + * @param structLogs Linear trace + * @param startAddress The address of initial context + */ export function getRevertTrace(structLogs: StructLog[], startAddress: string): EvmCallStack { const evmCallStack: EvmCallStack = []; const addressStack = [startAddress]; @@ -55,7 +60,7 @@ export function getRevertTrace(structLogs: StructLog[], startAddress: string): E // TODO: Refactor this logic to fetch the sub-called contract bytecode before the selfdestruct is called // in order to handle this edge-case. logUtils.warn( - "Detected a selfdestruct. Sol-cov currently doesn't support that scenario. We'll just skip the trace part for a destructed contract", + "Detected a selfdestruct. We currently do not support that scenario. We'll just skip the trace part for a destructed contract", ); } } else if (structLog.op === OpCode.Revert) { @@ -67,7 +72,7 @@ export function getRevertTrace(structLogs: StructLog[], startAddress: string): E } else if (structLog.op === OpCode.Create) { // TODO: Extract the new contract address from the stack and handle that scenario logUtils.warn( - "Detected a contract created from within another contract. Sol-cov currently doesn't support that scenario. We'll just skip that trace", + "Detected a contract created from within another contract. We currently do not support that scenario. We'll just skip that trace", ); return []; } else { diff --git a/packages/sol-cov/src/source_maps.ts b/packages/sol-tracing-utils/src/source_maps.ts index 90b21dda1..af0fb4035 100644 --- a/packages/sol-cov/src/source_maps.ts +++ b/packages/sol-tracing-utils/src/source_maps.ts @@ -1,7 +1,7 @@ import * as _ from 'lodash'; import { getPcToInstructionIndexMapping } from './instructions'; -import { LineColumn, LocationByOffset, SourceRange } from './types'; +import { LocationByOffset, SourceRange } from './types'; const RADIX = 10; @@ -11,6 +11,10 @@ export interface SourceLocation { fileIndex: number; } +/** + * Receives a string with newlines and returns a map of byte offset to LineColumn + * @param str A string to process + */ export function getLocationByOffset(str: string): LocationByOffset { const locationByOffset: LocationByOffset = { 0: { line: 1, column: 0 } }; let currentOffset = 0; @@ -26,8 +30,14 @@ export function getLocationByOffset(str: string): LocationByOffset { return locationByOffset; } -// Parses a sourcemap string -// The solidity sourcemap format is documented here: https://github.com/ethereum/solidity/blob/develop/docs/miscellaneous.rst#source-mappings +/** + * Parses a sourcemap string. + * The solidity sourcemap format is documented here: https://github.com/ethereum/solidity/blob/develop/docs/miscellaneous.rst#source-mappings + * @param sourceCodes sources contents + * @param srcMap source map string + * @param bytecodeHex contract bytecode + * @param sources sources file names + */ export function parseSourceMap( sourceCodes: string[], srcMap: string, diff --git a/packages/sol-cov/src/trace.ts b/packages/sol-tracing-utils/src/trace.ts index b38dbdce0..770080af3 100644 --- a/packages/sol-cov/src/trace.ts +++ b/packages/sol-tracing-utils/src/trace.ts @@ -8,6 +8,11 @@ export interface TraceByContractAddress { [contractAddress: string]: StructLog[]; } +/** + * Converts linear stack trace to `TraceByContractAddress`. + * @param structLogs stack trace + * @param startAddress initial context address + */ export function getTracesByContractAddress(structLogs: StructLog[], startAddress: string): TraceByContractAddress { const traceByContractAddress: TraceByContractAddress = {}; let currentTraceSegment = []; @@ -58,13 +63,13 @@ export function getTracesByContractAddress(structLogs: StructLog[], startAddress // TODO: Refactor this logic to fetch the sub-called contract bytecode before the selfdestruct is called // in order to handle this edge-case. logUtils.warn( - "Detected a selfdestruct. Sol-cov currently doesn't support that scenario. We'll just skip the trace part for a destructed contract", + "Detected a selfdestruct. We currently do not support that scenario. We'll just skip the trace part for a destructed contract", ); } } else if (structLog.op === OpCode.Create) { // TODO: Extract the new contract address from the stack and handle that scenario logUtils.warn( - "Detected a contract created from within another contract. Sol-cov currently doesn't support that scenario. We'll just skip that trace", + "Detected a contract created from within another contract. We currently do not support that scenario. We'll just skip that trace", ); return traceByContractAddress; } else { diff --git a/packages/sol-cov/src/trace_collection_subprovider.ts b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts index 25e38768d..25e38768d 100644 --- a/packages/sol-cov/src/trace_collection_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_collection_subprovider.ts diff --git a/packages/sol-cov/src/trace_collector.ts b/packages/sol-tracing-utils/src/trace_collector.ts index 44cffc238..943e208cf 100644 --- a/packages/sol-cov/src/trace_collector.ts +++ b/packages/sol-tracing-utils/src/trace_collector.ts @@ -51,7 +51,7 @@ export class TraceCollector { singleFileSubtraceHandler: SingleFileSubtraceHandler, ) { this._artifactAdapter = artifactAdapter; - this._logger = getLogger('sol-cov'); + this._logger = getLogger('sol-tracing-utils'); this._logger.setLevel(isVerbose ? levels.TRACE : levels.ERROR); this._singleFileSubtraceHandler = singleFileSubtraceHandler; } diff --git a/packages/sol-cov/src/trace_info_subprovider.ts b/packages/sol-tracing-utils/src/trace_info_subprovider.ts index 635a68f58..635a68f58 100644 --- a/packages/sol-cov/src/trace_info_subprovider.ts +++ b/packages/sol-tracing-utils/src/trace_info_subprovider.ts diff --git a/packages/sol-cov/src/types.ts b/packages/sol-tracing-utils/src/types.ts index 54ade0400..54ade0400 100644 --- a/packages/sol-cov/src/types.ts +++ b/packages/sol-tracing-utils/src/types.ts diff --git a/packages/sol-cov/src/utils.ts b/packages/sol-tracing-utils/src/utils.ts index d8bc65e73..d8bc65e73 100644 --- a/packages/sol-cov/src/utils.ts +++ b/packages/sol-tracing-utils/src/utils.ts diff --git a/packages/sol-cov/test/collect_coverage_entries_test.ts b/packages/sol-tracing-utils/test/collect_coverage_entries_test.ts index 7832ec316..7832ec316 100644 --- a/packages/sol-cov/test/collect_coverage_entries_test.ts +++ b/packages/sol-tracing-utils/test/collect_coverage_entries_test.ts diff --git a/packages/sol-cov/test/fixtures/contracts/AllSolidityFeatures.sol b/packages/sol-tracing-utils/test/fixtures/contracts/AllSolidityFeatures.sol index 21137347e..21137347e 100644 --- a/packages/sol-cov/test/fixtures/contracts/AllSolidityFeatures.sol +++ b/packages/sol-tracing-utils/test/fixtures/contracts/AllSolidityFeatures.sol diff --git a/packages/sol-cov/test/fixtures/contracts/SimpleStorage.sol b/packages/sol-tracing-utils/test/fixtures/contracts/SimpleStorage.sol index e4b4ac246..e4b4ac246 100644 --- a/packages/sol-cov/test/fixtures/contracts/SimpleStorage.sol +++ b/packages/sol-tracing-utils/test/fixtures/contracts/SimpleStorage.sol diff --git a/packages/sol-cov/test/fixtures/contracts/Simplest.sol b/packages/sol-tracing-utils/test/fixtures/contracts/Simplest.sol index d71016e07..d71016e07 100644 --- a/packages/sol-cov/test/fixtures/contracts/Simplest.sol +++ b/packages/sol-tracing-utils/test/fixtures/contracts/Simplest.sol diff --git a/packages/sol-cov/test/fixtures/contracts/SolcovIgnore.sol b/packages/sol-tracing-utils/test/fixtures/contracts/SolcovIgnore.sol index a7977ffb4..a7977ffb4 100644 --- a/packages/sol-cov/test/fixtures/contracts/SolcovIgnore.sol +++ b/packages/sol-tracing-utils/test/fixtures/contracts/SolcovIgnore.sol diff --git a/packages/sol-cov/test/instructions_test.ts b/packages/sol-tracing-utils/test/instructions_test.ts index 058053cf9..058053cf9 100644 --- a/packages/sol-cov/test/instructions_test.ts +++ b/packages/sol-tracing-utils/test/instructions_test.ts diff --git a/packages/sol-cov/test/sol_compiler_artifact_adapter_test.ts b/packages/sol-tracing-utils/test/sol_compiler_artifact_adapter_test.ts index 9c58d2cef..9c58d2cef 100644 --- a/packages/sol-cov/test/sol_compiler_artifact_adapter_test.ts +++ b/packages/sol-tracing-utils/test/sol_compiler_artifact_adapter_test.ts diff --git a/packages/sol-cov/test/source_maps_test.ts b/packages/sol-tracing-utils/test/source_maps_test.ts index 5820bedd7..5820bedd7 100644 --- a/packages/sol-cov/test/source_maps_test.ts +++ b/packages/sol-tracing-utils/test/source_maps_test.ts diff --git a/packages/sol-cov/test/trace_test.ts b/packages/sol-tracing-utils/test/trace_test.ts index 7a034362c..7a034362c 100644 --- a/packages/sol-cov/test/trace_test.ts +++ b/packages/sol-tracing-utils/test/trace_test.ts diff --git a/packages/sol-cov/test/utils_test.ts b/packages/sol-tracing-utils/test/utils_test.ts index 6fc8fcfe1..6fc8fcfe1 100644 --- a/packages/sol-cov/test/utils_test.ts +++ b/packages/sol-tracing-utils/test/utils_test.ts diff --git a/packages/sol-cov/tsconfig.json b/packages/sol-tracing-utils/tsconfig.json index 2ee711adc..2ee711adc 100644 --- a/packages/sol-cov/tsconfig.json +++ b/packages/sol-tracing-utils/tsconfig.json diff --git a/packages/sol-tracing-utils/tslint.json b/packages/sol-tracing-utils/tslint.json new file mode 100644 index 000000000..dd9053357 --- /dev/null +++ b/packages/sol-tracing-utils/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["@0x/tslint-config"] +} diff --git a/packages/sra-spec/src/md/introduction.md b/packages/sra-spec/src/md/introduction.md index 824df8998..ce61abff6 100644 --- a/packages/sra-spec/src/md/introduction.md +++ b/packages/sra-spec/src/md/introduction.md @@ -1,12 +1,12 @@ # Schemas -The [JSON schemas](http://json-schema.org/) for the API payloads and responses can be found in [@0xproject/json-schemas](https://github.com/0xProject/0x.js/tree/development/packages/json-schemas). Examples of each payload and response can be found in the library's [test suite](https://github.com/0xProject/0x.js/blob/development/packages/json-schemas/test/schema_test.ts#L1). +The [JSON schemas](http://json-schema.org/) for the API payloads and responses can be found in [@0xproject/json-schemas](https://github.com/0xProject/0x-monorepo/tree/development/packages/json-schemas). Examples of each payload and response can be found in the library's [test suite](https://github.com/0xProject/0x-monorepo/blob/development/packages/json-schemas/test/schema_test.ts#L1). ```bash npm install @0xproject/json-schemas --save ``` -You can easily validate your API's payloads and responses using the [@0xproject/json-schemas](https://github.com/0xProject/0x.js/tree/development/packages/json-schemas) package: +You can easily validate your API's payloads and responses using the [@0xproject/json-schemas](https://github.com/0xProject/0x-monorepo/tree/development/packages/json-schemas) package: ```js import {SchemaValidator, ValidatorResult, schemas} from '@0xproject/json-schemas'; diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index fb85c4174..d84e32dd2 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -1,5 +1,14 @@ [ { + "version": "3.0.0", + "changes": [ + { + "note": "Make `promisify` resolve when the callback error is undefined.", + "pr": 1501 + } + ] + }, + { "version": "2.1.1", "changes": [ { diff --git a/packages/utils/src/promisify.ts b/packages/utils/src/promisify.ts index 29d626b61..e82251a0f 100644 --- a/packages/utils/src/promisify.ts +++ b/packages/utils/src/promisify.ts @@ -10,7 +10,7 @@ export function promisify<T>(originalFn: (...args: any[]) => void, thisArg?: any const promisifiedFunction = async (...callArgs: any[]): Promise<T> => { return new Promise<T>((resolve, reject) => { const callback = (err: Error | null, data?: T) => { - _.isNull(err) ? resolve(data) : reject(err); + _.isNull(err) || _.isUndefined(err) ? resolve(data) : reject(err); }; originalFn.apply(thisArg, [...callArgs, callback]); }); diff --git a/packages/website/md/docs/sol_cov/1/installation.md b/packages/website/md/docs/sol_cov/1/installation.md deleted file mode 100644 index b9ce25a5f..000000000 --- a/packages/website/md/docs/sol_cov/1/installation.md +++ /dev/null @@ -1,17 +0,0 @@ -**Install** - -```bash -yarn add @0xproject/sol-cov -``` - -**Import** - -```javascript -import { CoverageSubprovider } from '@0xproject/sol-cov'; -``` - -or - -```javascript -var CoverageSubprovider = require('@0xproject/sol-cov').CoverageSubprovider; -``` diff --git a/packages/website/md/docs/sol_cov/1/introduction.md b/packages/website/md/docs/sol_cov/1/introduction.md deleted file mode 100644 index 7064a3554..000000000 --- a/packages/website/md/docs/sol_cov/1/introduction.md +++ /dev/null @@ -1 +0,0 @@ -Welcome to the [@0xproject/sol-cov](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-cov) documentation! Sol-cov is a Solidity coverage tool for your smart contract tests. diff --git a/packages/website/md/docs/sol_cov/2/installation.md b/packages/website/md/docs/sol_cov/2/installation.md deleted file mode 100644 index 1d4557cf5..000000000 --- a/packages/website/md/docs/sol_cov/2/installation.md +++ /dev/null @@ -1,17 +0,0 @@ -**Install** - -```bash -yarn add @0x/sol-cov -``` - -**Import** - -```javascript -import { CoverageSubprovider } from '@0x/sol-cov'; -``` - -or - -```javascript -var CoverageSubprovider = require('@0x/sol-cov').CoverageSubprovider; -``` diff --git a/packages/website/md/docs/sol_cov/2/introduction.md b/packages/website/md/docs/sol_cov/2/introduction.md deleted file mode 100644 index ac3256845..000000000 --- a/packages/website/md/docs/sol_cov/2/introduction.md +++ /dev/null @@ -1 +0,0 @@ -Welcome to the [sol-cov](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-cov) documentation! Sol-cov is a Solidity coverage tool for your smart contract tests. diff --git a/packages/website/md/docs/sol_coverage/installation.md b/packages/website/md/docs/sol_coverage/installation.md new file mode 100644 index 000000000..c7aaf07e9 --- /dev/null +++ b/packages/website/md/docs/sol_coverage/installation.md @@ -0,0 +1,17 @@ +**Install** + +```bash +yarn add @0x/sol-coverage +``` + +**Import** + +```javascript +import { CoverageSubprovider } from '@0x/sol-coverage'; +``` + +or + +```javascript +var CoverageSubprovider = require('@0x/sol-coverage').CoverageSubprovider; +``` diff --git a/packages/website/md/docs/sol_coverage/introduction.md b/packages/website/md/docs/sol_coverage/introduction.md new file mode 100644 index 000000000..3214e93a9 --- /dev/null +++ b/packages/website/md/docs/sol_coverage/introduction.md @@ -0,0 +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. diff --git a/packages/website/md/docs/sol_cov/2/usage.md b/packages/website/md/docs/sol_coverage/usage.md index 8e33f3bf5..dd3cdf597 100644 --- a/packages/website/md/docs/sol_cov/2/usage.md +++ b/packages/website/md/docs/sol_coverage/usage.md @@ -1,4 +1,4 @@ -Sol-cov 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. @@ -11,7 +11,7 @@ In order to use `CoverageSubprovider` with your favorite framework you need to p If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you. ```typescript -import { SolCompilerArtifactsAdapter } from '@0x/sol-cov'; +import { SolCompilerArtifactsAdapter } from '@0x/sol-coverage'; const artifactsPath = 'src/artifacts'; const contractsPath = 'src/contracts'; const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath); @@ -22,7 +22,7 @@ const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contract If your project is using [Truffle](https://truffleframework.com/), we've written a `TruffleArtifactsAdapter`for you. ```typescript -import { TruffleArtifactAdapter } from '@0x/sol-cov'; +import { TruffleArtifactAdapter } from '@0x/sol-coverage'; const contractsPath = 'src/contracts'; const artifactAdapter = new TruffleArtifactAdapter(contractsDir); ``` @@ -37,7 +37,7 @@ Look at the code of the two adapters above for examples. ### Usage ```typescript -import { CoverageSubprovider } from '@0x/sol-cov'; +import { CoverageSubprovider } from '@0x/sol-coverage'; import ProviderEngine = require('web3-provider-engine'); const provider = new ProviderEngine(); diff --git a/packages/website/md/docs/sol_profiler/installation.md b/packages/website/md/docs/sol_profiler/installation.md new file mode 100644 index 000000000..be9a365f5 --- /dev/null +++ b/packages/website/md/docs/sol_profiler/installation.md @@ -0,0 +1,17 @@ +**Install** + +```bash +yarn add @0x/sol-profiler +``` + +**Import** + +```javascript +import { ProfilerSubprovider } from '@0x/sol-profiler'; +``` + +or + +```javascript +var ProfilerSubprovider = require('@0x/sol-profiler').ProfilerSubprovider; +``` diff --git a/packages/website/md/docs/sol_profiler/introduction.md b/packages/website/md/docs/sol_profiler/introduction.md new file mode 100644 index 000000000..bd53fb0fe --- /dev/null +++ b/packages/website/md/docs/sol_profiler/introduction.md @@ -0,0 +1 @@ +Welcome to the [sol-profiler](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-profiler) documentation! Sol-profiler is a Solidity profiler tool. diff --git a/packages/website/md/docs/sol_cov/1/usage.md b/packages/website/md/docs/sol_profiler/usage.md index c2b8404af..35ea140da 100644 --- a/packages/website/md/docs/sol_cov/1/usage.md +++ b/packages/website/md/docs/sol_profiler/usage.md @@ -1,17 +1,17 @@ -Sol-cov 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-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 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. +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. -Coverage 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. +Profiler 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 `CoverageSubprovider` with your favorite framework you need to pass an `artifactsAdapter` to it. +In order to use `ProfilerSubprovider` with your favorite framework you need to pass an `artifactsAdapter` to it. ### Sol-compiler -If you are generating your artifacts with [@0xproject/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you. +If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you. ```typescript -import { SolCompilerArtifactsAdapter } from '@0xproject/sol-cov'; +import { SolCompilerArtifactsAdapter } from '@0x/sol-profiler'; const artifactsPath = 'src/artifacts'; const contractsPath = 'src/contracts'; const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath); @@ -22,7 +22,7 @@ const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contract If your project is using [Truffle](https://truffleframework.com/), we've written a `TruffleArtifactsAdapter`for you. ```typescript -import { TruffleArtifactAdapter } from '@0xproject/sol-cov'; +import { TruffleArtifactAdapter } from '@0x/sol-profiler'; const contractsPath = 'src/contracts'; const artifactAdapter = new TruffleArtifactAdapter(contractsDir); ``` @@ -37,7 +37,7 @@ Look at the code of the two adapters above for examples. ### Usage ```typescript -import { CoverageSubprovider } from '@0xproject/sol-cov'; +import { ProfilerSubprovider } from '@0x/sol-profiler'; import ProviderEngine = require('web3-provider-engine'); const provider = new ProviderEngine(); @@ -48,15 +48,15 @@ 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); +const profilerSubprovider = new ProfilerSubprovider(artifactsAdapter, defaultFromAddress, isVerbose); -provider.addProvider(coverageSubprovider); +provider.addProvider(profilerSubprovider); ``` After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call: ```typescript -await coverageSubprovider.writeCoverageAsync(); +await profilerSubprovider.writeProfilerAsync(); ``` -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. +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. diff --git a/packages/website/md/docs/sol_trace/installation.md b/packages/website/md/docs/sol_trace/installation.md new file mode 100644 index 000000000..2f794b2f8 --- /dev/null +++ b/packages/website/md/docs/sol_trace/installation.md @@ -0,0 +1,17 @@ +**Install** + +```bash +yarn add @0x/sol-trace +``` + +**Import** + +```javascript +import { TraceSubprovider } from '@0x/sol-trace'; +``` + +or + +```javascript +var TraceSubprovider = require('@0x/sol-trace').TraceSubprovider; +``` diff --git a/packages/website/md/docs/sol_trace/introduction.md b/packages/website/md/docs/sol_trace/introduction.md new file mode 100644 index 000000000..21fea764e --- /dev/null +++ b/packages/website/md/docs/sol_trace/introduction.md @@ -0,0 +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. diff --git a/packages/website/md/docs/sol_trace/usage.md b/packages/website/md/docs/sol_trace/usage.md new file mode 100644 index 000000000..f3aa6fc35 --- /dev/null +++ b/packages/website/md/docs/sol_trace/usage.md @@ -0,0 +1,62 @@ +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. + +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. + +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. + +### Sol-compiler + +If you are generating your artifacts with [@0x/sol-compiler](https://0x.org/docs/sol-compiler) you can use the `SolCompilerArtifactsAdapter` we've implemented for you. + +```typescript +import { SolCompilerArtifactsAdapter } from '@0x/sol-trace'; +const artifactsPath = 'src/artifacts'; +const contractsPath = 'src/contracts'; +const artifactsAdapter = new SolCompilerArtifactsAdapter(artifactsPath, contractsPath); +``` + +### Truffle + +If your project is using [Truffle](https://truffleframework.com/), we've written a `TruffleArtifactsAdapter`for you. + +```typescript +import { TruffleArtifactAdapter } from '@0x/sol-trace'; +const contractsPath = 'src/contracts'; +const artifactAdapter = new TruffleArtifactAdapter(contractsDir); +``` + +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`. + +### 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. + +### Usage + +```typescript +import { TraceSubprovider } 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); + +provider.addProvider(traceSubprovider); +``` + +After your test suite is complete (e.g in the Mocha global `after` hook), you'll need to call: + +```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. diff --git a/packages/website/ts/components/modals/modal_contact.tsx b/packages/website/ts/components/modals/modal_contact.tsx index a3a1f13f5..7414df7d9 100644 --- a/packages/website/ts/components/modals/modal_contact.tsx +++ b/packages/website/ts/components/modals/modal_contact.tsx @@ -12,6 +12,7 @@ import { Icon } from 'ts/components/icon'; import { Input, InputWidth } from 'ts/components/modals/input'; import { Heading, Paragraph } from 'ts/components/text'; import { GlobalStyle } from 'ts/constants/globalStyle'; +import { utils } from 'ts/utils/utils'; export enum ModalContactType { General = 'GENERAL', @@ -279,7 +280,7 @@ export class ModalContact extends React.Component<Props> { try { // Disabling no-unbound method b/c no reason for _.isEmpty to be bound // tslint:disable:no-unbound-method - const response = await fetch(`https://website-api.0xproject.com${endpoint}`, { + const response = await fetch(`${utils.getBackendBaseUrl()}${endpoint}`, { method: 'post', mode: 'cors', credentials: 'same-origin', diff --git a/packages/website/ts/components/newsletter_form.tsx b/packages/website/ts/components/newsletter_form.tsx index 4a7abb7ec..bd61e3f4d 100644 --- a/packages/website/ts/components/newsletter_form.tsx +++ b/packages/website/ts/components/newsletter_form.tsx @@ -4,6 +4,7 @@ import styled, { withTheme } from 'styled-components'; import { ThemeValuesInterface } from 'ts/components/siteWrap'; import { colors } from 'ts/style/colors'; import { errorReporter } from 'ts/utils/error_reporter'; +import { utils } from 'ts/utils/utils'; interface FormProps { theme: ThemeValuesInterface; @@ -92,7 +93,7 @@ class Form extends React.Component<FormProps> { } try { - await fetch('https://website-api.0x.org/newsletter_subscriber/substack', { + await fetch(`${utils.getBackendBaseUrl()}/newsletter_subscriber/substack`, { method: 'post', mode: 'cors', headers: { diff --git a/packages/website/ts/containers/asset_buyer_documentation.ts b/packages/website/ts/containers/asset_buyer_documentation.ts index c93b9332d..815176e47 100644 --- a/packages/website/ts/containers/asset_buyer_documentation.ts +++ b/packages/website/ts/containers/asset_buyer_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown = require('md/docs/asset_buyer/introduction'); @@ -25,7 +23,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/asset-buyer', type: SupportedDocJson.TypeDoc, displayName: 'AssetBuyer', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/asset-buyer', markdownMenu: { introduction: [markdownSections.introduction], install: [markdownSections.installation], @@ -40,31 +38,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/connect_documentation.ts b/packages/website/ts/containers/connect_documentation.ts index 0f11e0809..19fd0ee56 100644 --- a/packages/website/ts/containers/connect_documentation.ts +++ b/packages/website/ts/containers/connect_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/connect/1/introduction'); @@ -25,7 +23,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/connect', type: SupportedDocJson.TypeDoc, displayName: '0x Connect', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/connect', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation], }, @@ -45,31 +43,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/contract_wrappers_documentation.ts b/packages/website/ts/containers/contract_wrappers_documentation.ts index 4c05605e3..dec95ae62 100644 --- a/packages/website/ts/containers/contract_wrappers_documentation.ts +++ b/packages/website/ts/containers/contract_wrappers_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/contract_wrappers/1/introduction'); @@ -24,7 +22,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/contract-wrappers', type: SupportedDocJson.TypeDoc, displayName: 'Contract Wrappers', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/contract-wrappers', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation], }, @@ -40,31 +38,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - docsInfo, - translate: state.translate, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/ethereum_types_documentation.ts b/packages/website/ts/containers/ethereum_types_documentation.ts index 9d1df1d1f..9b668d515 100644 --- a/packages/website/ts/containers/ethereum_types_documentation.ts +++ b/packages/website/ts/containers/ethereum_types_documentation.ts @@ -1,12 +1,10 @@ -import { constants as docConstants, DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { constants as docConstants, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown = require('md/docs/ethereum_types/introduction'); @@ -36,31 +34,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/json_schemas_documentation.ts b/packages/website/ts/containers/json_schemas_documentation.ts index 9c4bb8e26..3862ba878 100644 --- a/packages/website/ts/containers/json_schemas_documentation.ts +++ b/packages/website/ts/containers/json_schemas_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/json_schemas/1/introduction'); @@ -32,7 +30,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/json-schemas', type: SupportedDocJson.TypeDoc, displayName: 'JSON Schemas', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/json-schemas', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation, markdownSections.usage], schemas: [markdownSections.schemas], @@ -65,31 +63,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/migrations_documentation.ts b/packages/website/ts/containers/migrations_documentation.ts index 02919e06e..dd5db3ac6 100644 --- a/packages/website/ts/containers/migrations_documentation.ts +++ b/packages/website/ts/containers/migrations_documentation.ts @@ -23,7 +23,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/migrations', type: SupportedDocJson.TypeDoc, displayName: 'Migrations', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/migrations', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation], }, diff --git a/packages/website/ts/containers/order_utils_documentation.ts b/packages/website/ts/containers/order_utils_documentation.ts index f1d794988..4996c329a 100644 --- a/packages/website/ts/containers/order_utils_documentation.ts +++ b/packages/website/ts/containers/order_utils_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/order_utils/1/introduction'); @@ -25,7 +23,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/order-utils', type: SupportedDocJson.TypeDoc, displayName: 'Order utils', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/order-utils', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation], }, @@ -41,31 +39,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/order_watcher_documentation.ts b/packages/website/ts/containers/order_watcher_documentation.ts index 683e1fe9f..f3d3bada8 100644 --- a/packages/website/ts/containers/order_watcher_documentation.ts +++ b/packages/website/ts/containers/order_watcher_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/order_watcher/1/introduction'); @@ -25,7 +23,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/order-watcher', type: SupportedDocJson.TypeDoc, displayName: 'Order Watcher', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/order-watcher', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation], }, @@ -41,31 +39,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/smart_contracts_documentation.ts b/packages/website/ts/containers/smart_contracts_documentation.ts index 57c98fa3b..7c0de5515 100644 --- a/packages/website/ts/containers/smart_contracts_documentation.ts +++ b/packages/website/ts/containers/smart_contracts_documentation.ts @@ -1,13 +1,11 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import { Networks } from '@0x/react-shared'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths, SmartContractDocSections as Sections } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages, SmartContractDocSections as Sections } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/smart_contracts/1/introduction'); @@ -91,31 +89,7 @@ const docsInfoConfig: DocsInfoConfig = { }, }, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; - docsInfo: DocsInfo; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), - docsInfo, -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/sol_compiler_documentation.ts b/packages/website/ts/containers/sol_compiler_documentation.ts index f3a793e80..e899e9627 100644 --- a/packages/website/ts/containers/sol_compiler_documentation.ts +++ b/packages/website/ts/containers/sol_compiler_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/sol-compiler/1/introduction'); @@ -27,7 +25,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/sol-compiler', type: SupportedDocJson.TypeDoc, displayName: 'Solidity Compiler', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/sol-compiler', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation, markdownSections.usage], }, @@ -45,31 +43,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/sol_cov_documentation.ts b/packages/website/ts/containers/sol_cov_documentation.ts deleted file mode 100644 index 8944ec70a..000000000 --- a/packages/website/ts/containers/sol_cov_documentation.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; -import * as React from 'react'; -import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; -import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; - -/* tslint:disable:no-var-requires */ -const IntroMarkdown1 = require('md/docs/sol_cov/1/introduction'); -const InstallationMarkdown1 = require('md/docs/sol_cov/1/installation'); -const UsageMarkdown1 = require('md/docs/sol_cov/1/usage'); -const IntroMarkdown2 = require('md/docs/sol_cov/2/introduction'); -const InstallationMarkdown2 = require('md/docs/sol_cov/2/installation'); -const UsageMarkdown2 = require('md/docs/sol_cov/2/usage'); -/* tslint:enable:no-var-requires */ - -const markdownSections = { - introduction: 'introduction', - installation: 'installation', - usage: 'usage', -}; - -const docsInfoConfig: DocsInfoConfig = { - id: DocPackages.SolCov, - packageName: '@0x/sol-cov', - type: SupportedDocJson.TypeDoc, - displayName: 'Sol-cov', - packageUrl: 'https://github.com/0xProject/0x-monorepo', - markdownMenu: { - 'getting-started': [markdownSections.introduction, markdownSections.installation, markdownSections.usage], - }, - sectionNameToMarkdownByVersion: { - '0.0.1': { - [markdownSections.introduction]: IntroMarkdown1, - [markdownSections.installation]: InstallationMarkdown1, - [markdownSections.usage]: UsageMarkdown1, - }, - '2.1.8': { - [markdownSections.introduction]: IntroMarkdown2, - [markdownSections.installation]: InstallationMarkdown2, - [markdownSections.usage]: UsageMarkdown2, - }, - }, - markdownSections, -}; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); - -export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( - DocPageComponent, -); diff --git a/packages/website/ts/containers/sol_coverage_documentation.ts b/packages/website/ts/containers/sol_coverage_documentation.ts new file mode 100644 index 000000000..25d67e2d0 --- /dev/null +++ b/packages/website/ts/containers/sol_coverage_documentation.ts @@ -0,0 +1,43 @@ +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; + +/* tslint:disable:no-var-requires */ +const IntroMarkdown = require('md/docs/sol_coverage/introduction'); +const InstallationMarkdown = require('md/docs/sol_coverage/installation'); +const UsageMarkdown = require('md/docs/sol_coverage/usage'); +/* tslint:enable:no-var-requires */ + +const markdownSections = { + introduction: 'introduction', + installation: 'installation', + usage: 'usage', +}; + +const docsInfoConfig: DocsInfoConfig = { + id: DocPackages.SolCoverage, + packageName: '@0x/sol-coverage', + type: SupportedDocJson.TypeDoc, + displayName: 'Sol-coverage', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/sol-coverage', + markdownMenu: { + 'getting-started': [markdownSections.introduction, markdownSections.installation, markdownSections.usage], + }, + sectionNameToMarkdownByVersion: { + '1.0.0': { + [markdownSections.introduction]: IntroMarkdown, + [markdownSections.installation]: InstallationMarkdown, + [markdownSections.usage]: UsageMarkdown, + }, + }, + markdownSections, +}; +const mapStateToProps = getMapStateToProps(docsInfoConfig); + +export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( + DocPageComponent, +); diff --git a/packages/website/ts/containers/sol_profiler_documentation.ts b/packages/website/ts/containers/sol_profiler_documentation.ts new file mode 100644 index 000000000..14839831e --- /dev/null +++ b/packages/website/ts/containers/sol_profiler_documentation.ts @@ -0,0 +1,43 @@ +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; + +/* tslint:disable:no-var-requires */ +const IntroMarkdown = require('md/docs/sol_profiler/introduction'); +const InstallationMarkdown = require('md/docs/sol_profiler/installation'); +const UsageMarkdown = require('md/docs/sol_profiler/usage'); +/* tslint:enable:no-var-requires */ + +const markdownSections = { + introduction: 'introduction', + installation: 'installation', + usage: 'usage', +}; + +const docsInfoConfig: DocsInfoConfig = { + id: DocPackages.SolProfiler, + packageName: '@0x/sol-profiler', + type: SupportedDocJson.TypeDoc, + displayName: 'Sol-profiler', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/sol-profiler', + markdownMenu: { + 'getting-started': [markdownSections.introduction, markdownSections.installation, markdownSections.usage], + }, + sectionNameToMarkdownByVersion: { + '1.0.0': { + [markdownSections.introduction]: IntroMarkdown, + [markdownSections.installation]: InstallationMarkdown, + [markdownSections.usage]: UsageMarkdown, + }, + }, + markdownSections, +}; +const mapStateToProps = getMapStateToProps(docsInfoConfig); + +export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( + DocPageComponent, +); diff --git a/packages/website/ts/containers/sol_trace_documentation.ts b/packages/website/ts/containers/sol_trace_documentation.ts new file mode 100644 index 000000000..c5286f1ff --- /dev/null +++ b/packages/website/ts/containers/sol_trace_documentation.ts @@ -0,0 +1,43 @@ +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; + +/* tslint:disable:no-var-requires */ +const IntroMarkdown = require('md/docs/sol_trace/introduction'); +const InstallationMarkdown = require('md/docs/sol_trace/installation'); +const UsageMarkdown = require('md/docs/sol_trace/usage'); +/* tslint:enable:no-var-requires */ + +const markdownSections = { + introduction: 'introduction', + installation: 'installation', + usage: 'usage', +}; + +const docsInfoConfig: DocsInfoConfig = { + id: DocPackages.SolTrace, + packageName: '@0x/sol-trace', + type: SupportedDocJson.TypeDoc, + displayName: 'Sol-trace', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/sol-trace', + markdownMenu: { + 'getting-started': [markdownSections.introduction, markdownSections.installation, markdownSections.usage], + }, + sectionNameToMarkdownByVersion: { + '1.0.0': { + [markdownSections.introduction]: IntroMarkdown, + [markdownSections.installation]: InstallationMarkdown, + [markdownSections.usage]: UsageMarkdown, + }, + }, + markdownSections, +}; +const mapStateToProps = getMapStateToProps(docsInfoConfig); + +export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( + DocPageComponent, +); diff --git a/packages/website/ts/containers/subproviders_documentation.ts b/packages/website/ts/containers/subproviders_documentation.ts index 0e421777b..c7fb807a6 100644 --- a/packages/website/ts/containers/subproviders_documentation.ts +++ b/packages/website/ts/containers/subproviders_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/subproviders/1/introduction'); @@ -26,7 +24,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/subproviders', type: SupportedDocJson.TypeDoc, displayName: 'Subproviders', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/subproviders', markdownMenu: { 'getting-started': [docSections.introduction, docSections.installation, docSections.ledgerNodeHid], }, @@ -44,31 +42,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections: docSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/web3_wrapper_documentation.ts b/packages/website/ts/containers/web3_wrapper_documentation.ts index 9c8c34621..ad286da1a 100644 --- a/packages/website/ts/containers/web3_wrapper_documentation.ts +++ b/packages/website/ts/containers/web3_wrapper_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdown1 = require('md/docs/web3_wrapper/1/introduction'); @@ -24,7 +22,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '@0x/web3-wrapper', type: SupportedDocJson.TypeDoc, displayName: 'Web3Wrapper', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/web3-wrapper', markdownMenu: { 'getting-started': [markdownSections.introduction, markdownSections.installation], }, @@ -40,31 +38,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - translate: state.translate, - docsInfo, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/containers/zero_ex_js_documentation.ts b/packages/website/ts/containers/zero_ex_js_documentation.ts index e0ea6e275..5da8d5e52 100644 --- a/packages/website/ts/containers/zero_ex_js_documentation.ts +++ b/packages/website/ts/containers/zero_ex_js_documentation.ts @@ -1,12 +1,10 @@ -import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; +import { DocsInfoConfig, SupportedDocJson } from '@0x/react-docs'; import * as React from 'react'; import { connect } from 'react-redux'; -import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { Dispatcher } from 'ts/redux/dispatcher'; -import { State } from 'ts/redux/reducer'; -import { DocPackages, ScreenWidths } from 'ts/types'; -import { Translate } from 'ts/utils/translate'; +import { DocPackages } from 'ts/types'; + +import { getMapStateToProps, mapDispatchToProps } from '../utils/documentation_container'; /* tslint:disable:no-var-requires */ const IntroMarkdownV0 = require('md/docs/0xjs/0.0.1/introduction'); @@ -37,7 +35,7 @@ const docsInfoConfig: DocsInfoConfig = { packageName: '0x.js', type: SupportedDocJson.TypeDoc, displayName: '0x.js', - packageUrl: 'https://github.com/0xProject/0x-monorepo', + packageUrl: 'https://github.com/0xProject/0x-monorepo/packages/0x.js', markdownMenu: { 'getting-started': [ markdownSections.introduction, @@ -72,31 +70,7 @@ const docsInfoConfig: DocsInfoConfig = { }, markdownSections, }; -const docsInfo = new DocsInfo(docsInfoConfig); - -interface ConnectedState { - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - translate: Translate; - screenWidth: ScreenWidths; -} - -interface ConnectedDispatch { - dispatcher: Dispatcher; -} - -const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ - docsVersion: state.docsVersion, - availableDocVersions: state.availableDocVersions, - docsInfo, - translate: state.translate, - screenWidth: state.screenWidth, -}); - -const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ - dispatcher: new Dispatcher(dispatch), -}); +const mapStateToProps = getMapStateToProps(docsInfoConfig); export const Documentation: React.ComponentClass<DocPageProps> = connect(mapStateToProps, mapDispatchToProps)( DocPageComponent, diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx index 45054772c..4ed66c572 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -69,8 +69,14 @@ const LazySolCompilerDocumentation = createLazyComponent('Documentation', async const LazyJSONSchemasDocumentation = createLazyComponent('Documentation', async () => import(/* webpackChunkName: "jsonSchemasDocs" */ 'ts/containers/json_schemas_documentation'), ); -const LazySolCovDocumentation = createLazyComponent('Documentation', async () => - import(/* webpackChunkName: "solCovDocs" */ 'ts/containers/sol_cov_documentation'), +const LazySolCoverageDocumentation = createLazyComponent('Documentation', async () => + import(/* webpackChunkName: "solCoverageDocs" */ 'ts/containers/sol_coverage_documentation'), +); +const LazySolTraceDocumentation = createLazyComponent('Documentation', async () => + import(/* webpackChunkName: "solTraceDocs" */ 'ts/containers/sol_trace_documentation'), +); +const LazySolProfilerDocumentation = createLazyComponent('Documentation', async () => + import(/* webpackChunkName: "solProfilerDocs" */ 'ts/containers/sol_profiler_documentation'), ); const LazySubprovidersDocumentation = createLazyComponent('Documentation', async () => import(/* webpackChunkName: "subproviderDocs" */ 'ts/containers/subproviders_documentation'), @@ -149,7 +155,18 @@ render( path={`${WebsitePaths.SolCompiler}/:version?`} component={LazySolCompilerDocumentation} /> - <Route path={`${WebsitePaths.SolCov}/:version?`} component={LazySolCovDocumentation} /> + <Route + path={`${WebsitePaths.SolCoverage}/:version?`} + component={LazySolCoverageDocumentation} + /> + <Route + path={`${WebsitePaths.SolTrace}/:version?`} + component={LazySolTraceDocumentation} + /> + <Route + path={`${WebsitePaths.SolProfiler}/:version?`} + component={LazySolProfilerDocumentation} + /> <Route path={`${WebsitePaths.JSONSchemas}/:version?`} component={LazyJSONSchemasDocumentation} diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx index 3ae071774..14bad7329 100644 --- a/packages/website/ts/pages/documentation/doc_page.tsx +++ b/packages/website/ts/pages/documentation/doc_page.tsx @@ -33,7 +33,9 @@ const docIdToSubpackageName: { [id: string]: string } = { [DocPackages.ContractWrappers]: 'contract-wrappers', [DocPackages.SolCompiler]: 'sol-compiler', [DocPackages.JSONSchemas]: 'json-schemas', - [DocPackages.SolCov]: 'sol-cov', + [DocPackages.SolCoverage]: 'sol-coverage', + [DocPackages.SolProfiler]: 'sol-profiler', + [DocPackages.SolTrace]: 'sol-trace', [DocPackages.Subproviders]: 'subproviders', [DocPackages.OrderUtils]: 'order-utils', [DocPackages.OrderWatcher]: 'order-watcher', diff --git a/packages/website/ts/pages/documentation/docs_home.tsx b/packages/website/ts/pages/documentation/docs_home.tsx index fd3932bfa..d11cf02fb 100644 --- a/packages/website/ts/pages/documentation/docs_home.tsx +++ b/packages/website/ts/pages/documentation/docs_home.tsx @@ -218,10 +218,26 @@ const CATEGORY_TO_PACKAGES: ObjectMap<Package[]> = { }, { description: - 'A Solidity code coverage tool. Sol-cov uses transaction traces to figure out which lines of your code has been covered by your tests.', + 'A Solidity code coverage tool. Sol-coverage uses transaction traces to figure out which lines of your code has been covered by your tests.', link: { - title: '@0x/sol-cov', - to: WebsitePaths.SolCov, + title: '@0x/sol-coverage', + to: WebsitePaths.SolCoverage, + }, + }, + { + description: + 'A Solidity profiler. Sol-profiler uses transaction traces to figure out line-by-line gas consumption.', + link: { + title: '@0x/sol-profiler', + to: WebsitePaths.SolProfiler, + }, + }, + { + description: + 'A Solidity revert trace tool. Sol-trace prints human-readable revert trace whenever the revert happens.', + link: { + title: '@0x/sol-trace', + to: WebsitePaths.SolTrace, }, }, { diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 37bd73063..50114e2d6 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -370,7 +370,9 @@ export enum WebsitePaths { OrderWatcher = '/docs/order-watcher', SolCompiler = '/docs/sol-compiler', JSONSchemas = '/docs/json-schemas', - SolCov = '/docs/sol-cov', + SolCoverage = '/docs/sol-coverage', + SolProfiler = '/docs/sol-profiler', + SolTrace = '/docs/sol-trace', Subproviders = '/docs/subproviders', OrderUtils = '/docs/order-utils', EthereumTypes = '/docs/ethereum-types', @@ -386,7 +388,9 @@ export enum DocPackages { Web3Wrapper = 'WEB3_WRAPPER', SolCompiler = 'SOL_COMPILER', JSONSchemas = 'JSON_SCHEMAS', - SolCov = 'SOL_COV', + SolCoverage = 'SOL_COVERAGE', + SolTrace = 'SOL_TRACE', + SolProfiler = 'SOL_PROFILER', Subproviders = 'SUBPROVIDERS', OrderUtils = 'ORDER_UTILS', EthereumTypes = 'ETHEREUM_TYPES', diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts index fab382b07..7cc854ca0 100644 --- a/packages/website/ts/utils/configs.ts +++ b/packages/website/ts/utils/configs.ts @@ -5,8 +5,8 @@ const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs'; export const configs = { AMOUNT_DISPLAY_PRECSION: 5, - BACKEND_BASE_PROD_URL: 'https://website-api.0xproject.com', - BACKEND_BASE_STAGING_URL: 'https://staging-website-api.0xproject.com', + BACKEND_BASE_PROD_URL: 'https://website-api.0x.org', + BACKEND_BASE_STAGING_URL: 'https://staging-website-api.0x.org', BASE_URL, BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208', DEFAULT_DERIVATION_PATH: `44'/60'/0'`, @@ -39,8 +39,8 @@ export const configs = { ] as OutdatedWrappedEtherByNetworkId[], // The order matters. We first try first node and only then fall back to others. PUBLIC_NODE_URLS_BY_NETWORK_ID: { - [1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0xproject.com'], - [42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0xproject.com'], + [1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0x.org'], + [42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0x.org'], [3]: [`https://ropsten.infura.io/${INFURA_API_KEY}`], [4]: [`https://rinkeby.infura.io/${INFURA_API_KEY}`], } as PublicNodeUrlsByNetworkId, diff --git a/packages/website/ts/utils/documentation_container.ts b/packages/website/ts/utils/documentation_container.ts new file mode 100644 index 000000000..54e8a2c1a --- /dev/null +++ b/packages/website/ts/utils/documentation_container.ts @@ -0,0 +1,35 @@ +import { DocsInfo, DocsInfoConfig } from '@0x/react-docs'; +import { Dispatch } from 'redux'; +import { DocPageProps } from 'ts/pages/documentation/doc_page'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { ScreenWidths } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; + +export interface ConnectedState { + docsVersion: string; + availableDocVersions: string[]; + docsInfo: DocsInfo; + translate: Translate; + screenWidth: ScreenWidths; +} + +export interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +export const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const getMapStateToProps = (docsInfoConfig: DocsInfoConfig) => { + const docsInfo = new DocsInfo(docsInfoConfig); + const mapStateToProps = (state: State, _ownProps: DocPageProps): ConnectedState => ({ + docsVersion: state.docsVersion, + availableDocVersions: state.availableDocVersions, + translate: state.translate, + docsInfo, + screenWidth: state.screenWidth, + }); + return mapStateToProps; +}; diff --git a/python-packages/contract_addresses/README.md b/python-packages/contract_addresses/README.md index e2714afdf..d5e098deb 100644 --- a/python-packages/contract_addresses/README.md +++ b/python-packages/contract_addresses/README.md @@ -18,16 +18,10 @@ Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting ### Install Code and Dependencies -Ensure that you have installed Python >=3.6 and Docker. Then: - ```bash pip install -e .[dev] ``` -### Test - -Tests depend on a running ganache instance with the 0x contracts deployed in it. For convenience, a docker container is provided that has ganache-cli and a snapshot containing the necessary contracts. A shortcut is provided to run that docker container: `./setup.py ganache`. With that running, the tests can be run with `./setup.py test`. - ### Clean `./setup.py clean --all` diff --git a/python-packages/contract_artifacts/README.md b/python-packages/contract_artifacts/README.md index e0a34cbca..caa6b5df4 100644 --- a/python-packages/contract_artifacts/README.md +++ b/python-packages/contract_artifacts/README.md @@ -18,16 +18,10 @@ Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting ### Install Code and Dependencies -Ensure that you have installed Python >=3.6 and Docker. Then: - ```bash pip install -e .[dev] ``` -### Test - -Tests depend on a running ganache instance with the 0x contracts deployed in it. For convenience, a docker container is provided that has ganache-cli and a snapshot containing the necessary contracts. A shortcut is provided to run that docker container: `./setup.py ganache`. With that running, the tests can be run with `./setup.py test`. - ### Clean `./setup.py clean --all` diff --git a/python-packages/json_schemas/README.md b/python-packages/json_schemas/README.md index ef8e888f3..29b18baea 100644 --- a/python-packages/json_schemas/README.md +++ b/python-packages/json_schemas/README.md @@ -18,15 +18,13 @@ Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting ### Install Code and Dependencies -Ensure that you have installed Python >=3.6 and Docker. Then: - ```bash pip install -e .[dev] ``` ### Test -Tests depend on a running ganache instance with the 0x contracts deployed in it. For convenience, a docker container is provided that has ganache-cli and a snapshot containing the necessary contracts. A shortcut is provided to run that docker container: `./setup.py ganache`. With that running, the tests can be run with `./setup.py test`. +`./setup.py test`. ### Clean diff --git a/python-packages/order_utils/setup.py b/python-packages/order_utils/setup.py index 01a6c7360..6f9465680 100755 --- a/python-packages/order_utils/setup.py +++ b/python-packages/order_utils/setup.py @@ -188,6 +188,7 @@ setup( "pylint", "pytest", "sphinx", + "sphinx-autodoc-typehints", "tox", "twine", ] diff --git a/python-packages/order_utils/src/conf.py b/python-packages/order_utils/src/conf.py index 6b6776d01..d8f56b29e 100644 --- a/python-packages/order_utils/src/conf.py +++ b/python-packages/order_utils/src/conf.py @@ -22,6 +22,7 @@ extensions = [ "sphinx.ext.intersphinx", "sphinx.ext.coverage", "sphinx.ext.viewcode", + "sphinx_autodoc_typehints", ] templates_path = ["doc_templates"] diff --git a/python-packages/order_utils/src/index.rst b/python-packages/order_utils/src/index.rst index 4d27a4b17..ce618c6ff 100644 --- a/python-packages/order_utils/src/index.rst +++ b/python-packages/order_utils/src/index.rst @@ -7,21 +7,27 @@ Python zero_ex.order_utils :maxdepth: 2 :caption: Contents: -.. autoclass:: zero_ex.order_utils.Order +.. automodule:: zero_ex.order_utils :members: -See source for class properties. Sphinx does not easily generate class property docs; pull requests welcome. +.. autoclass:: zero_ex.order_utils.Order -.. automodule:: zero_ex.order_utils - :members: + See source for class properties. Sphinx is having problems generating docs for ``TypedDict`` declarations; pull requests welcome. + +zero_ex.order_utils.asset_data_utils +------------------------------------ .. automodule:: zero_ex.order_utils.asset_data_utils :members: .. autoclass:: zero_ex.order_utils.asset_data_utils.ERC20AssetData + See source for class properties. Sphinx is having problems generating docs for ``TypedDict`` declarations; pull requests welcome. + .. autoclass:: zero_ex.order_utils.asset_data_utils.ERC721AssetData + See source for class properties. Sphinx is having problems generating docs for ``TypedDict`` declarations; pull requests welcome. + Indices and tables ================== diff --git a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py index 4697ad99c..39d411507 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/__init__.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/__init__.py @@ -1,13 +1,11 @@ """Order utilities for 0x applications. -Some methods require the caller to pass in a `Web3.HTTPProvider` object. For -local testing one may construct such a provider pointing at an instance of +Some methods require the caller to pass in a `Web3.BaseProvider`:code: object. +For local testing one may construct such a provider pointing at an instance of `ganache-cli <https://www.npmjs.com/package/ganache-cli>`_ which has the 0x contracts deployed on it. For convenience, a docker container is provided for -just this purpose. To start it: ``docker run -d -p 8545:8545 0xorg/ganache-cli ---gasLimit 10000000 --db /snapshot --noVMErrorsOnRPCResponse -p 8545 ---networkId 50 -m "concert load couple harbor equip island argue ramp clarify -fence smart topic"``. +just this purpose. To start it: +`docker run -d -p 8545:8545 0xorg/ganache-cli:2.2.2`:code:. """ from copy import copy @@ -85,17 +83,53 @@ class Order(TypedDict): # pylint: disable=too-many-instance-attributes """A Web3-compatible representation of the Exchange.Order struct.""" makerAddress: str + """Address that created the order.""" + takerAddress: str + """Address that is allowed to fill the order. + + If set to 0, any address is allowed to fill the order. + """ + feeRecipientAddress: str + """Address that will recieve fees when order is filled.""" + senderAddress: str + """Address that is allowed to call Exchange contract methods that affect + this order. If set to 0, any address is allowed to call these methods. + """ + makerAssetAmount: int + """Amount of makerAsset being offered by maker. Must be greater than 0.""" + takerAssetAmount: int + """Amount of takerAsset being bid on by maker. Must be greater than 0.""" + makerFee: int + """Amount of ZRX paid to feeRecipient by maker when order is filled. If + set to 0, no transfer of ZRX from maker to feeRecipient will be attempted. + """ + takerFee: int + """Amount of ZRX paid to feeRecipient by taker when order is filled. If + set to 0, no transfer of ZRX from taker to feeRecipient will be attempted. + """ + expirationTimeSeconds: int + """Timestamp in seconds at which order expires.""" + salt: int + """Arbitrary number to facilitate uniqueness of the order's hash.""" + makerAssetData: bytes + """Encoded data that can be decoded by a specified proxy contract when + transferring makerAsset. The last byte references the id of this proxy. + """ + takerAssetData: bytes + """Encoded data that can be decoded by a specified proxy contract when + transferring takerAsset. The last byte references the id of this proxy. + """ def make_empty_order() -> Order: @@ -125,7 +159,7 @@ def order_to_jsdict( ) -> dict: """Convert a Web3-compatible order struct to a JSON-schema-compatible dict. - More specifically, do explicit decoding for the `bytes` fields. + More specifically, do explicit decoding for the `bytes`:code: fields. >>> import pprint >>> pprint.pprint(order_to_jsdict( @@ -175,7 +209,7 @@ def order_to_jsdict( def jsdict_order_to_struct(jsdict: dict) -> Order: r"""Convert a JSON-schema-compatible dict order to a Web3-compatible struct. - More specifically, do explicit encoding of the `bytes` fields. + More specifically, do explicit encoding of the `bytes`:code: fields. >>> import pprint >>> pprint.pprint(jsdict_order_to_struct( @@ -234,7 +268,7 @@ def generate_order_hash_hex(order: Order, exchange_address: str) -> str: :param order: The order to be hashed. Must conform to `the 0x order JSON schema <https://github.com/0xProject/0x-monorepo/blob/development/packages/json-schemas/schemas/order_schema.json>`_. :param exchange_address: The address to which the 0x Exchange smart contract has been deployed. - :rtype: A string, of ASCII hex digits, representing the order hash. + :returns: A string, of ASCII hex digits, representing the order hash. >>> generate_order_hash_hex( ... { @@ -296,8 +330,13 @@ class OrderInfo(NamedTuple): """A Web3-compatible representation of the Exchange.OrderInfo struct.""" order_status: str + """A `str`:code: describing the order's validity and fillability.""" + order_hash: bytes + """A `bytes`:code: object representing the EIP712 hash of the order.""" + order_taker_asset_filled_amount: int + """An `int`:code: indicating the amount that has already been filled.""" def is_valid_signature( @@ -305,15 +344,15 @@ def is_valid_signature( ) -> Tuple[bool, str]: """Check the validity of the supplied signature. - Check if the supplied ``signature`` corresponds to signing ``data`` with - the private key corresponding to ``signer_address``. + Check if the supplied `signature`:code: corresponds to signing `data`:code: + with the private key corresponding to `signer_address`:code:. :param provider: A Web3 provider able to access the 0x Exchange contract. :param data: The hex encoded data signed by the supplied signature. :param signature: The hex encoded signature. :param signer_address: The hex encoded address that signed the data to produce the supplied signature. - :rtype: Tuple consisting of a boolean and a string. Boolean is true if + :returns: Tuple consisting of a boolean and a string. Boolean is true if valid, false otherwise. If false, the string describes the reason. >>> is_valid_signature( @@ -428,8 +467,8 @@ def sign_hash( :param provider: A Web3 provider. :param signer_address: The address of the signing account. :param hash_hex: A hex string representing the hash, like that returned - from `generate_order_hash_hex()`. - :rtype: A string, of ASCII hex digits, representing the signature. + from `generate_order_hash_hex()`:code:. + :returns: A string, of ASCII hex digits, representing the signature. >>> provider = Web3.HTTPProvider("http://127.0.0.1:8545") >>> sign_hash( diff --git a/python-packages/order_utils/src/zero_ex/order_utils/asset_data_utils.py b/python-packages/order_utils/src/zero_ex/order_utils/asset_data_utils.py index fab7479d2..f8e9bc42b 100644 --- a/python-packages/order_utils/src/zero_ex/order_utils/asset_data_utils.py +++ b/python-packages/order_utils/src/zero_ex/order_utils/asset_data_utils.py @@ -17,6 +17,8 @@ class ERC20AssetData(TypedDict): """Object interface to ERC20 asset data.""" asset_proxy_id: str + """asset proxy id""" + token_address: str @@ -32,7 +34,7 @@ def encode_erc20_asset_data(token_address: str) -> str: """Encode an ERC20 token address into an asset data string. :param token_address: the ERC20 token's contract address. - :rtype: hex encoded asset data string, usable in the makerAssetData or + :returns: hex encoded asset data string, usable in the makerAssetData or takerAssetData fields in a 0x order. >>> encode_erc20_asset_data('0x1dc4c1cefef38a777b15aa20260a54e584b16c48') @@ -85,7 +87,7 @@ def encode_erc721_asset_data(token_address: str, token_id: int) -> str: :param token_address: the ERC721 token's contract address. :param token_id: the identifier of the asset's instance of the token. - :rtype: hex encoded asset data string, usable in the makerAssetData or + :returns: hex encoded asset data string, usable in the makerAssetData or takerAssetData fields in a 0x order. >>> encode_erc721_asset_data('0x1dc4c1cefef38a777b15aa20260a54e584b16c48', 1) diff --git a/python-packages/sra_client/README.md b/python-packages/sra_client/README.md index 279fb41a4..78ed42b93 100644 --- a/python-packages/sra_client/README.md +++ b/python-packages/sra_client/README.md @@ -4,7 +4,7 @@ A Python client for interacting with servers conforming to [the Standard Relayer # Schemas -The [JSON schemas](http://json-schema.org/) for the API payloads and responses can be found in [@0xproject/json-schemas](https://github.com/0xProject/0x.js/tree/development/packages/json-schemas). Examples of each payload and response can be found in the 0x.js library's [test suite](https://github.com/0xProject/0x.js/blob/development/packages/json-schemas/test/schema_test.ts#L1). +The [JSON schemas](http://json-schema.org/) for the API payloads and responses can be found in [@0xproject/json-schemas](https://github.com/0xProject/0x-monorepo/tree/development/packages/json-schemas). Examples of each payload and response can be found in the 0x.js library's [test suite](https://github.com/0xProject/0x-monorepo/blob/development/packages/json-schemas/test/schema_test.ts#L1). ```bash pip install 0x-json-schemas diff --git a/tsconfig.json b/tsconfig.json index 751115554..a49483972 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -52,7 +52,10 @@ { "path": "./packages/react-docs" }, { "path": "./packages/react-shared" }, { "path": "./packages/sol-compiler" }, - { "path": "./packages/sol-cov" }, + { "path": "./packages/sol-coverage" }, + { "path": "./packages/sol-profiler" }, + { "path": "./packages/sol-trace" }, + { "path": "./packages/sol-tracing-utils" }, { "path": "./packages/sol-resolver" }, { "path": "./packages/sra-spec" }, { "path": "./packages/subproviders" }, |