diff --git a/.circleci/config.yml b/.circleci/config.yml index d5ae2c2fcc..537b193489 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -51,7 +51,7 @@ jobs: test-contracts-geth: docker: - image: circleci/node:9 - - image: albrow/0x-devnet + - image: 0xorg/devnet working_directory: ~/repo steps: - restore_cache: @@ -64,7 +64,7 @@ jobs: resource_class: medium+ docker: - image: circleci/node:9 - - image: verdaccio/verdaccio + - image: 0xorg/verdaccio working_directory: ~/repo steps: - restore_cache: diff --git a/README.md b/README.md index 0962d36fbf..6e697ee788 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,16 @@ If you're developing on 0x now or are interested in using 0x infrastructure in t | [`@0xproject/assert`](/packages/assert) | [![npm](https://img.shields.io/npm/v/@0xproject/assert.svg)](https://www.npmjs.com/package/@0xproject/assert) | Type and schema assertions used by our packages | | [`@0xproject/base-contract`](/packages/base-contract) | [![npm](https://img.shields.io/npm/v/@0xproject/base-contract.svg)](https://www.npmjs.com/package/@0xproject/base-contract) | BaseContract used by auto-generated `abi-gen` wrapper contracts | | [`@0xproject/connect`](/packages/connect) | [![npm](https://img.shields.io/npm/v/@0xproject/connect.svg)](https://www.npmjs.com/package/@0xproject/connect) | A Javascript library for interacting with the Standard Relayer API | -| [`@0xproject/sol-compiler`](/packages/sol-compiler) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-compiler.svg)](https://www.npmjs.com/package/@0xproject/sol-compiler) | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties. | | [`@0xproject/dev-utils`](/packages/dev-utils) | [![npm](https://img.shields.io/npm/v/@0xproject/dev-utils.svg)](https://www.npmjs.com/package/@0xproject/dev-utils) | Dev utils to be shared across 0x projects and packages | | [`@0xproject/json-schemas`](/packages/json-schemas) | [![npm](https://img.shields.io/npm/v/@0xproject/json-schemas.svg)](https://www.npmjs.com/package/@0xproject/json-schemas) | 0x-related json schemas | | [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts) | [![npm](https://img.shields.io/npm/v/@0xproject/monorepo-scripts.svg)](https://www.npmjs.com/package/@0xproject/monorepo-scripts) | Monorepo scripts | +| [`@0xproject/order-utils`](/packages/order-utils) | [![npm](https://img.shields.io/npm/v/@0xproject/order-utils.svg)](https://www.npmjs.com/package/@0xproject/order-utils) | A set of utilities for generating, parsing, signing and validating 0x orders. | | [`@0xproject/react-docs`](/packages/react-docs) | [![npm](https://img.shields.io/npm/v/@0xproject/react-docs.svg)](https://www.npmjs.com/package/@0xproject/react-docs) | React documentation component for rendering TypeDoc & Doxity generated JSON | | [`@0xproject/react-shared`](/packages/react-shared) | [![npm](https://img.shields.io/npm/v/@0xproject/react-shared.svg)](https://www.npmjs.com/package/@0xproject/react-shared) | 0x shared react components | +| [`@0xproject/sol-compiler`](/packages/sol-compiler) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-compiler.svg)](https://www.npmjs.com/package/@0xproject/sol-compiler) | A thin wrapper around Solc.js that outputs artifacts, resolves imports, only re-compiles when needed, and other niceties. | +| [`@0xproject/sol-cov`](/packages/sol-cov) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-cov.svg)](https://www.npmjs.com/package/@0xproject/sol-cov) | Solidity test coverage tool | | [`@0xproject/sra-spec`](/packages/sra-spec) | [![npm](https://img.shields.io/npm/v/@0xproject/sra-spec.svg)](https://www.npmjs.com/package/@0xproject/sra-spec) | OpenAPI specification for the standard relayer API | | [`@0xproject/sra-report`](/packages/sra-report) | [![npm](https://img.shields.io/npm/v/@0xproject/sra-report.svg)](https://www.npmjs.com/package/@0xproject/sra-report) | Generate reports for standard relayer API compliance | -| [`@0xproject/sol-cov`](/packages/sol-cov) | [![npm](https://img.shields.io/npm/v/@0xproject/sol-cov.svg)](https://www.npmjs.com/package/@0xproject/sol-cov) | Solidity test coverage tool | | [`@0xproject/subproviders`](/packages/subproviders) | [![npm](https://img.shields.io/npm/v/@0xproject/subproviders.svg)](https://www.npmjs.com/package/@0xproject/subproviders) | Useful web3 subproviders (e.g LedgerSubprovider) | | [`@0xproject/tslint-config`](/packages/tslint-config) | [![npm](https://img.shields.io/npm/v/@0xproject/tslint-config.svg)](https://www.npmjs.com/package/@0xproject/tslint-config) | Custom 0x development TSLint rules | | [`@0xproject/types`](/packages/types) | [![npm](https://img.shields.io/npm/v/@0xproject/types.svg)](https://www.npmjs.com/package/@0xproject/types) | Shared type declarations | diff --git a/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json index 86cf7a916d..3913353905 100644 --- a/packages/0x.js/CHANGELOG.json +++ b/packages/0x.js/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.6", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "1.0.3", "changes": [ diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index a6f23e6203..b9b3290852 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.6 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.3 - _September 19, 2018_ * Drastically reduce the bundle size by removing unused parts of included contract artifacts. diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index 6de57f210d..67cb0d5afb 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "1.0.3", + "version": "1.0.6", "engines": { "node": ">=6.12" }, @@ -41,14 +41,14 @@ }, "license": "Apache-2.0", "devDependencies": { - "@0xproject/abi-gen": "^1.0.8", - "@0xproject/dev-utils": "^1.0.7", - "@0xproject/migrations": "^1.0.9", - "@0xproject/monorepo-scripts": "^1.0.8", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/migrations": "^1.0.12", + "@0xproject/monorepo-scripts": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sinon": "^2.2.2", "@types/web3-provider-engine": "^14.0.0", "awesome-typescript-loader": "^3.1.3", @@ -73,17 +73,17 @@ "webpack": "^3.1.0" }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/base-contract": "^2.0.2", - "@0xproject/contract-wrappers": "^1.0.3", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/order-watcher": "^1.0.3", - "@0xproject/subproviders": "^2.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "ethereum-types": "^1.0.6", + "@0xproject/assert": "^1.0.11", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/contract-wrappers": "^2.0.0", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/order-watcher": "^2.0.0", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5", "web3-provider-engine": "14.0.6" diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index 640f76f070..5785571651 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.8", diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index 3c65739c04..ee46ca2a9f 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 5, 2018_ * Dependencies updated diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index 79c550a336..314addf521 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/abi-gen", - "version": "1.0.8", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -30,10 +30,10 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md", "dependencies": { - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", "chalk": "^2.3.0", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "glob": "^7.1.2", "handlebars": "^4.0.11", "lodash": "^4.17.5", @@ -48,7 +48,7 @@ "@types/glob": "5.0.35", "@types/handlebars": "^4.0.36", "@types/mkdirp": "^0.5.1", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sleep": "^0.0.7", "@types/tmp": "^0.0.33", "@types/yargs": "^10.0.0", diff --git a/packages/assert/CHANGELOG.json b/packages/assert/CHANGELOG.json index 53c892ef53..0aa9038d80 100644 --- a/packages/assert/CHANGELOG.json +++ b/packages/assert/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.8", diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md index 8b14373508..dab9f933b0 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 5, 2018_ * Dependencies updated diff --git a/packages/assert/package.json b/packages/assert/package.json index 23357dc997..3726f41369 100644 --- a/packages/assert/package.json +++ b/packages/assert/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/assert", - "version": "1.0.8", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -44,9 +44,9 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", "lodash": "^4.17.5", "valid-url": "^1.0.9" }, diff --git a/packages/forwarder-helper/.npmignore b/packages/asset-buyer/.npmignore similarity index 100% rename from packages/forwarder-helper/.npmignore rename to packages/asset-buyer/.npmignore diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json new file mode 100644 index 0000000000..d673f0a458 --- /dev/null +++ b/packages/asset-buyer/CHANGELOG.json @@ -0,0 +1,28 @@ +[ + { + "timestamp": 1537907159, + "version": "1.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.0", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "version": "1.0.0-rc.1", + "changes": [ + { + "note": "Init" + } + ] + } +] diff --git a/packages/asset-buyer/CHANGELOG.md b/packages/asset-buyer/CHANGELOG.md new file mode 100644 index 0000000000..bea4a551b1 --- /dev/null +++ b/packages/asset-buyer/CHANGELOG.md @@ -0,0 +1,18 @@ + + +CHANGELOG + +## v1.0.1 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.0 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.0-rc.1 - _Invalid date_ + + * Init diff --git a/packages/asset-buyer/README.md b/packages/asset-buyer/README.md new file mode 100644 index 0000000000..5f7f26f307 --- /dev/null +++ b/packages/asset-buyer/README.md @@ -0,0 +1,83 @@ +## @0xproject/asset-buyer + +Convenience package for buying assets represented on the Ethereum blockchain using 0x. In its simplest form, the package helps in the usage of the [0x forwarder contract](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarder-specification.md), which allows users to execute [Wrapped Ether](https://weth.io/) based 0x orders without having to set allowances, wrap Ether or buy ZRX, meaning they can buy tokens with Ether alone. Given some liquidity (0x signed orders), it helps estimate the Ether cost of buying a certain asset (giving a range) and then buying that asset. + +In its more advanced and useful form, it integrates with the [Standard Relayer API](https://github.com/0xProject/standard-relayer-api) and takes care of sourcing liquidity for you given an SRA compliant endpoint. The final result is a library that tells you what assets are available, provides an Ether based quote for any asset desired, and allows you to buy that asset using Ether alone. + +## Installation + +```bash +yarn add @0xproject/asset-buyer +``` + +**Import** + +```typescript +import { AssetBuyer } from '@0xproject/asset-buyer'; +``` + +or + +```javascript +var AssetBuyer = require('@0xproject/asset-buyer').AssetBuyer; +``` + +If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`: + +```json +"compilerOptions": { + "typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"], +} +``` + +## Contributing + +We 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=@0xproject/asset-buyer yarn build +``` + +Or continuously rebuild on change: + +```bash +PKG=@0xproject/asset-buyer yarn watch +``` + +### Clean + +```bash +yarn clean +``` + +### Lint + +```bash +yarn lint +``` + +### Run Tests + +```bash +yarn test +``` diff --git a/packages/forwarder-helper/package.json b/packages/asset-buyer/package.json similarity index 74% rename from packages/forwarder-helper/package.json rename to packages/asset-buyer/package.json index 305b3f6a77..ff0afb782a 100644 --- a/packages/forwarder-helper/package.json +++ b/packages/asset-buyer/package.json @@ -1,10 +1,10 @@ { - "name": "@0xproject/forwarder-helper", - "version": "1.0.3", + "name": "@0xproject/asset-buyer", + "version": "1.0.1", "engines": { "node": ">=6.12" }, - "description": "Convenience object for working with the forwarder contract", + "description": "Convenience package for buying assets", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", "scripts": { @@ -34,21 +34,26 @@ "bugs": { "url": "https://github.com/0xProject/0x-monorepo/issues" }, - "homepage": "https://github.com/0xProject/0x-monorepo/packages/forwarder-helper/README.md", + "homepage": "https://github.com/0xProject/0x-monorepo/packages/asset-buyer/README.md", "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@types/node": "^8.0.53", + "@0xproject/assert": "^1.0.11", + "@0xproject/connect": "^2.0.4", + "@0xproject/contract-wrappers": "^2.0.0", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", "lodash": "^4.17.10" }, "devDependencies": { "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "^4.14.116", "@types/mocha": "^2.2.42", + "@types/node": "*", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts new file mode 100644 index 0000000000..409e34e74b --- /dev/null +++ b/packages/asset-buyer/src/asset_buyer.ts @@ -0,0 +1,324 @@ +import { ContractWrappers } from '@0xproject/contract-wrappers'; +import { schemas } from '@0xproject/json-schemas'; +import { SignedOrder } from '@0xproject/order-utils'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { constants } from './constants'; +import { BasicOrderProvider } from './order_providers/basic_order_provider'; +import { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider'; +import { + AssetBuyerError, + AssetBuyerOrdersAndFillableAmounts, + BuyQuote, + BuyQuoteRequestOpts, + OrderProvider, + OrderProviderResponse, +} from './types'; + +import { assert } from './utils/assert'; +import { assetDataUtils } from './utils/asset_data_utils'; +import { buyQuoteCalculator } from './utils/buy_quote_calculator'; +import { orderProviderResponseProcessor } from './utils/order_provider_response_processor'; + +export class AssetBuyer { + public readonly provider: Provider; + public readonly assetData: string; + public readonly orderProvider: OrderProvider; + public readonly networkId: number; + public readonly orderRefreshIntervalMs: number; + public readonly expiryBufferSeconds: number; + private readonly _contractWrappers: ContractWrappers; + private _lastRefreshTimeIfExists?: number; + private _currentOrdersAndFillableAmountsIfExists?: AssetBuyerOrdersAndFillableAmounts; + /** + * Instantiates a new AssetBuyer instance given existing liquidity in the form of orders and feeOrders. + * @param provider The Provider instance you would like to use for interacting with the Ethereum network. + * @param orders A non-empty array of objects that conform to SignedOrder. All orders must have the same makerAssetData and takerAssetData (WETH). + * @param feeOrders A array of objects that conform to SignedOrder. All orders must have the same makerAssetData (ZRX) and takerAssetData (WETH). Defaults to an empty array. + * @param networkId The ethereum network id. Defaults to 1 (mainnet). + * @param orderRefreshIntervalMs The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). + * @param expiryBufferSeconds The number of seconds to add when calculating whether an order is expired or not. Defaults to 15s. + * + * @return An instance of AssetBuyer + */ + public static getAssetBuyerForProvidedOrders( + provider: Provider, + orders: SignedOrder[], + feeOrders: SignedOrder[] = [], + networkId: number = constants.MAINNET_NETWORK_ID, + orderRefreshIntervalMs: number = constants.DEFAULT_ORDER_REFRESH_INTERVAL_MS, + expiryBufferSeconds: number = constants.DEFAULT_EXPIRY_BUFFER_SECONDS, + ): AssetBuyer { + assert.isWeb3Provider('provider', provider); + assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema); + assert.doesConformToSchema('feeOrders', feeOrders, schemas.signedOrdersSchema); + assert.isNumber('networkId', networkId); + assert.isNumber('orderRefreshIntervalMs', orderRefreshIntervalMs); + assert.areValidProvidedOrders('orders', orders); + assert.areValidProvidedOrders('feeOrders', feeOrders); + assert.assert(orders.length !== 0, `Expected orders to contain at least one order`); + const assetData = orders[0].makerAssetData; + const orderProvider = new BasicOrderProvider(_.concat(orders, feeOrders)); + const assetBuyer = new AssetBuyer( + provider, + assetData, + orderProvider, + networkId, + orderRefreshIntervalMs, + expiryBufferSeconds, + ); + return assetBuyer; + } + /** + * Instantiates a new AssetBuyer instance given the desired assetData and a [Standard Relayer API](https://github.com/0xProject/standard-relayer-api) endpoint + * @param provider The Provider instance you would like to use for interacting with the Ethereum network. + * @param assetData The assetData that identifies the desired asset to buy. + * @param sraApiUrl The standard relayer API base HTTP url you would like to source orders from. + * @param networkId The ethereum network id. Defaults to 1 (mainnet). + * @param orderRefreshIntervalMs The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). + * @param expiryBufferSeconds The number of seconds to add when calculating whether an order is expired or not. Defaults to 15s. + * + * @return An instance of AssetBuyer + */ + public static getAssetBuyerForAssetData( + provider: Provider, + assetData: string, + sraApiUrl: string, + networkId: number = constants.MAINNET_NETWORK_ID, + orderRefreshIntervalMs: number = constants.DEFAULT_ORDER_REFRESH_INTERVAL_MS, + expiryBufferSeconds: number = constants.DEFAULT_EXPIRY_BUFFER_SECONDS, + ): AssetBuyer { + assert.isWeb3Provider('provider', provider); + assert.isHexString('assetData', assetData); + assert.isWebUri('sraApiUrl', sraApiUrl); + assert.isNumber('networkId', networkId); + assert.isNumber('orderRefreshIntervalMs', orderRefreshIntervalMs); + const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl); + const assetBuyer = new AssetBuyer( + provider, + assetData, + orderProvider, + networkId, + orderRefreshIntervalMs, + expiryBufferSeconds, + ); + return assetBuyer; + } + /** + * Instantiates a new AssetBuyer instance given the desired ERC20 token address and a [Standard Relayer API](https://github.com/0xProject/standard-relayer-api) endpoint + * @param provider The Provider instance you would like to use for interacting with the Ethereum network. + * @param tokenAddress The ERC20 token address that identifies the desired asset to buy. + * @param sraApiUrl The standard relayer API base HTTP url you would like to source orders from. + * @param networkId The ethereum network id. Defaults to 1 (mainnet). + * @param orderRefreshIntervalMs The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). + * @param expiryBufferSeconds The number of seconds to add when calculating whether an order is expired or not. Defaults to 15s. + * @return An instance of AssetBuyer + */ + public static getAssetBuyerForERC20TokenAddress( + provider: Provider, + tokenAddress: string, + sraApiUrl: string, + networkId: number = constants.MAINNET_NETWORK_ID, + orderRefreshIntervalMs: number = constants.DEFAULT_ORDER_REFRESH_INTERVAL_MS, + expiryBufferSeconds: number = constants.DEFAULT_EXPIRY_BUFFER_SECONDS, + ): AssetBuyer { + assert.isWeb3Provider('provider', provider); + assert.isETHAddressHex('tokenAddress', tokenAddress); + assert.isWebUri('sraApiUrl', sraApiUrl); + assert.isNumber('networkId', networkId); + assert.isNumber('orderRefreshIntervalMs', orderRefreshIntervalMs); + const assetData = assetDataUtils.encodeERC20AssetData(tokenAddress); + const assetBuyer = AssetBuyer.getAssetBuyerForAssetData( + provider, + assetData, + sraApiUrl, + networkId, + orderRefreshIntervalMs, + expiryBufferSeconds, + ); + return assetBuyer; + } + /** + * Instantiates a new AssetBuyer instance + * @param provider The Provider instance you would like to use for interacting with the Ethereum network. + * @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md). + * @param orderProvider An object that conforms to OrderProvider, see type for definition. + * @param networkId The ethereum network id. Defaults to 1 (mainnet). + * @param orderRefreshIntervalMs The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). + * @param expiryBufferSeconds The number of seconds to add when calculating whether an order is expired or not. Defaults to 15s. + * + * @return An instance of AssetBuyer + */ + constructor( + provider: Provider, + assetData: string, + orderProvider: OrderProvider, + networkId: number = constants.MAINNET_NETWORK_ID, + orderRefreshIntervalMs: number = constants.DEFAULT_ORDER_REFRESH_INTERVAL_MS, + expiryBufferSeconds: number = constants.DEFAULT_EXPIRY_BUFFER_SECONDS, + ) { + assert.isWeb3Provider('provider', provider); + assert.isString('assetData', assetData); + assert.isValidOrderProvider('orderProvider', orderProvider); + assert.isNumber('networkId', networkId); + assert.isNumber('orderRefreshIntervalMs', orderRefreshIntervalMs); + this.provider = provider; + this.assetData = assetData; + this.orderProvider = orderProvider; + this.networkId = networkId; + this.expiryBufferSeconds = expiryBufferSeconds; + this.orderRefreshIntervalMs = orderRefreshIntervalMs; + this._contractWrappers = new ContractWrappers(this.provider, { + networkId, + }); + } + /** + * Get a `BuyQuote` containing all information relevant to fulfilling a buy. + * You can then pass the `BuyQuote` to `executeBuyQuoteAsync` to execute the buy. + * @param assetBuyAmount The amount of asset to buy. + * @param feePercentage The affiliate fee percentage. Defaults to 0. + * @param forceOrderRefresh If set to true, new orders and state will be fetched instead of waiting for + * the next orderRefreshIntervalMs. Defaults to false. + * @return An object that conforms to BuyQuote that satisfies the request. See type definition for more information. + */ + public async getBuyQuoteAsync(assetBuyAmount: BigNumber, options: Partial): Promise { + const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = { + ...options, + ...constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS, + }; + assert.isBigNumber('assetBuyAmount', assetBuyAmount); + assert.isValidPercentage('feePercentage', feePercentage); + assert.isBoolean('shouldForceOrderRefresh', shouldForceOrderRefresh); + // we should refresh if: + // we do not have any orders OR + // we are forced to OR + // we have some last refresh time AND that time was sufficiently long ago + const shouldRefresh = + _.isUndefined(this._currentOrdersAndFillableAmountsIfExists) || + shouldForceOrderRefresh || + (!_.isUndefined(this._lastRefreshTimeIfExists) && + this._lastRefreshTimeIfExists + this.orderRefreshIntervalMs < Date.now()); + let ordersAndFillableAmounts: AssetBuyerOrdersAndFillableAmounts; + if (shouldRefresh) { + ordersAndFillableAmounts = await this._getLatestOrdersAndFillableAmountsAsync(); + this._lastRefreshTimeIfExists = Date.now(); + this._currentOrdersAndFillableAmountsIfExists = ordersAndFillableAmounts; + } else { + // it is safe to cast to AssetBuyerOrdersAndFillableAmounts because shouldRefresh catches the undefined case above + ordersAndFillableAmounts = this + ._currentOrdersAndFillableAmountsIfExists as AssetBuyerOrdersAndFillableAmounts; + } + const buyQuote = buyQuoteCalculator.calculate( + ordersAndFillableAmounts, + assetBuyAmount, + feePercentage, + slippagePercentage, + ); + return buyQuote; + } + /** + * Given a BuyQuote and desired rate, attempt to execute the buy. + * @param buyQuote An object that conforms to BuyQuote. See type definition for more information. + * @param rate The desired rate to execute the buy at. Affects the amount of ETH sent with the transaction, defaults to buyQuote.maxRate. + * @param takerAddress The address to perform the buy. Defaults to the first available address from the provider. + * @param feeRecipient The address where affiliate fees are sent. Defaults to null address (0x000...000). + * @return A promise of the txHash. + */ + public async executeBuyQuoteAsync( + buyQuote: BuyQuote, + rate?: BigNumber, + takerAddress?: string, + feeRecipient: string = constants.NULL_ADDRESS, + ): Promise { + assert.isValidBuyQuote('buyQuote', buyQuote); + if (!_.isUndefined(rate)) { + assert.isBigNumber('rate', rate); + } + if (!_.isUndefined(takerAddress)) { + assert.isETHAddressHex('takerAddress', takerAddress); + } + assert.isETHAddressHex('feeRecipient', feeRecipient); + const { orders, feeOrders, feePercentage, assetBuyAmount, maxRate } = buyQuote; + // if no takerAddress is provided, try to get one from the provider + let finalTakerAddress; + if (!_.isUndefined(takerAddress)) { + finalTakerAddress = takerAddress; + } else { + const web3Wrapper = new Web3Wrapper(this.provider); + const availableAddresses = await web3Wrapper.getAvailableAddressesAsync(); + const firstAvailableAddress = _.head(availableAddresses); + if (!_.isUndefined(firstAvailableAddress)) { + finalTakerAddress = firstAvailableAddress; + } else { + throw new Error(AssetBuyerError.NoAddressAvailable); + } + } + // if no rate is provided, default to the maxRate from buyQuote + const desiredRate = rate || maxRate; + // calculate how much eth is required to buy assetBuyAmount at the desired rate + const ethAmount = assetBuyAmount.dividedToIntegerBy(desiredRate); + const txHash = await this._contractWrappers.forwarder.marketBuyOrdersWithEthAsync( + orders, + assetBuyAmount, + finalTakerAddress, + ethAmount, + feeOrders, + feePercentage, + feeRecipient, + ); + return txHash; + } + /** + * Ask the order Provider for orders and process them. + */ + private async _getLatestOrdersAndFillableAmountsAsync(): Promise { + const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow(); + const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow(); + // construct order Provider requests + const targetOrderProviderRequest = { + makerAssetData: this.assetData, + takerAssetData: etherTokenAssetData, + networkId: this.networkId, + }; + const feeOrderProviderRequest = { + makerAssetData: zrxTokenAssetData, + takerAssetData: etherTokenAssetData, + networkId: this.networkId, + }; + const requests = [targetOrderProviderRequest, feeOrderProviderRequest]; + // fetch orders and possible fillable amounts + const [targetOrderProviderResponse, feeOrderProviderResponse] = await Promise.all( + _.map(requests, async request => this.orderProvider.getOrdersAsync(request)), + ); + // since the order provider is an injected dependency, validate that it respects the API + // ie. it should only return maker/taker assetDatas that are specified + orderProviderResponseProcessor.throwIfInvalidResponse(targetOrderProviderResponse, targetOrderProviderRequest); + orderProviderResponseProcessor.throwIfInvalidResponse(feeOrderProviderResponse, feeOrderProviderRequest); + // process the responses into one object + const ordersAndFillableAmounts = await orderProviderResponseProcessor.processAsync( + targetOrderProviderResponse, + feeOrderProviderResponse, + zrxTokenAssetData, + this.expiryBufferSeconds, + this._contractWrappers.orderValidator, + ); + return ordersAndFillableAmounts; + } + /** + * Get the assetData that represents the WETH token. + * Will throw if WETH does not exist for the current network. + */ + private _getEtherTokenAssetDataOrThrow(): string { + return assetDataUtils.getEtherTokenAssetDataOrThrow(this._contractWrappers); + } + /** + * Get the assetData that represents the ZRX token. + * Will throw if ZRX does not exist for the current network. + */ + private _getZrxTokenAssetDataOrThrow(): string { + return assetDataUtils.getZrxTokenAssetDataOrThrow(this._contractWrappers); + } +} diff --git a/packages/asset-buyer/src/constants.ts b/packages/asset-buyer/src/constants.ts new file mode 100644 index 0000000000..79b5d90525 --- /dev/null +++ b/packages/asset-buyer/src/constants.ts @@ -0,0 +1,20 @@ +import { BigNumber } from '@0xproject/utils'; + +import { BuyQuoteRequestOpts } from './types'; + +const DEFAULT_BUY_QUOTE_REQUEST_OPTS: BuyQuoteRequestOpts = { + feePercentage: 0, + shouldForceOrderRefresh: false, + slippagePercentage: 0.2, // 20% slippage protection +}; + +export const constants = { + ZERO_AMOUNT: new BigNumber(0), + NULL_ADDRESS: '0x0000000000000000000000000000000000000000', + MAINNET_NETWORK_ID: 1, + DEFAULT_ORDER_REFRESH_INTERVAL_MS: 10000, // 10 seconds + ETHER_TOKEN_DECIMALS: 18, + DEFAULT_BUY_QUOTE_REQUEST_OPTS, + MAX_PER_PAGE: 10000, + DEFAULT_EXPIRY_BUFFER_SECONDS: 15, +}; diff --git a/packages/forwarder-helper/src/globals.d.ts b/packages/asset-buyer/src/globals.d.ts similarity index 100% rename from packages/forwarder-helper/src/globals.d.ts rename to packages/asset-buyer/src/globals.d.ts diff --git a/packages/asset-buyer/src/index.ts b/packages/asset-buyer/src/index.ts new file mode 100644 index 0000000000..8ef529ac0e --- /dev/null +++ b/packages/asset-buyer/src/index.ts @@ -0,0 +1,17 @@ +export { Provider } from 'ethereum-types'; +export { SignedOrder } from '@0xproject/types'; +export { BigNumber } from '@0xproject/utils'; + +export { AssetBuyer } from './asset_buyer'; +export { BasicOrderProvider } from './order_providers/basic_order_provider'; +export { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider'; +export { StandardRelayerAPIAssetBuyerManager } from './standard_relayer_api_asset_buyer_manager'; +export { + AssetBuyerError, + BuyQuote, + OrderProvider, + OrderProviderRequest, + OrderProviderResponse, + SignedOrderWithRemainingFillableMakerAssetAmount, + StandardRelayerApiAssetBuyerManagerError, +} from './types'; diff --git a/packages/asset-buyer/src/order_providers/basic_order_provider.ts b/packages/asset-buyer/src/order_providers/basic_order_provider.ts new file mode 100644 index 0000000000..9bb2d90acd --- /dev/null +++ b/packages/asset-buyer/src/order_providers/basic_order_provider.ts @@ -0,0 +1,32 @@ +import { schemas } from '@0xproject/json-schemas'; +import { SignedOrder } from '@0xproject/types'; +import * as _ from 'lodash'; + +import { OrderProvider, OrderProviderRequest, OrderProviderResponse } from '../types'; +import { assert } from '../utils/assert'; + +export class BasicOrderProvider implements OrderProvider { + public readonly orders: SignedOrder[]; + /** + * Instantiates a new BasicOrderProvider instance + * @param orders An array of objects that conform to SignedOrder to fetch from. + * @return An instance of BasicOrderProvider + */ + constructor(orders: SignedOrder[]) { + assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema); + this.orders = orders; + } + /** + * Given an object that conforms to OrderFetcherRequest, return the corresponding OrderProviderResponse that satisfies the request. + * @param orderProviderRequest An instance of OrderFetcherRequest. See type for more information. + * @return An instance of OrderProviderResponse. See type for more information. + */ + public async getOrdersAsync(orderProviderRequest: OrderProviderRequest): Promise { + assert.isValidOrderProviderRequest('orderProviderRequest', orderProviderRequest); + const { makerAssetData, takerAssetData } = orderProviderRequest; + const orders = _.filter(this.orders, order => { + return order.makerAssetData === makerAssetData && order.takerAssetData === takerAssetData; + }); + return { orders }; + } +} diff --git a/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts b/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts new file mode 100644 index 0000000000..31942c25ba --- /dev/null +++ b/packages/asset-buyer/src/order_providers/standard_relayer_api_order_provider.ts @@ -0,0 +1,79 @@ +import { HttpClient } from '@0xproject/connect'; +import { APIOrder, OrderbookResponse } from '@0xproject/types'; +import * as _ from 'lodash'; + +import { + AssetBuyerError, + OrderProvider, + OrderProviderRequest, + OrderProviderResponse, + SignedOrderWithRemainingFillableMakerAssetAmount, +} from '../types'; +import { assert } from '../utils/assert'; +import { orderUtils } from '../utils/order_utils'; + +export class StandardRelayerAPIOrderProvider implements OrderProvider { + public readonly apiUrl: string; + private readonly _sraClient: HttpClient; + /** + * Given an array of APIOrder objects from a standard relayer api, return an array + * of SignedOrderWithRemainingFillableMakerAssetAmounts + */ + private static _getSignedOrderWithRemainingFillableMakerAssetAmountFromApi( + apiOrders: APIOrder[], + ): SignedOrderWithRemainingFillableMakerAssetAmount[] { + const result = _.map(apiOrders, apiOrder => { + const { order, metaData } = apiOrder; + // calculate remainingFillableMakerAssetAmount from api metadata, else assume order is completely fillable + const remainingFillableTakerAssetAmount = _.get( + metaData, + 'remainingTakerAssetAmount', + order.takerAssetAmount, + ); + const remainingFillableMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount( + order, + remainingFillableTakerAssetAmount, + ); + const newOrder = { + ...order, + remainingFillableMakerAssetAmount, + }; + return newOrder; + }); + return result; + } + /** + * Instantiates a new StandardRelayerAPIOrderProvider instance + * @param apiUrl The standard relayer API base HTTP url you would like to source orders from. + * @return An instance of StandardRelayerAPIOrderProvider + */ + constructor(apiUrl: string) { + assert.isWebUri('apiUrl', apiUrl); + this.apiUrl = apiUrl; + this._sraClient = new HttpClient(apiUrl); + } + /** + * Given an object that conforms to OrderProviderRequest, return the corresponding OrderProviderResponse that satisfies the request. + * @param orderProviderRequest An instance of OrderProviderRequest. See type for more information. + * @return An instance of OrderProviderResponse. See type for more information. + */ + public async getOrdersAsync(orderProviderRequest: OrderProviderRequest): Promise { + assert.isValidOrderProviderRequest('orderProviderRequest', orderProviderRequest); + const { makerAssetData, takerAssetData, networkId } = orderProviderRequest; + const orderbookRequest = { baseAssetData: makerAssetData, quoteAssetData: takerAssetData }; + const requestOpts = { networkId }; + let orderbook: OrderbookResponse; + try { + orderbook = await this._sraClient.getOrderbookAsync(orderbookRequest, requestOpts); + } catch (err) { + throw new Error(AssetBuyerError.StandardRelayerApiError); + } + const apiOrders = orderbook.asks.records; + const orders = StandardRelayerAPIOrderProvider._getSignedOrderWithRemainingFillableMakerAssetAmountFromApi( + apiOrders, + ); + return { + orders, + }; + } +} diff --git a/packages/asset-buyer/src/standard_relayer_api_asset_buyer_manager.ts b/packages/asset-buyer/src/standard_relayer_api_asset_buyer_manager.ts new file mode 100644 index 0000000000..947c738a19 --- /dev/null +++ b/packages/asset-buyer/src/standard_relayer_api_asset_buyer_manager.ts @@ -0,0 +1,133 @@ +import { HttpClient } from '@0xproject/connect'; +import { ContractWrappers } from '@0xproject/contract-wrappers'; +import { ObjectMap } from '@0xproject/types'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { AssetBuyer } from './asset_buyer'; +import { constants } from './constants'; +import { assert } from './utils/assert'; +import { assetDataUtils } from './utils/asset_data_utils'; + +import { OrderProvider, StandardRelayerApiAssetBuyerManagerError } from './types'; + +export class StandardRelayerAPIAssetBuyerManager { + // Map of assetData to AssetBuyer for that assetData + private readonly _assetBuyerMap: ObjectMap; + /** + * Returns an array of all assetDatas available at the provided sraApiUrl + * @param sraApiUrl The standard relayer API base HTTP url you would like to source orders from. + * @param pairedWithAssetData Optional filter argument to return assetDatas that only pair with this assetData value. + * + * @return An array of all assetDatas available at the provider sraApiUrl + */ + public static async getAllAvailableAssetDatasAsync( + sraApiUrl: string, + pairedWithAssetData?: string, + ): Promise { + const client = new HttpClient(sraApiUrl); + const params = { + assetDataA: pairedWithAssetData, + perPage: constants.MAX_PER_PAGE, + }; + const assetPairsResponse = await client.getAssetPairsAsync(params); + return _.uniq(_.map(assetPairsResponse.records, pairsItem => pairsItem.assetDataB.assetData)); + } + /** + * Instantiates a new StandardRelayerAPIAssetBuyerManager instance with all available assetDatas at the provided sraApiUrl + * @param provider The Provider instance you would like to use for interacting with the Ethereum network. + * @param sraApiUrl The standard relayer API base HTTP url you would like to source orders from. + * @param orderProvider An object that conforms to OrderProvider, see type for definition. + * @param networkId The ethereum network id. Defaults to 1 (mainnet). + * @param orderRefreshIntervalMs The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. + * Defaults to 10000ms (10s). + * @return An promise of an instance of StandardRelayerAPIAssetBuyerManager + */ + public static async getAssetBuyerManagerWithAllAvailableAssetDatasAsync( + provider: Provider, + sraApiUrl: string, + orderProvider: OrderProvider, + networkId: number = constants.MAINNET_NETWORK_ID, + orderRefreshIntervalMs?: number, + ): Promise { + const contractWrappers = new ContractWrappers(provider, { networkId }); + const etherTokenAssetData = assetDataUtils.getEtherTokenAssetDataOrThrow(contractWrappers); + const assetDatas = await StandardRelayerAPIAssetBuyerManager.getAllAvailableAssetDatasAsync( + sraApiUrl, + etherTokenAssetData, + ); + return new StandardRelayerAPIAssetBuyerManager( + provider, + assetDatas, + orderProvider, + networkId, + orderRefreshIntervalMs, + ); + } + /** + * Instantiates a new StandardRelayerAPIAssetBuyerManager instance + * @param provider The Provider instance you would like to use for interacting with the Ethereum network. + * @param assetDatas The assetDatas of the desired assets to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md). + * @param orderProvider An object that conforms to OrderProvider, see type for definition. + * @param networkId The ethereum network id. Defaults to 1 (mainnet). + * @param orderRefreshIntervalMs The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. + * Defaults to 10000ms (10s). + * @return An instance of StandardRelayerAPIAssetBuyerManager + */ + constructor( + provider: Provider, + assetDatas: string[], + orderProvider: OrderProvider, + networkId?: number, + orderRefreshIntervalMs?: number, + ) { + assert.assert(assetDatas.length > 0, `Expected 'assetDatas' to be a non-empty array.`); + this._assetBuyerMap = _.reduce( + assetDatas, + (accAssetBuyerMap: ObjectMap, assetData: string) => { + accAssetBuyerMap[assetData] = new AssetBuyer( + provider, + assetData, + orderProvider, + networkId, + orderRefreshIntervalMs, + ); + return accAssetBuyerMap; + }, + {}, + ); + } + /** + * Get an AssetBuyer for the provided assetData + * @param assetData The desired assetData. + * + * @return An instance of AssetBuyer + */ + public getAssetBuyerFromAssetData(assetData: string): AssetBuyer { + const assetBuyer = this._assetBuyerMap[assetData]; + if (_.isUndefined(assetBuyer)) { + throw new Error( + `${StandardRelayerApiAssetBuyerManagerError.AssetBuyerNotFound}: For assetData ${assetData}`, + ); + } + return assetBuyer; + } + /** + * Get an AssetBuyer for the provided ERC20 tokenAddress + * @param tokenAddress The desired tokenAddress. + * + * @return An instance of AssetBuyer + */ + public getAssetBuyerFromERC20TokenAddress(tokenAddress: string): AssetBuyer { + const assetData = assetDataUtils.encodeERC20AssetData(tokenAddress); + return this.getAssetBuyerFromAssetData(assetData); + } + /** + * Get a list of all the assetDatas that the instance supports + * + * @return An array of assetData strings + */ + public getAssetDatas(): string[] { + return _.keys(this._assetBuyerMap); + } +} diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts new file mode 100644 index 0000000000..ee6858525d --- /dev/null +++ b/packages/asset-buyer/src/types.ts @@ -0,0 +1,86 @@ +import { SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; + +/** + * makerAssetData: The assetData representing the desired makerAsset. + * takerAssetData: The assetData representing the desired takerAsset. + * networkId: The networkId that the desired orders should be for. + */ +export interface OrderProviderRequest { + makerAssetData: string; + takerAssetData: string; + networkId: number; +} + +/** + * orders: An array of orders with optional remaining fillable makerAsset amounts. See type for more info. + */ +export interface OrderProviderResponse { + orders: SignedOrderWithRemainingFillableMakerAssetAmount[]; +} + +/** + * A normal SignedOrder with one extra optional property `remainingFillableMakerAssetAmount` + * remainingFillableMakerAssetAmount: The amount of the makerAsset that is available to be filled + */ +export interface SignedOrderWithRemainingFillableMakerAssetAmount extends SignedOrder { + remainingFillableMakerAssetAmount?: BigNumber; +} +/** + * Given an OrderProviderRequest, get an OrderProviderResponse. + */ +export interface OrderProvider { + getOrdersAsync: (orderProviderRequest: OrderProviderRequest) => Promise; +} + +/** + * assetData: String that represents a specific asset (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md). + * orders: An array of objects conforming to SignedOrder. These orders can be used to cover the requested assetBuyAmount plus slippage. + * feeOrders: An array of objects conforming to SignedOrder. These orders can be used to cover the fees for the orders param above. + * minRate: Min rate that needs to be paid in order to execute the buy. + * maxRate: Max rate that can be paid in order to execute the buy. + * assetBuyAmount: The amount of asset to buy. + * feePercentage: Optional affiliate fee percentage used to calculate the eth amounts above. + */ +export interface BuyQuote { + assetData: string; + orders: SignedOrder[]; + feeOrders: SignedOrder[]; + minRate: BigNumber; + maxRate: BigNumber; + assetBuyAmount: BigNumber; + feePercentage?: number; +} + +export interface BuyQuoteRequestOpts { + feePercentage: number; + shouldForceOrderRefresh: boolean; + slippagePercentage: number; +} + +/** + * Possible errors thrown by an AssetBuyer instance or associated static methods. + */ +export enum AssetBuyerError { + NoEtherTokenContractFound = 'NO_ETHER_TOKEN_CONTRACT_FOUND', + NoZrxTokenContractFound = 'NO_ZRX_TOKEN_CONTRACT_FOUND', + StandardRelayerApiError = 'STANDARD_RELAYER_API_ERROR', + InsufficientAssetLiquidity = 'INSUFFICIENT_ASSET_LIQUIDITY', + InsufficientZrxLiquidity = 'INSUFFICIENT_ZRX_LIQUIDITY', + NoAddressAvailable = 'NO_ADDRESS_AVAILABLE', + InvalidOrderProviderResponse = 'INVALID_ORDER_PROVIDER_RESPONSE', +} + +/** + * Possible errors thrown by an StandardRelayerApiAssetBuyerManager instance or associated static methods. + */ +export enum StandardRelayerApiAssetBuyerManagerError { + AssetBuyerNotFound = 'ASSET_BUYER_NOT_FOUND', +} + +export interface AssetBuyerOrdersAndFillableAmounts { + orders: SignedOrder[]; + feeOrders: SignedOrder[]; + remainingFillableMakerAssetAmounts: BigNumber[]; + remainingFillableFeeAmounts: BigNumber[]; +} diff --git a/packages/asset-buyer/src/utils/assert.ts b/packages/asset-buyer/src/utils/assert.ts new file mode 100644 index 0000000000..04f4252376 --- /dev/null +++ b/packages/asset-buyer/src/utils/assert.ts @@ -0,0 +1,51 @@ +import { assert as sharedAssert } from '@0xproject/assert'; +import { schemas } from '@0xproject/json-schemas'; +import { SignedOrder } from '@0xproject/types'; +import * as _ from 'lodash'; + +import { BuyQuote, OrderProvider, OrderProviderRequest } from '../types'; + +export const assert = { + ...sharedAssert, + isValidBuyQuote(variableName: string, buyQuote: BuyQuote): void { + sharedAssert.isHexString(`${variableName}.assetData`, buyQuote.assetData); + sharedAssert.doesConformToSchema(`${variableName}.orders`, buyQuote.orders, schemas.signedOrdersSchema); + sharedAssert.doesConformToSchema(`${variableName}.feeOrders`, buyQuote.feeOrders, schemas.signedOrdersSchema); + sharedAssert.isBigNumber(`${variableName}.minRate`, buyQuote.minRate); + sharedAssert.isBigNumber(`${variableName}.maxRate`, buyQuote.maxRate); + sharedAssert.isBigNumber(`${variableName}.assetBuyAmount`, buyQuote.assetBuyAmount); + if (!_.isUndefined(buyQuote.feePercentage)) { + sharedAssert.isNumber(`${variableName}.feePercentage`, buyQuote.feePercentage); + } + }, + isValidOrderProvider(variableName: string, orderFetcher: OrderProvider): void { + sharedAssert.isFunction(`${variableName}.getOrdersAsync`, orderFetcher.getOrdersAsync); + }, + isValidOrderProviderRequest(variableName: string, orderFetcherRequest: OrderProviderRequest): void { + sharedAssert.isHexString(`${variableName}.makerAssetData`, orderFetcherRequest.makerAssetData); + sharedAssert.isHexString(`${variableName}.takerAssetData`, orderFetcherRequest.takerAssetData); + sharedAssert.isNumber(`${variableName}.networkId`, orderFetcherRequest.networkId); + }, + areValidProvidedOrders(variableName: string, orders: SignedOrder[]): void { + if (orders.length === 0) { + return; + } + const makerAssetData = orders[0].makerAssetData; + const takerAssetData = orders[0].takerAssetData; + const filteredOrders = _.filter( + orders, + order => order.makerAssetData === makerAssetData && order.takerAssetData === takerAssetData, + ); + sharedAssert.assert( + orders.length === filteredOrders.length, + `Expected all orders in ${variableName} to have the same makerAssetData and takerAssetData.`, + ); + }, + isValidPercentage(variableName: string, percentage: number): void { + assert.isNumber(variableName, percentage); + assert.assert( + percentage >= 0 && percentage <= 1, + `Expected ${variableName} to be between 0 and 1, but is ${percentage}`, + ); + }, +}; diff --git a/packages/asset-buyer/src/utils/asset_data_utils.ts b/packages/asset-buyer/src/utils/asset_data_utils.ts new file mode 100644 index 0000000000..d05ff25048 --- /dev/null +++ b/packages/asset-buyer/src/utils/asset_data_utils.ts @@ -0,0 +1,26 @@ +import { ContractWrappers } from '@0xproject/contract-wrappers'; +import { assetDataUtils as sharedAssetDataUtils } from '@0xproject/order-utils'; +import * as _ from 'lodash'; + +import { AssetBuyerError } from '../types'; + +export const assetDataUtils = { + ...sharedAssetDataUtils, + getEtherTokenAssetDataOrThrow(contractWrappers: ContractWrappers): string { + const etherTokenAddressIfExists = contractWrappers.etherToken.getContractAddressIfExists(); + if (_.isUndefined(etherTokenAddressIfExists)) { + throw new Error(AssetBuyerError.NoEtherTokenContractFound); + } + const etherTokenAssetData = sharedAssetDataUtils.encodeERC20AssetData(etherTokenAddressIfExists); + return etherTokenAssetData; + }, + getZrxTokenAssetDataOrThrow(contractWrappers: ContractWrappers): string { + let zrxTokenAssetData: string; + try { + zrxTokenAssetData = contractWrappers.exchange.getZRXAssetData(); + } catch (err) { + throw new Error(AssetBuyerError.NoZrxTokenContractFound); + } + return zrxTokenAssetData; + }, +}; diff --git a/packages/asset-buyer/src/utils/buy_quote_calculator.ts b/packages/asset-buyer/src/utils/buy_quote_calculator.ts new file mode 100644 index 0000000000..9946924ef8 --- /dev/null +++ b/packages/asset-buyer/src/utils/buy_quote_calculator.ts @@ -0,0 +1,89 @@ +import { marketUtils } from '@0xproject/order-utils'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { constants } from '../constants'; +import { AssetBuyerError, AssetBuyerOrdersAndFillableAmounts, BuyQuote } from '../types'; + +import { orderUtils } from './order_utils'; + +// Calculates a buy quote for orders that have WETH as the takerAsset +export const buyQuoteCalculator = { + calculate( + ordersAndFillableAmounts: AssetBuyerOrdersAndFillableAmounts, + assetBuyAmount: BigNumber, + feePercentage: number, + slippagePercentage: number, + ): BuyQuote { + const { + orders, + feeOrders, + remainingFillableMakerAssetAmounts, + remainingFillableFeeAmounts, + } = ordersAndFillableAmounts; + const slippageBufferAmount = assetBuyAmount.mul(slippagePercentage).round(); + const { + resultOrders, + remainingFillAmount, + ordersRemainingFillableMakerAssetAmounts, + } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(orders, assetBuyAmount, { + remainingFillableMakerAssetAmounts, + slippageBufferAmount, + }); + if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) { + throw new Error(AssetBuyerError.InsufficientAssetLiquidity); + } + // TODO(bmillman): optimization + // update this logic to find the minimum amount of feeOrders to cover the worst case as opposed to + // finding order that cover all fees, this will help with estimating ETH and minimizing gas usage + const { + resultFeeOrders, + remainingFeeAmount, + feeOrdersRemainingFillableMakerAssetAmounts, + } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders(resultOrders, feeOrders, { + remainingFillableMakerAssetAmounts, + remainingFillableFeeAmounts, + }); + if (remainingFeeAmount.gt(constants.ZERO_AMOUNT)) { + throw new Error(AssetBuyerError.InsufficientZrxLiquidity); + } + const assetData = orders[0].makerAssetData; + + // calculate minRate and maxRate by calculating min and max eth usage and then dividing into + // assetBuyAmount to get assetData / WETH, needs to take into account feePercentage as well + // minEthAmount = (sum(takerAssetAmount[i]) until sum(makerAssetAmount[i]) >= assetBuyAmount ) * (1 + feePercentage) + // maxEthAmount = (sum(takerAssetAmount[i]) until i == orders.length) * (1 + feePercentage) + const allOrders = _.concat(resultOrders, resultFeeOrders); + const allRemainingAmounts = _.concat( + ordersRemainingFillableMakerAssetAmounts, + feeOrdersRemainingFillableMakerAssetAmounts, + ); + let minEthAmount = constants.ZERO_AMOUNT; + let maxEthAmount = constants.ZERO_AMOUNT; + let cumulativeMakerAmount = constants.ZERO_AMOUNT; + _.forEach(allOrders, (order, index) => { + const remainingFillableMakerAssetAmount = allRemainingAmounts[index]; + const claimableTakerAssetAmount = orderUtils.calculateRemainingTakerAssetAmount( + order, + remainingFillableMakerAssetAmount, + ); + // taker asset is always assumed to be WETH + maxEthAmount = maxEthAmount.plus(claimableTakerAssetAmount); + if (cumulativeMakerAmount.lessThan(assetBuyAmount)) { + minEthAmount = minEthAmount.plus(claimableTakerAssetAmount); + } + cumulativeMakerAmount = cumulativeMakerAmount.plus(remainingFillableMakerAssetAmount); + }); + const feeAdjustedMinRate = minEthAmount.mul(feePercentage + 1).div(assetBuyAmount); + const feeAdjustedMaxRate = minEthAmount.mul(feePercentage + 1).div(assetBuyAmount); + return { + assetData, + orders: resultOrders, + feeOrders: resultFeeOrders, + minRate: feeAdjustedMinRate, + maxRate: feeAdjustedMaxRate, + assetBuyAmount, + feePercentage, + }; + }, +}; diff --git a/packages/asset-buyer/src/utils/order_provider_response_processor.ts b/packages/asset-buyer/src/utils/order_provider_response_processor.ts new file mode 100644 index 0000000000..31fdcc182e --- /dev/null +++ b/packages/asset-buyer/src/utils/order_provider_response_processor.ts @@ -0,0 +1,202 @@ +import { OrderAndTraderInfo, OrderStatus, OrderValidatorWrapper } from '@0xproject/contract-wrappers'; +import { sortingUtils } from '@0xproject/order-utils'; +import { RemainingFillableCalculator } from '@0xproject/order-utils/lib/src/remaining_fillable_calculator'; +import { SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { constants } from '../constants'; +import { + AssetBuyerError, + AssetBuyerOrdersAndFillableAmounts, + OrderProviderRequest, + OrderProviderResponse, + SignedOrderWithRemainingFillableMakerAssetAmount, +} from '../types'; + +import { orderUtils } from './order_utils'; + +interface OrdersAndRemainingFillableMakerAssetAmounts { + orders: SignedOrder[]; + remainingFillableMakerAssetAmounts: BigNumber[]; +} + +export const orderProviderResponseProcessor = { + throwIfInvalidResponse(response: OrderProviderResponse, request: OrderProviderRequest): void { + const { makerAssetData, takerAssetData } = request; + _.forEach(response.orders, order => { + if (order.makerAssetData !== makerAssetData || order.takerAssetData !== takerAssetData) { + throw new Error(AssetBuyerError.InvalidOrderProviderResponse); + } + }); + }, + /** + * Take the responses for the target orders to buy and fee orders and process them. + * Processing includes: + * - Drop orders that are expired or not open orders (null taker address) + * - If shouldValidateOnChain, attempt to grab fillable amounts from on-chain otherwise assume completely fillable + * - Sort by rate + */ + async processAsync( + targetOrderProviderResponse: OrderProviderResponse, + feeOrderProviderResponse: OrderProviderResponse, + zrxTokenAssetData: string, + expiryBufferSeconds: number, + orderValidator?: OrderValidatorWrapper, + ): Promise { + // drop orders that are expired or not open + const filteredTargetOrders = filterOutExpiredAndNonOpenOrders( + targetOrderProviderResponse.orders, + expiryBufferSeconds, + ); + const filteredFeeOrders = filterOutExpiredAndNonOpenOrders( + feeOrderProviderResponse.orders, + expiryBufferSeconds, + ); + // set the orders to be sorted equal to the filtered orders + let unsortedTargetOrders = filteredTargetOrders; + let unsortedFeeOrders = filteredFeeOrders; + // if an orderValidator is provided, use on chain information to calculate remaining fillable makerAsset amounts + if (!_.isUndefined(orderValidator)) { + // TODO(bmillman): improvement + // try/catch these requests and throw a more domain specific error + // TODO(bmillman): optimization + // reduce this to once RPC call buy combining orders into one array and then splitting up the response + const [targetOrdersAndTradersInfo, feeOrdersAndTradersInfo] = await Promise.all( + _.map([filteredTargetOrders, filteredFeeOrders], ordersToBeValidated => { + const takerAddresses = _.map(ordersToBeValidated, () => constants.NULL_ADDRESS); + return orderValidator.getOrdersAndTradersInfoAsync(ordersToBeValidated, takerAddresses); + }), + ); + // take orders + on chain information and find the valid orders and remaining fillable maker asset amounts + unsortedTargetOrders = getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain( + filteredTargetOrders, + targetOrdersAndTradersInfo, + zrxTokenAssetData, + ); + // take orders + on chain information and find the valid orders and remaining fillable maker asset amounts + unsortedFeeOrders = getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain( + filteredFeeOrders, + feeOrdersAndTradersInfo, + zrxTokenAssetData, + ); + } + // sort orders by rate + // TODO(bmillman): optimization + // provide a feeRate to the sorting function to more accurately sort based on the current market for ZRX tokens + const sortedTargetOrders = sortingUtils.sortOrdersByFeeAdjustedRate(unsortedTargetOrders); + const sortedFeeOrders = sortingUtils.sortFeeOrdersByFeeAdjustedRate(unsortedFeeOrders); + // unbundle orders and fillable amounts and compile final result + const targetOrdersAndRemainingFillableMakerAssetAmounts = unbundleOrdersWithAmounts(sortedTargetOrders); + const feeOrdersAndRemainingFillableMakerAssetAmounts = unbundleOrdersWithAmounts(sortedFeeOrders); + return { + orders: targetOrdersAndRemainingFillableMakerAssetAmounts.orders, + feeOrders: feeOrdersAndRemainingFillableMakerAssetAmounts.orders, + remainingFillableMakerAssetAmounts: + targetOrdersAndRemainingFillableMakerAssetAmounts.remainingFillableMakerAssetAmounts, + remainingFillableFeeAmounts: + feeOrdersAndRemainingFillableMakerAssetAmounts.remainingFillableMakerAssetAmounts, + }; + }, +}; + +/** + * Given an array of orders, return a new array with expired and non open orders filtered out. + */ +function filterOutExpiredAndNonOpenOrders( + orders: SignedOrderWithRemainingFillableMakerAssetAmount[], + expiryBufferSeconds: number, +): SignedOrderWithRemainingFillableMakerAssetAmount[] { + const result = _.filter(orders, order => { + return orderUtils.isOpenOrder(order) && !orderUtils.willOrderExpire(order, expiryBufferSeconds); + }); + return result; +} + +/** + * Given an array of orders and corresponding on-chain infos, return a subset of the orders + * that are still fillable orders with their corresponding remainingFillableMakerAssetAmounts. + */ +function getValidOrdersWithRemainingFillableMakerAssetAmountsFromOnChain( + inputOrders: SignedOrder[], + ordersAndTradersInfo: OrderAndTraderInfo[], + zrxAssetData: string, +): SignedOrderWithRemainingFillableMakerAssetAmount[] { + // iterate through the input orders and find the ones that are still fillable + // for the orders that are still fillable, calculate the remaining fillable maker asset amount + const result = _.reduce( + inputOrders, + (accOrders, order, index) => { + // get corresponding on-chain state for the order + const { orderInfo, traderInfo } = ordersAndTradersInfo[index]; + // if the order IS NOT fillable, do not add anything to the accumulations and continue iterating + if (orderInfo.orderStatus !== OrderStatus.FILLABLE) { + return accOrders; + } + // if the order IS fillable, add the order and calculate the remaining fillable amount + const transferrableAssetAmount = BigNumber.min([traderInfo.makerAllowance, traderInfo.makerBalance]); + const transferrableFeeAssetAmount = BigNumber.min([ + traderInfo.makerZrxAllowance, + traderInfo.makerZrxBalance, + ]); + const remainingTakerAssetAmount = order.takerAssetAmount.minus(orderInfo.orderTakerAssetFilledAmount); + const remainingMakerAssetAmount = orderUtils.calculateRemainingMakerAssetAmount( + order, + remainingTakerAssetAmount, + ); + const remainingFillableCalculator = new RemainingFillableCalculator( + order.makerFee, + order.makerAssetAmount, + order.makerAssetData === zrxAssetData, + transferrableAssetAmount, + transferrableFeeAssetAmount, + remainingMakerAssetAmount, + ); + const remainingFillableAmount = remainingFillableCalculator.computeRemainingFillable(); + // if the order does not have any remaining fillable makerAsset, do not add anything to the accumulations and continue iterating + if (remainingFillableAmount.lte(constants.ZERO_AMOUNT)) { + return accOrders; + } + const orderWithRemainingFillableMakerAssetAmount = { + ...order, + remainingFillableMakerAssetAmount: remainingFillableAmount, + }; + const newAccOrders = _.concat(accOrders, orderWithRemainingFillableMakerAssetAmount); + return newAccOrders; + }, + [] as SignedOrderWithRemainingFillableMakerAssetAmount[], + ); + return result; +} + +/** + * Given an array of orders with remaining fillable maker asset amounts. Unbundle into an instance of OrdersAndRemainingFillableMakerAssetAmounts. + * If an order is missing a corresponding remainingFillableMakerAssetAmount, assume it is completely fillable. + */ +function unbundleOrdersWithAmounts( + ordersWithAmounts: SignedOrderWithRemainingFillableMakerAssetAmount[], +): OrdersAndRemainingFillableMakerAssetAmounts { + const result = _.reduce( + ordersWithAmounts, + (acc, orderWithAmount) => { + const { orders, remainingFillableMakerAssetAmounts } = acc; + const { remainingFillableMakerAssetAmount, ...order } = orderWithAmount; + // if we are still missing a remainingFillableMakerAssetAmount, assume the order is completely fillable + const newRemainingAmount = remainingFillableMakerAssetAmount || order.makerAssetAmount; + // if remaining amount is less than or equal to zero, do not add it + if (newRemainingAmount.lte(constants.ZERO_AMOUNT)) { + return acc; + } + const newAcc = { + orders: _.concat(orders, order), + remainingFillableMakerAssetAmounts: _.concat(remainingFillableMakerAssetAmounts, newRemainingAmount), + }; + return newAcc; + }, + { + orders: [] as SignedOrder[], + remainingFillableMakerAssetAmounts: [] as BigNumber[], + }, + ); + return result; +} diff --git a/packages/asset-buyer/src/utils/order_utils.ts b/packages/asset-buyer/src/utils/order_utils.ts new file mode 100644 index 0000000000..62166eb76c --- /dev/null +++ b/packages/asset-buyer/src/utils/order_utils.ts @@ -0,0 +1,30 @@ +import { SignedOrder } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; + +import { constants } from '../constants'; + +export const orderUtils = { + isOrderExpired(order: SignedOrder): boolean { + return orderUtils.willOrderExpire(order, 0); + }, + willOrderExpire(order: SignedOrder, secondsFromNow: number): boolean { + const millisecondsInSecond = 1000; + const currentUnixTimestampSec = new BigNumber(Date.now() / millisecondsInSecond).round(); + return order.expirationTimeSeconds.lessThan(currentUnixTimestampSec.minus(secondsFromNow)); + }, + calculateRemainingMakerAssetAmount(order: SignedOrder, remainingTakerAssetAmount: BigNumber): BigNumber { + if (remainingTakerAssetAmount.eq(0)) { + return constants.ZERO_AMOUNT; + } + return remainingTakerAssetAmount.times(order.makerAssetAmount).dividedToIntegerBy(order.takerAssetAmount); + }, + calculateRemainingTakerAssetAmount(order: SignedOrder, remainingMakerAssetAmount: BigNumber): BigNumber { + if (remainingMakerAssetAmount.eq(0)) { + return constants.ZERO_AMOUNT; + } + return remainingMakerAssetAmount.times(order.takerAssetAmount).dividedToIntegerBy(order.makerAssetAmount); + }, + isOpenOrder(order: SignedOrder): boolean { + return order.takerAddress === constants.NULL_ADDRESS; + }, +}; diff --git a/packages/forwarder-helper/test/utils/chai_setup.ts b/packages/asset-buyer/test/utils/chai_setup.ts similarity index 100% rename from packages/forwarder-helper/test/utils/chai_setup.ts rename to packages/asset-buyer/test/utils/chai_setup.ts diff --git a/packages/forwarder-helper/tsconfig.json b/packages/asset-buyer/tsconfig.json similarity index 100% rename from packages/forwarder-helper/tsconfig.json rename to packages/asset-buyer/tsconfig.json diff --git a/packages/forwarder-helper/tslint.json b/packages/asset-buyer/tslint.json similarity index 100% rename from packages/forwarder-helper/tslint.json rename to packages/asset-buyer/tslint.json diff --git a/packages/forwarder-helper/typedoc-tsconfig.json b/packages/asset-buyer/typedoc-tsconfig.json similarity index 100% rename from packages/forwarder-helper/typedoc-tsconfig.json rename to packages/asset-buyer/typedoc-tsconfig.json diff --git a/packages/base-contract/CHANGELOG.json b/packages/base-contract/CHANGELOG.json index a15b020618..fba072011b 100644 --- a/packages/base-contract/CHANGELOG.json +++ b/packages/base-contract/CHANGELOG.json @@ -8,6 +8,33 @@ } ] }, + { + "timestamp": 1537907159, + "version": "2.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "2.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "2.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "2.0.2", diff --git a/packages/base-contract/CHANGELOG.md b/packages/base-contract/CHANGELOG.md index a81f7a3a7c..7a3e0f6614 100644 --- a/packages/base-contract/CHANGELOG.md +++ b/packages/base-contract/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v2.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v2.0.3 - _September 21, 2018_ + + * Dependencies updated + ## v2.0.2 - _September 5, 2018_ * Dependencies updated diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json index 4f7f571cc5..b4047691c7 100644 --- a/packages/base-contract/package.json +++ b/packages/base-contract/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/base-contract", - "version": "2.0.2", + "version": "2.0.5", "engines": { "node": ">=6.12" }, @@ -40,10 +40,10 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "ethereum-types": "^1.0.6", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5" }, diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json index c6e7532612..9de956d4d6 100644 --- a/packages/connect/CHANGELOG.json +++ b/packages/connect/CHANGELOG.json @@ -1,4 +1,32 @@ [ + { + "timestamp": 1537907159, + "version": "2.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "version": "2.0.3", + "changes": [ + { + "note": "Import SRA-related types from @0xproject/types", + "pr": 1085 + } + ], + "timestamp": 1537875740 + }, + { + "timestamp": 1537541580, + "version": "2.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537369748, "version": "2.0.1", diff --git a/packages/connect/CHANGELOG.md b/packages/connect/CHANGELOG.md index 8e9ebe3e00..75906ff4e1 100644 --- a/packages/connect/CHANGELOG.md +++ b/packages/connect/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v2.0.3 - _September 25, 2018_ + + * Import SRA-related types from @0xproject/types (#1085) + +## v2.0.2 - _September 21, 2018_ + + * Dependencies updated + ## v2.0.1 - _September 19, 2018_ * Dependencies updated diff --git a/packages/connect/package.json b/packages/connect/package.json index 1308aa5b23..5e1fa81d43 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/connect", - "version": "2.0.1", + "version": "2.0.4", "engines": { "node": ">=6.12" }, @@ -43,12 +43,12 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md", "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", + "@0xproject/assert": "^1.0.11", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", "lodash": "^4.17.5", "query-string": "^5.0.1", "sinon": "^4.0.0", diff --git a/packages/connect/src/http_client.ts b/packages/connect/src/http_client.ts index 87d5c30be2..8a68d6c233 100644 --- a/packages/connect/src/http_client.ts +++ b/packages/connect/src/http_client.ts @@ -1,19 +1,10 @@ import { assert } from '@0xproject/assert'; import { schemas } from '@0xproject/json-schemas'; -import { SignedOrder } from '@0xproject/types'; -import { fetchAsync } from '@0xproject/utils'; -import * as _ from 'lodash'; -import * as queryString from 'query-string'; - -import { schemas as clientSchemas } from './schemas/schemas'; import { APIOrder, AssetPairsRequestOpts, AssetPairsResponse, - Client, FeeRecipientsResponse, - HttpRequestOptions, - HttpRequestType, OrderbookRequest, OrderbookResponse, OrderConfigRequest, @@ -22,14 +13,21 @@ import { OrdersResponse, PagedRequestOpts, RequestOpts, -} from './types'; + SignedOrder, +} from '@0xproject/types'; +import { fetchAsync } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as queryString from 'query-string'; + +import { schemas as clientSchemas } from './schemas/schemas'; +import { Client, HttpRequestOptions, HttpRequestType } from './types'; import { relayerResponseJsonParsers } from './utils/relayer_response_json_parsers'; const TRAILING_SLASHES_REGEX = /\/+$/; /** * This class includes all the functionality related to interacting with a set of HTTP endpoints - * that implement the standard relayer API v0 + * that implement the standard relayer API v2 */ export class HttpClient implements Client { private readonly _apiEndpointUrl: string; diff --git a/packages/connect/src/index.ts b/packages/connect/src/index.ts index 0b9cad038c..0ec5a0f681 100644 --- a/packages/connect/src/index.ts +++ b/packages/connect/src/index.ts @@ -1,23 +1,20 @@ export { HttpClient } from './http_client'; export { ordersChannelFactory } from './orders_channel_factory'; +export { Client, OrdersChannel, OrdersChannelHandler } from './types'; export { - Client, - OrderConfigRequest, - OrderConfigResponse, - OrdersChannel, - OrdersChannelHandler, - OrdersChannelSubscriptionOpts, - OrderbookRequest, - OrderbookResponse, - OrdersRequestOpts, - PagedRequestOpts, + APIOrder, AssetPairsRequestOpts, - RequestOpts, AssetPairsResponse, FeeRecipientsResponse, - APIOrder, + OrderbookRequest, + OrderbookResponse, + OrderConfigRequest, + OrderConfigResponse, + OrdersChannelSubscriptionOpts, + OrdersRequestOpts, OrdersResponse, + PagedRequestOpts, PaginatedCollection, -} from './types'; - -export { SignedOrder } from '@0xproject/types'; + RequestOpts, + SignedOrder, +} from '@0xproject/types'; diff --git a/packages/connect/src/types.ts b/packages/connect/src/types.ts index b76af081ce..4bb0ae534a 100644 --- a/packages/connect/src/types.ts +++ b/packages/connect/src/types.ts @@ -1,5 +1,18 @@ -import { SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; +import { + APIOrder, + AssetPairsItem, + AssetPairsRequestOpts, + FeeRecipientsResponse, + OrderbookRequest, + OrderbookResponse, + OrderConfigRequest, + OrderConfigResponse, + OrdersChannelSubscriptionOpts, + OrdersRequestOpts, + PagedRequestOpts, + PaginatedCollection, + SignedOrder, +} from '@0xproject/types'; export interface Client { getAssetPairsAsync: ( @@ -18,140 +31,12 @@ export interface OrdersChannel { close: () => void; } -/** - * baseAssetData: The address of assetData designated as the baseToken in the currency pair calculation of price - * quoteAssetData: The address of assetData designated as the quoteToken in the currency pair calculation of price - * limit: Maximum number of bids and asks in orderbook snapshot - */ -export interface OrdersChannelSubscriptionOpts { - baseAssetData: string; - quoteAssetData: string; - limit: number; -} - export interface OrdersChannelHandler { onUpdate: (channel: OrdersChannel, subscriptionOpts: OrdersChannelSubscriptionOpts, orders: APIOrder[]) => void; onError: (channel: OrdersChannel, err: Error, subscriptionOpts?: OrdersChannelSubscriptionOpts) => void; onClose: (channel: OrdersChannel) => void; } -export type OrdersChannelMessage = UpdateOrdersChannelMessage | UnknownOrdersChannelMessage; - -export enum OrdersChannelMessageTypes { - Update = 'update', - Unknown = 'unknown', -} - -export interface UpdateOrdersChannelMessage { - type: OrdersChannelMessageTypes.Update; - requestId: string; - payload: APIOrder[]; -} - -export interface UnknownOrdersChannelMessage { - type: OrdersChannelMessageTypes.Unknown; - requestId: string; - payload: undefined; -} - -export enum WebsocketConnectionEventType { - Close = 'close', - Error = 'error', - Message = 'message', -} - -export enum WebsocketClientEventType { - Connect = 'connect', - ConnectFailed = 'connectFailed', -} - -export type OrdersResponse = PaginatedCollection; - -export interface APIOrder { - order: SignedOrder; - metaData: object; -} - -export interface AssetPairsRequestOpts { - assetDataA?: string; - assetDataB?: string; -} - -export type AssetPairsResponse = PaginatedCollection; - -export interface AssetPairsItem { - assetDataA: Asset; - assetDataB: Asset; -} - -export interface Asset { - assetData: string; - minAmount: BigNumber; - maxAmount: BigNumber; - precision: number; -} - -export interface OrdersRequestOpts { - makerAssetProxyId?: string; - takerAssetProxyId?: string; - makerAssetAddress?: string; - takerAssetAddress?: string; - exchangeAddress?: string; - senderAddress?: string; - makerAssetData?: string; - takerAssetData?: string; - makerAddress?: string; - takerAddress?: string; - traderAddress?: string; - feeRecipientAddress?: string; -} - -export interface OrderbookRequest { - baseAssetData: string; - quoteAssetData: string; -} - -export interface OrderbookResponse { - bids: PaginatedCollection; - asks: PaginatedCollection; -} - -export interface PaginatedCollection { - total: number; - page: number; - perPage: number; - records: T[]; -} - -export interface OrderConfigRequest { - makerAddress: string; - takerAddress: string; - makerAssetAmount: BigNumber; - takerAssetAmount: BigNumber; - makerAssetData: string; - takerAssetData: string; - exchangeAddress: string; - expirationTimeSeconds: BigNumber; -} - -export interface OrderConfigResponse { - makerFee: BigNumber; - takerFee: BigNumber; - feeRecipientAddress: string; - senderAddress: string; -} - -export type FeeRecipientsResponse = PaginatedCollection; - -export interface RequestOpts { - networkId?: number; -} - -export interface PagedRequestOpts { - page?: number; - perPage?: number; -} - export interface HttpRequestOptions { params?: object; payload?: object; diff --git a/packages/connect/src/utils/orders_channel_message_parser.ts b/packages/connect/src/utils/orders_channel_message_parser.ts index 1b6cda17b9..943d7802e4 100644 --- a/packages/connect/src/utils/orders_channel_message_parser.ts +++ b/packages/connect/src/utils/orders_channel_message_parser.ts @@ -2,7 +2,7 @@ import { assert } from '@0xproject/assert'; import { schemas } from '@0xproject/json-schemas'; import * as _ from 'lodash'; -import { OrdersChannelMessage, OrdersChannelMessageTypes } from '../types'; +import { OrdersChannelMessage, OrdersChannelMessageTypes } from '@0xproject/types'; import { relayerResponseJsonParsers } from './relayer_response_json_parsers'; diff --git a/packages/connect/src/utils/relayer_response_json_parsers.ts b/packages/connect/src/utils/relayer_response_json_parsers.ts index bc31f231de..356e2dde6a 100644 --- a/packages/connect/src/utils/relayer_response_json_parsers.ts +++ b/packages/connect/src/utils/relayer_response_json_parsers.ts @@ -9,7 +9,7 @@ import { OrderbookResponse, OrderConfigResponse, OrdersResponse, -} from '../types'; +} from '@0xproject/types'; import { typeConverters } from './type_converters'; diff --git a/packages/connect/src/utils/type_converters.ts b/packages/connect/src/utils/type_converters.ts index d57ea00e52..99760cf744 100644 --- a/packages/connect/src/utils/type_converters.ts +++ b/packages/connect/src/utils/type_converters.ts @@ -1,7 +1,7 @@ import { orderParsingUtils } from '@0xproject/order-utils'; import * as _ from 'lodash'; -import { APIOrder } from '../types'; +import { APIOrder } from '@0xproject/types'; export const typeConverters = { convertOrderbookStringFieldsToBigNumber(orderbook: any): any { diff --git a/packages/connect/src/ws_orders_channel.ts b/packages/connect/src/ws_orders_channel.ts index cde4acbc36..bf5e8508d8 100644 --- a/packages/connect/src/ws_orders_channel.ts +++ b/packages/connect/src/ws_orders_channel.ts @@ -1,8 +1,9 @@ +import { OrdersChannelMessageTypes, OrdersChannelSubscriptionOpts } from '@0xproject/types'; import * as _ from 'lodash'; import { v4 as uuid } from 'uuid'; import * as WebSocket from 'websocket'; -import { OrdersChannel, OrdersChannelHandler, OrdersChannelMessageTypes, OrdersChannelSubscriptionOpts } from './types'; +import { OrdersChannel, OrdersChannelHandler } from './types'; import { assert } from './utils/assert'; import { ordersChannelMessageParser } from './utils/orders_channel_message_parser'; diff --git a/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts b/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts index 5ce703317c..27216e4214 100644 --- a/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts +++ b/packages/connect/test/fixtures/standard_relayer_api/asset_pairs.ts @@ -1,6 +1,6 @@ import { BigNumber } from '@0xproject/utils'; -import { AssetPairsResponse } from '../../../src/types'; +import { AssetPairsResponse } from '@0xproject/types'; export const assetDataPairsResponse: AssetPairsResponse = { total: 43, diff --git a/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts b/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts index e17ffe7a85..6f544e9d36 100644 --- a/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts +++ b/packages/connect/test/fixtures/standard_relayer_api/fee_recipients.ts @@ -1,4 +1,4 @@ -import { FeeRecipientsResponse } from '../../../src/types'; +import { FeeRecipientsResponse } from '@0xproject/types'; export const feeRecipientsResponse: FeeRecipientsResponse = { total: 3, diff --git a/packages/connect/test/fixtures/standard_relayer_api/order_config.ts b/packages/connect/test/fixtures/standard_relayer_api/order_config.ts index 36f01a0094..56a4ac5500 100644 --- a/packages/connect/test/fixtures/standard_relayer_api/order_config.ts +++ b/packages/connect/test/fixtures/standard_relayer_api/order_config.ts @@ -1,6 +1,6 @@ import { BigNumber } from '@0xproject/utils'; -import { OrderConfigResponse } from '../../../src/types'; +import { OrderConfigResponse } from '@0xproject/types'; export const orderConfigResponse: OrderConfigResponse = { senderAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32', diff --git a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts index d5f39a51fc..21d51da742 100644 --- a/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts +++ b/packages/connect/test/fixtures/standard_relayer_api/orderbook.ts @@ -1,6 +1,6 @@ import { BigNumber } from '@0xproject/utils'; -import { OrderbookResponse } from '../../../src/types'; +import { OrderbookResponse } from '@0xproject/types'; export const orderbookResponse: OrderbookResponse = { bids: { diff --git a/packages/connect/test/fixtures/standard_relayer_api/orders.ts b/packages/connect/test/fixtures/standard_relayer_api/orders.ts index 01f8974b81..fb85990d07 100644 --- a/packages/connect/test/fixtures/standard_relayer_api/orders.ts +++ b/packages/connect/test/fixtures/standard_relayer_api/orders.ts @@ -1,6 +1,6 @@ import { BigNumber } from '@0xproject/utils'; -import { OrdersResponse } from '../../../src/types'; +import { OrdersResponse } from '@0xproject/types'; export const ordersResponse: OrdersResponse = { total: 984, diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json index a9e631157a..8863f61f44 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -1,4 +1,38 @@ [ + { + "version": "2.0.0", + "changes": [ + { + "note": + "Fixes dropped events in subscriptions by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too.", + "pr": 1080 + }, + { + "note": + "Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it", + "pr": 1080 + } + ], + "timestamp": 1537907159 + }, + { + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537875740 + }, + { + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537541580 + }, { "version": "1.0.3", "changes": [ diff --git a/packages/contract-wrappers/CHANGELOG.md b/packages/contract-wrappers/CHANGELOG.md index 69561213e9..41e5645a37 100644 --- a/packages/contract-wrappers/CHANGELOG.md +++ b/packages/contract-wrappers/CHANGELOG.md @@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.0 - _September 25, 2018_ + + * Fixes dropped events in subscriptions by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too. (#1080) + * Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it (#1080) + +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.3 - _September 19, 2018_ * Drastically reduce the bundle size by removing unused parts of included contract artifacts. diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 0d830f6c21..e30bf079c0 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/contract-wrappers", - "version": "1.0.3", + "version": "2.0.0", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", @@ -41,14 +41,14 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^1.0.8", - "@0xproject/dev-utils": "^1.0.7", - "@0xproject/migrations": "^1.0.9", - "@0xproject/subproviders": "^2.0.2", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/migrations": "^1.0.12", + "@0xproject/subproviders": "^2.0.5", "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sinon": "^2.2.2", "@types/uuid": "^3.4.2", "@types/web3-provider-engine": "^14.0.0", @@ -72,17 +72,17 @@ "web3-provider-engine": "14.0.6" }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/base-contract": "^2.0.2", - "@0xproject/fill-scenarios": "^1.0.2", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "ethereum-types": "^1.0.6", - "ethereumjs-blockstream": "5.0.0", + "@0xproject/assert": "^1.0.11", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/fill-scenarios": "^1.0.5", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", + "ethereumjs-blockstream": "6.0.0", "ethereumjs-util": "^5.1.1", "ethers": "^4.0.0-beta.14", "js-sha3": "^0.7.0", diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts index 19de17c0ab..f7a89e3bea 100644 --- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts @@ -1,5 +1,5 @@ import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; import { BlockParamLiteral, ContractAbi, @@ -8,6 +8,7 @@ import { LogEntry, LogWithDecodedArgs, RawLog, + RawLogEntry, } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -157,7 +158,8 @@ export abstract class ContractWrapper { return addressIfExists; } } - private _onLogStateChanged(isRemoved: boolean, log: LogEntry): void { + private _onLogStateChanged(isRemoved: boolean, rawLog: RawLogEntry): void { + const log: LogEntry = marshaller.unmarshalLog(rawLog); _.forEach(this._filters, (filter: FilterObject, filterToken: string) => { if (filterUtils.matchesFilter(log, filter)) { const decodedLog = this._tryToDecodeLogOrNoop(log) as LogWithDecodedArgs; @@ -174,8 +176,8 @@ export abstract class ContractWrapper { throw new Error(ContractWrappersError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( - this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._blockstreamGetBlockOrNullAsync.bind(this), + this._blockstreamGetLogsAsync.bind(this), ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose), ); const catchAllLogFilter = {}; @@ -194,6 +196,32 @@ export abstract class ContractWrapper { this._onLogStateChanged.bind(this, isRemoved), ); } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetBlockOrNullAsync(hash: string): Promise { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync({ + method: 'eth_getBlockByHash', + params: [hash, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLatestBlockOrNullAsync(): Promise { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync({ + method: 'eth_getBlockByNumber', + params: [BlockParamLiteral.Latest, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLogsAsync(filterOptions: FilterObject): Promise { + const logs = await this._web3Wrapper.sendRawPayloadAsync({ + method: 'eth_getLogs', + params: [filterOptions], + }); + return logs as RawLogEntry[]; + } // HACK: This should be a package-scoped method (which doesn't exist in TS) // We don't want this method available in the public interface for all classes // who inherit from ContractWrapper, and it is only used by the internal implementation @@ -212,11 +240,14 @@ export abstract class ContractWrapper { delete this._blockAndLogStreamerIfExists; } private async _reconcileBlockAsync(): Promise { - const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest); + const latestBlockOrNull = await this._blockstreamGetLatestBlockOrNullAsync(); + if (_.isNull(latestBlockOrNull)) { + return; // noop + } // We need to coerce to Block type cause Web3.Block includes types for mempool blocks if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined - await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block); + await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull); } } } diff --git a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts index 13ef0fe01f..9062227317 100644 --- a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts @@ -12,6 +12,7 @@ import { TransactionOpts } from '../types'; import { assert } from '../utils/assert'; import { calldataOptimizationUtils } from '../utils/calldata_optimization_utils'; import { constants } from '../utils/constants'; +import { utils } from '../utils/utils'; import { ContractWrapper } from './contract_wrapper'; import { ForwarderContract } from './generated/forwarder'; @@ -57,7 +58,7 @@ export class ForwarderWrapper extends ContractWrapper { takerAddress: string, ethAmount: BigNumber, signedFeeOrders: SignedOrder[] = [], - feePercentage: BigNumber = constants.ZERO_AMOUNT, + feePercentage: number = 0, feeRecipientAddress: string = constants.NULL_ADDRESS, txOpts: TransactionOpts = {}, ): Promise { @@ -66,7 +67,7 @@ export class ForwarderWrapper extends ContractWrapper { await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); assert.isBigNumber('ethAmount', ethAmount); assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema); - assert.isBigNumber('feePercentage', feePercentage); + assert.isNumber('feePercentage', feePercentage); assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress); assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); // other assertions @@ -76,6 +77,8 @@ export class ForwarderWrapper extends ContractWrapper { this.getZRXTokenAddress(), this.getEtherTokenAddress(), ); + // format feePercentage + const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage); // lowercase input addresses const normalizedTakerAddress = takerAddress.toLowerCase(); const normalizedFeeRecipientAddress = feeRecipientAddress.toLowerCase(); @@ -89,7 +92,7 @@ export class ForwarderWrapper extends ContractWrapper { _.map(optimizedMarketOrders, order => order.signature), optimizedFeeOrders, _.map(optimizedFeeOrders, order => order.signature), - feePercentage, + formattedFeePercentage, feeRecipientAddress, { value: ethAmount, @@ -124,7 +127,7 @@ export class ForwarderWrapper extends ContractWrapper { takerAddress: string, ethAmount: BigNumber, signedFeeOrders: SignedOrder[] = [], - feePercentage: BigNumber = constants.ZERO_AMOUNT, + feePercentage: number = 0, feeRecipientAddress: string = constants.NULL_ADDRESS, txOpts: TransactionOpts = {}, ): Promise { @@ -134,7 +137,7 @@ export class ForwarderWrapper extends ContractWrapper { await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); assert.isBigNumber('ethAmount', ethAmount); assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema); - assert.isBigNumber('feePercentage', feePercentage); + assert.isNumber('feePercentage', feePercentage); assert.isETHAddressHex('feeRecipientAddress', feeRecipientAddress); assert.doesConformToSchema('txOpts', txOpts, txOptsSchema); // other assertions @@ -144,6 +147,8 @@ export class ForwarderWrapper extends ContractWrapper { this.getZRXTokenAddress(), this.getEtherTokenAddress(), ); + // format feePercentage + const formattedFeePercentage = utils.numberPercentageToEtherTokenAmountPercentage(feePercentage); // lowercase input addresses const normalizedTakerAddress = takerAddress.toLowerCase(); const normalizedFeeRecipientAddress = feeRecipientAddress.toLowerCase(); @@ -158,7 +163,7 @@ export class ForwarderWrapper extends ContractWrapper { _.map(optimizedMarketOrders, order => order.signature), optimizedFeeOrders, _.map(optimizedFeeOrders, order => order.signature), - feePercentage, + formattedFeePercentage, feeRecipientAddress, { value: ethAmount, diff --git a/packages/contract-wrappers/src/utils/constants.ts b/packages/contract-wrappers/src/utils/constants.ts index 2df11538cc..78441decf7 100644 --- a/packages/contract-wrappers/src/utils/constants.ts +++ b/packages/contract-wrappers/src/utils/constants.ts @@ -12,4 +12,6 @@ export const constants = { UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1), DEFAULT_BLOCK_POLLING_INTERVAL: 1000, ZERO_AMOUNT: new BigNumber(0), + ONE_AMOUNT: new BigNumber(1), + ETHER_TOKEN_DECIMALS: 18, }; diff --git a/packages/contract-wrappers/src/utils/utils.ts b/packages/contract-wrappers/src/utils/utils.ts index 689a7ee0a4..f7949ec34d 100644 --- a/packages/contract-wrappers/src/utils/utils.ts +++ b/packages/contract-wrappers/src/utils/utils.ts @@ -1,4 +1,7 @@ import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; + +import { constants } from './constants'; export const utils = { getCurrentUnixTimestampSec(): BigNumber { @@ -8,4 +11,7 @@ export const utils = { getCurrentUnixTimestampMs(): BigNumber { return new BigNumber(Date.now()); }, + numberPercentageToEtherTokenAmountPercentage(percentage: number): BigNumber { + return Web3Wrapper.toBaseUnitAmount(constants.ONE_AMOUNT, constants.ETHER_TOKEN_DECIMALS).mul(percentage); + }, }; diff --git a/packages/contract-wrappers/test/subscription_test.ts b/packages/contract-wrappers/test/subscription_test.ts index 81b9012bd5..68ef7225ed 100644 --- a/packages/contract-wrappers/test/subscription_test.ts +++ b/packages/contract-wrappers/test/subscription_test.ts @@ -61,7 +61,7 @@ describe('SubscriptionTest', () => { callback, ); stubs = [ - Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws( + Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockIfExistsAsync').throws( new Error('JSON RPC error'), ), ]; diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 628e74a784..a6e7af0ac5 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "contracts", - "version": "2.1.44", + "version": "2.1.47", "engines": { "node": ">=6.12" }, @@ -45,16 +45,16 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md", "devDependencies": { - "@0xproject/abi-gen": "^1.0.8", - "@0xproject/dev-utils": "^1.0.7", - "@0xproject/sol-compiler": "^1.1.2", - "@0xproject/sol-cov": "^2.1.2", - "@0xproject/subproviders": "^2.0.2", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/sol-compiler": "^1.1.5", + "@0xproject/sol-cov": "^2.1.5", + "@0xproject/subproviders": "^2.0.5", "@0xproject/tslint-config": "^1.0.7", "@types/bn.js": "^4.11.0", "@types/ethereumjs-abi": "^0.6.0", "@types/lodash": "4.14.104", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/yargs": "^10.0.0", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", @@ -72,15 +72,15 @@ "yargs": "^10.0.3" }, "dependencies": { - "@0xproject/base-contract": "^2.0.2", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "@types/js-combinatorics": "^0.5.29", "bn.js": "^4.11.8", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-abi": "0.6.5", "ethereumjs-util": "^5.1.1", "ethers": "^4.0.0-beta.14", diff --git a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts index 05d8bbb36f..0b17c298b5 100644 --- a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts @@ -269,7 +269,10 @@ describe('MultiSigWalletWithTimeLock', () => { expect(confirmRes.logs).to.have.length(2); const blockNum = await web3Wrapper.getBlockNumberAsync(); - const blockInfo = await web3Wrapper.getBlockAsync(blockNum); + const blockInfo = await web3Wrapper.getBlockIfExistsAsync(blockNum); + if (_.isUndefined(blockInfo)) { + throw new Error(`Unexpectedly failed to fetch block at #${blockNum}`); + } const timestamp = new BigNumber(blockInfo.timestamp); const confirmationTimeBigNum = new BigNumber(await multiSig.confirmationTimes.callAsync(txId)); diff --git a/packages/contracts/test/utils/block_timestamp.ts b/packages/contracts/test/utils/block_timestamp.ts index 1159792c4c..66c13eed11 100644 --- a/packages/contracts/test/utils/block_timestamp.ts +++ b/packages/contracts/test/utils/block_timestamp.ts @@ -35,6 +35,9 @@ export async function increaseTimeAndMineBlockAsync(seconds: number): Promise { - const currentBlock = await web3Wrapper.getBlockAsync('latest'); - return currentBlock.timestamp; + const currentBlockIfExists = await web3Wrapper.getBlockIfExistsAsync('latest'); + if (_.isUndefined(currentBlockIfExists)) { + throw new Error(`Unable to fetch latest block.`); + } + return currentBlockIfExists.timestamp; } diff --git a/packages/dev-utils/CHANGELOG.json b/packages/dev-utils/CHANGELOG.json index 839af99ac2..b0b703b343 100644 --- a/packages/dev-utils/CHANGELOG.json +++ b/packages/dev-utils/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.8", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.7", diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index c1737c8842..220d499d3d 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.8 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.7 - _September 5, 2018_ * Dependencies updated diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index ff8bb3534e..876bb60d73 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/dev-utils", - "version": "1.0.7", + "version": "1.0.10", "engines": { "node": ">=6.12" }, @@ -42,12 +42,12 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/subproviders": "^2.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "ethereum-types": "^1.0.6", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", "lodash": "^4.17.5" }, "publishConfig": { diff --git a/packages/ethereum-types/CHANGELOG.json b/packages/ethereum-types/CHANGELOG.json index 5bb6965eeb..ab3018e4b8 100644 --- a/packages/ethereum-types/CHANGELOG.json +++ b/packages/ethereum-types/CHANGELOG.json @@ -1,4 +1,22 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.8", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.7", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.6", diff --git a/packages/ethereum-types/CHANGELOG.md b/packages/ethereum-types/CHANGELOG.md index 0131f6319e..d286fbbfd9 100644 --- a/packages/ethereum-types/CHANGELOG.md +++ b/packages/ethereum-types/CHANGELOG.md @@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.8 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.7 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.6 - _September 5, 2018_ * Dependencies updated diff --git a/packages/ethereum-types/package.json b/packages/ethereum-types/package.json index afe480916d..32fad87cb4 100644 --- a/packages/ethereum-types/package.json +++ b/packages/ethereum-types/package.json @@ -1,6 +1,6 @@ { "name": "ethereum-types", - "version": "1.0.6", + "version": "1.0.8", "engines": { "node": ">=6.12" }, @@ -36,7 +36,7 @@ "typescript": "3.0.1" }, "dependencies": { - "@types/node": "^8.0.53", + "@types/node": "*", "bignumber.js": "~4.1.0" }, "publishConfig": { diff --git a/packages/ethereum-types/src/index.ts b/packages/ethereum-types/src/index.ts index 3b6fdc77be..a3ff2fddbe 100644 --- a/packages/ethereum-types/src/index.ts +++ b/packages/ethereum-types/src/index.ts @@ -181,6 +181,7 @@ export interface CallData extends CallTxDataBase { export interface FilterObject { fromBlock?: number | string; toBlock?: number | string; + blockHash?: string; address?: string; topics?: LogTopic[]; } @@ -238,7 +239,7 @@ export enum AbiType { Fallback = 'fallback', } -export type ContractEventArg = string | BigNumber | number | boolean; +export type ContractEventArg = any; export interface DecodedLogArgs { [argName: string]: ContractEventArg; diff --git a/packages/fill-scenarios/CHANGELOG.json b/packages/fill-scenarios/CHANGELOG.json index dbcabe632b..8e6ff9b332 100644 --- a/packages/fill-scenarios/CHANGELOG.json +++ b/packages/fill-scenarios/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "1.0.2", "changes": [ diff --git a/packages/fill-scenarios/CHANGELOG.md b/packages/fill-scenarios/CHANGELOG.md index 409e5035c8..4cc8cd8555 100644 --- a/packages/fill-scenarios/CHANGELOG.md +++ b/packages/fill-scenarios/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.3 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.2 - _September 19, 2018_ * Drastically reduce the bundle size by removing unused parts of included contract artifacts. diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json index 5598b2b5f7..60b99e8fe8 100644 --- a/packages/fill-scenarios/package.json +++ b/packages/fill-scenarios/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/fill-scenarios", - "version": "1.0.2", + "version": "1.0.5", "description": "0x order fill scenario generator", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -26,7 +26,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/fill-scenarios/README.md", "devDependencies": { - "@0xproject/abi-gen": "^1.0.8", + "@0xproject/abi-gen": "^1.0.11", "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "4.14.104", "copyfiles": "^2.0.0", @@ -37,13 +37,13 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/base-contract": "^2.0.2", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "ethereum-types": "^1.0.6", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5" }, diff --git a/packages/forwarder-helper/CHANGELOG.json b/packages/forwarder-helper/CHANGELOG.json deleted file mode 100644 index aef30e4d0d..0000000000 --- a/packages/forwarder-helper/CHANGELOG.json +++ /dev/null @@ -1,48 +0,0 @@ -[ - { - "timestamp": 1537369748, - "version": "1.0.3", - "changes": [ - { - "note": "Dependencies updated" - } - ] - }, - { - "timestamp": 1537265493, - "version": "1.0.2", - "changes": [ - { - "note": "Dependencies updated" - } - ] - }, - { - "timestamp": 1536142250, - "version": "1.0.1", - "changes": [ - { - "note": "Dependencies updated" - } - ] - }, - { - "version": "1.0.1-rc.2", - "changes": [ - { - "note": "Dependencies updated" - } - ], - "timestamp": 1535377027 - }, - { - "version": "1.0.1-rc.1", - "changes": [ - { - "note": "Add initial forwarderHelperFactory", - "pr": 997 - } - ], - "timestamp": 1535133899 - } -] diff --git a/packages/forwarder-helper/CHANGELOG.md b/packages/forwarder-helper/CHANGELOG.md deleted file mode 100644 index 4c26e69801..0000000000 --- a/packages/forwarder-helper/CHANGELOG.md +++ /dev/null @@ -1,26 +0,0 @@ - - -CHANGELOG - -## v1.0.3 - _September 19, 2018_ - - * Dependencies updated - -## v1.0.2 - _September 18, 2018_ - - * Dependencies updated - -## v1.0.1 - _September 5, 2018_ - - * Dependencies updated - -## v1.0.1-rc.2 - _August 27, 2018_ - - * Dependencies updated - -## v1.0.1-rc.1 - _August 24, 2018_ - - * Add initial forwarderHelperFactory (#997) diff --git a/packages/forwarder-helper/README.md b/packages/forwarder-helper/README.md deleted file mode 100644 index c745269102..0000000000 --- a/packages/forwarder-helper/README.md +++ /dev/null @@ -1,83 +0,0 @@ -## @0xproject/forwarder-helper - -Provides convenience objects to help work with the Forwarder Contract - -### Read the [Documentation](https://0xproject.com/docs/forwarder-helper). - -## Installation - -```bash -yarn add @0xproject/forwarder-helper -``` - -**Import** - -```typescript -import { forwarderHelperFactory } from '@0xproject/forwarder-helper'; -``` - -or - -```javascript -var forwarderHelperFactory = require('@0xproject/forwarder-helper').forwarderHelperFactory; -``` - -If your project is in [TypeScript](https://www.typescriptlang.org/), add the following to your `tsconfig.json`: - -```json -"compilerOptions": { - "typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"], -} -``` - -## Contributing - -We 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=@0xproject/forwarder-helper yarn build -``` - -Or continuously rebuild on change: - -```bash -PKG=@0xproject/forwarder-helper yarn watch -``` - -### Clean - -```bash -yarn clean -``` - -### Lint - -```bash -yarn lint -``` - -### Run Tests - -```bash -yarn test -``` diff --git a/packages/forwarder-helper/src/constants.ts b/packages/forwarder-helper/src/constants.ts deleted file mode 100644 index 0ad30e4c0a..0000000000 --- a/packages/forwarder-helper/src/constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { BigNumber } from '@0xproject/utils'; - -export const constants = { - ZERO_AMOUNT: new BigNumber(0), -}; diff --git a/packages/forwarder-helper/src/forwarder_helper_factory.ts b/packages/forwarder-helper/src/forwarder_helper_factory.ts deleted file mode 100644 index 95f11f555a..0000000000 --- a/packages/forwarder-helper/src/forwarder_helper_factory.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { assert } from '@0xproject/assert'; -import { schemas } from '@0xproject/json-schemas'; -import { SignedOrder } from '@0xproject/types'; - -import { ForwarderHelperImpl, ForwarderHelperImplConfig } from './forwarder_helper_impl'; -import { ForwarderHelper } from './types'; - -export const forwarderHelperFactory = { - /** - * Given an array of orders and an array of feeOrders - * @param orders An array of objects conforming to SignedOrder. Each order should specify the same makerAssetData and takerAssetData - * @param feeOrders An array of objects conforming to SignedOrder. Each order should specify ZRX as makerAssetData WETH as takerAssetData - * @return A ForwarderHelper, see type for definition - */ - getForwarderHelperForOrders(orders: SignedOrder[], feeOrders: SignedOrder[] = []): ForwarderHelper { - assert.doesConformToSchema('orders', orders, schemas.signedOrdersSchema); - assert.doesConformToSchema('feeOrders', orders, schemas.signedOrdersSchema); - const config: ForwarderHelperImplConfig = { - orders, - feeOrders, - }; - const helper = new ForwarderHelperImpl(config); - return helper; - }, -}; diff --git a/packages/forwarder-helper/src/forwarder_helper_impl.ts b/packages/forwarder-helper/src/forwarder_helper_impl.ts deleted file mode 100644 index a90edb0bba..0000000000 --- a/packages/forwarder-helper/src/forwarder_helper_impl.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { marketUtils } from '@0xproject/order-utils'; -import { SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; - -import { constants } from './constants'; -import { ForwarderHelper, ForwarderHelperError, MarketBuyOrdersInfo, MarketBuyOrdersInfoRequest } from './types'; -import { forwarderHelperImplConfigUtils } from './utils/forwarder_helper_impl_config_utils'; - -const SLIPPAGE_PERCENTAGE = new BigNumber(0.2); // 20% slippage protection, possibly move this into request interface - -export interface ForwarderHelperImplConfig { - orders: SignedOrder[]; - feeOrders: SignedOrder[]; - remainingFillableMakerAssetAmounts?: BigNumber[]; - remainingFillableFeeAmounts?: BigNumber[]; -} - -export class ForwarderHelperImpl implements ForwarderHelper { - public readonly config: ForwarderHelperImplConfig; - constructor(config: ForwarderHelperImplConfig) { - this.config = forwarderHelperImplConfigUtils.sortedConfig(config); - } - public getMarketBuyOrdersInfo(request: MarketBuyOrdersInfoRequest): MarketBuyOrdersInfo { - const { makerAssetFillAmount, feePercentage } = request; - const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = this.config; - // TODO: make the slippage percentage customizable - const slippageBufferAmount = makerAssetFillAmount.mul(SLIPPAGE_PERCENTAGE).round(); - const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( - orders, - makerAssetFillAmount, - { - remainingFillableMakerAssetAmounts, - slippageBufferAmount, - }, - ); - if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) { - throw new Error(ForwarderHelperError.InsufficientMakerAssetLiquidity); - } - // TODO: update this logic to find the minimum amount of feeOrders to cover the worst case as opposed to - // finding order that cover all fees, this will help with estimating ETH and minimizing gas usage - const { resultFeeOrders, remainingFeeAmount } = marketUtils.findFeeOrdersThatCoverFeesForTargetOrders( - resultOrders, - feeOrders, - { - remainingFillableMakerAssetAmounts, - remainingFillableFeeAmounts, - }, - ); - if (remainingFeeAmount.gt(constants.ZERO_AMOUNT)) { - throw new Error(ForwarderHelperError.InsufficientZrxLiquidity); - } - // TODO: calculate min and max eth usage - // TODO: optimize orders call data - return { - makerAssetFillAmount, - orders: resultOrders, - feeOrders: resultFeeOrders, - minEthAmount: constants.ZERO_AMOUNT, - maxEthAmount: constants.ZERO_AMOUNT, - feePercentage, - }; - } -} diff --git a/packages/forwarder-helper/src/index.ts b/packages/forwarder-helper/src/index.ts deleted file mode 100644 index eb3a34bd54..0000000000 --- a/packages/forwarder-helper/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { forwarderHelperFactory } from './forwarder_helper_factory'; -export { ForwarderHelper, ForwarderHelperError, MarketBuyOrdersInfoRequest, MarketBuyOrdersInfo } from './types'; diff --git a/packages/forwarder-helper/src/types.ts b/packages/forwarder-helper/src/types.ts deleted file mode 100644 index fb171cc902..0000000000 --- a/packages/forwarder-helper/src/types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; - -export interface ForwarderHelper { - /** - * Given a MarketBuyOrdersInfoRequest, returns a MarketBuyOrdersInfo containing all information relevant to fulfilling the request - * using the ForwarderContract marketBuyOrdersWithEth function. - * @param request An object that conforms to MarketBuyOrdersInfoRequest. See type definition for more information. - * @return An object that conforms to MarketBuyOrdersInfo that satisfies the request. See type definition for more information. - */ - getMarketBuyOrdersInfo: (request: MarketBuyOrdersInfoRequest) => MarketBuyOrdersInfo; -} - -export enum ForwarderHelperError { - InsufficientMakerAssetLiquidity = 'INSUFFICIENT_MAKER_ASSET_LIQUIDITY', - InsufficientZrxLiquidity = 'INSUFFICIENT_ZRX_LIQUIDITY', -} - -/** - * makerAssetFillAmount: The amount of makerAsset requesting to be filled - * feePercentage: Optional affiliate percentage amount factoring into eth amount calculations - */ -export interface MarketBuyOrdersInfoRequest { - makerAssetFillAmount: BigNumber; - feePercentage?: BigNumber; -} - -/** - * makerAssetFillAmount: The amount of makerAsset requesting to be filled - * orders: An array of objects conforming to SignedOrder. These orders can be used to cover the requested makerAssetFillAmount plus slippage - * feeOrders: An array of objects conforming to SignedOrder. These orders can be used to cover the fees for the orders param above - * minEthAmount: Amount of eth in wei to send with the tx for the most optimistic case - * maxEthAmount: Amount of eth in wei to send with the tx for the worst case - * feePercentage: Affiliate fee percentage used to calculate the eth amounts above. Passed thru directly from the request - */ -export interface MarketBuyOrdersInfo { - makerAssetFillAmount: BigNumber; - orders: SignedOrder[]; - feeOrders: SignedOrder[]; - minEthAmount: BigNumber; - maxEthAmount: BigNumber; - feePercentage?: BigNumber; -} diff --git a/packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts b/packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts deleted file mode 100644 index 253384f655..0000000000 --- a/packages/forwarder-helper/src/utils/forwarder_helper_impl_config_utils.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { sortingUtils } from '@0xproject/order-utils'; -import { SignedOrder } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; - -import { ForwarderHelperImplConfig } from '../forwarder_helper_impl'; - -interface SignedOrderWithAmount extends SignedOrder { - remainingFillAmount: BigNumber; -} - -export const forwarderHelperImplConfigUtils = { - sortedConfig(config: ForwarderHelperImplConfig): ForwarderHelperImplConfig { - const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = config; - // TODO: provide a feeRate to the sorting function to more accurately sort based on the current market for ZRX tokens - const orderSorter = (ordersToSort: SignedOrder[]) => { - return sortingUtils.sortOrdersByFeeAdjustedRate(ordersToSort); - }; - const sortOrdersResult = sortOrdersAndRemainingFillAmounts( - orderSorter, - orders, - remainingFillableMakerAssetAmounts, - ); - const feeOrderSorter = (ordersToSort: SignedOrder[]) => { - return sortingUtils.sortFeeOrdersByFeeAdjustedRate(ordersToSort); - }; - const sortFeeOrdersResult = sortOrdersAndRemainingFillAmounts( - feeOrderSorter, - feeOrders, - remainingFillableFeeAmounts, - ); - return { - orders: sortOrdersResult.orders, - feeOrders: sortFeeOrdersResult.orders, - remainingFillableMakerAssetAmounts: sortOrdersResult.remainingFillAmounts, - remainingFillableFeeAmounts: sortFeeOrdersResult.remainingFillAmounts, - }; - }, -}; - -type OrderSorter = (orders: SignedOrder[]) => SignedOrder[]; - -function sortOrdersAndRemainingFillAmounts( - orderSorter: OrderSorter, - orders: SignedOrder[], - remainingFillAmounts?: BigNumber[], -): { orders: SignedOrder[]; remainingFillAmounts?: BigNumber[] } { - if (!_.isUndefined(remainingFillAmounts)) { - // Bundle orders together with their remainingFillAmounts so that we can sort them together - const orderWithAmounts = bundleSignedOrderWithAmounts(orders, remainingFillAmounts); - // Sort - const sortedOrderWithAmounts = orderSorter(orderWithAmounts) as SignedOrderWithAmount[]; - // Unbundle after sorting - const unbundledSortedOrderWithAmounts = unbundleSignedOrderWithAmounts(sortedOrderWithAmounts); - return { - orders: unbundledSortedOrderWithAmounts.orders, - remainingFillAmounts: unbundledSortedOrderWithAmounts.amounts, - }; - } else { - const sortedOrders = orderSorter(orders); - return { - orders: sortedOrders, - }; - } -} - -function bundleSignedOrderWithAmounts(orders: SignedOrder[], amounts: BigNumber[]): SignedOrderWithAmount[] { - const ordersAndAmounts = _.map(orders, (order, index) => { - return { - ...order, - remainingFillAmount: amounts[index], - }; - }); - return ordersAndAmounts; -} - -function unbundleSignedOrderWithAmounts( - signedOrderWithAmounts: SignedOrderWithAmount[], -): { orders: SignedOrder[]; amounts: BigNumber[] } { - const orders = _.map(signedOrderWithAmounts, order => { - const { remainingFillAmount, ...rest } = order; - return rest; - }); - const amounts = _.map(signedOrderWithAmounts, order => { - const { remainingFillAmount } = order; - return remainingFillAmount; - }); - return { - orders, - amounts, - }; -} diff --git a/packages/forwarder-helper/test/forwarder_helper_impl_test.ts b/packages/forwarder-helper/test/forwarder_helper_impl_test.ts deleted file mode 100644 index 3c3b6db921..0000000000 --- a/packages/forwarder-helper/test/forwarder_helper_impl_test.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { testOrderFactory } from '@0xproject/order-utils/lib/test/utils/test_order_factory'; -import { BigNumber } from '@0xproject/utils'; -import * as chai from 'chai'; -import * as _ from 'lodash'; -import 'mocha'; - -import { ForwarderHelperImpl, ForwarderHelperImplConfig } from '../src/forwarder_helper_impl'; -import { ForwarderHelperError } from '../src/types'; - -import { chaiSetup } from './utils/chai_setup'; - -chaiSetup.configure(); -const expect = chai.expect; - -describe('ForwarderHelperImpl', () => { - // rate: 2 takerAsset / makerAsset - const testOrder1 = testOrderFactory.generateTestSignedOrder({ - makerAssetAmount: new BigNumber(100), - takerAssetAmount: new BigNumber(200), - }); - // rate: 1 takerAsset / makerAsset - const testOrder2 = testOrderFactory.generateTestSignedOrder({ - makerAssetAmount: new BigNumber(100), - takerAssetAmount: new BigNumber(100), - }); - // rate: 3 takerAsset / makerAsset - const testOrder3 = testOrderFactory.generateTestSignedOrder({ - makerAssetAmount: new BigNumber(100), - takerAssetAmount: new BigNumber(300), - takerFee: new BigNumber(1), - }); - // rate: 3 WETH / ZRX - const testFeeOrder1 = testOrderFactory.generateTestSignedOrder({ - makerAssetAmount: new BigNumber(100), - takerAssetAmount: new BigNumber(300), - }); - // rate: 2 WETH / ZRX - const testFeeOrder2 = testOrderFactory.generateTestSignedOrder({ - makerAssetAmount: new BigNumber(100), - takerAssetAmount: new BigNumber(200), - }); - // rate: 1 WETH / ZRX - const testFeeOrder3 = testOrderFactory.generateTestSignedOrder({ - makerAssetAmount: new BigNumber(100), - takerAssetAmount: new BigNumber(100), - }); - const inputForwarderHelperConfig: ForwarderHelperImplConfig = { - orders: [testOrder1, testOrder2, testOrder3], - feeOrders: [testFeeOrder1, testFeeOrder2, testFeeOrder3], - remainingFillableMakerAssetAmounts: [new BigNumber(1), new BigNumber(2), new BigNumber(3)], - remainingFillableFeeAmounts: [new BigNumber(4), new BigNumber(5), new BigNumber(6)], - }; - describe('#constructor', () => { - const inputForwarderHelperConfigNoRemainingAmounts: ForwarderHelperImplConfig = { - orders: [testOrder1, testOrder2, testOrder3], - feeOrders: [testFeeOrder1, testFeeOrder2, testFeeOrder3], - }; - it('sorts orders', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - expect(forwarderHelper.config.orders).deep.equals([testOrder2, testOrder1, testOrder3]); - }); - it('sorts fee orders', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - expect(forwarderHelper.config.feeOrders).deep.equals([testFeeOrder3, testFeeOrder2, testFeeOrder1]); - }); - it('sorts remainingFillableMakerAssetAmounts', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - expect(forwarderHelper.config.remainingFillableMakerAssetAmounts).to.be.not.undefined(); - expect(_.nth(forwarderHelper.config.remainingFillableMakerAssetAmounts, 0)).to.bignumber.equal( - new BigNumber(2), - ); - expect(_.nth(forwarderHelper.config.remainingFillableMakerAssetAmounts, 1)).to.bignumber.equal( - new BigNumber(1), - ); - expect(_.nth(forwarderHelper.config.remainingFillableMakerAssetAmounts, 2)).to.bignumber.equal( - new BigNumber(3), - ); - }); - it('sorts remainingFillableFeeAmounts', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - expect(forwarderHelper.config.remainingFillableFeeAmounts).to.be.not.undefined(); - expect(_.nth(forwarderHelper.config.remainingFillableFeeAmounts, 0)).to.bignumber.equal(new BigNumber(6)); - expect(_.nth(forwarderHelper.config.remainingFillableFeeAmounts, 1)).to.bignumber.equal(new BigNumber(5)); - expect(_.nth(forwarderHelper.config.remainingFillableFeeAmounts, 2)).to.bignumber.equal(new BigNumber(4)); - }); - it('remainingFillableMakerAssetAmounts is undefined if none provided', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfigNoRemainingAmounts); - expect(forwarderHelper.config.remainingFillableMakerAssetAmounts).to.be.undefined(); - }); - it('remainingFillableFeeAmounts is undefined if none provided', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfigNoRemainingAmounts); - expect(forwarderHelper.config.remainingFillableFeeAmounts).to.be.undefined(); - }); - }); - describe('#getMarketBuyOrdersInfo', () => { - it('throws if not enough makerAsset liquidity', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - expect(() => { - // request for 6 makerAsset units, because we have exactly 6 available we should throw because there is a built in slippage buffer - forwarderHelper.getMarketBuyOrdersInfo({ - makerAssetFillAmount: new BigNumber(6), - }); - }).to.throw(ForwarderHelperError.InsufficientMakerAssetLiquidity); - }); - it('throws if not enough ZRX liquidity', () => { - const inputForwarderHelperConfigNoFees: ForwarderHelperImplConfig = { - orders: [testOrder1, testOrder2, testOrder3], - feeOrders: [], - }; - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfigNoFees); - expect(() => { - // request for 4 makerAsset units, we need fees but no fee orders exist, show we should throw - forwarderHelper.getMarketBuyOrdersInfo({ - makerAssetFillAmount: new BigNumber(250), - }); - }).to.throw(ForwarderHelperError.InsufficientZrxLiquidity); - }); - it('passes the makerAssetFillAmount from the request to the info response', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - const makerAssetFillAmount = new BigNumber(4); - const info = forwarderHelper.getMarketBuyOrdersInfo({ - makerAssetFillAmount, - }); - expect(info.makerAssetFillAmount).to.bignumber.equal(makerAssetFillAmount); - }); - it('passes the feePercentage from the request to the info response', () => { - const forwarderHelper = new ForwarderHelperImpl(inputForwarderHelperConfig); - const feePercentage = new BigNumber(0.2); - const info = forwarderHelper.getMarketBuyOrdersInfo({ - makerAssetFillAmount: new BigNumber(4), - feePercentage, - }); - expect(info.feePercentage).to.bignumber.equal(feePercentage); - }); - }); -}); diff --git a/packages/json-schemas/CHANGELOG.json b/packages/json-schemas/CHANGELOG.json index 09d7fb9320..facd90878d 100644 --- a/packages/json-schemas/CHANGELOG.json +++ b/packages/json-schemas/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.1", diff --git a/packages/json-schemas/CHANGELOG.md b/packages/json-schemas/CHANGELOG.md index b68c1a1f92..763e9dd050 100644 --- a/packages/json-schemas/CHANGELOG.md +++ b/packages/json-schemas/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.3 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.2 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.1 - _September 5, 2018_ * Dependencies updated diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json index 776f26664d..02f00ccc36 100644 --- a/packages/json-schemas/package.json +++ b/packages/json-schemas/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/json-schemas", - "version": "1.0.1", + "version": "1.0.4", "engines": { "node": ">=6.12" }, @@ -38,14 +38,14 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/json-schemas/README.md", "dependencies": { - "@0xproject/typescript-typings": "^2.0.0", - "@types/node": "^8.0.53", + "@0xproject/typescript-typings": "^2.0.2", + "@types/node": "*", "jsonschema": "^1.2.0", "lodash.values": "^4.3.0" }, "devDependencies": { "@0xproject/tslint-config": "^1.0.7", - "@0xproject/utils": "^1.0.8", + "@0xproject/utils": "^1.0.11", "@types/lodash.foreach": "^4.5.3", "@types/lodash.values": "^4.3.3", "@types/mocha": "^2.2.42", diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json index 4339956866..0940ddfe3f 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/metacoin", - "version": "0.0.18", + "version": "0.0.21", "engines": { "node": ">=6.12" }, @@ -28,25 +28,25 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@0xproject/abi-gen": "^1.0.8", - "@0xproject/base-contract": "^2.0.2", - "@0xproject/sol-cov": "^2.1.2", - "@0xproject/subproviders": "^2.0.2", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/sol-cov": "^2.1.5", + "@0xproject/subproviders": "^2.0.5", "@0xproject/tslint-config": "^1.0.7", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "@types/mocha": "^5.2.2", "copyfiles": "^2.0.0", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5", "run-s": "^0.0.0" }, "devDependencies": { - "@0xproject/dev-utils": "^1.0.7", - "@0xproject/sol-compiler": "^1.1.2", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/sol-compiler": "^1.1.5", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", "chai-bignumber": "^2.0.1", diff --git a/packages/migrations/.gitignore b/packages/migrations/.gitignore new file mode 100644 index 0000000000..dc4af7cedb --- /dev/null +++ b/packages/migrations/.gitignore @@ -0,0 +1 @@ +artifacts/development diff --git a/packages/migrations/CHANGELOG.json b/packages/migrations/CHANGELOG.json index 84ec503bfa..25b523e8fc 100644 --- a/packages/migrations/CHANGELOG.json +++ b/packages/migrations/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.12", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537369748, "version": "1.0.9", diff --git a/packages/migrations/CHANGELOG.md b/packages/migrations/CHANGELOG.md index aff23b0cfb..a637f30ef8 100644 --- a/packages/migrations/CHANGELOG.md +++ b/packages/migrations/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.12 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 19, 2018_ * Dependencies updated diff --git a/packages/migrations/package.json b/packages/migrations/package.json index a669b3fefd..e7e08d132d 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/migrations", - "version": "1.0.9", + "version": "1.0.12", "engines": { "node": ">=6.12" }, @@ -30,10 +30,10 @@ }, "license": "Apache-2.0", "devDependencies": { - "@0xproject/abi-gen": "^1.0.8", - "@0xproject/dev-utils": "^1.0.7", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/dev-utils": "^1.0.10", "@0xproject/tslint-config": "^1.0.7", - "@0xproject/types": "^1.0.1", + "@0xproject/types": "^1.1.1", "@types/yargs": "^10.0.0", "copyfiles": "^2.0.0", "make-promises-safe": "^1.1.0", @@ -44,15 +44,15 @@ "yargs": "^10.0.3" }, "dependencies": { - "@0xproject/base-contract": "^2.0.2", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/sol-compiler": "^1.1.2", - "@0xproject/subproviders": "^2.0.2", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/sol-compiler": "^1.1.5", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "@ledgerhq/hw-app-eth": "^4.3.0", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5" }, diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json index cddb6ec3da..e776569b15 100644 --- a/packages/monorepo-scripts/package.json +++ b/packages/monorepo-scripts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/monorepo-scripts", - "version": "1.0.8", + "version": "1.0.9", "engines": { "node": ">=6.12" }, @@ -33,7 +33,7 @@ "devDependencies": { "@types/glob": "^5.0.33", "@types/mkdirp": "^0.5.2", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/opn": "^5.1.0", "@types/rimraf": "^2.0.2", "@types/semver": "5.5.0", diff --git a/packages/monorepo-scripts/src/publish_release_notes.ts b/packages/monorepo-scripts/src/publish_release_notes.ts index a9bc8fe75b..6090498e08 100644 --- a/packages/monorepo-scripts/src/publish_release_notes.ts +++ b/packages/monorepo-scripts/src/publish_release_notes.ts @@ -1,3 +1,4 @@ +import * as _ from 'lodash'; import * as yargs from 'yargs'; import { publishReleaseNotesAsync } from './utils/github_release_utils'; @@ -9,14 +10,25 @@ const args = yargs type: 'boolean', demandOption: true, }) - .example('$0 --isDryRun true', 'Full usage example').argv; + .option('packages', { + describe: + 'Space-separated list of packages to generated release notes for. If not supplied, it does all `Lerna updated` packages.', + type: 'string', + }) + .example('$0 --isDryRun true --packages "0x.js @0xproject/web3-wrapper"', 'Full usage example').argv; (async () => { const isDryRun = args.isDryRun; - const shouldIncludePrivate = false; - const allUpdatedPackages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + let packages; + if (_.isUndefined(args.packages)) { + const shouldIncludePrivate = false; + packages = await utils.getUpdatedPackagesAsync(shouldIncludePrivate); + } else { + const packageNames = args.packages.split(' '); + packages = await utils.getPackagesByNameAsync(packageNames); + } - await publishReleaseNotesAsync(allUpdatedPackages, isDryRun); + await publishReleaseNotesAsync(packages, isDryRun); process.exit(0); })().catch(err => { utils.log(err); diff --git a/packages/monorepo-scripts/src/utils/utils.ts b/packages/monorepo-scripts/src/utils/utils.ts index 2ce36942c7..5e2e877c70 100644 --- a/packages/monorepo-scripts/src/utils/utils.ts +++ b/packages/monorepo-scripts/src/utils/utils.ts @@ -54,6 +54,13 @@ export const utils = { } return packages; }, + async getPackagesByNameAsync(packageNames: string[]): Promise { + const allPackages = utils.getPackages(constants.monorepoRootPath); + const updatedPackages = _.filter(allPackages, pkg => { + return _.includes(packageNames, pkg.packageJson.name); + }); + return updatedPackages; + }, async getUpdatedPackagesAsync(shouldIncludePrivate: boolean): Promise { const updatedPublicPackages = await utils.getLernaUpdatedPackagesAsync(shouldIncludePrivate); const updatedPackageNames = _.map(updatedPublicPackages, pkg => pkg.name); diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index d202d779cf..1162bbc832 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "1.0.2", "changes": [ diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md index 077f017dbc..8372ddf165 100644 --- a/packages/order-utils/CHANGELOG.md +++ b/packages/order-utils/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.3 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.2 - _September 19, 2018_ * Drastically reduce the bundle size by removing unused parts of included contract artifacts. diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index a114c17517..64f1c9d667 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-utils", - "version": "1.0.2", + "version": "1.0.5", "engines": { "node": ">=6.12" }, @@ -38,7 +38,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md", "devDependencies": { - "@0xproject/dev-utils": "^1.0.7", + "@0xproject/dev-utils": "^1.0.10", "@0xproject/tslint-config": "^1.0.7", "@types/bn.js": "^4.11.0", "@types/lodash": "4.14.104", @@ -57,16 +57,16 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/base-contract": "^2.0.2", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "@types/node": "^8.0.53", + "@0xproject/assert": "^1.0.11", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "@types/node": "*", "bn.js": "^4.11.8", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-abi": "0.6.5", "ethereumjs-util": "^5.1.1", "ethers": "^4.0.0-beta.14", diff --git a/packages/order-utils/src/market_utils.ts b/packages/order-utils/src/market_utils.ts index 4a664cb14b..ed6af7d857 100644 --- a/packages/order-utils/src/market_utils.ts +++ b/packages/order-utils/src/market_utils.ts @@ -51,17 +51,23 @@ export const marketUtils = { // iterate through the orders input from left to right until we have enough makerAsset to fill totalFillAmount const result = _.reduce( orders, - ({ resultOrders, remainingFillAmount }, order, index) => { + ({ resultOrders, remainingFillAmount, ordersRemainingFillableMakerAssetAmounts }, order, index) => { if (remainingFillAmount.lessThanOrEqualTo(constants.ZERO_AMOUNT)) { - return { resultOrders, remainingFillAmount: constants.ZERO_AMOUNT }; + return { + resultOrders, + remainingFillAmount: constants.ZERO_AMOUNT, + ordersRemainingFillableMakerAssetAmounts, + }; } else { const makerAssetAmountAvailable = remainingFillableMakerAssetAmounts[index]; + const shouldIncludeOrder = makerAssetAmountAvailable.gt(constants.ZERO_AMOUNT); // if there is no makerAssetAmountAvailable do not append order to resultOrders // if we have exceeded the total amount we want to fill set remainingFillAmount to 0 return { - resultOrders: makerAssetAmountAvailable.gt(constants.ZERO_AMOUNT) - ? _.concat(resultOrders, order) - : resultOrders, + resultOrders: shouldIncludeOrder ? _.concat(resultOrders, order) : resultOrders, + ordersRemainingFillableMakerAssetAmounts: shouldIncludeOrder + ? _.concat(ordersRemainingFillableMakerAssetAmounts, makerAssetAmountAvailable) + : ordersRemainingFillableMakerAssetAmounts, remainingFillAmount: BigNumber.max( constants.ZERO_AMOUNT, remainingFillAmount.minus(makerAssetAmountAvailable), @@ -69,7 +75,11 @@ export const marketUtils = { }; } }, - { resultOrders: [] as T[], remainingFillAmount: totalFillAmount }, + { + resultOrders: [] as T[], + remainingFillAmount: totalFillAmount, + ordersRemainingFillableMakerAssetAmounts: [] as BigNumber[], + }, ); return result; }, @@ -133,17 +143,18 @@ export const marketUtils = { }, constants.ZERO_AMOUNT, ); - const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount( - feeOrders, - totalFeeAmount, - { - remainingFillableMakerAssetAmounts: remainingFillableFeeAmounts, - slippageBufferAmount, - }, - ); + const { + resultOrders, + remainingFillAmount, + ordersRemainingFillableMakerAssetAmounts, + } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(feeOrders, totalFeeAmount, { + remainingFillableMakerAssetAmounts: remainingFillableFeeAmounts, + slippageBufferAmount, + }); return { resultFeeOrders: resultOrders, remainingFeeAmount: remainingFillAmount, + feeOrdersRemainingFillableMakerAssetAmounts: ordersRemainingFillableMakerAssetAmounts, }; // TODO: add more orders here to cover rounding // https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarding-contract-specification.md#over-buying-zrx diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts index 8398776aac..9b21ef6e96 100644 --- a/packages/order-utils/src/order_state_utils.ts +++ b/packages/order-utils/src/order_state_utils.ts @@ -114,7 +114,7 @@ export class OrderStateUtils { * @return State relevant to the signedOrder, as well as whether the signedOrder is "valid". * Validity is defined as a non-zero amount of the order can still be filled. */ - public async getOpenOrderStateAsync(signedOrder: SignedOrder): Promise { + public async getOpenOrderStateAsync(signedOrder: SignedOrder, transactionHash?: string): Promise { const orderRelevantState = await this.getOpenOrderRelevantStateAsync(signedOrder); const orderHash = orderHashUtils.getOrderHashHex(signedOrder); const isOrderCancelled = await this._orderFilledCancelledFetcher.isOrderCancelledAsync(orderHash); @@ -134,6 +134,7 @@ export class OrderStateUtils { isValid: true, orderHash, orderRelevantState, + transactionHash, }; return orderState; } else { @@ -141,6 +142,7 @@ export class OrderStateUtils { isValid: false, orderHash, error: orderValidationResult.error, + transactionHash, }; return orderState; } diff --git a/packages/order-utils/src/types.ts b/packages/order-utils/src/types.ts index 09292e557f..a843efaa47 100644 --- a/packages/order-utils/src/types.ts +++ b/packages/order-utils/src/types.ts @@ -72,10 +72,12 @@ export interface FindFeeOrdersThatCoverFeesForTargetOrdersOpts { export interface FeeOrdersAndRemainingFeeAmount { resultFeeOrders: T[]; + feeOrdersRemainingFillableMakerAssetAmounts: BigNumber[]; remainingFeeAmount: BigNumber; } export interface OrdersAndRemainingFillAmount { resultOrders: T[]; + ordersRemainingFillableMakerAssetAmounts: BigNumber[]; remainingFillAmount: BigNumber; } diff --git a/packages/order-utils/test/order_state_utils_test.ts b/packages/order-utils/test/order_state_utils_test.ts index 91ef23b695..ea88027ae3 100644 --- a/packages/order-utils/test/order_state_utils_test.ts +++ b/packages/order-utils/test/order_state_utils_test.ts @@ -120,5 +120,25 @@ describe('OrderStateUtils', () => { const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder); expect(orderState.isValid).to.eq(false); }); + it('should include the transactionHash in orderState if supplied in method invocation', async () => { + const makerAssetAmount = new BigNumber(10); + const takerAssetAmount = new BigNumber(10000000000000000); + const takerBalance = takerAssetAmount; + const orderFilledAmount = new BigNumber(0); + const mockBalanceFetcher = buildMockBalanceFetcher(takerBalance); + const mockOrderFilledFetcher = buildMockOrderFilledFetcher(orderFilledAmount); + const [signedOrder] = testOrderFactory.generateTestSignedOrders( + { + makerAssetAmount, + takerAssetAmount, + }, + 1, + ); + + const orderStateUtils = new OrderStateUtils(mockBalanceFetcher, mockOrderFilledFetcher); + const transactionHash = '0xdeadbeef'; + const orderState = await orderStateUtils.getOpenOrderStateAsync(signedOrder, transactionHash); + expect(orderState.transactionHash).to.eq(transactionHash); + }); }); }); diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index 8d8aaf7027..fc7037bfb9 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -1,4 +1,43 @@ [ + { + "version": "2.0.0", + "changes": [ + { + "note": + "Fixes dropped events issue by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too.", + "pr": 1080 + }, + { + "note": + "Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it", + "pr": 1080 + }, + { + "note": + "Add `transactionHash` to `OrderState` emitted by `OrderWatcher` subscriptions if the order's state change originated from a transaction.", + "pr": 1087 + } + ], + "timestamp": 1537907159 + }, + { + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537875740 + }, + { + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537541580 + }, { "version": "1.0.3", "changes": [ diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md index e79bf638e4..32837337ab 100644 --- a/packages/order-watcher/CHANGELOG.md +++ b/packages/order-watcher/CHANGELOG.md @@ -5,6 +5,20 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.0 - _September 25, 2018_ + + * Fixes dropped events issue by fetching logs by blockHash instead of blockNumber. Support for fetching by blockHash was added in Geth > v1.8.13 and Parity > v2.1.0. Infura works too. (#1080) + * Fix misunderstanding about blockstream interface callbacks and pass the raw JSON RPC responses to it (#1080) + * Add `transactionHash` to `OrderState` emitted by `OrderWatcher` subscriptions if the order's state change originated from a transaction. (#1087) + +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.4 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.3 - _September 19, 2018_ * Drastically reduce the bundle size by removing unused parts of included contract artifacts. diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index 07040a421e..8c0ec87e07 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-watcher", - "version": "1.0.3", + "version": "2.0.0", "description": "An order watcher daemon that watches for order validity", "keywords": [ "0x", @@ -42,14 +42,14 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^1.0.8", - "@0xproject/dev-utils": "^1.0.7", - "@0xproject/migrations": "^1.0.9", + "@0xproject/abi-gen": "^1.0.11", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/migrations": "^1.0.12", "@0xproject/tslint-config": "^1.0.7", "@types/bintrees": "^1.0.2", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sinon": "^2.2.2", "awesome-typescript-loader": "^3.1.3", "chai": "^4.0.1", @@ -70,19 +70,19 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/base-contract": "^2.0.2", - "@0xproject/contract-wrappers": "^1.0.3", - "@0xproject/fill-scenarios": "^1.0.2", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/assert": "^1.0.11", + "@0xproject/base-contract": "^2.0.5", + "@0xproject/contract-wrappers": "^2.0.0", + "@0xproject/fill-scenarios": "^1.0.5", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "bintrees": "^1.0.2", - "ethereum-types": "^1.0.6", - "ethereumjs-blockstream": "5.0.0", + "ethereum-types": "^1.0.8", + "ethereumjs-blockstream": "6.0.0", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5" }, diff --git a/packages/order-watcher/src/order_watcher/event_watcher.ts b/packages/order-watcher/src/order_watcher/event_watcher.ts index 9509c75de3..9ea301815c 100644 --- a/packages/order-watcher/src/order_watcher/event_watcher.ts +++ b/packages/order-watcher/src/order_watcher/event_watcher.ts @@ -1,6 +1,6 @@ import { intervalUtils, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import { BlockParamLiteral, LogEntry, Provider } from 'ethereum-types'; +import { marshaller, Web3Wrapper } from '@0xproject/web3-wrapper'; +import { BlockParamLiteral, FilterObject, LogEntry, Provider, RawLogEntry } from 'ethereum-types'; import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream'; import * as _ from 'lodash'; @@ -20,7 +20,6 @@ enum LogEventState { */ export class EventWatcher { private readonly _web3Wrapper: Web3Wrapper; - private readonly _stateLayer: BlockParamLiteral; private readonly _isVerbose: boolean; private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined; private _blockAndLogStreamIntervalIfExists?: NodeJS.Timer; @@ -35,7 +34,6 @@ export class EventWatcher { ) { this._isVerbose = isVerbose; this._web3Wrapper = new Web3Wrapper(provider); - this._stateLayer = stateLayer; this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ? DEFAULT_EVENT_POLLING_INTERVAL_MS : pollingIntervalIfExistsMs; @@ -62,8 +60,8 @@ export class EventWatcher { throw new Error(OrderWatcherError.SubscriptionAlreadyPresent); } this._blockAndLogStreamerIfExists = new BlockAndLogStreamer( - this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper), - this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper), + this._blockstreamGetBlockOrNullAsync.bind(this), + this._blockstreamGetLogsAsync.bind(this), this._onBlockAndLogStreamerError.bind(this), ); const catchAllLogFilter = {}; @@ -82,6 +80,32 @@ export class EventWatcher { this._onLogStateChangedAsync.bind(this, callback, isRemoved), ); } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetBlockOrNullAsync(hash: string): Promise { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync({ + method: 'eth_getBlockByHash', + params: [hash, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLatestBlockOrNullAsync(): Promise { + const shouldIncludeTransactionData = false; + const blockOrNull = await this._web3Wrapper.sendRawPayloadAsync({ + method: 'eth_getBlockByNumber', + params: [BlockParamLiteral.Latest, shouldIncludeTransactionData], + }); + return blockOrNull; + } + // This method only exists in order to comply with the expected interface of Blockstream's constructor + private async _blockstreamGetLogsAsync(filterOptions: FilterObject): Promise { + const logs = await this._web3Wrapper.sendRawPayloadAsync({ + method: 'eth_getLogs', + params: [filterOptions], + }); + return logs as RawLogEntry[]; + } private _stopBlockAndLogStream(): void { if (_.isUndefined(this._blockAndLogStreamerIfExists)) { throw new Error(OrderWatcherError.SubscriptionNotFound); @@ -95,16 +119,20 @@ export class EventWatcher { private async _onLogStateChangedAsync( callback: EventWatcherCallback, isRemoved: boolean, - log: LogEntry, + rawLog: RawLogEntry, ): Promise { + const log: LogEntry = marshaller.unmarshalLog(rawLog); await this._emitDifferencesAsync(log, isRemoved ? LogEventState.Removed : LogEventState.Added, callback); } private async _reconcileBlockAsync(): Promise { - const latestBlock = await this._web3Wrapper.getBlockAsync(this._stateLayer); + const latestBlockOrNull = await this._blockstreamGetLatestBlockOrNullAsync(); + if (_.isNull(latestBlockOrNull)) { + return; // noop + } // We need to coerce to Block type cause Web3.Block includes types for mempool blocks if (!_.isUndefined(this._blockAndLogStreamerIfExists)) { // If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined - await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block); + await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlockOrNull); } } private async _emitDifferencesAsync( diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts index cab2efa4b2..f9a63efe3a 100644 --- a/packages/order-watcher/src/order_watcher/order_watcher.ts +++ b/packages/order-watcher/src/order_watcher/order_watcher.ts @@ -275,6 +275,7 @@ export class OrderWatcher { return; // noop } const decodedLog = (maybeDecodedLog as any) as LogWithDecodedArgs; + const transactionHash = decodedLog.transactionHash; switch (decodedLog.event) { case ERC20TokenEvents.Approval: case ERC721TokenEvents.Approval: { @@ -290,7 +291,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } else { // ERC721 @@ -303,7 +304,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } } @@ -322,7 +323,7 @@ export class OrderWatcher { args._from, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } else { // ERC721 @@ -336,7 +337,7 @@ export class OrderWatcher { args._from, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } } @@ -350,7 +351,7 @@ export class OrderWatcher { args._owner, tokenAddress, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case WETH9Events.Deposit: { @@ -363,7 +364,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case WETH9Events.Withdrawal: { @@ -376,7 +377,7 @@ export class OrderWatcher { args._owner, tokenAssetData, ); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } case ExchangeEvents.Fill: { @@ -387,7 +388,7 @@ export class OrderWatcher { const orderHash = args.orderHash; const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); + await this._emitRevalidateOrdersAsync([orderHash], transactionHash); } break; } @@ -399,7 +400,7 @@ export class OrderWatcher { const orderHash = args.orderHash; const isOrderWatched = !_.isUndefined(this._orderByOrderHash[orderHash]); if (isOrderWatched) { - await this._emitRevalidateOrdersAsync([orderHash]); + await this._emitRevalidateOrdersAsync([orderHash], transactionHash); } break; } @@ -410,7 +411,7 @@ export class OrderWatcher { this._orderFilledCancelledLazyStore.deleteAllIsCancelled(); // Revalidate orders const orderHashes = this._dependentOrderHashesTracker.getDependentOrderHashesByMaker(args.makerAddress); - await this._emitRevalidateOrdersAsync(orderHashes); + await this._emitRevalidateOrdersAsync(orderHashes, transactionHash); break; } @@ -418,12 +419,12 @@ export class OrderWatcher { throw errorUtils.spawnSwitchErr('decodedLog.event', decodedLog.event); } } - private async _emitRevalidateOrdersAsync(orderHashes: string[]): Promise { + private async _emitRevalidateOrdersAsync(orderHashes: string[], transactionHash?: string): Promise { for (const orderHash of orderHashes) { const signedOrder = this._orderByOrderHash[orderHash]; // Most of these calls will never reach the network because the data is fetched from stores // and only updated when cache is invalidated - const orderState = await this._orderStateUtils.getOpenOrderStateAsync(signedOrder); + const orderState = await this._orderStateUtils.getOpenOrderStateAsync(signedOrder, transactionHash); if (_.isUndefined(this._callbackIfExists)) { break; // Unsubscribe was called } diff --git a/packages/order-watcher/test/order_watcher_test.ts b/packages/order-watcher/test/order_watcher_test.ts index 38bfde7ef2..60d9069e8f 100644 --- a/packages/order-watcher/test/order_watcher_test.ts +++ b/packages/order-watcher/test/order_watcher_test.ts @@ -250,6 +250,32 @@ describe('OrderWatcher', () => { await contractWrappers.exchange.fillOrderAsync(signedOrder, fillableAmount, takerAddress); })().catch(done); }); + it('should include transactionHash in emitted orderStateInvalid when watched order fully filled', (done: DoneCallback) => { + (async () => { + signedOrder = await fillScenarios.createFillableSignedOrderAsync( + makerAssetData, + takerAssetData, + makerAddress, + takerAddress, + fillableAmount, + ); + await orderWatcher.addOrderAsync(signedOrder); + + let transactionHash: string; + const callback = callbackErrorReporter.reportNodeCallbackErrors(done)((orderState: OrderState) => { + expect(orderState.isValid).to.be.false(); + const invalidOrderState = orderState as OrderStateInvalid; + expect(invalidOrderState.transactionHash).to.be.equal(transactionHash); + }); + orderWatcher.subscribe(callback); + + transactionHash = await contractWrappers.exchange.fillOrderAsync( + signedOrder, + fillableAmount, + takerAddress, + ); + })().catch(done); + }); it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => { (async () => { signedOrder = await fillScenarios.createFillableSignedOrderAsync( diff --git a/packages/react-docs/CHANGELOG.json b/packages/react-docs/CHANGELOG.json index d1e846bb19..82aaf4e32d 100644 --- a/packages/react-docs/CHANGELOG.json +++ b/packages/react-docs/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.8", diff --git a/packages/react-docs/CHANGELOG.md b/packages/react-docs/CHANGELOG.md index 679f000976..8f5cc0cfd6 100644 --- a/packages/react-docs/CHANGELOG.md +++ b/packages/react-docs/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 5, 2018_ * Dependencies updated diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index 3455220744..be80f80288 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/react-docs", - "version": "1.0.8", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -23,7 +23,7 @@ "url": "https://github.com/0xProject/0x-monorepo.git" }, "devDependencies": { - "@0xproject/dev-utils": "^1.0.7", + "@0xproject/dev-utils": "^1.0.10", "@0xproject/tslint-config": "^1.0.7", "@types/compare-versions": "^3.0.0", "copyfiles": "^2.0.0", @@ -33,11 +33,11 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/react-shared": "^1.0.9", - "@0xproject/utils": "^1.0.8", + "@0xproject/react-shared": "^1.0.12", + "@0xproject/utils": "^1.0.11", "@types/lodash": "4.14.104", "@types/material-ui": "^0.20.0", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/react": "*", "@types/react-dom": "*", "@types/react-scroll": "1.5.3", diff --git a/packages/react-docs/src/components/signature.tsx b/packages/react-docs/src/components/signature.tsx index bf9c8be24f..4f10f46658 100644 --- a/packages/react-docs/src/components/signature.tsx +++ b/packages/react-docs/src/components/signature.tsx @@ -134,14 +134,19 @@ function renderTypeParameter( ): React.ReactNode { const typeParam = ( - {`<${typeParameter.name} extends `} - + {`<${typeParameter.name}`} + {!_.isUndefined(typeParameter.type) && ( + + {' extends '} + + + )} {`>`} ); diff --git a/packages/react-docs/src/types.ts b/packages/react-docs/src/types.ts index f9cb5e26ab..29f5664f57 100644 --- a/packages/react-docs/src/types.ts +++ b/packages/react-docs/src/types.ts @@ -150,7 +150,7 @@ export interface Parameter { export interface TypeParameter { name: string; - type: Type; + type?: Type; } export interface Type { diff --git a/packages/react-docs/src/utils/typedoc_utils.ts b/packages/react-docs/src/utils/typedoc_utils.ts index f449453694..e3e9c11fbf 100644 --- a/packages/react-docs/src/utils/typedoc_utils.ts +++ b/packages/react-docs/src/utils/typedoc_utils.ts @@ -419,7 +419,10 @@ export class TypeDocUtils { return func; } private _convertTypeParameter(entity: TypeDocNode, sectionName: string): TypeParameter { - const type = this._convertType(entity.type, sectionName); + let type; + if (!_.isUndefined(entity.type)) { + type = this._convertType(entity.type, sectionName); + } const parameter = { name: entity.name, type, diff --git a/packages/react-shared/CHANGELOG.json b/packages/react-shared/CHANGELOG.json index 7f88a4db2d..32cf666912 100644 --- a/packages/react-shared/CHANGELOG.json +++ b/packages/react-shared/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.12", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.9", diff --git a/packages/react-shared/CHANGELOG.md b/packages/react-shared/CHANGELOG.md index bc524322c8..fb2bac27ed 100644 --- a/packages/react-shared/CHANGELOG.md +++ b/packages/react-shared/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.12 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 5, 2018_ * Dependencies updated diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 49b3a4ac37..9ffafc4eeb 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/react-shared", - "version": "1.0.9", + "version": "1.0.12", "engines": { "node": ">=6.12" }, @@ -24,7 +24,7 @@ "url": "https://github.com/0xProject/0x-monorepo.git" }, "devDependencies": { - "@0xproject/dev-utils": "^1.0.7", + "@0xproject/dev-utils": "^1.0.10", "@0xproject/tslint-config": "^1.0.7", "copyfiles": "^2.0.0", "make-promises-safe": "^1.1.0", @@ -37,7 +37,7 @@ "@types/is-mobile": "0.3.0", "@types/lodash": "4.14.104", "@types/material-ui": "0.18.0", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/react": "*", "@types/react-dom": "*", "@types/react-scroll": "1.5.3", diff --git a/packages/sol-compiler/CHANGELOG.json b/packages/sol-compiler/CHANGELOG.json index 8c5c84ce88..69cc7fa0fc 100644 --- a/packages/sol-compiler/CHANGELOG.json +++ b/packages/sol-compiler/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.1.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.1.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.1.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.1.2", diff --git a/packages/sol-compiler/CHANGELOG.md b/packages/sol-compiler/CHANGELOG.md index 8b0e124416..0fc0ff7b11 100644 --- a/packages/sol-compiler/CHANGELOG.md +++ b/packages/sol-compiler/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.5 - _September 25, 2018_ + + * Dependencies updated + +## v1.1.4 - _September 25, 2018_ + + * Dependencies updated + +## v1.1.3 - _September 21, 2018_ + + * Dependencies updated + ## v1.1.2 - _September 5, 2018_ * Dependencies updated diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 8395eccb52..9d16101800 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sol-compiler", - "version": "1.1.2", + "version": "1.1.5", "engines": { "node": ">=6.12" }, @@ -41,7 +41,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-compiler/README.md", "devDependencies": { - "@0xproject/dev-utils": "^1.0.7", + "@0xproject/dev-utils": "^1.0.10", "@0xproject/tslint-config": "^1.0.7", "@types/mkdirp": "^0.5.2", "@types/require-from-string": "^1.2.0", @@ -64,16 +64,16 @@ "zeppelin-solidity": "1.8.0" }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/sol-resolver": "^1.0.8", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/assert": "^1.0.11", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/sol-resolver": "^1.0.11", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "@types/yargs": "^11.0.0", "chalk": "^2.3.0", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-util": "^5.1.1", "lodash": "^4.17.5", "mkdirp": "^0.5.1", diff --git a/packages/sol-cov/CHANGELOG.json b/packages/sol-cov/CHANGELOG.json index e57939f4f5..5fde6d5ee4 100644 --- a/packages/sol-cov/CHANGELOG.json +++ b/packages/sol-cov/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "2.1.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "2.1.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "2.1.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "2.1.2", diff --git a/packages/sol-cov/CHANGELOG.md b/packages/sol-cov/CHANGELOG.md index b41dc00e66..bf48a74a48 100644 --- a/packages/sol-cov/CHANGELOG.md +++ b/packages/sol-cov/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.1.5 - _September 25, 2018_ + + * Dependencies updated + +## v2.1.4 - _September 25, 2018_ + + * Dependencies updated + +## v2.1.3 - _September 21, 2018_ + + * Dependencies updated + ## v2.1.2 - _September 5, 2018_ * Dependencies updated diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json index f51a76155c..dff24181ca 100644 --- a/packages/sol-cov/package.json +++ b/packages/sol-cov/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sol-cov", - "version": "2.1.2", + "version": "2.1.5", "engines": { "node": ">=6.12" }, @@ -41,13 +41,13 @@ }, "homepage": "https://github.com/0xProject/0x.js/packages/sol-cov/README.md", "dependencies": { - "@0xproject/dev-utils": "^1.0.7", - "@0xproject/sol-compiler": "^1.1.2", - "@0xproject/subproviders": "^2.0.2", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", - "ethereum-types": "^1.0.6", + "@0xproject/dev-utils": "^1.0.10", + "@0xproject/sol-compiler": "^1.1.5", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", + "ethereum-types": "^1.0.8", "ethereumjs-util": "^5.1.1", "glob": "^7.1.2", "istanbul": "^0.4.5", @@ -64,7 +64,7 @@ "@types/loglevel": "^1.5.3", "@types/mkdirp": "^0.5.1", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/rimraf": "^2.0.2", "@types/solidity-parser-antlr": "^0.2.0", "chai": "^4.0.1", diff --git a/packages/sol-resolver/CHANGELOG.json b/packages/sol-resolver/CHANGELOG.json index e7f5177f88..72928bbed5 100644 --- a/packages/sol-resolver/CHANGELOG.json +++ b/packages/sol-resolver/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.8", diff --git a/packages/sol-resolver/CHANGELOG.md b/packages/sol-resolver/CHANGELOG.md index c14ef93360..e2959bbaa3 100644 --- a/packages/sol-resolver/CHANGELOG.md +++ b/packages/sol-resolver/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 5, 2018_ * Dependencies updated diff --git a/packages/sol-resolver/package.json b/packages/sol-resolver/package.json index 2e0ce319c1..535749bc65 100644 --- a/packages/sol-resolver/package.json +++ b/packages/sol-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sol-resolver", - "version": "1.0.8", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -30,8 +30,8 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", "lodash": "^4.17.5" }, "publishConfig": { diff --git a/packages/sra-report/CHANGELOG.json b/packages/sra-report/CHANGELOG.json index 4d9dc80f70..8f70482439 100644 --- a/packages/sra-report/CHANGELOG.json +++ b/packages/sra-report/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.8", diff --git a/packages/sra-report/CHANGELOG.md b/packages/sra-report/CHANGELOG.md index d3c9251f3f..9a83159ba0 100644 --- a/packages/sra-report/CHANGELOG.md +++ b/packages/sra-report/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 5, 2018_ * Dependencies updated diff --git a/packages/sra-report/package.json b/packages/sra-report/package.json index 98d10be07f..6b73fb6e02 100644 --- a/packages/sra-report/package.json +++ b/packages/sra-report/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sra-report", - "version": "1.0.8", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -33,13 +33,13 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sra-report/README.md", "dependencies": { - "@0xproject/assert": "^1.0.8", + "@0xproject/assert": "^1.0.11", "@0xproject/connect": "1.0.4", "@0xproject/json-schemas": "^0.8.3", "@0xproject/order-utils": "^0.0.9", "@0xproject/types": "^0.8.2", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", "chalk": "^2.3.0", "lodash": "^4.17.5", "newman": "^3.9.3", @@ -51,7 +51,7 @@ "@types/mocha": "^2.2.48", "@types/newman": "^3.9.0", "@types/nock": "^9.1.2", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/yargs": "^10.0.0", "chai": "^4.0.1", "chai-as-promised": "^7.1.0", diff --git a/packages/sra-spec/CHANGELOG.json b/packages/sra-spec/CHANGELOG.json index 715f1a2f1a..b50b98127a 100644 --- a/packages/sra-spec/CHANGELOG.json +++ b/packages/sra-spec/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.1", diff --git a/packages/sra-spec/CHANGELOG.md b/packages/sra-spec/CHANGELOG.md index 52b99f5381..501a4cf89b 100644 --- a/packages/sra-spec/CHANGELOG.md +++ b/packages/sra-spec/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.3 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.2 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.1 - _September 5, 2018_ * Dependencies updated diff --git a/packages/sra-spec/package.json b/packages/sra-spec/package.json index 82559a0899..f16711ea08 100644 --- a/packages/sra-spec/package.json +++ b/packages/sra-spec/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sra-spec", - "version": "1.0.1", + "version": "1.0.4", "engines": { "node": ">=6.12" }, @@ -34,7 +34,7 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/sra-spec/README.md", "dependencies": { - "@0xproject/json-schemas": "^1.0.1" + "@0xproject/json-schemas": "^1.0.4" }, "devDependencies": { "@0xproject/tslint-config": "^1.0.7", diff --git a/packages/subproviders/CHANGELOG.json b/packages/subproviders/CHANGELOG.json index 0df16acf25..3cd7c20520 100644 --- a/packages/subproviders/CHANGELOG.json +++ b/packages/subproviders/CHANGELOG.json @@ -1,4 +1,31 @@ [ + { + "timestamp": 1537907159, + "version": "2.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "2.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "2.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "2.0.2", diff --git a/packages/subproviders/CHANGELOG.md b/packages/subproviders/CHANGELOG.md index db75710d70..fac8d619d2 100644 --- a/packages/subproviders/CHANGELOG.md +++ b/packages/subproviders/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.5 - _September 25, 2018_ + + * Dependencies updated + +## v2.0.4 - _September 25, 2018_ + + * Dependencies updated + +## v2.0.3 - _September 21, 2018_ + + * Dependencies updated + ## v2.0.2 - _September 5, 2018_ * Dependencies updated diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index b96166d370..d513c868bb 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/subproviders", - "version": "2.0.2", + "version": "2.0.5", "engines": { "node": ">=6.12" }, @@ -28,11 +28,11 @@ } }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/assert": "^1.0.11", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "@ledgerhq/hw-app-eth": "^4.3.0", "@ledgerhq/hw-transport-u2f": "^4.3.0", "@types/eth-lightwallet": "^3.0.0", @@ -41,7 +41,7 @@ "bip39": "^2.5.0", "bn.js": "^4.11.8", "eth-lightwallet": "^3.0.1", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-tx": "^1.3.5", "ethereumjs-util": "^5.1.1", "ganache-core": "0xProject/ganache-core#monorepo-dep", @@ -59,7 +59,7 @@ "@types/hdkey": "^0.7.0", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/sinon": "^2.2.2", "@types/web3-provider-engine": "^14.0.0", "chai": "^4.0.1", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index d4e68559fb..a25924de52 100644 --- a/packages/testnet-faucets/package.json +++ b/packages/testnet-faucets/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@0xproject/testnet-faucets", - "version": "1.0.46", + "version": "1.0.49", "engines": { "node": ">=6.12" }, @@ -17,13 +17,13 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^1.0.3", - "@0xproject/subproviders": "^2.0.2", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "0x.js": "^1.0.6", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "body-parser": "^1.17.1", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-tx": "^1.3.5", "ethereumjs-util": "^5.1.1", "express": "^4.15.2", diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index 008ff8ff4e..e076991319 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,36 @@ [ + { + "timestamp": 1537907159, + "version": "1.1.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "version": "1.1.0", + "changes": [ + { + "note": "Add ObjectMap type", + "pr": 1037 + }, + { + "note": "Add SRA types from connect", + "pr": 1085 + } + ], + "timestamp": 1537875740 + }, + { + "timestamp": 1537541580, + "version": "1.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "1.0.1", "changes": [ diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 759a93fb01..3534200812 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.1 - _September 25, 2018_ + + * Dependencies updated + +## v1.1.0 - _September 25, 2018_ + + * Add ObjectMap type (#1037) + * Add SRA types from connect (#1085) + +## v1.0.2 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.1 - _September 5, 2018_ * Add AssetProxyOwner revert reasons (#1041) diff --git a/packages/types/package.json b/packages/types/package.json index 15f0a54b45..f5d57635d0 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/types", - "version": "1.0.1", + "version": "1.1.1", "engines": { "node": ">=6.12" }, @@ -30,9 +30,9 @@ "typescript": "3.0.1" }, "dependencies": { - "@types/node": "^8.0.53", + "@types/node": "*", "bignumber.js": "~4.1.0", - "ethereum-types": "^1.0.6" + "ethereum-types": "^1.0.8" }, "publishConfig": { "access": "public" diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 48a9e23d11..5223bf2996 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -111,12 +111,14 @@ export interface OrderStateValid { isValid: true; orderHash: string; orderRelevantState: OrderRelevantState; + transactionHash?: string; } export interface OrderStateInvalid { isValid: false; orderHash: string; error: ExchangeContractErrs; + transactionHash?: string; } export type OrderState = OrderStateValid | OrderStateInvalid; @@ -239,3 +241,135 @@ export enum StatusCodes { MethodNotAllowed = 405, GatewayTimeout = 504, } + +export interface ObjectMap { + [key: string]: T; +} + +/** + * baseAssetData: The address of assetData designated as the baseToken in the currency pair calculation of price + * quoteAssetData: The address of assetData designated as the quoteToken in the currency pair calculation of price + * limit: Maximum number of bids and asks in orderbook snapshot + */ +export interface OrdersChannelSubscriptionOpts { + baseAssetData: string; + quoteAssetData: string; + limit: number; +} + +export type OrdersChannelMessage = UpdateOrdersChannelMessage | UnknownOrdersChannelMessage; + +export enum OrdersChannelMessageTypes { + Update = 'update', + Unknown = 'unknown', +} + +export interface UpdateOrdersChannelMessage { + type: OrdersChannelMessageTypes.Update; + requestId: string; + payload: APIOrder[]; +} + +export interface UnknownOrdersChannelMessage { + type: OrdersChannelMessageTypes.Unknown; + requestId: string; + payload: undefined; +} + +export enum WebsocketConnectionEventType { + Close = 'close', + Error = 'error', + Message = 'message', +} + +export enum WebsocketClientEventType { + Connect = 'connect', + ConnectFailed = 'connectFailed', +} + +export type OrdersResponse = PaginatedCollection; + +export interface APIOrder { + order: SignedOrder; + metaData: object; +} + +export interface AssetPairsRequestOpts { + assetDataA?: string; + assetDataB?: string; +} + +export type AssetPairsResponse = PaginatedCollection; + +export interface AssetPairsItem { + assetDataA: Asset; + assetDataB: Asset; +} + +export interface Asset { + assetData: string; + minAmount: BigNumber; + maxAmount: BigNumber; + precision: number; +} + +export interface OrdersRequestOpts { + makerAssetProxyId?: string; + takerAssetProxyId?: string; + makerAssetAddress?: string; + takerAssetAddress?: string; + exchangeAddress?: string; + senderAddress?: string; + makerAssetData?: string; + takerAssetData?: string; + makerAddress?: string; + takerAddress?: string; + traderAddress?: string; + feeRecipientAddress?: string; +} + +export interface OrderbookRequest { + baseAssetData: string; + quoteAssetData: string; +} + +export interface OrderbookResponse { + bids: PaginatedCollection; + asks: PaginatedCollection; +} + +export interface PaginatedCollection { + total: number; + page: number; + perPage: number; + records: T[]; +} + +export interface OrderConfigRequest { + makerAddress: string; + takerAddress: string; + makerAssetAmount: BigNumber; + takerAssetAmount: BigNumber; + makerAssetData: string; + takerAssetData: string; + exchangeAddress: string; + expirationTimeSeconds: BigNumber; +} + +export interface OrderConfigResponse { + makerFee: BigNumber; + takerFee: BigNumber; + feeRecipientAddress: string; + senderAddress: string; +} + +export type FeeRecipientsResponse = PaginatedCollection; + +export interface RequestOpts { + networkId?: number; +} + +export interface PagedRequestOpts { + page?: number; + perPage?: number; +} diff --git a/packages/typescript-typings/CHANGELOG.json b/packages/typescript-typings/CHANGELOG.json index c5aa11d77e..7ee78a4805 100644 --- a/packages/typescript-typings/CHANGELOG.json +++ b/packages/typescript-typings/CHANGELOG.json @@ -8,6 +8,24 @@ } ] }, + { + "timestamp": 1537907159, + "version": "2.0.2", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "2.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "version": "2.0.0", "changes": [ diff --git a/packages/typescript-typings/CHANGELOG.md b/packages/typescript-typings/CHANGELOG.md index e19e01509e..1be65ddece 100644 --- a/packages/typescript-typings/CHANGELOG.md +++ b/packages/typescript-typings/CHANGELOG.md @@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.2 - _September 25, 2018_ + + * Dependencies updated + +## v2.0.1 - _September 21, 2018_ + + * Dependencies updated + ## v2.0.0 - _September 5, 2018_ * Remove types for web3-provider-engine, newman, ganache-core, detect-node, eth-lightwallet (#1052) diff --git a/packages/typescript-typings/package.json b/packages/typescript-typings/package.json index 4b521d6d04..6db9b31603 100644 --- a/packages/typescript-typings/package.json +++ b/packages/typescript-typings/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/typescript-typings", - "version": "2.0.0", + "version": "2.0.2", "engines": { "node": ">=6.12" }, @@ -26,7 +26,7 @@ "@types/bn.js": "^4.11.0", "@types/react": "*", "bignumber.js": "~4.1.0", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "popper.js": "1.14.3" }, "devDependencies": { diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index 1a868d676a..b4f4389666 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -8,6 +8,33 @@ } ] }, + { + "timestamp": 1537907159, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "timestamp": 1537541580, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1536142250, "version": "1.0.8", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 2452cf42ed..60b6d1b7e1 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -5,6 +5,18 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + +## v1.0.9 - _September 21, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 5, 2018_ * Dependencies updated diff --git a/packages/utils/package.json b/packages/utils/package.json index c9e8fba837..8b9161ce7f 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/utils", - "version": "1.0.8", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -41,13 +41,13 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@types/node": "^8.0.53", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@types/node": "*", "abortcontroller-polyfill": "^1.1.9", "bignumber.js": "~4.1.0", "detect-node": "2.0.3", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-util": "^5.1.1", "ethers": "^4.0.0-beta.14", "isomorphic-fetch": "^2.2.1", diff --git a/packages/verdaccio/Dockerfile b/packages/verdaccio/Dockerfile new file mode 100644 index 0000000000..6a6a64abf5 --- /dev/null +++ b/packages/verdaccio/Dockerfile @@ -0,0 +1,3 @@ +FROM verdaccio/verdaccio + +ADD conf.yaml /verdaccio/conf/config.yaml diff --git a/packages/verdaccio/README.md b/packages/verdaccio/README.md new file mode 100644 index 0000000000..340cd55124 --- /dev/null +++ b/packages/verdaccio/README.md @@ -0,0 +1,18 @@ +## 0x Verdaccio + +This package contains a Dockerfile and conf.yaml file for configuring our own +Docker image for Verdaccio. + +See https://verdaccio.org/docs/en/configuration for more information. + +## Build + +In the root directory for _this package_, run: + +`sudo docker build . -t 0x-verdaccio` + +## Run + +To start Verdaccio run: + +`sudo docker run --rm -i -p 4873:4873 0x-verdaccio` diff --git a/packages/verdaccio/conf.yaml b/packages/verdaccio/conf.yaml new file mode 100644 index 0000000000..24e0369328 --- /dev/null +++ b/packages/verdaccio/conf.yaml @@ -0,0 +1,71 @@ +# +# Copied from https://github.com/verdaccio/verdaccio/blob/90fc216649ecd8df31d3706b5c17555fa0a35e4a/conf/docker.yaml +# Only the uplinks section has been modified. +# +# This is the config file used for the docker images. +# It allows all users to do anything, so don't use it on production systems. +# +# Do not configure host and port under `listen` in this file +# as it will be ignored when using docker. +# see https://github.com/verdaccio/verdaccio/blob/master/wiki/docker.md#docker-and-custom-port-configuration +# +# Look here for more config file examples: +# https://github.com/verdaccio/verdaccio/tree/master/conf +# + +# path to a directory with all packages +storage: /verdaccio/storage +# path to a directory with plugins to include +plugins: /verdaccio/plugins + +web: + # WebUI is enabled as default, if you want disable it, just uncomment this line + enable: false + +auth: + htpasswd: + file: /verdaccio/conf/htpasswd + # Maximum amount of users allowed to register, defaults to "+infinity". + # You can set this to -1 to disable registration. + #max_users: 1000 + +# a list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.npmjs.org/ + cache: true + max_fails: 5 + +packages: + '@*/*': + # scoped packages + access: $all + publish: $authenticated + proxy: npmjs + + '**': + # allow all users (including non-authenticated users) to read and + # publish all packages + # + # you can specify usernames/groupnames (depending on your auth plugin) + # and three keywords: "$all", "$anonymous", "$authenticated" + access: $all + + # allow all known users to publish packages + # (anyone can register by default, remember?) + publish: $authenticated + + # if package is not available locally, proxy requests to 'npmjs' registry + proxy: npmjs + +# To use `npm audit` uncomment the following section +# middlewares: +# audit: +# enabled: true + +# log settings +logs: + - {type: stdout, format: pretty, level: http} + #- {type: file, path: verdaccio.log, level: info} + +max_body_size: 100mb diff --git a/packages/web3-wrapper/CHANGELOG.json b/packages/web3-wrapper/CHANGELOG.json index 57e6f7689c..1ab2acafcb 100644 --- a/packages/web3-wrapper/CHANGELOG.json +++ b/packages/web3-wrapper/CHANGELOG.json @@ -1,4 +1,40 @@ [ + { + "timestamp": 1537907159, + "version": "3.0.1", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, + { + "version": "3.0.0", + "changes": [ + { + "note": + "Rename `getBlockAsync` to `getBlockIfExistsAsync` and rather then throw if the requested block wasn't found, return undefined.", + "pr": 1082 + }, + { + "note": + "Expose `sendRawPayloadAsync` so one can easily extend `Web3Wrapper` with their own custom JSON RPC calls", + "pr": 1080 + } + ], + "timestamp": 1537875740 + }, + { + "version": "2.0.3", + "changes": [ + { + "note": + "Fixes issue #1076 where Parity now returns a placeholder transactionReceipt before the transaction is mined.", + "pr": 1079 + } + ], + "timestamp": 1537541580 + }, { "timestamp": 1536142250, "version": "2.0.2", diff --git a/packages/web3-wrapper/CHANGELOG.md b/packages/web3-wrapper/CHANGELOG.md index 17f2b9f487..1c592d22e2 100644 --- a/packages/web3-wrapper/CHANGELOG.md +++ b/packages/web3-wrapper/CHANGELOG.md @@ -5,6 +5,19 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.0.1 - _September 25, 2018_ + + * Dependencies updated + +## v3.0.0 - _September 25, 2018_ + + * Rename `getBlockAsync` to `getBlockIfExistsAsync` and rather then throw if the requested block wasn't found, return undefined. (#1082) + * Expose `sendRawPayloadAsync` so one can easily extend `Web3Wrapper` with their own custom JSON RPC calls (#1080) + +## v2.0.3 - _September 21, 2018_ + + * Fixes issue #1076 where Parity now returns a placeholder transactionReceipt before the transaction is mined. (#1079) + ## v2.0.2 - _September 5, 2018_ * Dependencies updated diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index cad814d8d9..3193604099 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/web3-wrapper", - "version": "2.0.2", + "version": "3.0.1", "engines": { "node": ">=6.12" }, @@ -53,11 +53,11 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.8", - "@0xproject/json-schemas": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "ethereum-types": "^1.0.6", + "@0xproject/assert": "^1.0.11", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "ethereum-types": "^1.0.8", "ethereumjs-util": "^5.1.1", "ethers": "^4.0.0-beta.14", "lodash": "^4.17.5" diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts index ea78f8801c..d52c1cb6e5 100644 --- a/packages/web3-wrapper/src/web3_wrapper.ts +++ b/packages/web3-wrapper/src/web3_wrapper.ts @@ -193,7 +193,7 @@ export class Web3Wrapper { * @returns Ethereum node's version string */ public async getNodeVersionAsync(): Promise { - const nodeVersion = await this._sendRawPayloadAsync({ method: 'web3_clientVersion' }); + const nodeVersion = await this.sendRawPayloadAsync({ method: 'web3_clientVersion' }); return nodeVersion; } /** @@ -201,7 +201,7 @@ export class Web3Wrapper { * @returns The network id */ public async getNetworkIdAsync(): Promise { - const networkIdStr = await this._sendRawPayloadAsync({ method: 'net_version' }); + const networkIdStr = await this.sendRawPayloadAsync({ method: 'net_version' }); const networkId = _.parseInt(networkIdStr); return networkId; } @@ -212,7 +212,7 @@ export class Web3Wrapper { */ public async getTransactionReceiptAsync(txHash: string): Promise { assert.isHexString('txHash', txHash); - const transactionReceipt = await this._sendRawPayloadAsync({ + const transactionReceipt = await this.sendRawPayloadAsync({ method: 'eth_getTransactionReceipt', params: [txHash], }); @@ -228,7 +228,7 @@ export class Web3Wrapper { */ public async getTransactionByHashAsync(txHash: string): Promise { assert.isHexString('txHash', txHash); - const transaction = await this._sendRawPayloadAsync({ + const transaction = await this.sendRawPayloadAsync({ method: 'eth_getTransactionByHash', params: [txHash], }); @@ -247,7 +247,7 @@ export class Web3Wrapper { } const marshalledDefaultBlock = marshaller.marshalBlockParam(defaultBlock); const encodedOwner = marshaller.marshalAddress(owner); - const balanceInWei = await this._sendRawPayloadAsync({ + const balanceInWei = await this.sendRawPayloadAsync({ method: 'eth_getBalance', params: [encodedOwner, marshalledDefaultBlock], }); @@ -279,7 +279,7 @@ export class Web3Wrapper { } const marshalledDefaultBlock = marshaller.marshalBlockParam(defaultBlock); const encodedAddress = marshaller.marshalAddress(address); - const code = await this._sendRawPayloadAsync({ + const code = await this.sendRawPayloadAsync({ method: 'eth_getCode', params: [encodedAddress, marshalledDefaultBlock], }); @@ -293,7 +293,7 @@ export class Web3Wrapper { */ public async getTransactionTraceAsync(txHash: string, traceParams: TraceParams): Promise { assert.isHexString('txHash', txHash); - const trace = await this._sendRawPayloadAsync({ + const trace = await this.sendRawPayloadAsync({ method: 'debug_traceTransaction', params: [txHash, traceParams], }); @@ -308,7 +308,7 @@ export class Web3Wrapper { public async signMessageAsync(address: string, message: string): Promise { assert.isETHAddressHex('address', address); assert.isString('message', message); // TODO: Should this be stricter? Hex string? - const signData = await this._sendRawPayloadAsync({ + const signData = await this.sendRawPayloadAsync({ method: 'eth_sign', params: [address, message], }); @@ -319,7 +319,7 @@ export class Web3Wrapper { * @returns Block number */ public async getBlockNumberAsync(): Promise { - const blockNumberHex = await this._sendRawPayloadAsync({ + const blockNumberHex = await this.sendRawPayloadAsync({ method: 'eth_blockNumber', params: [], }); @@ -329,23 +329,29 @@ export class Web3Wrapper { /** * Fetch a specific Ethereum block without transaction data * @param blockParam The block you wish to fetch (blockHash, blockNumber or blockLiteral) - * @returns The requested block without transaction data + * @returns The requested block without transaction data, or undefined if block was not found + * (e.g the node isn't fully synced, there was a block re-org and the requested block was uncles, etc...) */ - public async getBlockAsync(blockParam: string | BlockParam): Promise { + public async getBlockIfExistsAsync( + blockParam: string | BlockParam, + ): Promise { Web3Wrapper._assertBlockParamOrString(blockParam); const encodedBlockParam = marshaller.marshalBlockParam(blockParam); const method = utils.isHexStrict(blockParam) ? 'eth_getBlockByHash' : 'eth_getBlockByNumber'; const shouldIncludeTransactionData = false; - const blockWithoutTransactionDataWithHexValues = await this._sendRawPayloadAsync< + const blockWithoutTransactionDataWithHexValuesOrNull = await this.sendRawPayloadAsync< BlockWithoutTransactionDataRPC >({ method, params: [encodedBlockParam, shouldIncludeTransactionData], }); - const blockWithoutTransactionData = marshaller.unmarshalIntoBlockWithoutTransactionData( - blockWithoutTransactionDataWithHexValues, - ); - return blockWithoutTransactionData; + let blockWithoutTransactionDataIfExists; + if (!_.isNull(blockWithoutTransactionDataWithHexValuesOrNull)) { + blockWithoutTransactionDataIfExists = marshaller.unmarshalIntoBlockWithoutTransactionData( + blockWithoutTransactionDataWithHexValuesOrNull, + ); + } + return blockWithoutTransactionDataIfExists; } /** * Fetch a specific Ethereum block with transaction data @@ -360,7 +366,7 @@ export class Web3Wrapper { } const method = utils.isHexStrict(blockParam) ? 'eth_getBlockByHash' : 'eth_getBlockByNumber'; const shouldIncludeTransactionData = true; - const blockWithTransactionDataWithHexValues = await this._sendRawPayloadAsync({ + const blockWithTransactionDataWithHexValues = await this.sendRawPayloadAsync({ method, params: [encodedBlockParam, shouldIncludeTransactionData], }); @@ -376,15 +382,18 @@ export class Web3Wrapper { */ public async getBlockTimestampAsync(blockParam: string | BlockParam): Promise { Web3Wrapper._assertBlockParamOrString(blockParam); - const { timestamp } = await this.getBlockAsync(blockParam); - return timestamp; + const blockIfExists = await this.getBlockIfExistsAsync(blockParam); + if (_.isUndefined(blockIfExists)) { + throw new Error(`Failed to fetch block with blockParam: ${JSON.stringify(blockParam)}`); + } + return blockIfExists.timestamp; } /** * Retrieve the user addresses available through the backing provider * @returns Available user addresses */ public async getAvailableAddressesAsync(): Promise { - const addresses = await this._sendRawPayloadAsync({ + const addresses = await this.sendRawPayloadAsync({ method: 'eth_accounts', params: [], }); @@ -396,7 +405,7 @@ export class Web3Wrapper { * @returns The snapshot id. This can be used to revert to this snapshot */ public async takeSnapshotAsync(): Promise { - const snapshotId = Number(await this._sendRawPayloadAsync({ method: 'evm_snapshot', params: [] })); + const snapshotId = Number(await this.sendRawPayloadAsync({ method: 'evm_snapshot', params: [] })); return snapshotId; } /** @@ -406,14 +415,14 @@ export class Web3Wrapper { */ public async revertSnapshotAsync(snapshotId: number): Promise { assert.isNumber('snapshotId', snapshotId); - const didRevert = await this._sendRawPayloadAsync({ method: 'evm_revert', params: [snapshotId] }); + const didRevert = await this.sendRawPayloadAsync({ method: 'evm_revert', params: [snapshotId] }); return didRevert; } /** * Mine a block on a TestRPC/Ganache local node */ public async mineBlockAsync(): Promise { - await this._sendRawPayloadAsync({ method: 'evm_mine', params: [] }); + await this.sendRawPayloadAsync({ method: 'evm_mine', params: [] }); } /** * Increase the next blocks timestamp on TestRPC/Ganache or Geth local node. @@ -425,9 +434,9 @@ export class Web3Wrapper { // Detect Geth vs. Ganache and use appropriate endpoint. const version = await this.getNodeVersionAsync(); if (_.includes(version, uniqueVersionIds.geth)) { - return this._sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); + return this.sendRawPayloadAsync({ method: 'debug_increaseTime', params: [timeDelta] }); } else if (_.includes(version, uniqueVersionIds.ganache)) { - return this._sendRawPayloadAsync({ method: 'evm_increaseTime', params: [timeDelta] }); + return this.sendRawPayloadAsync({ method: 'evm_increaseTime', params: [timeDelta] }); } else { throw new Error(`Unknown client version: ${version}`); } @@ -438,6 +447,12 @@ export class Web3Wrapper { * @returns The corresponding log entries */ public async getLogsAsync(filter: FilterObject): Promise { + if (!_.isUndefined(filter.blockHash) && (!_.isUndefined(filter.fromBlock) || !_.isUndefined(filter.toBlock))) { + throw new Error( + `Cannot specify 'blockHash' as well as 'fromBlock'/'toBlock' in the filter supplied to 'getLogsAsync'`, + ); + } + let fromBlock = filter.fromBlock; if (_.isNumber(fromBlock)) { fromBlock = utils.numberToHex(fromBlock); @@ -455,7 +470,7 @@ export class Web3Wrapper { method: 'eth_getLogs', params: [serializedFilter], }; - const rawLogs = await this._sendRawPayloadAsync(payload); + const rawLogs = await this.sendRawPayloadAsync(payload); const formattedLogs = _.map(rawLogs, marshaller.unmarshalLog.bind(marshaller)); return formattedLogs; } @@ -471,7 +486,7 @@ export class Web3Wrapper { schemas.jsNumber, ]); const txDataHex = marshaller.marshalTxData(txData); - const gasHex = await this._sendRawPayloadAsync({ method: 'eth_estimateGas', params: [txDataHex] }); + const gasHex = await this.sendRawPayloadAsync({ method: 'eth_estimateGas', params: [txDataHex] }); const gas = utils.convertHexToNumber(gasHex); return gas; } @@ -492,7 +507,7 @@ export class Web3Wrapper { } const marshalledDefaultBlock = marshaller.marshalBlockParam(defaultBlock); const callDataHex = marshaller.marshalCallData(callData); - const rawCallResult = await this._sendRawPayloadAsync({ + const rawCallResult = await this.sendRawPayloadAsync({ method: 'eth_call', params: [callDataHex, marshalledDefaultBlock], }); @@ -513,7 +528,7 @@ export class Web3Wrapper { schemas.jsNumber, ]); const txDataHex = marshaller.marshalTxData(txData); - const txHash = await this._sendRawPayloadAsync({ method: 'eth_sendTransaction', params: [txDataHex] }); + const txHash = await this.sendRawPayloadAsync({ method: 'eth_sendTransaction', params: [txDataHex] }); return txHash; } /** @@ -539,7 +554,7 @@ export class Web3Wrapper { } // Immediately check if the transaction has already been mined. let transactionReceipt = await this.getTransactionReceiptAsync(txHash); - if (!_.isNull(transactionReceipt)) { + if (!_.isNull(transactionReceipt) && !_.isNull(transactionReceipt.blockNumber)) { const logsWithDecodedArgs = _.map( transactionReceipt.logs, this.abiDecoder.tryToDecodeLogOrNoop.bind(this.abiDecoder), @@ -623,7 +638,24 @@ export class Web3Wrapper { */ public async setHeadAsync(blockNumber: number): Promise { assert.isNumber('blockNumber', blockNumber); - await this._sendRawPayloadAsync({ method: 'debug_setHead', params: [utils.numberToHex(blockNumber)] }); + await this.sendRawPayloadAsync({ method: 'debug_setHead', params: [utils.numberToHex(blockNumber)] }); + } + /** + * Sends a raw Ethereum JSON RPC payload and returns the response's `result` key + * @param payload A partial JSON RPC payload. No need to include version, id, params (if none needed) + * @return The contents nested under the result key of the response body + */ + public async sendRawPayloadAsync(payload: Partial): Promise { + const sendAsync = this._provider.sendAsync.bind(this._provider); + const payloadWithDefaults = { + id: this._jsonRpcRequestId++, + params: [], + jsonrpc: '2.0', + ...payload, + }; + const response = await promisify(sendAsync)(payloadWithDefaults); + const result = response.result; + return result; } /** * Returns either NodeType.Geth or NodeType.Ganache depending on the type of @@ -639,16 +671,4 @@ export class Web3Wrapper { throw new Error(`Unknown client version: ${version}`); } } - private async _sendRawPayloadAsync(payload: Partial): Promise { - const sendAsync = this._provider.sendAsync.bind(this._provider); - const payloadWithDefaults = { - id: this._jsonRpcRequestId++, - params: [], - jsonrpc: '2.0', - ...payload, - }; - const response = await promisify(sendAsync)(payloadWithDefaults); - const result = response.result; - return result; - } } // tslint:disable-line:max-file-line-count diff --git a/packages/web3-wrapper/test/web3_wrapper_test.ts b/packages/web3-wrapper/test/web3_wrapper_test.ts index b4fd8bb443..385c469bfa 100644 --- a/packages/web3-wrapper/test/web3_wrapper_test.ts +++ b/packages/web3-wrapper/test/web3_wrapper_test.ts @@ -85,28 +85,40 @@ describe('Web3Wrapper tests', () => { expect(typeof blockNumber).to.be.equal('number'); }); }); - describe('#getBlockAsync', () => { + describe('#getBlockIfExistsAsync', () => { it('gets block when supplied a valid BlockParamLiteral value', async () => { const blockParamLiteral = BlockParamLiteral.Earliest; - const block = await web3Wrapper.getBlockAsync(blockParamLiteral); - expect(block.number).to.be.equal(0); - expect(utils.isBigNumber(block.difficulty)).to.equal(true); - expect(_.isNumber(block.gasLimit)).to.equal(true); + const blockIfExists = await web3Wrapper.getBlockIfExistsAsync(blockParamLiteral); + if (_.isUndefined(blockIfExists)) { + throw new Error('Expected block to exist'); + } + expect(blockIfExists.number).to.be.equal(0); + expect(utils.isBigNumber(blockIfExists.difficulty)).to.equal(true); + expect(_.isNumber(blockIfExists.gasLimit)).to.equal(true); }); it('gets block when supplied a block number', async () => { const blockParamLiteral = 0; - const block = await web3Wrapper.getBlockAsync(blockParamLiteral); - expect(block.number).to.be.equal(0); + const blockIfExists = await web3Wrapper.getBlockIfExistsAsync(blockParamLiteral); + if (_.isUndefined(blockIfExists)) { + throw new Error('Expected block to exist'); + } + expect(blockIfExists.number).to.be.equal(0); }); it('gets block when supplied a block hash', async () => { const blockParamLiteral = 0; - const block = await web3Wrapper.getBlockAsync(blockParamLiteral); - const sameBlock = await web3Wrapper.getBlockAsync(block.hash as string); - expect(sameBlock.number).to.be.equal(0); + const blockIfExists = await web3Wrapper.getBlockIfExistsAsync(blockParamLiteral); + if (_.isUndefined(blockIfExists)) { + throw new Error('Expected block to exist'); + } + const sameBlockIfExists = await web3Wrapper.getBlockIfExistsAsync(blockIfExists.hash as string); + if (_.isUndefined(sameBlockIfExists)) { + throw new Error('Expected block to exist'); + } + expect(sameBlockIfExists.number).to.be.equal(0); }); it('should throw if supplied invalid blockParam value', async () => { const invalidBlockParam = 'deadbeef'; - expect(web3Wrapper.getBlockAsync(invalidBlockParam)).to.eventually.to.be.rejected(); + expect(web3Wrapper.getBlockIfExistsAsync(invalidBlockParam)).to.eventually.to.be.rejected(); }); }); describe('#getBlockWithTransactionDataAsync', () => { diff --git a/packages/website/package.json b/packages/website/package.json index 911a4ccba0..6adbbede0a 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/website", - "version": "0.0.49", + "version": "0.0.52", "engines": { "node": ">=6.12" }, @@ -19,21 +19,22 @@ "license": "Apache-2.0", "dependencies": { "0x.js": "^0.38.6", - "@0xproject/contract-wrappers": "^1.0.3", - "@0xproject/order-utils": "^1.0.2", - "@0xproject/react-docs": "^1.0.8", - "@0xproject/react-shared": "^1.0.9", - "@0xproject/subproviders": "^2.0.2", - "@0xproject/types": "^1.0.1", - "@0xproject/typescript-typings": "^2.0.0", - "@0xproject/utils": "^1.0.8", - "@0xproject/web3-wrapper": "^2.0.2", + "@0xproject/contract-wrappers": "^2.0.0", + "@0xproject/json-schemas": "^1.0.4", + "@0xproject/order-utils": "^1.0.5", + "@0xproject/react-docs": "^1.0.11", + "@0xproject/react-shared": "^1.0.12", + "@0xproject/subproviders": "^2.0.5", + "@0xproject/types": "^1.1.1", + "@0xproject/typescript-typings": "^2.0.2", + "@0xproject/utils": "^1.0.11", + "@0xproject/web3-wrapper": "^3.0.1", "accounting": "^0.4.1", "basscss": "^8.0.3", "blockies": "^0.0.2", "bowser": "^1.9.3", "deep-equal": "^1.0.1", - "ethereum-types": "^1.0.6", + "ethereum-types": "^1.0.8", "ethereumjs-util": "^5.1.1", "find-versions": "^2.0.0", "jsonschema": "^1.2.0", @@ -72,7 +73,7 @@ "@types/jsonschema": "^1.1.1", "@types/lodash": "4.14.104", "@types/material-ui": "^0.20.0", - "@types/node": "^8.0.53", + "@types/node": "*", "@types/numeral": "^0.0.22", "@types/query-string": "^5.1.0", "@types/react": "^16.4.2", diff --git a/packages/website/public/images/team/rahul.png b/packages/website/public/images/team/rahul.png new file mode 100644 index 0000000000..b63cc12b1a Binary files /dev/null and b/packages/website/public/images/team/rahul.png differ diff --git a/packages/website/public/images/team/weijie.png b/packages/website/public/images/team/weijie.png new file mode 100644 index 0000000000..69fd517943 Binary files /dev/null and b/packages/website/public/images/team/weijie.png differ diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index d3f2f3f7b8..632a630162 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -228,7 +228,7 @@ export class Blockchain { const tokenSymbolToAddressOverrides = tokenAddressOverrides[this.networkId]; let isTokenAddressInOverrides = false; if (!_.isUndefined(tokenSymbolToAddressOverrides)) { - isTokenAddressInOverrides = _.keys(tokenSymbolToAddressOverrides).includes(tokenAddress); + isTokenAddressInOverrides = _.values(tokenSymbolToAddressOverrides).includes(tokenAddress); } return !_.isUndefined(tokenIfExists) || isTokenAddressInOverrides; } diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx index 93ef516cfc..db093fb68c 100644 --- a/packages/website/ts/components/inputs/token_amount_input.tsx +++ b/packages/website/ts/components/inputs/token_amount_input.tsx @@ -111,7 +111,7 @@ export class TokenAmountInput extends React.Component Insufficient allowance.{' '} Set allowance diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx index 42237bec31..75295349db 100644 --- a/packages/website/ts/pages/about/about.tsx +++ b/packages/website/ts/pages/about/about.tsx @@ -216,6 +216,23 @@ const teamRow7: ProfileInfo[] = [ }, ]; +const teamRow8: ProfileInfo[] = [ + { + name: 'Weijie Wu', + title: 'Research Fellow', + description: `Researching decentralized governance. Previously Researcher at Huawei and Assistant Professor at Shanghai Jiao Tong University. PhD in Computer Science at The Chinese University of Hong Kong.`, + image: 'images/team/weijie.png', + linkedIn: 'https://www.linkedin.com/in/weijiewu/', + }, + { + name: 'Rahul Singireddy', + title: 'Relayer Success Manager', + description: `Previously community at Zeppelin, growth at Dharma, and cryptocurrency contributor at Forbes. Symbolic Systems at Stanford.`, + image: 'images/team/rahul.png', + linkedIn: 'https://www.linkedin.com/in/rahul-singireddy-3037908a/', + }, +]; + const advisors1: ProfileInfo[] = [ { name: 'Fred Ehrsam', @@ -323,6 +340,7 @@ export class About extends React.Component {
{this._renderProfiles(teamRow5)}
{this._renderProfiles(teamRow6)}
{this._renderProfiles(teamRow7)}
+
{this._renderProfiles(teamRow8)}
= ObjectMap; -export interface ObjectMap { - [key: string]: T; -} - export type TokenStateByAddress = ItemByAddress; export interface TokenState { diff --git a/packages/website/ts/utils/analytics.ts b/packages/website/ts/utils/analytics.ts index 62dbff2b95..3aae317b03 100644 --- a/packages/website/ts/utils/analytics.ts +++ b/packages/website/ts/utils/analytics.ts @@ -1,6 +1,7 @@ import { assetDataUtils } from '@0xproject/order-utils'; +import { ObjectMap } from '@0xproject/types'; import * as _ from 'lodash'; -import { ObjectMap, PortalOrder } from 'ts/types'; +import { PortalOrder } from 'ts/types'; import { utils } from 'ts/utils/utils'; export interface HeapAnalytics { diff --git a/packages/website/ts/utils/token_address_overrides.ts b/packages/website/ts/utils/token_address_overrides.ts index 8353358bc3..e7e9162737 100644 --- a/packages/website/ts/utils/token_address_overrides.ts +++ b/packages/website/ts/utils/token_address_overrides.ts @@ -1,4 +1,4 @@ -import { ObjectMap } from 'ts/types'; +import { ObjectMap } from '@0xproject/types'; import { constants } from 'ts/utils/constants'; // Map of networkId -> tokenSymbol -> tokenAddress diff --git a/tsconfig.json b/tsconfig.json index a931b28b9f..bc71dfb703 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,7 @@ { "path": "./packages/0x.js" }, { "path": "./packages/abi-gen" }, { "path": "./packages/assert" }, + { "path": "./packages/asset-buyer" }, { "path": "./packages/base-contract" }, { "path": "./packages/connect" }, { "path": "./packages/contract-wrappers" }, @@ -30,7 +31,6 @@ { "path": "./packages/dev-utils" }, { "path": "./packages/ethereum-types" }, { "path": "./packages/fill-scenarios" }, - { "path": "./packages/forwarder-helper" }, { "path": "./packages/json-schemas" }, { "path": "./packages/metacoin" }, { "path": "./packages/migrations" }, diff --git a/yarn.lock b/yarn.lock index 16648eb790..19dd0c86e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1360,9 +1360,9 @@ aes-js@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" -aes-js@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" +aes-js@^0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" ajv-keywords@^2.1.0: version "2.1.1" @@ -2428,6 +2428,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base-x@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-1.1.0.tgz#42d3d717474f9ea02207f6d1aa1f426913eeb7ac" + base-x@^3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77" @@ -2839,7 +2843,7 @@ browserslist@^2.1.2: caniuse-lite "^1.0.30000792" electron-to-chromium "^1.3.30" -bs58@=4.0.1, bs58@^4.0.0: +bs58@=4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" dependencies: @@ -2849,13 +2853,18 @@ bs58@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" +bs58@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-3.1.0.tgz#d4c26388bf4804cac714141b1945aa47e5eb248e" dependencies: - bs58 "^4.0.0" + base-x "^1.1.0" + +bs58check@^1.0.8: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-1.3.4.tgz#c52540073749117714fa042c3047eb8f9151cbf8" + dependencies: + bs58 "^3.1.0" create-hash "^1.1.0" - safe-buffer "^5.1.2" btoa@1.1.2: version "1.1.2" @@ -5207,6 +5216,14 @@ ethereumjs-blockstream@5.0.0: source-map-support "0.5.6" uuid "3.2.1" +ethereumjs-blockstream@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/ethereumjs-blockstream/-/ethereumjs-blockstream-6.0.0.tgz#79d726d1f358935eb65195e91d40344c31e87eff" + dependencies: + immutable "3.8.2" + source-map-support "0.5.6" + uuid "3.2.1" + ethereumjs-tx@0xProject/ethereumjs-tx#fake-tx-include-signature-by-default: version "1.3.4" resolved "https://codeload.github.com/0xProject/ethereumjs-tx/tar.gz/29d1153889c389591f74b2401da8a0c6ad40f9a7" @@ -5233,7 +5250,7 @@ ethereumjs-util@5.1.5, ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumj safe-buffer "^5.1.1" secp256k1 "^3.0.1" -ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0: +ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz#3e9428b317eebda3d7260d854fddda954b1f1bc6" dependencies: @@ -5287,18 +5304,17 @@ ethereumjs-vm@^2.0.2, ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4: rustbn.js "~0.1.1" safe-buffer "^5.1.1" -ethereumjs-wallet@~0.6.0: - version "0.6.2" - resolved "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" +ethereumjs-wallet@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz#82763b1697ee7a796be7155da9dfb49b2f98cfdb" dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereumjs-util "^5.2.0" - hdkey "^1.0.0" - safe-buffer "^5.1.2" + aes-js "^0.2.3" + bs58check "^1.0.8" + ethereumjs-util "^4.4.0" + hdkey "^0.7.0" scrypt.js "^0.2.0" - utf8 "^3.0.0" - uuid "^3.3.2" + utf8 "^2.1.1" + uuid "^2.0.1" ethers@3.0.22: version "3.0.22" @@ -6072,7 +6088,7 @@ ganache-core@0xProject/ganache-core#monorepo-dep: ethereumjs-tx "0xProject/ethereumjs-tx#fake-tx-include-signature-by-default" ethereumjs-util "^5.2.0" ethereumjs-vm "2.3.5" - ethereumjs-wallet "~0.6.0" + ethereumjs-wallet "0.6.0" fake-merkle-patricia-tree "~1.0.1" heap "~0.2.6" js-scrypt "^0.2.0" @@ -6754,21 +6770,13 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -hdkey@^0.7.1: +hdkey@^0.7.0, hdkey@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-0.7.1.tgz#caee4be81aa77921e909b8d228dd0f29acaee632" dependencies: coinstring "^2.0.0" secp256k1 "^3.0.1" -hdkey@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" - dependencies: - coinstring "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -14261,10 +14269,6 @@ utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" -utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"