b74fb8174d
* feat: add RouterPreference.PRICE * docs: add reference to quote params * fix: cache routers between usages * fix: tune price inquiries * fix: note price queries tuning * fix: clean up params - nix mixed * fix: defer PRICE tuning
94 lines
3.4 KiB
TypeScript
94 lines
3.4 KiB
TypeScript
import { Currency, CurrencyAmount, Price, Token, TradeType } from '@uniswap/sdk-core'
|
|
import { useWeb3React } from '@web3-react/core'
|
|
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
|
|
import { useMemo, useRef } from 'react'
|
|
import { RouterPreference } from 'state/routing/slice'
|
|
import { useRoutingAPITrade } from 'state/routing/useRoutingAPITrade'
|
|
|
|
import { SupportedChainId } from '../constants/chains'
|
|
import { CUSD_CELO, DAI_OPTIMISM, USDC_ARBITRUM, USDC_MAINNET, USDC_POLYGON } from '../constants/tokens'
|
|
|
|
// Stablecoin amounts used when calculating spot price for a given currency.
|
|
// The amount is large enough to filter low liquidity pairs.
|
|
export const STABLECOIN_AMOUNT_OUT: { [chainId: number]: CurrencyAmount<Token> } = {
|
|
[SupportedChainId.MAINNET]: CurrencyAmount.fromRawAmount(USDC_MAINNET, 100_000e6),
|
|
[SupportedChainId.ARBITRUM_ONE]: CurrencyAmount.fromRawAmount(USDC_ARBITRUM, 10_000e6),
|
|
[SupportedChainId.OPTIMISM]: CurrencyAmount.fromRawAmount(DAI_OPTIMISM, 10_000e18),
|
|
[SupportedChainId.POLYGON]: CurrencyAmount.fromRawAmount(USDC_POLYGON, 10_000e6),
|
|
[SupportedChainId.CELO]: CurrencyAmount.fromRawAmount(CUSD_CELO, 10_000e18),
|
|
}
|
|
|
|
/**
|
|
* Returns the price in USDC of the input currency
|
|
* @param currency currency to compute the USDC price of
|
|
*/
|
|
export default function useStablecoinPrice(currency?: Currency): Price<Currency, Token> | undefined {
|
|
const chainId = currency?.chainId
|
|
|
|
const amountOut = chainId ? STABLECOIN_AMOUNT_OUT[chainId] : undefined
|
|
const stablecoin = amountOut?.currency
|
|
|
|
const { trade } = useRoutingAPITrade(TradeType.EXACT_OUTPUT, amountOut, currency, RouterPreference.PRICE)
|
|
const price = useMemo(() => {
|
|
if (!currency || !stablecoin) {
|
|
return undefined
|
|
}
|
|
|
|
// handle usdc
|
|
if (currency?.wrapped.equals(stablecoin)) {
|
|
return new Price(stablecoin, stablecoin, '1', '1')
|
|
}
|
|
|
|
if (trade) {
|
|
const { numerator, denominator } = trade.routes[0].midPrice
|
|
return new Price(currency, stablecoin, denominator, numerator)
|
|
}
|
|
|
|
return undefined
|
|
}, [currency, stablecoin, trade])
|
|
|
|
const lastPrice = useRef(price)
|
|
if (!price || !lastPrice.current || !price.equalTo(lastPrice.current)) {
|
|
lastPrice.current = price
|
|
}
|
|
return lastPrice.current
|
|
}
|
|
|
|
export function useStablecoinValue(currencyAmount: CurrencyAmount<Currency> | undefined | null) {
|
|
const price = useStablecoinPrice(currencyAmount?.currency)
|
|
|
|
return useMemo(() => {
|
|
if (!price || !currencyAmount) return null
|
|
try {
|
|
return price.quote(currencyAmount)
|
|
} catch (error) {
|
|
return null
|
|
}
|
|
}, [currencyAmount, price])
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param fiatValue string representation of a USD amount
|
|
* @returns CurrencyAmount where currency is stablecoin on active chain
|
|
*/
|
|
export function useStablecoinAmountFromFiatValue(fiatValue: string | null | undefined) {
|
|
const { chainId } = useWeb3React()
|
|
const stablecoin = chainId ? STABLECOIN_AMOUNT_OUT[chainId]?.currency : undefined
|
|
|
|
return useMemo(() => {
|
|
if (fiatValue === null || fiatValue === undefined || !chainId || !stablecoin) {
|
|
return undefined
|
|
}
|
|
|
|
// trim for decimal precision when parsing
|
|
const parsedForDecimals = parseFloat(fiatValue).toFixed(stablecoin.decimals).toString()
|
|
try {
|
|
// parse USD string into CurrencyAmount based on stablecoin decimals
|
|
return tryParseCurrencyAmount(parsedForDecimals, stablecoin)
|
|
} catch (error) {
|
|
return undefined
|
|
}
|
|
}, [chainId, fiatValue, stablecoin])
|
|
}
|