diff options
Diffstat (limited to 'packages/asset-buyer/src')
-rw-r--r-- | packages/asset-buyer/src/asset_buyer.ts | 107 | ||||
-rw-r--r-- | packages/asset-buyer/src/asset_buyer_manager.ts | 171 | ||||
-rw-r--r-- | packages/asset-buyer/src/constants.ts | 24 | ||||
-rw-r--r-- | packages/asset-buyer/src/index.ts | 7 | ||||
-rw-r--r-- | packages/asset-buyer/src/standard_relayer_api_asset_buyer_manager.ts | 133 | ||||
-rw-r--r-- | packages/asset-buyer/src/types.ts | 31 |
6 files changed, 256 insertions, 217 deletions
diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts index 409e34e74..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<AssetBuyerOpts>, ): 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<AssetBuyerOpts>, ): 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<AssetBuyerOpts>, ): 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<AssetBuyerOpts>) { + 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<BuyQuoteRequestOpts>): Promise<BuyQuote> { const { feePercentage, shouldForceOrderRefresh, slippagePercentage } = { - ...options, ...constants.DEFAULT_BUY_QUOTE_REQUEST_OPTS, + ...options, }; assert.isBigNumber('assetBuyAmount', assetBuyAmount); assert.isValidPercentage('feePercentage', feePercentage); @@ -222,17 +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<string> { + public async executeBuyQuoteAsync(buyQuote: BuyQuote, options: Partial<BuyQuoteExecutionOpts>): Promise<string> { + 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 new file mode 100644 index 000000000..1bde55eff --- /dev/null +++ b/packages/asset-buyer/src/asset_buyer_manager.ts @@ -0,0 +1,171 @@ +import { HttpClient } from '@0xproject/connect'; +import { ContractWrappers } from '@0xproject/contract-wrappers'; +import { SignedOrder } from '@0xproject/order-utils'; +import { ObjectMap } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import { Provider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { AssetBuyer } from './asset_buyer'; +import { constants } from './constants'; +import { BasicOrderProvider } from './order_providers/basic_order_provider'; +import { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider'; +import { assert } from './utils/assert'; +import { assetDataUtils } from './utils/asset_data_utils'; + +import { + AssetBuyerManagerError, + AssetBuyerOpts, + BuyQuote, + BuyQuoteExecutionOpts, + BuyQuoteRequestOpts, + OrderProvider, +} from './types'; + +export class AssetBuyerManager { + // Map of assetData to AssetBuyer for that assetData + private readonly _assetBuyerMap: ObjectMap<AssetBuyer>; + /** + * 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<string[]> { + 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 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 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, + options: Partial<AssetBuyerOpts>, + ): Promise<AssetBuyerManager> { + 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, 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 options Initialization options for an AssetBuyer. See type definition for details. + * + * @return An instance of AssetBuyerManager + */ + public static getAssetBuyerManagerFromProvidedOrders( + provider: Provider, + orders: SignedOrder[], + feeOrders: SignedOrder[] = [], + options: Partial<AssetBuyerOpts>, + ): AssetBuyerManager { + const assetDatas = _.map(orders, order => order.makerAssetData); + const orderProvider = new BasicOrderProvider(_.concat(orders, feeOrders)); + 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 options Initialization options for an AssetBuyer. See type definition for details. + * + * @return An instance of AssetBuyerManager + */ + constructor( + provider: Provider, + assetDatas: string[], + orderProvider: OrderProvider, + options: Partial<AssetBuyerOpts>, + ) { + assert.assert(assetDatas.length > 0, `Expected 'assetDatas' to be a non-empty array.`); + this._assetBuyerMap = _.reduce( + assetDatas, + (accAssetBuyerMap: ObjectMap<AssetBuyer>, assetData: string) => { + accAssetBuyerMap[assetData] = new AssetBuyer(provider, assetData, orderProvider, options); + 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(`${AssetBuyerManagerError.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); + } + /** + * Get a `BuyQuote` containing all information relevant to fulfilling a buy. + * You can then pass the `BuyQuote` to `executeBuyQuoteAsync` to execute the buy. + * + * @param assetData The assetData that identifies the desired asset to buy. + * @param assetBuyAmount The amount of asset to buy. + * @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( + assetData: string, + assetBuyAmount: BigNumber, + options: Partial<BuyQuoteRequestOpts>, + ): Promise<BuyQuote> { + return this.getAssetBuyerFromAssetData(assetData).getBuyQuoteAsync(assetBuyAmount, options); + } + /** + * 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, options: Partial<BuyQuoteExecutionOpts>): Promise<string> { + 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 8ef529ac0..830b4d8b8 100644 --- a/packages/asset-buyer/src/index.ts +++ b/packages/asset-buyer/src/index.ts @@ -5,13 +5,16 @@ 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 { AssetBuyerManager } from './asset_buyer_manager'; export { AssetBuyerError, + AssetBuyerOpts, BuyQuote, + BuyQuoteExecutionOpts, + BuyQuoteRequestOpts, OrderProvider, OrderProviderRequest, OrderProviderResponse, SignedOrderWithRemainingFillableMakerAssetAmount, - StandardRelayerApiAssetBuyerManagerError, + AssetBuyerManagerError, } from './types'; 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 deleted file mode 100644 index 947c738a1..000000000 --- a/packages/asset-buyer/src/standard_relayer_api_asset_buyer_manager.ts +++ /dev/null @@ -1,133 +0,0 @@ -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<AssetBuyer>; - /** - * 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<string[]> { - 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<StandardRelayerAPIAssetBuyerManager> { - 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<AssetBuyer>, 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 index ee6858525..67baa51c7 100644 --- a/packages/asset-buyer/src/types.ts +++ b/packages/asset-buyer/src/types.ts @@ -52,6 +52,11 @@ 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; @@ -59,6 +64,28 @@ export interface BuyQuoteRequestOpts { } /** + * 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. */ export enum AssetBuyerError { @@ -72,9 +99,9 @@ export enum AssetBuyerError { } /** - * Possible errors thrown by an StandardRelayerApiAssetBuyerManager instance or associated static methods. + * Possible errors thrown by an AssetBuyerManager instance or associated static methods. */ -export enum StandardRelayerApiAssetBuyerManagerError { +export enum AssetBuyerManagerError { AssetBuyerNotFound = 'ASSET_BUYER_NOT_FOUND', } |