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/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json index 391c5fa17d..38966a0b73 100644 --- a/packages/0x.js/CHANGELOG.json +++ b/packages/0x.js/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.4", diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md index 7031425ab2..d881cd825c 100644 --- a/packages/0x.js/CHANGELOG.md +++ b/packages/0x.js/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.4 - _September 21, 2018_ * Dependencies updated diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json index c92e24c520..d53571dbfe 100644 --- a/packages/0x.js/package.json +++ b/packages/0x.js/package.json @@ -1,6 +1,6 @@ { "name": "0x.js", - "version": "1.0.4", + "version": "1.0.5", "engines": { "node": ">=6.12" }, @@ -41,9 +41,9 @@ }, "license": "Apache-2.0", "devDependencies": { - "@0xproject/abi-gen": "^1.0.9", - "@0xproject/dev-utils": "^1.0.8", - "@0xproject/migrations": "^1.0.10", + "@0xproject/abi-gen": "^1.0.10", + "@0xproject/dev-utils": "^1.0.9", + "@0xproject/migrations": "^1.0.11", "@0xproject/monorepo-scripts": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "4.14.104", @@ -73,16 +73,16 @@ "webpack": "^3.1.0" }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/base-contract": "^2.0.3", - "@0xproject/contract-wrappers": "^1.0.4", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/order-watcher": "^1.0.4", - "@0xproject/subproviders": "^2.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/contract-wrappers": "^1.0.5", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/order-watcher": "^1.0.5", + "@0xproject/subproviders": "^2.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", "ethers": "3.0.22", "lodash": "^4.17.5", diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json index 2ecacb05d6..18aed8716a 100644 --- a/packages/abi-gen/CHANGELOG.json +++ b/packages/abi-gen/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.9", diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md index 88ab428641..99fc44f0cb 100644 --- a/packages/abi-gen/CHANGELOG.md +++ b/packages/abi-gen/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 21, 2018_ * Dependencies updated diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json index 6b8581ef3e..1fb697299f 100644 --- a/packages/abi-gen/package.json +++ b/packages/abi-gen/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/abi-gen", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, @@ -31,7 +31,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md", "dependencies": { "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", + "@0xproject/utils": "^1.0.10", "chalk": "^2.3.0", "ethereum-types": "^1.0.7", "glob": "^7.1.2", diff --git a/packages/assert/CHANGELOG.json b/packages/assert/CHANGELOG.json index 8a9b6afd65..851ba6c045 100644 --- a/packages/assert/CHANGELOG.json +++ b/packages/assert/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.9", diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md index d394413387..26760306e0 100644 --- a/packages/assert/CHANGELOG.md +++ b/packages/assert/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 21, 2018_ * Dependencies updated diff --git a/packages/assert/package.json b/packages/assert/package.json index 629cb23e55..ee510d14f5 100644 --- a/packages/assert/package.json +++ b/packages/assert/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/assert", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, @@ -44,9 +44,9 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/json-schemas": "^1.0.2", + "@0xproject/json-schemas": "^1.0.3", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", + "@0xproject/utils": "^1.0.10", "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..50b965f2de --- /dev/null +++ b/packages/asset-buyer/CHANGELOG.json @@ -0,0 +1,19 @@ +[ + { + "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..b27795d187 --- /dev/null +++ b/packages/asset-buyer/CHANGELOG.md @@ -0,0 +1,14 @@ + + +CHANGELOG + +## 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 77% rename from packages/forwarder-helper/package.json rename to packages/asset-buyer/package.json index a76e5c990e..d15213e0b4 100644 --- a/packages/forwarder-helper/package.json +++ b/packages/asset-buyer/package.json @@ -1,10 +1,10 @@ { - "name": "@0xproject/forwarder-helper", - "version": "1.0.4", + "name": "@0xproject/asset-buyer", + "version": "1.0.0", "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.9", - "@0xproject/json-schemas": "^1.0.2", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/connect": "^2.0.3", + "@0xproject/contract-wrappers": "^1.0.5", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/subproviders": "^2.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@types/node": "*", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", + "ethereum-types": "^1.0.6", "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 723963f87d..5f94afa43e 100644 --- a/packages/base-contract/CHANGELOG.json +++ b/packages/base-contract/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "2.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "2.0.3", diff --git a/packages/base-contract/CHANGELOG.md b/packages/base-contract/CHANGELOG.md index c4ba59e26b..b3f3b5619a 100644 --- a/packages/base-contract/CHANGELOG.md +++ b/packages/base-contract/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.4 - _September 25, 2018_ + + * Dependencies updated + ## v2.0.3 - _September 21, 2018_ * Dependencies updated diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json index 44b0807ba8..cd7f291140 100644 --- a/packages/base-contract/package.json +++ b/packages/base-contract/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/base-contract", - "version": "2.0.3", + "version": "2.0.4", "engines": { "node": ">=6.12" }, @@ -41,8 +41,8 @@ }, "dependencies": { "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", "ethers": "3.0.22", "lodash": "^4.17.5" diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json index f5ca802791..d4c501eb19 100644 --- a/packages/connect/CHANGELOG.json +++ b/packages/connect/CHANGELOG.json @@ -1,4 +1,14 @@ [ + { + "version": "2.0.3", + "changes": [ + { + "note": "Import SRA-related types from @0xproject/types", + "pr": 1085 + } + ], + "timestamp": 1537875740 + }, { "timestamp": 1537541580, "version": "2.0.2", diff --git a/packages/connect/CHANGELOG.md b/packages/connect/CHANGELOG.md index 1f8116f887..2c2483cb66 100644 --- a/packages/connect/CHANGELOG.md +++ b/packages/connect/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.3 - _September 25, 2018_ + + * Import SRA-related types from @0xproject/types (#1085) + ## v2.0.2 - _September 21, 2018_ * Dependencies updated diff --git a/packages/connect/package.json b/packages/connect/package.json index 1575afe01e..075089fd2a 100644 --- a/packages/connect/package.json +++ b/packages/connect/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/connect", - "version": "2.0.2", + "version": "2.0.3", "engines": { "node": ">=6.12" }, @@ -43,12 +43,12 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md", "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/json-schemas": "^1.0.2", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", + "@0xproject/utils": "^1.0.10", "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 9ee8124260..d3e0ad5d1c 100644 --- a/packages/contract-wrappers/CHANGELOG.json +++ b/packages/contract-wrappers/CHANGELOG.json @@ -14,6 +14,15 @@ } ] }, + { + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537875740 + }, { "version": "1.0.4", "changes": [ diff --git a/packages/contract-wrappers/CHANGELOG.md b/packages/contract-wrappers/CHANGELOG.md index 3757bd6ba5..98de9c7f2c 100644 --- a/packages/contract-wrappers/CHANGELOG.md +++ b/packages/contract-wrappers/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.4 - _September 21, 2018_ * Dependencies updated diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json index 8f60759f6f..57f994ff1c 100644 --- a/packages/contract-wrappers/package.json +++ b/packages/contract-wrappers/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/contract-wrappers", - "version": "1.0.4", + "version": "1.0.5", "description": "Smart TS wrappers for 0x smart contracts", "keywords": [ "0xproject", @@ -41,10 +41,10 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^1.0.9", - "@0xproject/dev-utils": "^1.0.8", - "@0xproject/migrations": "^1.0.10", - "@0xproject/subproviders": "^2.0.3", + "@0xproject/abi-gen": "^1.0.10", + "@0xproject/dev-utils": "^1.0.9", + "@0xproject/migrations": "^1.0.11", + "@0xproject/subproviders": "^2.0.4", "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "4.14.104", "@types/mocha": "^2.2.42", @@ -72,15 +72,15 @@ "web3-provider-engine": "14.0.6" }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/base-contract": "^2.0.3", - "@0xproject/fill-scenarios": "^1.0.3", - "@0xproject/json-schemas": "^1.0.2", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/fill-scenarios": "^1.0.4", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", "ethereumjs-blockstream": "6.0.0", "ethereumjs-util": "^5.1.1", 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/contracts/package.json b/packages/contracts/package.json index 63de510b10..6a7a7c208c 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "contracts", - "version": "2.1.45", + "version": "2.1.46", "engines": { "node": ">=6.12" }, @@ -45,11 +45,11 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/contracts/README.md", "devDependencies": { - "@0xproject/abi-gen": "^1.0.9", - "@0xproject/dev-utils": "^1.0.8", - "@0xproject/sol-compiler": "^1.1.3", - "@0xproject/sol-cov": "^2.1.3", - "@0xproject/subproviders": "^2.0.3", + "@0xproject/abi-gen": "^1.0.10", + "@0xproject/dev-utils": "^1.0.9", + "@0xproject/sol-compiler": "^1.1.4", + "@0xproject/sol-cov": "^2.1.4", + "@0xproject/subproviders": "^2.0.4", "@0xproject/tslint-config": "^1.0.7", "@types/bn.js": "^4.11.0", "@types/ethereumjs-abi": "^0.6.0", @@ -72,12 +72,12 @@ "yargs": "^10.0.3" }, "dependencies": { - "@0xproject/base-contract": "^2.0.3", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "@types/js-combinatorics": "^0.5.29", "bn.js": "^4.11.8", "ethereum-types": "^1.0.7", diff --git a/packages/dev-utils/CHANGELOG.json b/packages/dev-utils/CHANGELOG.json index e834eb1a37..bd4f280ba5 100644 --- a/packages/dev-utils/CHANGELOG.json +++ b/packages/dev-utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.9", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.8", diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 34f29418bc..a362330c25 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.9 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.8 - _September 21, 2018_ * Dependencies updated diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 3ded87c059..c45581e45e 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/dev-utils", - "version": "1.0.8", + "version": "1.0.9", "engines": { "node": ">=6.12" }, @@ -42,11 +42,11 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/subproviders": "^2.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/subproviders": "^2.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", "lodash": "^4.17.5" }, diff --git a/packages/fill-scenarios/CHANGELOG.json b/packages/fill-scenarios/CHANGELOG.json index e378c7cf06..3023a43c5b 100644 --- a/packages/fill-scenarios/CHANGELOG.json +++ b/packages/fill-scenarios/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.3", diff --git a/packages/fill-scenarios/CHANGELOG.md b/packages/fill-scenarios/CHANGELOG.md index 16fbb4f345..4fb3f3c541 100644 --- a/packages/fill-scenarios/CHANGELOG.md +++ b/packages/fill-scenarios/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.4 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.3 - _September 21, 2018_ * Dependencies updated diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json index 474618a14a..857ec496fd 100644 --- a/packages/fill-scenarios/package.json +++ b/packages/fill-scenarios/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/fill-scenarios", - "version": "1.0.3", + "version": "1.0.4", "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.9", + "@0xproject/abi-gen": "^1.0.10", "@0xproject/tslint-config": "^1.0.7", "@types/lodash": "4.14.104", "copyfiles": "^2.0.0", @@ -37,12 +37,12 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/base-contract": "^2.0.3", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", "ethers": "3.0.22", "lodash": "^4.17.5" diff --git a/packages/forwarder-helper/CHANGELOG.json b/packages/forwarder-helper/CHANGELOG.json deleted file mode 100644 index 084811c264..0000000000 --- a/packages/forwarder-helper/CHANGELOG.json +++ /dev/null @@ -1,57 +0,0 @@ -[ - { - "timestamp": 1537541580, - "version": "1.0.4", - "changes": [ - { - "note": "Dependencies updated" - } - ] - }, - { - "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 338d03d54c..0000000000 --- a/packages/forwarder-helper/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ - - -CHANGELOG - -## v1.0.4 - _September 21, 2018_ - - * Dependencies updated - -## 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 e3308f98b4..afe8c6f55f 100644 --- a/packages/json-schemas/CHANGELOG.json +++ b/packages/json-schemas/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.2", diff --git a/packages/json-schemas/CHANGELOG.md b/packages/json-schemas/CHANGELOG.md index 0817874ba3..dc9a69a3cf 100644 --- a/packages/json-schemas/CHANGELOG.md +++ b/packages/json-schemas/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.3 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.2 - _September 21, 2018_ * Dependencies updated diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json index 3d5399d2ad..7dfdb10661 100644 --- a/packages/json-schemas/package.json +++ b/packages/json-schemas/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/json-schemas", - "version": "1.0.2", + "version": "1.0.3", "engines": { "node": ">=6.12" }, @@ -45,7 +45,7 @@ }, "devDependencies": { "@0xproject/tslint-config": "^1.0.7", - "@0xproject/utils": "^1.0.9", + "@0xproject/utils": "^1.0.10", "@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 9824da332f..924408d530 100644 --- a/packages/metacoin/package.json +++ b/packages/metacoin/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/metacoin", - "version": "0.0.19", + "version": "0.0.20", "engines": { "node": ">=6.12" }, @@ -28,15 +28,15 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "@0xproject/abi-gen": "^1.0.9", - "@0xproject/base-contract": "^2.0.3", - "@0xproject/sol-cov": "^2.1.3", - "@0xproject/subproviders": "^2.0.3", + "@0xproject/abi-gen": "^1.0.10", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/sol-cov": "^2.1.4", + "@0xproject/subproviders": "^2.0.4", "@0xproject/tslint-config": "^1.0.7", - "@0xproject/types": "^1.0.2", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "@types/mocha": "^5.2.2", "copyfiles": "^2.0.0", "ethereum-types": "^1.0.7", @@ -45,8 +45,8 @@ "run-s": "^0.0.0" }, "devDependencies": { - "@0xproject/dev-utils": "^1.0.8", - "@0xproject/sol-compiler": "^1.1.3", + "@0xproject/dev-utils": "^1.0.9", + "@0xproject/sol-compiler": "^1.1.4", "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 a25de1a77f..1c8418818b 100644 --- a/packages/migrations/CHANGELOG.json +++ b/packages/migrations/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.10", diff --git a/packages/migrations/CHANGELOG.md b/packages/migrations/CHANGELOG.md index 2a6aeb96d4..80038bebb3 100644 --- a/packages/migrations/CHANGELOG.md +++ b/packages/migrations/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.10 - _September 21, 2018_ * Dependencies updated diff --git a/packages/migrations/package.json b/packages/migrations/package.json index 1229c78dc1..f44a254ed9 100644 --- a/packages/migrations/package.json +++ b/packages/migrations/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/migrations", - "version": "1.0.10", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -30,10 +30,10 @@ }, "license": "Apache-2.0", "devDependencies": { - "@0xproject/abi-gen": "^1.0.9", - "@0xproject/dev-utils": "^1.0.8", + "@0xproject/abi-gen": "^1.0.10", + "@0xproject/dev-utils": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", - "@0xproject/types": "^1.0.2", + "@0xproject/types": "^1.1.0", "@types/yargs": "^10.0.0", "copyfiles": "^2.0.0", "make-promises-safe": "^1.1.0", @@ -44,13 +44,13 @@ "yargs": "^10.0.3" }, "dependencies": { - "@0xproject/base-contract": "^2.0.3", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/sol-compiler": "^1.1.3", - "@0xproject/subproviders": "^2.0.3", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/sol-compiler": "^1.1.4", + "@0xproject/subproviders": "^2.0.4", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "@ledgerhq/hw-app-eth": "^4.3.0", "ethereum-types": "^1.0.7", "ethers": "3.0.22", diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json index 5bf538c1f4..d6742df2e6 100644 --- a/packages/order-utils/CHANGELOG.json +++ b/packages/order-utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.3", diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md index e35867fa6f..67e5a54a6c 100644 --- a/packages/order-utils/CHANGELOG.md +++ b/packages/order-utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.4 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.3 - _September 21, 2018_ * Dependencies updated diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json index c9620bffac..167d32608c 100644 --- a/packages/order-utils/package.json +++ b/packages/order-utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-utils", - "version": "1.0.3", + "version": "1.0.4", "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.8", + "@0xproject/dev-utils": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", "@types/bn.js": "^4.11.0", "@types/lodash": "4.14.104", @@ -57,13 +57,13 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/base-contract": "^2.0.3", - "@0xproject/json-schemas": "^1.0.2", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "@types/node": "*", "bn.js": "^4.11.8", "ethereum-types": "^1.0.7", 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/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-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json index eded891d67..9ab0905fef 100644 --- a/packages/order-watcher/CHANGELOG.json +++ b/packages/order-watcher/CHANGELOG.json @@ -14,6 +14,15 @@ } ] }, + { + "version": "1.0.5", + "changes": [ + { + "note": "Dependencies updated" + } + ], + "timestamp": 1537875740 + }, { "version": "1.0.4", "changes": [ diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md index a4e1cc79fb..d179b2e1a3 100644 --- a/packages/order-watcher/CHANGELOG.md +++ b/packages/order-watcher/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.5 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.4 - _September 21, 2018_ * Dependencies updated diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json index f764b6518a..b00a76e557 100644 --- a/packages/order-watcher/package.json +++ b/packages/order-watcher/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/order-watcher", - "version": "1.0.4", + "version": "1.0.5", "description": "An order watcher daemon that watches for order validity", "keywords": [ "0x", @@ -42,9 +42,9 @@ "node": ">=6.0.0" }, "devDependencies": { - "@0xproject/abi-gen": "^1.0.9", - "@0xproject/dev-utils": "^1.0.8", - "@0xproject/migrations": "^1.0.10", + "@0xproject/abi-gen": "^1.0.10", + "@0xproject/dev-utils": "^1.0.9", + "@0xproject/migrations": "^1.0.11", "@0xproject/tslint-config": "^1.0.7", "@types/bintrees": "^1.0.2", "@types/lodash": "4.14.104", @@ -70,16 +70,16 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/base-contract": "^2.0.3", - "@0xproject/contract-wrappers": "^1.0.4", - "@0xproject/fill-scenarios": "^1.0.3", - "@0xproject/json-schemas": "^1.0.2", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/base-contract": "^2.0.4", + "@0xproject/contract-wrappers": "^1.0.5", + "@0xproject/fill-scenarios": "^1.0.4", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "bintrees": "^1.0.2", "ethereum-types": "^1.0.7", "ethereumjs-blockstream": "6.0.0", diff --git a/packages/react-docs/CHANGELOG.json b/packages/react-docs/CHANGELOG.json index c8a44aa9e8..4e3dfed999 100644 --- a/packages/react-docs/CHANGELOG.json +++ b/packages/react-docs/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.9", diff --git a/packages/react-docs/CHANGELOG.md b/packages/react-docs/CHANGELOG.md index 595b0cf987..ca96d479d8 100644 --- a/packages/react-docs/CHANGELOG.md +++ b/packages/react-docs/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 21, 2018_ * Dependencies updated diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index 0efe7dbc99..d933489b7a 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/react-docs", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, @@ -23,7 +23,7 @@ "url": "https://github.com/0xProject/0x-monorepo.git" }, "devDependencies": { - "@0xproject/dev-utils": "^1.0.8", + "@0xproject/dev-utils": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", "@types/compare-versions": "^3.0.0", "copyfiles": "^2.0.0", @@ -33,8 +33,8 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/react-shared": "^1.0.10", - "@0xproject/utils": "^1.0.9", + "@0xproject/react-shared": "^1.0.11", + "@0xproject/utils": "^1.0.10", "@types/lodash": "4.14.104", "@types/material-ui": "^0.20.0", "@types/node": "*", diff --git a/packages/react-shared/CHANGELOG.json b/packages/react-shared/CHANGELOG.json index 898ab26aa6..96e2a92f97 100644 --- a/packages/react-shared/CHANGELOG.json +++ b/packages/react-shared/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.11", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.10", diff --git a/packages/react-shared/CHANGELOG.md b/packages/react-shared/CHANGELOG.md index f6878e43fc..09f6066cdd 100644 --- a/packages/react-shared/CHANGELOG.md +++ b/packages/react-shared/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.11 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.10 - _September 21, 2018_ * Dependencies updated diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json index 458968c399..9154c2bb69 100644 --- a/packages/react-shared/package.json +++ b/packages/react-shared/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/react-shared", - "version": "1.0.10", + "version": "1.0.11", "engines": { "node": ">=6.12" }, @@ -24,7 +24,7 @@ "url": "https://github.com/0xProject/0x-monorepo.git" }, "devDependencies": { - "@0xproject/dev-utils": "^1.0.8", + "@0xproject/dev-utils": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", "copyfiles": "^2.0.0", "make-promises-safe": "^1.1.0", diff --git a/packages/sol-compiler/CHANGELOG.json b/packages/sol-compiler/CHANGELOG.json index 9a1961b799..af6897b402 100644 --- a/packages/sol-compiler/CHANGELOG.json +++ b/packages/sol-compiler/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.1.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.1.3", diff --git a/packages/sol-compiler/CHANGELOG.md b/packages/sol-compiler/CHANGELOG.md index a5d1332f8f..02058b378c 100644 --- a/packages/sol-compiler/CHANGELOG.md +++ b/packages/sol-compiler/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.4 - _September 25, 2018_ + + * Dependencies updated + ## v1.1.3 - _September 21, 2018_ * Dependencies updated diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json index 2ad0f9f090..841e2960c4 100644 --- a/packages/sol-compiler/package.json +++ b/packages/sol-compiler/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sol-compiler", - "version": "1.1.3", + "version": "1.1.4", "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.8", + "@0xproject/dev-utils": "^1.0.9", "@0xproject/tslint-config": "^1.0.7", "@types/mkdirp": "^0.5.2", "@types/require-from-string": "^1.2.0", @@ -64,13 +64,13 @@ "zeppelin-solidity": "1.8.0" }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/json-schemas": "^1.0.2", - "@0xproject/sol-resolver": "^1.0.9", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/sol-resolver": "^1.0.10", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "@types/yargs": "^11.0.0", "chalk": "^2.3.0", "ethereum-types": "^1.0.7", diff --git a/packages/sol-cov/CHANGELOG.json b/packages/sol-cov/CHANGELOG.json index 5f49e04430..ef009b586b 100644 --- a/packages/sol-cov/CHANGELOG.json +++ b/packages/sol-cov/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "2.1.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "2.1.3", diff --git a/packages/sol-cov/CHANGELOG.md b/packages/sol-cov/CHANGELOG.md index e1b898b194..5dddb1c4dd 100644 --- a/packages/sol-cov/CHANGELOG.md +++ b/packages/sol-cov/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.1.4 - _September 25, 2018_ + + * Dependencies updated + ## v2.1.3 - _September 21, 2018_ * Dependencies updated diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json index f80ae78e05..63b8f06d50 100644 --- a/packages/sol-cov/package.json +++ b/packages/sol-cov/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sol-cov", - "version": "2.1.3", + "version": "2.1.4", "engines": { "node": ">=6.12" }, @@ -41,12 +41,12 @@ }, "homepage": "https://github.com/0xProject/0x.js/packages/sol-cov/README.md", "dependencies": { - "@0xproject/dev-utils": "^1.0.8", - "@0xproject/sol-compiler": "^1.1.3", - "@0xproject/subproviders": "^2.0.3", + "@0xproject/dev-utils": "^1.0.9", + "@0xproject/sol-compiler": "^1.1.4", + "@0xproject/subproviders": "^2.0.4", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "ethereum-types": "^1.0.7", "ethereumjs-util": "^5.1.1", "glob": "^7.1.2", diff --git a/packages/sol-resolver/CHANGELOG.json b/packages/sol-resolver/CHANGELOG.json index bfc7cb93b3..ee439c2d01 100644 --- a/packages/sol-resolver/CHANGELOG.json +++ b/packages/sol-resolver/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.9", diff --git a/packages/sol-resolver/CHANGELOG.md b/packages/sol-resolver/CHANGELOG.md index 5bed9f43cb..53354f4eff 100644 --- a/packages/sol-resolver/CHANGELOG.md +++ b/packages/sol-resolver/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 21, 2018_ * Dependencies updated diff --git a/packages/sol-resolver/package.json b/packages/sol-resolver/package.json index da3f187887..caf7df3aaa 100644 --- a/packages/sol-resolver/package.json +++ b/packages/sol-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sol-resolver", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, @@ -30,7 +30,7 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/types": "^1.0.2", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", "lodash": "^4.17.5" }, diff --git a/packages/sra-report/CHANGELOG.json b/packages/sra-report/CHANGELOG.json index ee12caf34e..006965b015 100644 --- a/packages/sra-report/CHANGELOG.json +++ b/packages/sra-report/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.9", diff --git a/packages/sra-report/CHANGELOG.md b/packages/sra-report/CHANGELOG.md index 5e75625df7..298ea66ec9 100644 --- a/packages/sra-report/CHANGELOG.md +++ b/packages/sra-report/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 21, 2018_ * Dependencies updated diff --git a/packages/sra-report/package.json b/packages/sra-report/package.json index eebf0cc0b9..c916765e2b 100644 --- a/packages/sra-report/package.json +++ b/packages/sra-report/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sra-report", - "version": "1.0.9", + "version": "1.0.10", "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.9", + "@0xproject/assert": "^1.0.10", "@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.1", - "@0xproject/utils": "^1.0.9", + "@0xproject/utils": "^1.0.10", "chalk": "^2.3.0", "lodash": "^4.17.5", "newman": "^3.9.3", diff --git a/packages/sra-spec/CHANGELOG.json b/packages/sra-spec/CHANGELOG.json index e0b3731917..a4a1fe8ff1 100644 --- a/packages/sra-spec/CHANGELOG.json +++ b/packages/sra-spec/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.3", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.2", diff --git a/packages/sra-spec/CHANGELOG.md b/packages/sra-spec/CHANGELOG.md index 59f397bc62..e279d517fc 100644 --- a/packages/sra-spec/CHANGELOG.md +++ b/packages/sra-spec/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.3 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.2 - _September 21, 2018_ * Dependencies updated diff --git a/packages/sra-spec/package.json b/packages/sra-spec/package.json index 3da886e34e..0c51318486 100644 --- a/packages/sra-spec/package.json +++ b/packages/sra-spec/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/sra-spec", - "version": "1.0.2", + "version": "1.0.3", "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.2" + "@0xproject/json-schemas": "^1.0.3" }, "devDependencies": { "@0xproject/tslint-config": "^1.0.7", diff --git a/packages/subproviders/CHANGELOG.json b/packages/subproviders/CHANGELOG.json index 2d3c376152..8b6b87d2ab 100644 --- a/packages/subproviders/CHANGELOG.json +++ b/packages/subproviders/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "2.0.4", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "2.0.3", diff --git a/packages/subproviders/CHANGELOG.md b/packages/subproviders/CHANGELOG.md index 6e268d7ecd..708a94b21d 100644 --- a/packages/subproviders/CHANGELOG.md +++ b/packages/subproviders/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v2.0.4 - _September 25, 2018_ + + * Dependencies updated + ## v2.0.3 - _September 21, 2018_ * Dependencies updated diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json index 347c717269..6740a0743f 100644 --- a/packages/subproviders/package.json +++ b/packages/subproviders/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/subproviders", - "version": "2.0.3", + "version": "2.0.4", "engines": { "node": ">=6.12" }, @@ -28,11 +28,11 @@ } }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/types": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "@ledgerhq/hw-app-eth": "^4.3.0", "@ledgerhq/hw-transport-u2f": "^4.3.0", "@types/eth-lightwallet": "^3.0.0", diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json index 448186b340..cfac1b0187 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.47", + "version": "1.0.48", "engines": { "node": ">=6.12" }, @@ -17,11 +17,11 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^1.0.4", - "@0xproject/subproviders": "^2.0.3", + "0x.js": "^1.0.5", + "@0xproject/subproviders": "^2.0.4", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "body-parser": "^1.17.1", "ethereum-types": "^1.0.7", "ethereumjs-tx": "^1.3.5", diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json index a1fc1dcd0e..f9479f789e 100644 --- a/packages/types/CHANGELOG.json +++ b/packages/types/CHANGELOG.json @@ -1,4 +1,18 @@ [ + { + "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", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index d89416fd62..9841aa301a 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -5,6 +5,11 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.1.0 - _September 25, 2018_ + + * Add ObjectMap type (#1037) + * Add SRA types from connect (#1085) + ## v1.0.2 - _September 21, 2018_ * Dependencies updated diff --git a/packages/types/package.json b/packages/types/package.json index f1c04b39ba..f783681980 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/types", - "version": "1.0.2", + "version": "1.1.0", "engines": { "node": ">=6.12" }, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 48a9e23d11..d27060ee55 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -239,3 +239,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/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json index 7449355ceb..1536c1960a 100644 --- a/packages/utils/CHANGELOG.json +++ b/packages/utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "timestamp": 1537875740, + "version": "1.0.10", + "changes": [ + { + "note": "Dependencies updated" + } + ] + }, { "timestamp": 1537541580, "version": "1.0.9", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index aa2c089406..ff26a09006 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v1.0.10 - _September 25, 2018_ + + * Dependencies updated + ## v1.0.9 - _September 21, 2018_ * Dependencies updated diff --git a/packages/utils/package.json b/packages/utils/package.json index a3977cef68..77d11c41c1 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/utils", - "version": "1.0.9", + "version": "1.0.10", "engines": { "node": ">=6.12" }, @@ -41,7 +41,7 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/types": "^1.0.2", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", "@types/node": "*", "abortcontroller-polyfill": "^1.1.9", 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 18ce5acd51..8895951bce 100644 --- a/packages/web3-wrapper/CHANGELOG.json +++ b/packages/web3-wrapper/CHANGELOG.json @@ -12,7 +12,8 @@ "Expose `sendRawPayloadAsync` so one can easily extend `Web3Wrapper` with their own custom JSON RPC calls", "pr": 1080 } - ] + ], + "timestamp": 1537875740 }, { "version": "2.0.3", diff --git a/packages/web3-wrapper/CHANGELOG.md b/packages/web3-wrapper/CHANGELOG.md index 72aff4a95a..cafbe13403 100644 --- a/packages/web3-wrapper/CHANGELOG.md +++ b/packages/web3-wrapper/CHANGELOG.md @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. CHANGELOG +## v3.0.0 - _September 25, 2018_ + + * Rename `getBlockAsync` to `getBlockIfExistsAsync` and rather then throw if the requested block wasn't found, return undefined. (#1082) + ## v2.0.3 - _September 21, 2018_ * Fixes issue #1076 where Parity now returns a placeholder transactionReceipt before the transaction is mined. (#1079) diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json index bcd640839f..f895296e97 100644 --- a/packages/web3-wrapper/package.json +++ b/packages/web3-wrapper/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/web3-wrapper", - "version": "2.0.3", + "version": "3.0.0", "engines": { "node": ">=6.12" }, @@ -53,10 +53,10 @@ "typescript": "3.0.1" }, "dependencies": { - "@0xproject/assert": "^1.0.9", - "@0xproject/json-schemas": "^1.0.2", + "@0xproject/assert": "^1.0.10", + "@0xproject/json-schemas": "^1.0.3", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", + "@0xproject/utils": "^1.0.10", "ethereum-types": "^1.0.7", "ethereumjs-util": "^5.1.1", "ethers": "3.0.22", diff --git a/packages/website/package.json b/packages/website/package.json index 54ec1c84bf..67b2fb4ec4 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -1,6 +1,6 @@ { "name": "@0xproject/website", - "version": "0.0.50", + "version": "0.0.51", "engines": { "node": ">=6.12" }, @@ -19,15 +19,16 @@ "license": "Apache-2.0", "dependencies": { "0x.js": "^0.38.6", - "@0xproject/contract-wrappers": "^1.0.4", - "@0xproject/order-utils": "^1.0.3", - "@0xproject/react-docs": "^1.0.9", - "@0xproject/react-shared": "^1.0.10", - "@0xproject/subproviders": "^2.0.3", - "@0xproject/types": "^1.0.2", + "@0xproject/contract-wrappers": "^1.0.5", + "@0xproject/json-schemas": "^1.0.3", + "@0xproject/order-utils": "^1.0.4", + "@0xproject/react-docs": "^1.0.10", + "@0xproject/react-shared": "^1.0.11", + "@0xproject/subproviders": "^2.0.4", + "@0xproject/types": "^1.1.0", "@0xproject/typescript-typings": "^2.0.1", - "@0xproject/utils": "^1.0.9", - "@0xproject/web3-wrapper": "^2.0.3", + "@0xproject/utils": "^1.0.10", + "@0xproject/web3-wrapper": "^3.0.0", "accounting": "^0.4.1", "basscss": "^8.0.3", "blockies": "^0.0.2", 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/types.ts b/packages/website/ts/types.ts index 5fe9eef991..3c6d3df4da 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -1,4 +1,4 @@ -import { SignedOrder } from '@0xproject/types'; +import { ObjectMap, SignedOrder } from '@0xproject/types'; import { BigNumber } from '@0xproject/utils'; import { Provider } from 'ethereum-types'; import * as React from 'react'; @@ -519,10 +519,6 @@ export interface OutdatedWrappedEtherByNetworkId { export type ItemByAddress = 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" },