Skip to content

Commit

Permalink
feat(apps/swap): use fiat value from AMM in CurrencyInput
Browse files Browse the repository at this point in the history
  • Loading branch information
0xMasayoshi committed Jun 26, 2023
1 parent 0e479aa commit bb849e4
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 21 deletions.
14 changes: 8 additions & 6 deletions apps/_root/lib/swap/usePctChange.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { useMemo } from 'react'
import { ZERO } from '@sushiswap/math'
import { useSwapState } from '../../ui/swap/trade/TradeProvider'
import { usePrice } from '@sushiswap/react-query'
import { useUSDCPrice } from '@sushiswap/wagmi/future/hooks'
import { useTrade } from './useTrade'

export const usePctChange = () => {
const { token1, token0, network0, network1, amount } = useSwapState()
const { data: price0 } = usePrice({ chainId: network0, address: token0?.wrapped?.address })
const { data: price1 } = usePrice({ chainId: network1, address: token1?.wrapped?.address })
const { data: price0 } = useUSDCPrice({ currency: token0, chainId: network0 })
const { data: price1 } = useUSDCPrice({ currency: token1, chainId: network1 })
const { data: trade } = useTrade({ crossChain: network0 !== network1 })

return useMemo(() => {
if (!trade?.priceImpact) return undefined

const inputUSD = amount && price0 ? amount.multiply(price0.asFraction) : undefined
const outputUSD = trade?.amountOut && price1 ? trade.amountOut.multiply(price1.asFraction) : undefined
return inputUSD && outputUSD && inputUSD?.greaterThan(ZERO)
const inputUSD = amount && price0 ? price0.quote(amount) : undefined
const outputUSD =
trade?.amountOut && price1 ? price1.quote(trade.amountOut) : undefined

return inputUSD && outputUSD && inputUSD.greaterThan(ZERO)
? ((Number(outputUSD?.toExact()) - Number(inputUSD?.toExact())) / Number(inputUSD?.toExact())) * 100
: undefined
}, [trade?.priceImpact, trade?.amountOut, amount, price0, price1])
Expand Down
3 changes: 1 addition & 2 deletions apps/_root/ui/swap/widget/SwapCurrencyOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ export const SwapCurrencyOutput: FC = () => {
onSelect={setToken1}
value={trade?.amountOut?.toSignificant() ?? ''}
currency={token1}
usdPctChange={undefined}
// usdPctChange={trade?.route?.status === 'NoWay' ? undefined : usdPctChange}
usdPctChange={trade?.route?.status === 'NoWay' ? undefined : usdPctChange}
loading={Boolean(isLoading && +value > 0) || isFetching || tokensLoading}
disableMaxButton
currencyLoading={tokensLoading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import { useAccount } from 'wagmi'
import { TokenSelector } from '../../TokenSelector/TokenSelector'
import { BalancePanel } from './BalancePanel'
import { PricePanel } from './PricePanel'
import { usePrice } from '@sushiswap/react-query'
import { useBalanceWeb3 } from '../../../hooks'
import { useBalanceWeb3, useUSDCPrice } from '../../../hooks'
import dynamic from 'next/dynamic'

export interface CurrencyInputProps {
Expand Down Expand Up @@ -63,9 +62,9 @@ export const Component: FC<CurrencyInputProps> = ({
currency,
})

const { data: price, isInitialLoading: isPriceLoading } = usePrice({
const { data: price, isInitialLoading: isPriceLoading } = useUSDCPrice({
chainId: currency?.chainId,
address: currency?.wrapped?.address,
currency
})

const _value = useMemo(() => tryParseAmount(value, currency), [value, currency])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { tryParseAmount } from '@sushiswap/currency'
import { Price, Type, tryParseAmount } from '@sushiswap/currency'
import { classNames } from '@sushiswap/ui'
import { Skeleton } from '@sushiswap/ui/future/components/skeleton'
import { FC, useMemo } from 'react'

import { CurrencyInputProps } from './CurrencyInput'
import { Fraction, ZERO } from '@sushiswap/math'
import { ZERO } from '@sushiswap/math'

type PricePanel = Pick<CurrencyInputProps, 'loading' | 'currency' | 'value' | 'usdPctChange'> & {
error?: string
price: Fraction | undefined
price: Price<Type, Type> | undefined
}

export const PricePanel: FC<PricePanel> = ({ loading, price, currency, value, usdPctChange, error }) => {
const parsedValue = useMemo(() => tryParseAmount(value, currency), [currency, value])
const [big, portion] = (parsedValue && price ? `${parsedValue.multiply(price.asFraction).toFixed(2)}` : '0.00').split(

const [big, portion] = (parsedValue && price ? `${price.quote(parsedValue).toFixed(2)}` : '0.00').split(
'.'
)

Expand All @@ -37,7 +37,7 @@ export const PricePanel: FC<PricePanel> = ({ loading, price, currency, value, us
$ {big}.<span className="text-sm font-semibold">{portion}</span>
</>
)}
{!(!loading && price?.equalTo(ZERO)) && usdPctChange && usdPctChange !== 0 && (
{!(!loading && price?.equalTo(ZERO)) && usdPctChange && usdPctChange !== 0 ? (
<span
className={classNames(
'text-sm pl-1',
Expand All @@ -55,7 +55,7 @@ export const PricePanel: FC<PricePanel> = ({ loading, price, currency, value, us
usdPctChange?.toFixed(2) === '0.00' ? '' : `${usdPctChange?.toFixed(2)}%)`
}`}
</span>
)}
) : null}
</p>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const getAllPoolsCodeMap = async ({ currencyA, currencyB, chainId }: Omit

const testLiquidityProviders = [...sushiLiquidityProviders]

const dataFetcher = DataFetcher.onChain(chainId)
const dataFetcher = new DataFetcher(chainId)
console.log('IS TEST', isTest)
dataFetcher.startDataFetching(isTest ? testLiquidityProviders : liquidityProviders)
await dataFetcher.fetchPoolsForToken(currencyA, currencyB)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getAllPoolsCodeMap } from '../actions/getAllPoolsCodeMap'
export const usePoolsCodeMap = ({ enabled = true, ...variables }: UsePoolsParams) => {
const { chainId, currencyA, currencyB } = variables
return useQuery({
queryKey: ['usePools', { chainId, currencyA, currencyB }],
queryKey: ['usePoolsCodeMap', { chainId, currencyA, currencyB }],
queryFn: async () => await getAllPoolsCodeMap(variables),
refetchInterval: 10000,
enabled,
Expand Down
1 change: 1 addition & 0 deletions packages/wagmi/src/future/hooks/trade/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './useClientTrade'
export * from './useUSDCPrice'
97 changes: 97 additions & 0 deletions packages/wagmi/src/future/hooks/trade/hooks/useUSDCPrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useMemo } from 'react'
import { useFeeData } from 'wagmi'
import { Amount, Price, Type, USDC } from '@sushiswap/currency'
import { ChainId } from '@sushiswap/chain'
import { useQuery } from '@tanstack/react-query'
import { usePoolsCodeMap } from '../../pools'
import { Router } from '@sushiswap/router'
import { ZERO } from '@sushiswap/math'
import { parseUnits } from 'ethers/lib/utils.js'

export const useUSDCPrice = ({
currency,
chainId,
enabled = true,
}: {
currency: Type | undefined
chainId: ChainId | undefined
enabled?: boolean
}) => {
const { usdc, usdcIn } = useMemo(() => {
const usdc =
chainId && chainId in USDC
? USDC[chainId as keyof typeof USDC]
: undefined

return {
usdc,
usdcIn: usdc ? parseUnits('1000', usdc.decimals) : undefined,
}
}, [chainId])

const { data: feeData } = useFeeData({ chainId: chainId })

const _chainId = chainId || 1

const { data: poolsCodeMap } = usePoolsCodeMap({
chainId: _chainId,
currencyA: usdc,
currencyB: currency,
enabled: Boolean(chainId && usdc && currency),
withBentoPools: true,
})

return useQuery({
queryKey: [
'useUSDCPrice',
{
chainId,
currency,
poolsCodeMap,
},
],
queryFn: async () => {
if (
!chainId ||
!poolsCodeMap ||
!usdc ||
!usdcIn ||
!currency ||
!feeData?.gasPrice
)
return null

if (currency.equals(usdc)) {
const amount = Amount.fromRawAmount(usdc, usdcIn.toString())
return new Price({ baseAmount: amount, quoteAmount: amount })
}

const route = Router.findBestRoute(
poolsCodeMap,
chainId,
usdc,
usdcIn,
currency,
feeData.gasPrice.toNumber(),
)

if (route) {
const amountOut = Amount.fromRawAmount(
currency,
route.amountOutBN.toString(),
)
const amountIn = Amount.fromRawAmount(usdc, route.amountInBN.toString())

return amountOut.greaterThan(ZERO)
? new Price({ baseAmount: amountOut, quoteAmount: amountIn })
: null
}

return null
},
refetchInterval: 10000,
enabled: Boolean(
enabled && chainId && poolsCodeMap && feeData && usdcIn && currency,
),
})
}

0 comments on commit bb849e4

Please sign in to comment.