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.

90 lines 3.56 kB
import { getTokenBalances } from '@lifi/sdk'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useCallback, useMemo } from 'react'; import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'; import { getQueryKey } from '../utils/queries.js'; const defaultRefetchInterval = 30000; export const useTokenBalance = (accountAddress, token) => { const queryClient = useQueryClient(); const { keyPrefix } = useWidgetConfig(); const tokenBalanceQueryKey = useMemo(() => [ getQueryKey('token-balance', keyPrefix), accountAddress, token?.chainId, token?.address, ], [token?.address, token?.chainId, accountAddress, keyPrefix]); const { data, isLoading, refetch } = useQuery({ queryKey: tokenBalanceQueryKey, queryFn: async ({ queryKey: [, accountAddress, tokenChainId, tokenAddress], }) => { const tokenBalances = await getTokenBalancesWithRetry(accountAddress, [token]); if (!tokenBalances?.length) { throw new Error('Could not get tokens balance.'); } const cachedTokenAmount = queryClient.getQueryData(tokenBalanceQueryKey); const tokenAmount = tokenBalances[0].amount; if (cachedTokenAmount?.amount !== tokenAmount) { queryClient.setQueryDefaults(tokenBalanceQueryKey, { refetchInterval: defaultRefetchInterval, staleTime: defaultRefetchInterval, }); } queryClient.setQueriesData({ queryKey: [ getQueryKey('token-balances', keyPrefix), accountAddress, tokenChainId, ], }, (data) => { if (data) { const clonedData = [...data]; const index = clonedData.findIndex((dataToken) => dataToken.address === tokenAddress); clonedData[index] = { ...clonedData[index], amount: tokenAmount, }; return clonedData; } }); return { ...tokenBalances[0], amount: tokenAmount, }; }, enabled: Boolean(accountAddress && token), refetchInterval: defaultRefetchInterval, staleTime: defaultRefetchInterval, }); const refetchNewBalance = useCallback(() => { queryClient.setQueryDefaults(tokenBalanceQueryKey, { refetchInterval: 250, staleTime: 250, }); }, [queryClient, tokenBalanceQueryKey]); return { token: data, isLoading, refetch, refetchNewBalance, getTokenBalancesWithRetry, }; }; export const getTokenBalancesWithRetry = async (accountAddress, tokens, depth = 0) => { try { const tokenBalances = await getTokenBalances(accountAddress, tokens); if (!tokenBalances.every((token) => token.blockNumber)) { if (depth > 10) { console.warn('Token balance backoff depth exceeded.'); return undefined; } await new Promise((resolve) => { setTimeout(resolve, 1.5 ** depth * 100); }); return getTokenBalancesWithRetry(accountAddress, tokens, depth + 1); } return tokenBalances; } catch (_error) { // } }; //# sourceMappingURL=useTokenBalance.js.map