From 47f8b5d6fc941b3f9c5cf8bb00c3be6123be629f Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 25 Sep 2018 13:55:07 +0200 Subject: Use options object convention everywhere, and make package private --- packages/asset-buyer/src/asset_buyer.ts | 106 +++++++----------------- packages/asset-buyer/src/asset_buyer_manager.ts | 82 +++++------------- packages/asset-buyer/src/constants.ts | 24 ++++-- packages/asset-buyer/src/index.ts | 3 + packages/asset-buyer/src/types.ts | 27 ++++++ 5 files changed, 103 insertions(+), 139 deletions(-) (limited to 'packages/asset-buyer/src') diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts index 39b0aa619..afef0d070 100644 --- a/packages/asset-buyer/src/asset_buyer.ts +++ b/packages/asset-buyer/src/asset_buyer.ts @@ -11,8 +11,10 @@ import { BasicOrderProvider } from './order_providers/basic_order_provider'; import { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider'; import { AssetBuyerError, + AssetBuyerOpts, AssetBuyerOrdersAndFillableAmounts, BuyQuote, + BuyQuoteExecutionOpts, BuyQuoteRequestOpts, OrderProvider, OrderProviderResponse, @@ -38,9 +40,7 @@ export class AssetBuyer { * @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. + * @param options Initialization options for the AssetBuyer. See type definition for details. * * @return An instance of AssetBuyer */ @@ -48,28 +48,17 @@ export class AssetBuyer { 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, + options: Partial, ): 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, - ); + const assetBuyer = new AssetBuyer(provider, assetData, orderProvider, options); return assetBuyer; } /** @@ -77,9 +66,7 @@ export class AssetBuyer { * @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. + * @param options Initialization options for the AssetBuyer. See type definition for details. * * @return An instance of AssetBuyer */ @@ -87,24 +74,13 @@ export class AssetBuyer { 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, + options: Partial, ): 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, - ); + const assetBuyer = new AssetBuyer(provider, assetData, orderProvider, options); return assetBuyer; } /** @@ -112,59 +88,43 @@ export class AssetBuyer { * @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. + * @param options Initialization options for the AssetBuyer. See type definition for details. + * * @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, + options: Partial, ): 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, - ); + const assetBuyer = AssetBuyer.getAssetBuyerForAssetData(provider, assetData, sraApiUrl, options); 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. + * @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 options Initialization options for the AssetBuyer. See type definition for details. * * @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, - ) { + constructor(provider: Provider, assetData: string, orderProvider: OrderProvider, options: Partial) { + const { networkId, orderRefreshIntervalMs, expiryBufferSeconds } = { + ...constants.DEFAULT_ASSET_BUYER_OPTS, + ...options, + }; assert.isWeb3Provider('provider', provider); assert.isString('assetData', assetData); assert.isValidOrderProvider('orderProvider', orderProvider); assert.isNumber('networkId', networkId); assert.isNumber('orderRefreshIntervalMs', orderRefreshIntervalMs); + assert.isNumber('expiryBufferSeconds', expiryBufferSeconds); this.provider = provider; this.assetData = assetData; this.orderProvider = orderProvider; @@ -179,15 +139,14 @@ export class AssetBuyer { * 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. + * @param options Options for the request. See type definition for more information. + * * @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, + ...options, }; assert.isBigNumber('assetBuyAmount', assetBuyAmount); assert.isValidPercentage('feePercentage', feePercentage); @@ -222,18 +181,15 @@ export class AssetBuyer { /** * 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). + * @param options Options for the execution of the BuyQuote. See type definition for more information. * * @return A promise of the txHash. */ - public async executeBuyQuoteAsync( - buyQuote: BuyQuote, - rate?: BigNumber, - takerAddress?: string, - feeRecipient: string = constants.NULL_ADDRESS, - ): Promise { + public async executeBuyQuoteAsync(buyQuote: BuyQuote, options: Partial): Promise { + const { rate, takerAddress, feeRecipient } = { + ...constants.DEFAULT_BUY_QUOTE_EXECUTION_OPTS, + ...options, + }; assert.isValidBuyQuote('buyQuote', buyQuote); if (!_.isUndefined(rate)) { assert.isBigNumber('rate', rate); diff --git a/packages/asset-buyer/src/asset_buyer_manager.ts b/packages/asset-buyer/src/asset_buyer_manager.ts index 1e2c5db5e..1bde55eff 100644 --- a/packages/asset-buyer/src/asset_buyer_manager.ts +++ b/packages/asset-buyer/src/asset_buyer_manager.ts @@ -13,7 +13,14 @@ import { StandardRelayerAPIOrderProvider } from './order_providers/standard_rela import { assert } from './utils/assert'; import { assetDataUtils } from './utils/asset_data_utils'; -import { AssetBuyerManagerError, BuyQuote, BuyQuoteRequestOpts, OrderProvider } from './types'; +import { + AssetBuyerManagerError, + AssetBuyerOpts, + BuyQuote, + BuyQuoteExecutionOpts, + BuyQuoteRequestOpts, + OrderProvider, +} from './types'; export class AssetBuyerManager { // Map of assetData to AssetBuyer for that assetData @@ -41,40 +48,28 @@ export class AssetBuyerManager { * Instantiates a new AssetBuyerManager 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 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. + * @param options Initialization options for an AssetBuyer. See type definition for details. * * @return An promise of an instance of AssetBuyerManager */ public static async getAssetBuyerManagerFromStandardRelayerApiAsync( provider: Provider, sraApiUrl: string, - networkId: number = constants.MAINNET_NETWORK_ID, - orderRefreshIntervalMs?: number, - expiryBufferSeconds?: number, + options: Partial, ): Promise { + const networkId = options.networkId || constants.MAINNET_NETWORK_ID; const contractWrappers = new ContractWrappers(provider, { networkId }); const etherTokenAssetData = assetDataUtils.getEtherTokenAssetDataOrThrow(contractWrappers); const assetDatas = await AssetBuyerManager.getAllAvailableAssetDatasAsync(sraApiUrl, etherTokenAssetData); const orderProvider = new StandardRelayerAPIOrderProvider(sraApiUrl); - return new AssetBuyerManager( - provider, - assetDatas, - orderProvider, - networkId, - orderRefreshIntervalMs, - expiryBufferSeconds, - ); + return new AssetBuyerManager(provider, assetDatas, orderProvider, options); } /** * Instantiates a new AssetBuyerManager 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. + * @param options Initialization options for an AssetBuyer. See type definition for details. * * @return An instance of AssetBuyerManager */ @@ -82,29 +77,18 @@ export class AssetBuyerManager { provider: Provider, orders: SignedOrder[], feeOrders: SignedOrder[] = [], - networkId?: number, - orderRefreshIntervalMs?: number, - expiryBufferSeconds?: number, + options: Partial, ): AssetBuyerManager { const assetDatas = _.map(orders, order => order.makerAssetData); const orderProvider = new BasicOrderProvider(_.concat(orders, feeOrders)); - return new AssetBuyerManager( - provider, - assetDatas, - orderProvider, - networkId, - orderRefreshIntervalMs, - expiryBufferSeconds, - ); + return new AssetBuyerManager(provider, assetDatas, orderProvider, options); } /** * Instantiates a new AssetBuyerManager 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). - * @param expiryBufferSeconds The number of seconds to add when calculating whether an order is expired or not. Defaults to 15s. + * @param orderProvider An object that conforms to OrderProvider, see type for definition. + * @param options Initialization options for an AssetBuyer. See type definition for details. * * @return An instance of AssetBuyerManager */ @@ -112,22 +96,13 @@ export class AssetBuyerManager { provider: Provider, assetDatas: string[], orderProvider: OrderProvider, - networkId?: number, - orderRefreshIntervalMs?: number, - expiryBufferSeconds?: number, + options: Partial, ) { 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, - expiryBufferSeconds, - ); + accAssetBuyerMap[assetData] = new AssetBuyer(provider, assetData, orderProvider, options); return accAssetBuyerMap; }, {}, @@ -170,9 +145,8 @@ export class AssetBuyerManager { * * @param assetData The assetData that identifies the desired asset to 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. + * @param options Options for the execution of the BuyQuote. See type definition for more information. + * * @return An object that conforms to BuyQuote that satisfies the request. See type definition for more information. */ public async getBuyQuoteAsync( @@ -191,17 +165,7 @@ export class AssetBuyerManager { * * @return A promise of the txHash. */ - public async executeBuyQuoteAsync( - buyQuote: BuyQuote, - rate?: BigNumber, - takerAddress?: string, - feeRecipient?: string, - ): Promise { - return this.getAssetBuyerFromAssetData(buyQuote.assetData).executeBuyQuoteAsync( - buyQuote, - rate, - takerAddress, - feeRecipient, - ); + public async executeBuyQuoteAsync(buyQuote: BuyQuote, options: Partial): Promise { + return this.getAssetBuyerFromAssetData(buyQuote.assetData).executeBuyQuoteAsync(buyQuote, options); } } diff --git a/packages/asset-buyer/src/constants.ts b/packages/asset-buyer/src/constants.ts index 79b5d9052..e1056e39b 100644 --- a/packages/asset-buyer/src/constants.ts +++ b/packages/asset-buyer/src/constants.ts @@ -1,6 +1,15 @@ import { BigNumber } from '@0xproject/utils'; -import { BuyQuoteRequestOpts } from './types'; +import { AssetBuyerOpts, BuyQuoteExecutionOpts, BuyQuoteRequestOpts } from './types'; + +const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; +const MAINNET_NETWORK_ID = 1; + +const DEFAULT_ASSET_BUYER_OPTS: AssetBuyerOpts = { + networkId: MAINNET_NETWORK_ID, + orderRefreshIntervalMs: 10000, // 10 seconds + expiryBufferSeconds: 15, +}; const DEFAULT_BUY_QUOTE_REQUEST_OPTS: BuyQuoteRequestOpts = { feePercentage: 0, @@ -8,13 +17,18 @@ const DEFAULT_BUY_QUOTE_REQUEST_OPTS: BuyQuoteRequestOpts = { slippagePercentage: 0.2, // 20% slippage protection }; +// Other default values are dynamically determined +const DEFAULT_BUY_QUOTE_EXECUTION_OPTS: BuyQuoteExecutionOpts = { + feeRecipient: NULL_ADDRESS, +}; + export const constants = { ZERO_AMOUNT: new BigNumber(0), - NULL_ADDRESS: '0x0000000000000000000000000000000000000000', - MAINNET_NETWORK_ID: 1, - DEFAULT_ORDER_REFRESH_INTERVAL_MS: 10000, // 10 seconds + NULL_ADDRESS, + MAINNET_NETWORK_ID, ETHER_TOKEN_DECIMALS: 18, + DEFAULT_ASSET_BUYER_OPTS, + DEFAULT_BUY_QUOTE_EXECUTION_OPTS, DEFAULT_BUY_QUOTE_REQUEST_OPTS, MAX_PER_PAGE: 10000, - DEFAULT_EXPIRY_BUFFER_SECONDS: 15, }; diff --git a/packages/asset-buyer/src/index.ts b/packages/asset-buyer/src/index.ts index cedb3bbf4..830b4d8b8 100644 --- a/packages/asset-buyer/src/index.ts +++ b/packages/asset-buyer/src/index.ts @@ -8,7 +8,10 @@ export { StandardRelayerAPIOrderProvider } from './order_providers/standard_rela export { AssetBuyerManager } from './asset_buyer_manager'; export { AssetBuyerError, + AssetBuyerOpts, BuyQuote, + BuyQuoteExecutionOpts, + BuyQuoteRequestOpts, OrderProvider, OrderProviderRequest, OrderProviderResponse, diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts index 141193b7b..67baa51c7 100644 --- a/packages/asset-buyer/src/types.ts +++ b/packages/asset-buyer/src/types.ts @@ -52,12 +52,39 @@ export interface BuyQuote { feePercentage?: number; } +/** + * feePercentage: The affiliate fee percentage. Defaults to 0. + * shouldForceOrderRefresh: If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs. Defaults to false. + * slippagePercentage: The percentage buffer to add to account for slippage. Affects max ETH price estimates. Defaults to 0.2 (20%). + */ export interface BuyQuoteRequestOpts { feePercentage: number; shouldForceOrderRefresh: boolean; slippagePercentage: number; } +/** + * rate: The desired rate to execute the buy at. Affects the amount of ETH sent with the transaction, defaults to buyQuote.maxRate. + * takerAddress: The address to perform the buy. Defaults to the first available address from the provider. + * feeRecipient: The address where affiliate fees are sent. Defaults to null address (0x000...000). + */ +export interface BuyQuoteExecutionOpts { + rate?: BigNumber; + takerAddress?: string; + feeRecipient: string; +} + +/** + * networkId: The ethereum network id. Defaults to 1 (mainnet). + * orderRefreshIntervalMs: The interval in ms that getBuyQuoteAsync should trigger an refresh of orders and order states. Defaults to 10000ms (10s). + * expiryBufferSeconds: The number of seconds to add when calculating whether an order is expired or not. Defaults to 15s. + */ +export interface AssetBuyerOpts { + networkId: number; + orderRefreshIntervalMs: number; + expiryBufferSeconds: number; +} + /** * Possible errors thrown by an AssetBuyer instance or associated static methods. */ -- cgit v1.2.3