65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
|
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
|
||
|
import { Trade } from '@uniswap/v3-sdk'
|
||
|
import { V3TradeState } from 'state/routing/types'
|
||
|
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
|
||
|
import { useRoutingAPIEnabled } from 'state/user/hooks'
|
||
|
import { useClientSideV3Trade } from './useClientSideV3Trade'
|
||
|
import useDebounce from './useDebounce'
|
||
|
import useIsWindowVisible from './useIsWindowVisible'
|
||
|
|
||
|
/**
|
||
|
* Returns the best v3 trade for a desired swap.
|
||
|
* Uses optimized routes from the Routing API and falls back to the v3 router.
|
||
|
* @param tradeType whether the swap is an exact in/out
|
||
|
* @param amountSpecified the exact amount to swap in/out
|
||
|
* @param otherCurrency the desired output/payment currency
|
||
|
*/
|
||
|
export function useBestV3Trade(
|
||
|
tradeType: TradeType,
|
||
|
amountSpecified?: CurrencyAmount<Currency>,
|
||
|
otherCurrency?: Currency
|
||
|
): {
|
||
|
state: V3TradeState
|
||
|
trade: Trade<Currency, Currency, typeof tradeType> | null
|
||
|
} {
|
||
|
const routingAPIEnabled = useRoutingAPIEnabled()
|
||
|
const isWindowVisible = useIsWindowVisible()
|
||
|
|
||
|
const debouncedAmount = useDebounce(amountSpecified, 100)
|
||
|
|
||
|
const routingAPITrade = useRoutingAPITrade(
|
||
|
tradeType,
|
||
|
routingAPIEnabled && isWindowVisible ? debouncedAmount : undefined,
|
||
|
otherCurrency
|
||
|
)
|
||
|
|
||
|
const isLoading = amountSpecified !== undefined && debouncedAmount === undefined
|
||
|
|
||
|
// consider trade debouncing when inputs/outputs do not match
|
||
|
const debouncing =
|
||
|
routingAPITrade.trade &&
|
||
|
amountSpecified &&
|
||
|
(tradeType === TradeType.EXACT_INPUT
|
||
|
? !routingAPITrade.trade.inputAmount.equalTo(amountSpecified) ||
|
||
|
!amountSpecified.currency.equals(routingAPITrade.trade.inputAmount.currency) ||
|
||
|
!otherCurrency?.equals(routingAPITrade.trade.outputAmount.currency)
|
||
|
: !routingAPITrade.trade.outputAmount.equalTo(amountSpecified) ||
|
||
|
!amountSpecified.currency.equals(routingAPITrade.trade.outputAmount.currency) ||
|
||
|
!otherCurrency?.equals(routingAPITrade.trade.inputAmount.currency))
|
||
|
|
||
|
const useFallback = !routingAPIEnabled || (!debouncing && routingAPITrade.state === V3TradeState.NO_ROUTE_FOUND)
|
||
|
|
||
|
// only use client side router if routing api trade failed
|
||
|
const bestV3Trade = useClientSideV3Trade(
|
||
|
tradeType,
|
||
|
useFallback ? debouncedAmount : undefined,
|
||
|
useFallback ? otherCurrency : undefined
|
||
|
)
|
||
|
|
||
|
return {
|
||
|
...(useFallback ? bestV3Trade : routingAPITrade),
|
||
|
...(debouncing ? { state: V3TradeState.SYNCING } : {}),
|
||
|
...(isLoading ? { state: V3TradeState.LOADING } : {}),
|
||
|
}
|
||
|
}
|