Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apps/swap): use fiat value from tines in CurrencyInput #948

Merged
merged 1 commit into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
95 changes: 95 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,95 @@
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
)
throw new Error('useUSDCPrice: Invalid input')

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())

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

throw Error(`useUSDCPrice: Unable to calculate USDC price for ${currency.name}`)
},
refetchInterval: 10000,
enabled: Boolean(
enabled && chainId && poolsCodeMap && feeData && usdcIn && currency,
),
})
}