From 64d25e6522e7eaecdfdbb7b784a984f381af9a98 Mon Sep 17 00:00:00 2001 From: David Sun Date: Tue, 12 Nov 2019 16:30:13 -0500 Subject: [PATCH] removed buyer and adding in asset-swapper --- packages/instant/package.json | 2 +- packages/instant/src/constants.ts | 6 +- ...d_buy_order_progress_or_payment_method.tsx | 2 +- .../latest_buy_quote_order_details.ts | 2 +- .../selected_asset_buy_order_progress.ts | 4 +- .../selected_asset_instant_heading.ts | 6 +- .../selected_erc20_asset_amount_input.ts | 34 +++++----- packages/instant/src/redux/actions.ts | 28 ++++---- packages/instant/src/redux/async_data.ts | 20 +++--- packages/instant/src/redux/reducer.ts | 66 +++++++++---------- packages/instant/src/types.ts | 5 +- packages/instant/src/util/analytics.ts | 53 +++++++-------- packages/instant/src/util/asset.ts | 12 ++-- .../instant/src/util/asset_buyer_factory.ts | 17 ----- .../instant/src/util/asset_swapper_factory.ts | 23 +++++++ .../instant/src/util/heartbeater_factory.ts | 4 +- .../src/util/provider_state_factory.ts | 11 ++-- ...quote_updater.ts => swap_quote_updater.ts} | 41 ++++++------ 18 files changed, 172 insertions(+), 164 deletions(-) delete mode 100644 packages/instant/src/util/asset_buyer_factory.ts create mode 100644 packages/instant/src/util/asset_swapper_factory.ts rename packages/instant/src/util/{buy_quote_updater.ts => swap_quote_updater.ts} (60%) diff --git a/packages/instant/package.json b/packages/instant/package.json index cc1a332cb0..dbd13c6ba3 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -44,7 +44,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md", "dependencies": { "@0x/assert": "^2.2.0-beta.2", - "@0x/asset-buyer": "6.1.8", + "@0x/asset-swapper": "^2.1.0-beta.2", "@0x/json-schemas": "^4.1.0-beta.2", "@0x/order-utils": "^8.5.0-beta.3", "@0x/subproviders": "^5.1.0-beta.2", diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index bcd1a05096..627106edee 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -16,12 +16,12 @@ export const ONE_SECOND_MS = 1000; export const ONE_MINUTE_MS = ONE_SECOND_MS * 60; export const GIT_SHA = process.env.GIT_SHA; export const NODE_ENV = process.env.NODE_ENV; -export const ERC20_BUY_QUOTE_SLIPPAGE_PERCENTAGE = 0.2; -export const ERC721_BUY_QUOTE_SLIPPAGE_PERCENTAGE = 0; +export const ERC20_SWAP_QUOTE_SLIPPAGE_PERCENTAGE = 0.2; +export const ERC721_SWAP_QUOTE_SLIPPAGE_PERCENTAGE = 0; export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION; export const DEFAULT_UNKOWN_ASSET_NAME = '???'; export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5; -export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; +export const SWAP_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.multipliedBy(6); export const DEFAULT_ESTIMATED_TRANSACTION_TIME_MS = ONE_MINUTE_MS * 2; export const MAGIC_TRIGGER_ERROR_INPUT = '0€'; diff --git a/packages/instant/src/containers/connected_buy_order_progress_or_payment_method.tsx b/packages/instant/src/containers/connected_buy_order_progress_or_payment_method.tsx index cace18e7ec..543edac925 100644 --- a/packages/instant/src/containers/connected_buy_order_progress_or_payment_method.tsx +++ b/packages/instant/src/containers/connected_buy_order_progress_or_payment_method.tsx @@ -28,7 +28,7 @@ interface ConnectedState extends BuyOrderProgressOrPaymentMethodProps {} export interface ConnectedBuyOrderProgressOrPaymentMethodProps {} const mapStateToProps = (state: State, _ownProps: ConnectedBuyOrderProgressOrPaymentMethodProps): ConnectedState => ({ - orderProcessState: state.buyOrderState.processState, + orderProcessState: state.swapOrderState.processState, }); export const ConnectedBuyOrderProgressOrPaymentMethod: React.ComponentClass< ConnectedBuyOrderProgressOrPaymentMethodProps diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts index 148735c47c..79c5e15541 100644 --- a/packages/instant/src/containers/latest_buy_quote_order_details.ts +++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts @@ -16,7 +16,7 @@ type DispatchProperties = 'onBaseCurrencySwitchEth' | 'onBaseCurrencySwitchUsd'; interface ConnectedState extends Omit {} const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({ // use the worst case quote info - buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(), + buyQuoteInfo: oc(state).latestSwapQuote.worstCaseQuoteInfo(), selectedAssetUnitAmount: state.selectedAssetUnitAmount, ethUsdPrice: state.ethUsdPrice, isLoading: state.quoteRequestState === AsyncProcessState.Pending, diff --git a/packages/instant/src/containers/selected_asset_buy_order_progress.ts b/packages/instant/src/containers/selected_asset_buy_order_progress.ts index 7c8c246764..7303f5a174 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_progress.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_progress.ts @@ -5,9 +5,9 @@ import { State } from '../redux/reducer'; import { OrderState } from '../types'; interface ConnectedState { - buyOrderState: OrderState; + swapOrderState: OrderState; } const mapStateToProps = (state: State, _ownProps: {}): ConnectedState => ({ - buyOrderState: state.buyOrderState, + swapOrderState: state.swapOrderState, }); export const SelectedAssetBuyOrderProgress = connect(mapStateToProps)(BuyOrderProgress); diff --git a/packages/instant/src/containers/selected_asset_instant_heading.ts b/packages/instant/src/containers/selected_asset_instant_heading.ts index 9b278de582..5cf6925bfb 100644 --- a/packages/instant/src/containers/selected_asset_instant_heading.ts +++ b/packages/instant/src/containers/selected_asset_instant_heading.ts @@ -19,16 +19,16 @@ interface ConnectedState { totalEthBaseUnitAmount?: BigNumber; ethUsdPrice?: BigNumber; quoteRequestState: AsyncProcessState; - buyOrderState: OrderState; + swapOrderState: OrderState; } const mapStateToProps = (state: State, _ownProps: InstantHeadingProps): ConnectedState => ({ selectedAsset: state.selectedAsset, selectedAssetUnitAmount: state.selectedAssetUnitAmount, - totalEthBaseUnitAmount: oc(state).latestBuyQuote.worstCaseQuoteInfo.totalEthAmount(), + totalEthBaseUnitAmount: oc(state).latestSwapQuote.worstCaseQuoteInfo.totalTakerAssetAmount(), ethUsdPrice: state.ethUsdPrice, quoteRequestState: state.quoteRequestState, - buyOrderState: state.buyOrderState, + swapOrderState: state.swapOrderState, }); export const SelectedAssetInstantHeading: React.ComponentClass = connect(mapStateToProps)( diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index bb174b97fd..59c5c1011f 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -1,4 +1,4 @@ -import { AssetBuyer } from '@0x/asset-buyer'; +import { SwapQuoter } from '@0x/asset-swapper'; import { AssetProxyId } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; @@ -11,7 +11,7 @@ import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; import { AffiliateInfo, ERC20Asset, Omit, OrderProcessState, QuoteFetchOrigin } from '../types'; -import { buyQuoteUpdater } from '../util/buy_quote_updater'; +import { swapQuoteUpdater } from '../util/swap_quote_updater'; export interface SelectedERC20AssetAmountInputProps { fontColor?: ColorOption; @@ -20,7 +20,7 @@ export interface SelectedERC20AssetAmountInputProps { } interface ConnectedState { - assetBuyer: AssetBuyer; + swapQuoter: SwapQuoter; value?: BigNumber; asset?: ERC20Asset; isInputDisabled: boolean; @@ -30,8 +30,8 @@ interface ConnectedState { } interface ConnectedDispatch { - updateBuyQuote: ( - assetBuyer: AssetBuyer, + updateSwapQuote: ( + swapQuoter: SwapQuoter, value?: BigNumber, asset?: ERC20Asset, affiliateInfo?: AffiliateInfo, @@ -43,7 +43,7 @@ type ConnectedProps = Omit { - const processState = state.buyOrderState.processState; + const processState = state.swapOrderState.processState; const isInputEnabled = processState === OrderProcessState.None || processState === OrderProcessState.Failure; const isInputDisabled = !isInputEnabled; const selectedAsset = @@ -56,9 +56,9 @@ const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputP ? isInputEnabled || processState === OrderProcessState.Success : false; - const assetBuyer = state.providerState.assetBuyer; + const swapQuoter = state.providerState.swapQuoter; return { - assetBuyer, + swapQuoter, value: state.selectedAssetUnitAmount, asset: selectedAsset, isInputDisabled, @@ -68,27 +68,27 @@ const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputP }; }; -const debouncedUpdateBuyQuoteAsync = _.debounce(buyQuoteUpdater.updateBuyQuoteAsync.bind(buyQuoteUpdater), 200, { +const debouncedUpdateSwapQuoteAsync = _.debounce(swapQuoteUpdater.updateSwapQuoteAsync.bind(swapQuoteUpdater), 200, { trailing: true, -}) as typeof buyQuoteUpdater.updateBuyQuoteAsync; +}) as typeof swapQuoteUpdater.updateSwapQuoteAsync; const mapDispatchToProps = ( dispatch: Dispatch, _ownProps: SelectedERC20AssetAmountInputProps, ): ConnectedDispatch => ({ - updateBuyQuote: (assetBuyer, value, asset, affiliateInfo) => { + updateSwapQuote: (swapQuoter, value, asset, affiliateInfo) => { // Update the input dispatch(actions.updateSelectedAssetAmount(value)); - // invalidate the last buy quote. - dispatch(actions.updateLatestBuyQuote(undefined)); - // reset our buy state - dispatch(actions.setBuyOrderStateNone()); + // invalidate the last swap quote. + dispatch(actions.updateLatestSwapQuote(undefined)); + // reset our swap state + dispatch(actions.setSwapOrderStateNone()); if (value !== undefined && value.isGreaterThan(0) && asset !== undefined) { // even if it's debounced, give them the illusion it's loading dispatch(actions.setQuoteRequestStatePending()); // tslint:disable-next-line:no-floating-promises - debouncedUpdateBuyQuoteAsync(assetBuyer, dispatch, asset, value, QuoteFetchOrigin.Manual, { + debouncedUpdateSwapQuoteAsync(swapQuoter, dispatch, asset, value, QuoteFetchOrigin.Manual, { setPending: true, dispatchErrors: true, affiliateInfo, @@ -107,7 +107,7 @@ const mergeProps = ( asset: connectedState.asset, value: connectedState.value, onChange: (value, asset) => { - connectedDispatch.updateBuyQuote(connectedState.assetBuyer, value, asset, connectedState.affiliateInfo); + connectedDispatch.updateSwapQuote(connectedState.swapQuoter, value, asset, connectedState.affiliateInfo); }, isInputDisabled: connectedState.isInputDisabled, numberOfAssetsAvailable: connectedState.numberOfAssetsAvailable, diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index 013527f752..1bd23851db 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -1,4 +1,4 @@ -import { BuyQuote } from '@0x/asset-buyer'; +import { MarketBuySwapQuote } from '@0x/asset-swapper'; import { BigNumber } from '@0x/utils'; import { ActionsUnion, AddressAndEthBalanceInWei, Asset, BaseCurrency, StandardSlidingPanelContent } from '../types'; @@ -26,12 +26,12 @@ export enum ActionTypes { UpdateAccountEthBalance = 'UPDATE_ACCOUNT_ETH_BALANCE', UpdateEthUsdPrice = 'UPDATE_ETH_USD_PRICE', UpdateSelectedAssetUnitAmount = 'UPDATE_SELECTED_ASSET_UNIT_AMOUNT', - SetBuyOrderStateNone = 'SET_BUY_ORDER_STATE_NONE', - SetBuyOrderStateValidating = 'SET_BUY_ORDER_STATE_VALIDATING', - SetBuyOrderStateProcessing = 'SET_BUY_ORDER_STATE_PROCESSING', - SetBuyOrderStateFailure = 'SET_BUY_ORDER_STATE_FAILURE', - SetBuyOrderStateSuccess = 'SET_BUY_ORDER_STATE_SUCCESS', - UpdateLatestBuyQuote = 'UPDATE_LATEST_BUY_QUOTE', + SetSwapOrderStateNone = 'SET_SWAP_ORDER_STATE_NONE', + SetSwapOrderStateValidating = 'SET_SWAP_ORDER_STATE_VALIDATING', + SetSwapOrderStateProcessing = 'SET_SWAP_ORDER_STATE_PROCESSING', + SetSwapOrderStateFailure = 'SET_SWAP_ORDER_STATE_FAILURE', + SetSwapOrderStateSuccess = 'SET_SWAP_ORDER_STATE_SUCCESS', + UpdateLatestSwapQuote = 'UPDATE_LATEST_SWAP_QUOTE', UpdateSelectedAsset = 'UPDATE_SELECTED_ASSET', SetAvailableAssets = 'SET_AVAILABLE_ASSETS', SetQuoteRequestStatePending = 'SET_QUOTE_REQUEST_STATE_PENDING', @@ -53,13 +53,13 @@ export const actions = { createAction(ActionTypes.UpdateAccountEthBalance, addressAndBalance), updateEthUsdPrice: (price?: BigNumber) => createAction(ActionTypes.UpdateEthUsdPrice, price), updateSelectedAssetAmount: (amount?: BigNumber) => createAction(ActionTypes.UpdateSelectedAssetUnitAmount, amount), - setBuyOrderStateNone: () => createAction(ActionTypes.SetBuyOrderStateNone), - setBuyOrderStateValidating: () => createAction(ActionTypes.SetBuyOrderStateValidating), - setBuyOrderStateProcessing: (txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => - createAction(ActionTypes.SetBuyOrderStateProcessing, { txHash, startTimeUnix, expectedEndTimeUnix }), - setBuyOrderStateFailure: (txHash: string) => createAction(ActionTypes.SetBuyOrderStateFailure, txHash), - setBuyOrderStateSuccess: (txHash: string) => createAction(ActionTypes.SetBuyOrderStateSuccess, txHash), - updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UpdateLatestBuyQuote, buyQuote), + setSwapOrderStateNone: () => createAction(ActionTypes.SetSwapOrderStateNone), + setSwapOrderStateValidating: () => createAction(ActionTypes.SetSwapOrderStateValidating), + setSwapOrderStateProcessing: (txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => + createAction(ActionTypes.SetSwapOrderStateProcessing, { txHash, startTimeUnix, expectedEndTimeUnix }), + setSwapOrderStateFailure: (txHash: string) => createAction(ActionTypes.SetSwapOrderStateFailure, txHash), + setSwapOrderStateSuccess: (txHash: string) => createAction(ActionTypes.SetSwapOrderStateSuccess, txHash), + updateLatestSwapQuote: (swapQuote?: MarketBuySwapQuote) => createAction(ActionTypes.UpdateLatestSwapQuote, swapQuote), updateSelectedAsset: (asset: Asset) => createAction(ActionTypes.UpdateSelectedAsset, asset), setAvailableAssets: (availableAssets: Asset[]) => createAction(ActionTypes.SetAvailableAssets, availableAssets), setQuoteRequestStatePending: () => createAction(ActionTypes.SetQuoteRequestStatePending), diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts index 5737e3f3f5..5a77525fba 100644 --- a/packages/instant/src/redux/async_data.ts +++ b/packages/instant/src/redux/async_data.ts @@ -6,10 +6,10 @@ import { BIG_NUMBER_ZERO } from '../constants'; import { AccountState, BaseCurrency, OrderProcessState, ProviderState, QuoteFetchOrigin } from '../types'; import { analytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; -import { buyQuoteUpdater } from '../util/buy_quote_updater'; import { coinbaseApi } from '../util/coinbase_api'; import { errorFlasher } from '../util/error_flasher'; import { errorReporter } from '../util/error_reporter'; +import { swapQuoteUpdater } from '../util/swap_quote_updater'; import { actions } from './actions'; import { State } from './reducer'; @@ -30,9 +30,11 @@ export const asyncData = { }, fetchAvailableAssetDatasAndDispatchToStore: async (state: State, dispatch: Dispatch) => { const { providerState, assetMetaDataMap, network } = state; - const assetBuyer = providerState.assetBuyer; + const swapQuoter = providerState.swapQuoter; try { - const assetDatas = await assetBuyer.getAvailableAssetDatasAsync(); + // TODO(dave4506) + const wethAssetData = ''; + const assetDatas = await swapQuoter.getAvailableMakerAssetDatasAsync(wethAssetData); const deduplicatedAssetDatas = _.uniq(assetDatas); const assets = assetUtils.createAssetsFromAssetDatas(deduplicatedAssetDatas, assetMetaDataMap, network); dispatch(actions.setAvailableAssets(assets)); @@ -87,22 +89,22 @@ export const asyncData = { return; } }, - fetchCurrentBuyQuoteAndDispatchToStore: async ( + fetchCurrentSwapQuoteAndDispatchToStore: async ( state: State, dispatch: Dispatch, fetchOrigin: QuoteFetchOrigin, options: { updateSilently: boolean }, ) => { - const { buyOrderState, providerState, selectedAsset, selectedAssetUnitAmount, affiliateInfo } = state; - const assetBuyer = providerState.assetBuyer; + const { swapOrderState, providerState, selectedAsset, selectedAssetUnitAmount, affiliateInfo } = state; + const swapQuoter = providerState.swapQuoter; if ( selectedAssetUnitAmount !== undefined && selectedAsset !== undefined && selectedAssetUnitAmount.isGreaterThan(BIG_NUMBER_ZERO) && - buyOrderState.processState === OrderProcessState.None + swapOrderState.processState === OrderProcessState.None ) { - await buyQuoteUpdater.updateBuyQuoteAsync( - assetBuyer, + await swapQuoteUpdater.updateSwapQuoteAsync( + swapQuoter, dispatch, selectedAsset, selectedAssetUnitAmount, diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index fd57ba322c..46f68d1877 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -1,4 +1,4 @@ -import { BuyQuote } from '@0x/asset-buyer'; +import { MarketBuySwapQuote } from '@0x/asset-swapper'; import { AssetProxyId, ObjectMap } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -30,7 +30,7 @@ import { Action, ActionTypes } from './actions'; export interface DefaultState { network: Network; assetMetaDataMap: ObjectMap; - buyOrderState: OrderState; + swapOrderState: OrderState; latestErrorDisplayStatus: DisplayStatus; quoteRequestState: AsyncProcessState; standardSlidingPanelSettings: StandardSlidingPanelSettings; @@ -48,7 +48,7 @@ interface OptionalState { availableAssets: Asset[]; selectedAssetUnitAmount: BigNumber; ethUsdPrice: BigNumber; - latestBuyQuote: BuyQuote; + latestSwapQuote: MarketBuySwapQuote; latestErrorMessage: string; affiliateInfo: AffiliateInfo; walletDisplayName: string; @@ -60,7 +60,7 @@ export type State = DefaultState & PropsDerivedState & Partial; export const DEFAULT_STATE: DefaultState = { network: Network.Mainnet, assetMetaDataMap, - buyOrderState: { processState: OrderProcessState.None }, + swapOrderState: { processState: OrderProcessState.None }, latestErrorDisplayStatus: DisplayStatus.Hidden, quoteRequestState: AsyncProcessState.None, standardSlidingPanelSettings: { @@ -115,14 +115,14 @@ export const createReducer = (initialState: State) => { ...state, selectedAssetUnitAmount: action.data, }; - case ActionTypes.UpdateLatestBuyQuote: - const newBuyQuoteIfExists = action.data; + case ActionTypes.UpdateLatestSwapQuote: + const newSwapQuoteIfExists = action.data; const shouldUpdate = - newBuyQuoteIfExists === undefined || doesBuyQuoteMatchState(newBuyQuoteIfExists, state); + newSwapQuoteIfExists === undefined || doesSwapQuoteMatchState(newSwapQuoteIfExists, state); if (shouldUpdate) { return { ...state, - latestBuyQuote: newBuyQuoteIfExists, + latestSwapQuote: newSwapQuoteIfExists, quoteRequestState: AsyncProcessState.Success, }; } else { @@ -131,31 +131,31 @@ export const createReducer = (initialState: State) => { case ActionTypes.SetQuoteRequestStatePending: return { ...state, - latestBuyQuote: undefined, + latestSwapQuote: undefined, quoteRequestState: AsyncProcessState.Pending, }; case ActionTypes.SetQuoteRequestStateFailure: return { ...state, - latestBuyQuote: undefined, + latestSwapQuote: undefined, quoteRequestState: AsyncProcessState.Failure, }; - case ActionTypes.SetBuyOrderStateNone: + case ActionTypes.SetSwapOrderStateNone: return { ...state, - buyOrderState: { processState: OrderProcessState.None }, + swapOrderState: { processState: OrderProcessState.None }, }; - case ActionTypes.SetBuyOrderStateValidating: + case ActionTypes.SetSwapOrderStateValidating: return { ...state, - buyOrderState: { processState: OrderProcessState.Validating }, + swapOrderState: { processState: OrderProcessState.Validating }, }; - case ActionTypes.SetBuyOrderStateProcessing: + case ActionTypes.SetSwapOrderStateProcessing: const processingData = action.data; const { startTimeUnix, expectedEndTimeUnix } = processingData; return { ...state, - buyOrderState: { + swapOrderState: { processState: OrderProcessState.Processing, txHash: processingData.txHash, progress: { @@ -164,14 +164,14 @@ export const createReducer = (initialState: State) => { }, }, }; - case ActionTypes.SetBuyOrderStateFailure: + case ActionTypes.SetSwapOrderStateFailure: const failureTxHash = action.data; - if ('txHash' in state.buyOrderState) { - if (state.buyOrderState.txHash === failureTxHash) { - const { txHash, progress } = state.buyOrderState; + if ('txHash' in state.swapOrderState) { + if (state.swapOrderState.txHash === failureTxHash) { + const { txHash, progress } = state.swapOrderState; return { ...state, - buyOrderState: { + swapOrderState: { processState: OrderProcessState.Failure, txHash, progress, @@ -180,14 +180,14 @@ export const createReducer = (initialState: State) => { } } return state; - case ActionTypes.SetBuyOrderStateSuccess: + case ActionTypes.SetSwapOrderStateSuccess: const successTxHash = action.data; - if ('txHash' in state.buyOrderState) { - if (state.buyOrderState.txHash === successTxHash) { - const { txHash, progress } = state.buyOrderState; + if ('txHash' in state.swapOrderState) { + if (state.swapOrderState.txHash === successTxHash) { + const { txHash, progress } = state.swapOrderState; return { ...state, - buyOrderState: { + swapOrderState: { processState: OrderProcessState.Success, txHash, progress, @@ -221,9 +221,9 @@ export const createReducer = (initialState: State) => { case ActionTypes.ResetAmount: return { ...state, - latestBuyQuote: undefined, + latestSwapQuote: undefined, quoteRequestState: AsyncProcessState.None, - buyOrderState: { processState: OrderProcessState.None }, + swapOrderState: { processState: OrderProcessState.None }, selectedAssetUnitAmount: undefined, }; case ActionTypes.SetAvailableAssets: @@ -271,18 +271,18 @@ const reduceStateWithAccount = (state: State, account: Account) => { }; }; -const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => { +const doesSwapQuoteMatchState = (swapQuote: MarketBuySwapQuote , state: State): boolean => { const selectedAssetIfExists = state.selectedAsset; const selectedAssetUnitAmountIfExists = state.selectedAssetUnitAmount; // if no selectedAsset or selectedAssetAmount exists on the current state, return false if (selectedAssetIfExists === undefined || selectedAssetUnitAmountIfExists === undefined) { return false; } - // if buyQuote's assetData does not match that of the current selected asset, return false - if (selectedAssetIfExists.assetData !== buyQuote.assetData) { + // if swapQuote's assetData does not match that of the current selected asset, return false + if (selectedAssetIfExists.assetData !== swapQuote.makerAssetData) { return false; } - // if ERC20 and buyQuote's assetBuyAmount does not match selectedAssetAmount, return false + // if ERC20 and swapQuote's makerAssetFillAmount does not match selectedAssetAmount, return false // if ERC721, return true const selectedAssetMetaData = selectedAssetIfExists.metaData; if (selectedAssetMetaData.assetProxyId === AssetProxyId.ERC20) { @@ -290,7 +290,7 @@ const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => { selectedAssetUnitAmountIfExists, selectedAssetMetaData.decimals, ); - const doesAssetAmountMatch = selectedAssetAmountBaseUnits.eq(buyQuote.assetBuyAmount); + const doesAssetAmountMatch = selectedAssetAmountBaseUnits.eq(swapQuote.makerAssetFillAmount); return doesAssetAmountMatch; } else { return true; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index ee94b885f4..0656a7374c 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -1,4 +1,4 @@ -import { AssetBuyer, BigNumber } from '@0x/asset-buyer'; +import { BigNumber, SwapQuoteConsumer, SwapQuoter } from '@0x/asset-swapper'; import { AssetProxyId, ObjectMap, SignedOrder } from '@0x/types'; import { Web3Wrapper } from '@0x/web3-wrapper'; import { SupportedProvider, ZeroExProvider } from 'ethereum-types'; @@ -110,7 +110,8 @@ export interface ProviderState { name: string; displayName: string; provider: ZeroExProvider; - assetBuyer: AssetBuyer; + swapQuoter: SwapQuoter; + swapQuoteConsumer: SwapQuoteConsumer; web3Wrapper: Web3Wrapper; account: Account; } diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 06e84cecbb..0e4e8530dc 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -1,4 +1,4 @@ -import { BuyQuote } from '@0x/asset-buyer'; +import { MarketBuySwapQuote, SwapQuote } from '@0x/asset-swapper'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; @@ -82,20 +82,17 @@ function trackingEventFnWithPayload(eventName: EventNames): (eventProperties: Ev }; } -const buyQuoteEventProperties = (buyQuote: BuyQuote) => { - const assetBuyAmount = buyQuote.assetBuyAmount.toString(); - const assetEthAmount = buyQuote.worstCaseQuoteInfo.assetEthAmount.toString(); - const feeEthAmount = buyQuote.worstCaseQuoteInfo.feeEthAmount.toString(); - const totalEthAmount = buyQuote.worstCaseQuoteInfo.totalEthAmount.toString(); - const feePercentage = buyQuote.feePercentage !== undefined ? buyQuote.feePercentage.toString() : 0; - const hasFeeOrders = !_.isEmpty(buyQuote.feeOrders) ? 'true' : 'false'; +const swapQuoteEventProperties = (swapQuote: MarketBuySwapQuote) => { + const assetBuyAmount = swapQuote.makerAssetFillAmount.toString(); + const assetEthAmount = swapQuote.worstCaseQuoteInfo.takerAssetAmount.toString(); + const feeEthAmount = swapQuote.worstCaseQuoteInfo.protocolFeeInEthAmount.plus(swapQuote.worstCaseQuoteInfo.feeTakerAssetAmount).toString(); + const totalEthAmount = swapQuote.worstCaseQuoteInfo.totalTakerAssetAmount.toString(); + // const feePercentage = swapQuote.feePercentage !== undefined ? buyQuote.feePercentage.toString() : 0; return { assetBuyAmount, assetEthAmount, feeEthAmount, totalEthAmount, - feePercentage, - hasFeeOrders, }; }; @@ -182,35 +179,35 @@ export const analytics = { trackPaymentMethodDropdownOpened: trackingEventFnWithoutPayload(EventNames.PaymentMethodDropdownOpened), trackPaymentMethodOpenedEtherscan: trackingEventFnWithoutPayload(EventNames.PaymentMethodOpenedEtherscan), trackPaymentMethodCopiedAddress: trackingEventFnWithoutPayload(EventNames.PaymentMethodCopiedAddress), - trackBuyNotEnoughEth: (buyQuote: BuyQuote) => - trackingEventFnWithPayload(EventNames.BuyNotEnoughEth)(buyQuoteEventProperties(buyQuote)), - trackBuyStarted: (buyQuote: BuyQuote) => - trackingEventFnWithPayload(EventNames.BuyStarted)(buyQuoteEventProperties(buyQuote)), - trackBuySignatureDenied: (buyQuote: BuyQuote) => - trackingEventFnWithPayload(EventNames.BuySignatureDenied)(buyQuoteEventProperties(buyQuote)), - trackBuySimulationFailed: (buyQuote: BuyQuote) => - trackingEventFnWithPayload(EventNames.BuySimulationFailed)(buyQuoteEventProperties(buyQuote)), - trackBuyUnknownError: (buyQuote: BuyQuote, errorMessage: string) => + trackBuyNotEnoughEth: (swapQuote: MarketBuySwapQuote) => + trackingEventFnWithPayload(EventNames.BuyNotEnoughEth)(swapQuoteEventProperties(swapQuote)), + trackBuyStarted: (swapQuote: MarketBuySwapQuote) => + trackingEventFnWithPayload(EventNames.BuyStarted)(swapQuoteEventProperties(swapQuote)), + trackBuySignatureDenied: (swapQuote: MarketBuySwapQuote) => + trackingEventFnWithPayload(EventNames.BuySignatureDenied)(swapQuoteEventProperties(swapQuote)), + trackBuySimulationFailed: (swapQuote: MarketBuySwapQuote) => + trackingEventFnWithPayload(EventNames.BuySimulationFailed)(swapQuoteEventProperties(swapQuote)), + trackBuyUnknownError: (swapQuote: MarketBuySwapQuote, errorMessage: string) => trackingEventFnWithPayload(EventNames.BuyUnknownError)({ - ...buyQuoteEventProperties(buyQuote), + ...swapQuoteEventProperties(swapQuote), errorMessage, }), - trackBuyTxSubmitted: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => + trackBuyTxSubmitted: (swapQuote: MarketBuySwapQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => trackingEventFnWithPayload(EventNames.BuyTxSubmitted)({ - ...buyQuoteEventProperties(buyQuote), + ...swapQuoteEventProperties(swapQuote), txHash, expectedTxTimeMs: expectedEndTimeUnix - startTimeUnix, }), - trackBuyTxSucceeded: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => + trackBuyTxSucceeded: (swapQuote: MarketBuySwapQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => trackingEventFnWithPayload(EventNames.BuyTxSucceeded)({ - ...buyQuoteEventProperties(buyQuote), + ...swapQuoteEventProperties(swapQuote), txHash, expectedTxTimeMs: expectedEndTimeUnix - startTimeUnix, actualTxTimeMs: new Date().getTime() - startTimeUnix, }), - trackBuyTxFailed: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => + trackBuyTxFailed: (swapQuote: MarketBuySwapQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => trackingEventFnWithPayload(EventNames.BuyTxFailed)({ - ...buyQuoteEventProperties(buyQuote), + ...swapQuoteEventProperties(swapQuote), txHash, expectedTxTimeMs: expectedEndTimeUnix - startTimeUnix, actualTxTimeMs: new Date().getTime() - startTimeUnix, @@ -232,9 +229,9 @@ export const analytics = { trackingEventFnWithPayload(EventNames.TokenSelectorSearched)({ searchText }), trackTransactionViewed: (orderProcesState: OrderProcessState) => trackingEventFnWithPayload(EventNames.TransactionViewed)({ orderState: orderProcesState }), - trackQuoteFetched: (buyQuote: BuyQuote, fetchOrigin: QuoteFetchOrigin) => + trackQuoteFetched: (swapQuote: MarketBuySwapQuote, fetchOrigin: QuoteFetchOrigin) => trackingEventFnWithPayload(EventNames.QuoteFetched)({ - ...buyQuoteEventProperties(buyQuote), + ...swapQuoteEventProperties(swapQuote), fetchOrigin, }), trackQuoteError: (errorMessage: string, assetBuyAmount: BigNumber, fetchOrigin: QuoteFetchOrigin) => { diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index 13d991f6e5..954723bcee 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -1,4 +1,4 @@ -import { AssetBuyerError, InsufficientAssetLiquidityError } from '@0x/asset-buyer'; +import { InsufficientAssetLiquidityError, SwapQuoterError } from '@0x/asset-swapper'; import { AssetProxyId, ObjectMap } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -109,8 +109,8 @@ export const assetUtils = { ); return _.compact(erc20sOrUndefined); }, - assetBuyerErrorMessage: (asset: Asset, error: Error): string | undefined => { - if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { + swapQuoterErrorMessage: (asset: Asset, error: Error): string | undefined => { + if (error.message === SwapQuoterError.InsufficientAssetLiquidity) { const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); if ( error instanceof InsufficientAssetLiquidityError && @@ -131,11 +131,9 @@ export const assetUtils = { } return `Not enough ${assetName} available`; - } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { - return 'Not enough ZRX available'; } else if ( - error.message === AssetBuyerError.StandardRelayerApiError || - error.message.startsWith(AssetBuyerError.AssetUnavailable) + error.message === SwapQuoterError.StandardRelayerApiError || + error.message.startsWith(SwapQuoterError.AssetUnavailable) ) { const assetName = assetUtils.bestNameForAsset(asset, 'This asset'); return `${assetName} is currently unavailable`; diff --git a/packages/instant/src/util/asset_buyer_factory.ts b/packages/instant/src/util/asset_buyer_factory.ts deleted file mode 100644 index b70f0d612a..0000000000 --- a/packages/instant/src/util/asset_buyer_factory.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { AssetBuyer, AssetBuyerOpts } from '@0x/asset-buyer'; -import { SupportedProvider } from 'ethereum-types'; -import * as _ from 'lodash'; - -import { Network, OrderSource } from '../types'; - -export const assetBuyerFactory = { - getAssetBuyer: (supportedProvider: SupportedProvider, orderSource: OrderSource, network: Network): AssetBuyer => { - const assetBuyerOptions: Partial = { - networkId: network, - }; - const assetBuyer = _.isString(orderSource) - ? AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(supportedProvider, orderSource, assetBuyerOptions) - : AssetBuyer.getAssetBuyerForProvidedOrders(supportedProvider, orderSource, assetBuyerOptions); - return assetBuyer; - }, -}; diff --git a/packages/instant/src/util/asset_swapper_factory.ts b/packages/instant/src/util/asset_swapper_factory.ts new file mode 100644 index 0000000000..18b5185ecb --- /dev/null +++ b/packages/instant/src/util/asset_swapper_factory.ts @@ -0,0 +1,23 @@ +import { SwapQuoteConsumer, SwapQuoter, SwapQuoteConsumerOpts, SwapQuoterOpts } from '@0x/asset-swapper'; +import { SupportedProvider } from 'ethereum-types'; +import * as _ from 'lodash'; + +import { Network, OrderSource } from '../types'; + +export const assetSwapperFactory = { + getSwapQuoter: (supportedProvider: SupportedProvider, orderSource: OrderSource, network: Network): SwapQuoter => { + const swapQuoterOpts: Partial = { + chainId: network, + }; + const swapQuoter = _.isString(orderSource) + ? SwapQuoter.getSwapQuoterForStandardRelayerAPIUrl(supportedProvider, orderSource, swapQuoterOpts) + : SwapQuoter.getSwapQuoterForProvidedOrders(supportedProvider, orderSource, swapQuoterOpts); + return swapQuoter; + }, + getSwapQuoteConsumer: (supportedProvider: SupportedProvider, network: Network): SwapQuoteConsumer => { + const swapQuoteConsumerOptions: Partial = { + chainId: network, + }; + return new SwapQuoteConsumer(supportedProvider, swapQuoteConsumerOptions ); + }, +}; diff --git a/packages/instant/src/util/heartbeater_factory.ts b/packages/instant/src/util/heartbeater_factory.ts index cf29bf3ea5..c80eccd8b2 100644 --- a/packages/instant/src/util/heartbeater_factory.ts +++ b/packages/instant/src/util/heartbeater_factory.ts @@ -15,10 +15,10 @@ export const generateAccountHeartbeater = (options: HeartbeatFactoryOptions): He }, shouldPerformImmediatelyOnStart); }; -export const generateBuyQuoteHeartbeater = (options: HeartbeatFactoryOptions): Heartbeater => { +export const generateSwapQuoteHeartbeater = (options: HeartbeatFactoryOptions): Heartbeater => { const { store, shouldPerformImmediatelyOnStart } = options; return new Heartbeater(async () => { - await asyncData.fetchCurrentBuyQuoteAndDispatchToStore( + await asyncData.fetchCurrentSwapQuoteAndDispatchToStore( store.getState(), store.dispatch, QuoteFetchOrigin.Heartbeat, diff --git a/packages/instant/src/util/provider_state_factory.ts b/packages/instant/src/util/provider_state_factory.ts index 1c35dc688b..fd59fa4a58 100644 --- a/packages/instant/src/util/provider_state_factory.ts +++ b/packages/instant/src/util/provider_state_factory.ts @@ -7,7 +7,7 @@ import { LOADING_ACCOUNT, NO_ACCOUNT } from '../constants'; import { Maybe, Network, OrderSource, ProviderState } from '../types'; import { envUtil } from '../util/env'; -import { assetBuyerFactory } from './asset_buyer_factory'; +import { assetSwapperFactory } from './asset_swapper_factory'; import { providerFactory } from './provider_factory'; export const providerStateFactory = { @@ -48,7 +48,8 @@ export const providerStateFactory = { displayName: walletDisplayName || envUtil.getProviderDisplayName(provider), provider, web3Wrapper: new Web3Wrapper(provider), - assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network), + swapQuoter: assetSwapperFactory.getSwapQuoter(provider, orderSource, network), + swapQuoteConsumer: assetSwapperFactory.getSwapQuoteConsumer(provider, network), account: LOADING_ACCOUNT, }; return providerState; @@ -65,7 +66,8 @@ export const providerStateFactory = { displayName: walletDisplayName || envUtil.getProviderDisplayName(injectedProviderIfExists), provider: injectedProviderIfExists, web3Wrapper: new Web3Wrapper(injectedProviderIfExists), - assetBuyer: assetBuyerFactory.getAssetBuyer(injectedProviderIfExists, orderSource, network), + swapQuoter: assetSwapperFactory.getSwapQuoter(injectedProviderIfExists, orderSource, network), + swapQuoteConsumer: assetSwapperFactory.getSwapQuoteConsumer(injectedProviderIfExists, network), account: LOADING_ACCOUNT, }; return providerState; @@ -84,7 +86,8 @@ export const providerStateFactory = { displayName: walletDisplayName || envUtil.getProviderDisplayName(provider), provider, web3Wrapper: new Web3Wrapper(provider), - assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network), + swapQuoter: assetSwapperFactory.getSwapQuoter(provider, orderSource, network), + swapQuoteConsumer: assetSwapperFactory.getSwapQuoteConsumer(provider, network), account: NO_ACCOUNT, }; return providerState; diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/swap_quote_updater.ts similarity index 60% rename from packages/instant/src/util/buy_quote_updater.ts rename to packages/instant/src/util/swap_quote_updater.ts index e4463c915d..d53036d993 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/swap_quote_updater.ts @@ -1,4 +1,4 @@ -import { AssetBuyer, BuyQuote } from '@0x/asset-buyer'; +import { SwapQuote, SwapQuoter } from '@0x/asset-swapper'; import { AssetProxyId } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -6,17 +6,17 @@ import * as _ from 'lodash'; import { Dispatch } from 'redux'; import { oc } from 'ts-optchain'; -import { ERC20_BUY_QUOTE_SLIPPAGE_PERCENTAGE, ERC721_BUY_QUOTE_SLIPPAGE_PERCENTAGE } from '../constants'; +import { ERC20_SWAP_QUOTE_SLIPPAGE_PERCENTAGE, ERC721_SWAP_QUOTE_SLIPPAGE_PERCENTAGE } from '../constants'; import { Action, actions } from '../redux/actions'; import { AffiliateInfo, Asset, QuoteFetchOrigin } from '../types'; -import { analytics } from '../util/analytics'; -import { assetUtils } from '../util/asset'; -import { errorFlasher } from '../util/error_flasher'; -import { errorReporter } from '../util/error_reporter'; +import { analytics } from './analytics'; +import { assetUtils } from './asset'; +import { errorFlasher } from './error_flasher'; +import { errorReporter } from './error_reporter'; -export const buyQuoteUpdater = { - updateBuyQuoteAsync: async ( - assetBuyer: AssetBuyer, +export const swapQuoteUpdater = { + updateSwapQuoteAsync: async ( + swapQuoter: SwapQuoter, dispatch: Dispatch, asset: Asset, assetUnitAmount: BigNumber, @@ -27,7 +27,7 @@ export const buyQuoteUpdater = { affiliateInfo?: AffiliateInfo; }, ): Promise => { - // get a new buy quote. + // get a new swap quote. const baseUnitValue = asset.metaData.assetProxyId === AssetProxyId.ERC20 ? Web3Wrapper.toBaseUnitAmount(assetUnitAmount, asset.metaData.decimals) @@ -36,19 +36,20 @@ export const buyQuoteUpdater = { // mark quote as pending dispatch(actions.setQuoteRequestStatePending()); } + // TODO(dave4506) expose wethAssetData + feePercentage utils + const wethAssetData = ''; const feePercentage = oc(options.affiliateInfo).feePercentage(); - let newBuyQuote: BuyQuote | undefined; + let newSwapQuote: SwapQuote | undefined; const slippagePercentage = asset.metaData.assetProxyId === AssetProxyId.ERC20 - ? ERC20_BUY_QUOTE_SLIPPAGE_PERCENTAGE - : ERC721_BUY_QUOTE_SLIPPAGE_PERCENTAGE; + ? ERC20_SWAP_QUOTE_SLIPPAGE_PERCENTAGE + : ERC721_SWAP_QUOTE_SLIPPAGE_PERCENTAGE; try { - newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { - feePercentage, + newSwapQuote = await swapQuoter.getMarketBuySwapQuoteAsync(wethAssetData, asset.assetData, assetUnitAmount, { slippagePercentage, }); } catch (error) { - const errorMessage = assetUtils.assetBuyerErrorMessage(asset, error); + const errorMessage = assetUtils.swapQuoterErrorMessage(asset, error); errorReporter.report(error); analytics.trackQuoteError(error.message ? error.message : 'other', baseUnitValue, fetchOrigin); @@ -59,10 +60,10 @@ export const buyQuoteUpdater = { } return; } - // We have a successful new buy quote + // We have a successful new swap quote errorFlasher.clearError(dispatch); - // invalidate the last buy quote. - dispatch(actions.updateLatestBuyQuote(newBuyQuote)); - analytics.trackQuoteFetched(newBuyQuote, fetchOrigin); + // invalidate the last swap quote. + dispatch(actions.updateLatestSwapQuote(newSwapQuote)); + analytics.trackQuoteFetched(newSwapQuote, fetchOrigin); }, };