UNPKG

@lifi/widget

Version:

LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

91 lines (77 loc) 2.89 kB
import type { RouteExtended } from '@lifi/sdk' import { useAccount } from '@lifi/wallet-management' import { keepPreviousData, useQuery } from '@tanstack/react-query' import { parseUnits } from 'viem' import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js' import { useFieldValues } from '../stores/form/useFieldValues.js' import { isRouteDone } from '../stores/routes/utils.js' import { getQueryKey } from '../utils/queries.js' import { useTokenAddressBalance } from './useTokenAddressBalance.js' import { getTokenBalancesWithRetry } from './useTokenBalance.js' const refetchInterval = 30_000 export const useFromTokenSufficiency = (route?: RouteExtended) => { const [fromChainId, fromTokenAddress, fromAmount] = useFieldValues( 'fromChain', 'fromToken', 'fromAmount' ) const { keyPrefix } = useWidgetConfig() let chainId = fromChainId let tokenAddress = fromTokenAddress if (route) { chainId = route.fromToken.chainId tokenAddress = route.fromToken.address } const { token, chain, isLoading: isTokenAddressBalanceLoading, } = useTokenAddressBalance(chainId, tokenAddress) const { account } = useAccount({ chainType: chain?.chainType }) const { data: insufficientFromToken, isLoading } = useQuery({ queryKey: [ getQueryKey('from-token-sufficiency-check', keyPrefix), account.address, chainId, tokenAddress, route?.id ?? fromAmount, ] as const, queryFn: async ({ queryKey: [, accountAddress] }) => { if (!accountAddress || !token) { return } const parsedFromAmount = parseUnits(fromAmount, token.decimals) let currentTokenBalance = token.amount ?? 0n if (!route || isRouteDone(route)) { const insufficientFunds = currentTokenBalance < parsedFromAmount return insufficientFunds } const currentAction = route.steps.filter( (step) => !step.execution || step.execution.status !== 'DONE' )[0]?.action if ( token.chainId === currentAction.fromToken.chainId && token.address === currentAction.fromToken.address && currentTokenBalance > 0 ) { const insufficientFunds = BigInt(route.fromAmount) > currentTokenBalance return insufficientFunds } const tokenBalances = await getTokenBalancesWithRetry(accountAddress, [ currentAction.fromToken, ]) currentTokenBalance = tokenBalances?.[0]?.amount ?? 0n const insufficientFunds = BigInt(currentAction.fromAmount) > currentTokenBalance return insufficientFunds }, enabled: Boolean(account.address && token && !isTokenAddressBalanceLoading), refetchInterval, staleTime: refetchInterval, placeholderData: account.address ? keepPreviousData : undefined, }) return { insufficientFromToken, isLoading, } }