Skip to content

Commit

Permalink
fix: ton swap status and pricing
Browse files Browse the repository at this point in the history
  • Loading branch information
chef-eric committed Feb 13, 2025
1 parent db2c328 commit c98bc49
Show file tree
Hide file tree
Showing 18 changed files with 283 additions and 107 deletions.
1 change: 1 addition & 0 deletions apps/ton/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@pancakeswap/ton-v2-sdk": "workspace:*",
"@pancakeswap/uikit": "workspace:*",
"@pancakeswap/utils": "workspace:*",
"@pancakeswap/widgets-internal": "workspace:*",
"@tanstack/query-core": "^5.62.16",
"@tanstack/react-query": "^5.52.1",
"@ton-community/assets-sdk": "^0.0.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ const CurrencyInputPanelSimplify = memo(function CurrencyInputPanel({
wrapperRef={wrapperRef}
top={
<Flex justifyContent="space-between" alignItems="center" width="100%" position="relative">
{title || <>&nbsp;</>}
{title}
<LazyAnimatePresence mode="wait" features={domAnimation}>
{account ? (
!isInputFocus || !onMax ? (
Expand Down
34 changes: 34 additions & 0 deletions apps/ton/src/components/TonSwap/PricingAndSlippage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Currency, Price } from '@pancakeswap/ton-v2-sdk'
import { useModal } from '@pancakeswap/uikit'
import { useUserSlippage } from '@pancakeswap/utils/user'
import { SwapUIV2 } from '@pancakeswap/widgets-internal'
import { SettingsModal } from 'components/Modals/SettingsModal'

interface Props {
showSlippage?: boolean
priceLoading?: boolean
price?: Price<Currency, Currency>
}

export const PricingAndSlippage = ({ priceLoading, price, showSlippage = true }: Props) => {
const [allowedSlippage] = useUserSlippage()
const [onPresentSettingsModal] = useModal(<SettingsModal isOpen={false} />)

if (!price) {
return null
}

const priceNode = price ? (
<>
<SwapUIV2.TradePrice price={price as any} loading={priceLoading} />
</>
) : null

return (
<SwapUIV2.SwapInfo
price={priceNode}
allowedSlippage={showSlippage ? allowedSlippage : undefined}
onSlippageClick={onPresentSettingsModal}
/>
)
}
26 changes: 20 additions & 6 deletions apps/ton/src/components/TonSwap/SwapCommitButton.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import { useTranslation } from '@pancakeswap/localization'
import { Button, ButtonProps } from '@pancakeswap/uikit'
import { toNano } from '@ton/ton'
import { inputCurrencyAtom, typedValueAtom } from 'atoms/swap/swapStateAtom'
import { useAtomValue } from 'jotai'
import { isConnectedAtom } from 'ton/atom/isConnectedAtom'
import { balanceAtom } from 'ton/logic/balanceAtom'
import { tryParseAmount } from 'utils/tryParseAmount'

interface SwapCommitButtonProps extends ButtonProps {}
interface SwapCommitButtonProps extends ButtonProps {
isLoading?: boolean
}

export const SwapCommitButton = (props: SwapCommitButtonProps) => {
export const SwapCommitButton = ({ isLoading = false, ...props }: SwapCommitButtonProps) => {
const { t } = useTranslation()
const isConnected = useAtomValue(isConnectedAtom)

const inputCurrency = useAtomValue(inputCurrencyAtom)

const typedValue = useAtomValue(typedValueAtom)
const typedAmount = tryParseAmount(typedValue, inputCurrency)
const { data: balance0 } = useAtomValue(balanceAtom(inputCurrency))

const isInsufficientBalance0 = balance0 < toNano(typedValue) // TODO: decimals
const isInsufficientBalance0 = inputCurrency && typedAmount ? typedAmount.greaterThan(balance0) : false

return (
<Button disabled={isInsufficientBalance0} {...props}>
{t('Swap')}
<Button disabled={isInsufficientBalance0 || !isConnected || isLoading} {...props}>
{!isConnected
? t('Connect Wallet')
: !typedValue
? t('Enter an amount')
: isLoading
? t('Updating the quote')
: isInsufficientBalance0
? t('Insufficient %symbol% balance', { symbol: inputCurrency?.symbol })
: t('Swap')}
</Button>
)
}
27 changes: 21 additions & 6 deletions apps/ton/src/hooks/swap/useAllCommonPairs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import uniqBy from 'lodash/uniqBy'
import { Currency, Token, Pair, CurrencyAmount } from '@pancakeswap/ton-v2-sdk'
import { ADDITIONAL_BASES, BASES_TO_CHECK_TRADES_AGAINST, CUSTOM_BASES } from 'config/constants/exchange'
import { useAtomValue } from 'jotai'
import { poolDataQueriesAtom } from 'ton/atom/liquidity/poolDataQueriesAtom'
import { poolDataQueriesAtom, useRefreshPoolData } from 'ton/atom/liquidity/poolDataQueriesAtom'
import { useUserAddress } from 'hooks/useUserAddress'

export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): { isLoading: boolean; data: Pair[] } {
interface UseAllCommonPairsReturnType {
isLoading: boolean
data: Pair[]
refresh: () => void
}

export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): UseAllCommonPairsReturnType {
const chainId = currencyA?.chainId

const [tokenA, tokenB] = chainId ? [currencyA?.wrapped, currencyB?.wrapped] : [undefined, undefined]
Expand Down Expand Up @@ -60,7 +66,7 @@ export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): {
[tokenA, tokenB, bases, basePairs, chainId],
)

const { data: allPairs, isLoading } = usePairs(allPairCombinations)
const { data: allPairs, isLoading, refresh } = usePairs(allPairCombinations)

// only pass along valid pairs, non-duplicated pairs
return useMemo(
Expand All @@ -69,17 +75,19 @@ export function useAllCommonPairs(currencyA?: Currency, currencyB?: Currency): {
? {
isLoading,
data: [],
refresh,
}
: {
isLoading,
refresh,
data: allPairs
? uniqBy(
allPairs.filter((result): result is NonNullable<typeof result> => Boolean(result)),
(p) => p.poolAddress,
)
: [],
},
[allPairs, isLoading],
[allPairs, isLoading, refresh],
)
}

Expand All @@ -101,11 +109,17 @@ const usePairs = (pairs: [Token, Token][]) => {
[pairs, userAddress],
)
const result = useAtomValue(poolDataQueriesAtom(pairsAddress))
const { refresh } = useRefreshPoolData(pairsAddress)
return useMemo(() => {
const res = {
isLoading: result.isLoading,
data: result.data,
refresh,
}
if (result.isLoading) {
return {
...res,
isLoading: result.isLoading,
data: result.data,
}
}
const data = pairs.map(([token0_, token1_], idx) => {
Expand All @@ -124,8 +138,9 @@ const usePairs = (pairs: [Token, Token][]) => {
}
})
return {
...res,
isLoading: false,
data,
}
}, [pairs, result.data, result.isLoading])
}, [pairs, result.data, result.isLoading, refresh])
}
42 changes: 42 additions & 0 deletions apps/ton/src/hooks/swap/useBestTrade.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useCallback } from 'react'
import { Currency, CurrencyAmount } from '@pancakeswap/ton-v2-sdk'
import { useTradeExactIn } from './useTradeExactIn'
import { useTradeExactOut } from './useTradeExactOut'

export const useBestTrade = ({
isExactIn,
amount,
inputCurrency,
outputCurrency,
}: {
isExactIn: boolean
amount: CurrencyAmount<Currency> | undefined
inputCurrency: Currency | undefined
outputCurrency: Currency | undefined
}) => {
const {
isLoading: isTradeExactInLoading,
data: bestTradeExactIn,
refresh: refreshTradeExactIn,
} = useTradeExactIn(isExactIn ? amount : undefined, outputCurrency ?? undefined)

const {
isLoading: isTradeExactOutLoading,
data: bestTradeExactOut,
refresh: refreshTradeExactOut,
} = useTradeExactOut(isExactIn ? undefined : amount, inputCurrency ?? undefined)

const trade = isExactIn ? bestTradeExactIn : bestTradeExactOut

const refreshTrade = useCallback(() => {
refreshTradeExactIn()
refreshTradeExactOut()
}, [refreshTradeExactIn, refreshTradeExactOut])

return {
isTradeExactInLoading,
isTradeExactOutLoading,
trade,
refreshTrade,
}
}
20 changes: 12 additions & 8 deletions apps/ton/src/hooks/swap/useTradeExactIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@ import { useAllCommonPairs } from './useAllCommonPairs'
export function useTradeExactIn(
currencyAmountIn?: CurrencyAmount<Currency>,
currencyOut?: Currency,
): { isLoading: boolean; data: Trade<Currency, Currency, TradeType> | null } {
const { data: allowedPairs, isLoading } = useAllCommonPairs(currencyAmountIn?.currency, currencyOut)
): { isLoading: boolean; data: Trade<Currency, Currency, TradeType> | null; refresh: () => void } {
const { data: allowedPairs, isLoading, refresh } = useAllCommonPairs(currencyAmountIn?.currency, currencyOut)

const [singleHopOnly] = useUserSingleHopOnly()

return useMemo(() => {
const res = {
isLoading,
refresh,
data: null,
}
if (isLoading) {
return {
isLoading,
data: null,
}
return res
}
if (currencyAmountIn && currencyOut && allowedPairs.length > 0) {
if (singleHopOnly) {
return {
...res,
isLoading: false,
data:
bestTradeExactIn(allowedPairs, currencyAmountIn, currencyOut, { maxHops: 1, maxNumResults: 1 })[0] ?? null,
Expand All @@ -42,12 +45,13 @@ export function useTradeExactIn(
bestTradeSoFar = currentTrade
}
}
return { isLoading: false, data: bestTradeSoFar }
return { ...res, isLoading: false, data: bestTradeSoFar }
}

return {
...res,
isLoading: false,
data: null,
}
}, [allowedPairs, currencyAmountIn, currencyOut, singleHopOnly, isLoading])
}, [refresh, allowedPairs, currencyAmountIn, currencyOut, singleHopOnly, isLoading])
}
19 changes: 12 additions & 7 deletions apps/ton/src/hooks/swap/useTradeExactOut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@ import { useAllCommonPairs } from './useAllCommonPairs'
export function useTradeExactOut(
currencyAmountOut?: CurrencyAmount<Currency>,
currencyIn?: Currency,
): { isLoading: boolean; data: Trade<Currency, Currency, TradeType> | null } {
const { data: allowedPairs, isLoading } = useAllCommonPairs(currencyIn, currencyAmountOut?.currency)
): { isLoading: boolean; data: Trade<Currency, Currency, TradeType> | null; refresh: () => void } {
const { data: allowedPairs, isLoading, refresh } = useAllCommonPairs(currencyIn, currencyAmountOut?.currency)

const [singleHopOnly] = useUserSingleHopOnly()

return useMemo(() => {
const res = {
isLoading,
refresh,
data: null,
}
if (isLoading) {
return {
isLoading,
data: null,
}
return res
}
if (currencyIn && currencyAmountOut && allowedPairs.length > 0) {
if (singleHopOnly) {
return {
...res,
isLoading: false,
data:
bestTradeExactOut(allowedPairs, currencyIn, currencyAmountOut, { maxHops: 1, maxNumResults: 1 })[0] ?? null,
Expand All @@ -42,13 +45,15 @@ export function useTradeExactOut(
}
}
return {
...res,
isLoading: false,
data: bestTradeSoFar,
}
}
return {
...res,
isLoading: false,
data: null,
}
}, [currencyIn, currencyAmountOut, allowedPairs, singleHopOnly, isLoading])
}, [currencyIn, currencyAmountOut, allowedPairs, singleHopOnly, isLoading, refresh])
}
23 changes: 22 additions & 1 deletion apps/ton/src/ton/atom/liquidity/poolDataQueriesAtom.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useQueryClient } from '@tanstack/react-query'
import { useAtomValue } from 'jotai'
import { QUERY_DEFAULT_STALE_TIME } from 'config/constants/exchange'
import { atomWithQuery } from 'jotai-tanstack-query'
import { atomFamily } from 'jotai/utils'
Expand All @@ -11,8 +13,12 @@ interface PoolDataAtomParams {
token1Address?: string
}

const getKeyByPairs = (pairs: PoolDataAtomParams[]) => {
return pairs.map(({ token0Address, token1Address }) => `${token0Address}-${token1Address}`)
}

export const poolDataQueriesAtom = atomFamily((pairs: PoolDataAtomParams[]) => {
const key = pairs.map(({ token0Address, token1Address }) => `${token0Address}-${token1Address}`)
const key = getKeyByPairs(pairs)
return atomWithQuery((get) => ({
queryKey: ['poolData', get(networkAtom), ...key],
queryFn: async () => {
Expand All @@ -38,3 +44,18 @@ export const poolDataQueriesAtom = atomFamily((pairs: PoolDataAtomParams[]) => {
retry: 10,
}))
}, isEqual)

export function useRefreshPoolData(pairs: PoolDataAtomParams[]) {
const queryClient = useQueryClient()
const network = useAtomValue(networkAtom)
const key = getKeyByPairs(pairs)

const refresh = () => {
// Invalidate all queries
queryClient.invalidateQueries({
queryKey: ['poolData', network, ...key],
})
}

return { refresh }
}
Loading

0 comments on commit c98bc49

Please sign in to comment.