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.

99 lines (88 loc) 3.16 kB
import { useMemo } from 'react' import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js' import type { FormType } from '../stores/form/types.js' import { isSearchMatch, processTokenBalances } from '../utils/tokenList.js' import { useAccountsBalancesData } from './useAccountsBalancesData.js' import { useTokenBalancesQueries } from './useTokenBalancesQueries.js' import { useTokens } from './useTokens.js' export const useTokenBalances = ( selectedChainId?: number, formType?: FormType, isAllNetworks?: boolean, search?: string ) => { const { allTokens, isLoading: isTokensLoading, isSearchLoading, } = useTokens(formType, search, isAllNetworks ? undefined : selectedChainId) const { data: accountsWithAllTokens, isLoading: isAccountsLoading } = useAccountsBalancesData(selectedChainId, formType, isAllNetworks, allTokens) const isBalanceLoadingEnabled = Boolean(accountsWithAllTokens) && !isAccountsLoading const { data: allTokensWithBalances, isLoading: isBalanceQueriesLoading } = useTokenBalancesQueries(accountsWithAllTokens, isBalanceLoadingEnabled) const { tokens: configTokens } = useWidgetConfig() const isBalanceLoading = (isBalanceQueriesLoading || isAccountsLoading) && !allTokensWithBalances?.length const displayedTokensList = useMemo(() => { const tokensByChain = isAllNetworks ? Object.values(allTokens ?? {}).flat() : selectedChainId ? allTokens?.[selectedChainId] : undefined return tokensByChain?.filter((t) => isSearchMatch(t, search)) ?? [] }, [allTokens, isAllNetworks, selectedChainId, search]) const displayedTokensWithBalances = useMemo(() => { const balancesByChain = isAllNetworks ? allTokensWithBalances : selectedChainId ? allTokensWithBalances?.filter((t) => t.chainId === selectedChainId) : undefined const displayedTokensSet = new Set( displayedTokensList?.map( (t) => `${t.chainId}-${t.address.toLowerCase()}` ) || [] ) return balancesByChain?.filter((token) => { const tokenKey = `${token.chainId}-${token.address.toLowerCase()}` // Check if token is in displayed list and has amount const isInDisplayedList = displayedTokensSet.has(tokenKey) && token.amount // Check if it matches search (for cached appended tokens) const matchesSearch = isSearchMatch(token, search) return isInDisplayedList || matchesSearch }) }, [ allTokensWithBalances, displayedTokensList, search, selectedChainId, isAllNetworks, ]) const { processedTokens, withCategories } = useMemo(() => { return processTokenBalances( isBalanceLoading, isAllNetworks || !!search, configTokens, selectedChainId, displayedTokensList, displayedTokensWithBalances ) }, [ isBalanceLoading, isAllNetworks, configTokens, selectedChainId, displayedTokensList, displayedTokensWithBalances, search, ]) return { tokens: processedTokens ?? [], withCategories, isTokensLoading, isSearchLoading, isBalanceLoading, } }