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.

97 lines 4.34 kB
import { ChainType, getToken, getTokens, } from '@lifi/sdk'; import { useQuery } from '@tanstack/react-query'; import { useMemo } from 'react'; import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'; import { defaultChainIdsByType, getChainTypeFromAddress, } from '../utils/chainType.js'; import { isItemAllowed } from '../utils/item.js'; import { getQueryKey } from '../utils/queries.js'; import { filterAllowedTokens, mergeVerifiedWithSearchTokens, } from '../utils/token.js'; const refetchInterval = 300000; export const useTokens = (formType, search, chainId) => { const { tokens: configTokens, chains: chainsConfig, keyPrefix, } = useWidgetConfig(); // Main tokens cache - verified tokens from API const { data: verifiedTokens, isLoading } = useQuery({ queryKey: [getQueryKey('tokens', keyPrefix)], queryFn: async ({ signal }) => { const chainTypes = [ ChainType.EVM, ChainType.SVM, ChainType.UTXO, ChainType.MVM, ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types)); const tokensResponse = await getTokens({ chainTypes, orderBy: 'volumeUSD24H', extended: true, limit: 1000, }, { signal }); // Mark all tokens as verified const tokens = Object.fromEntries(Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [ chainId, tokens.map((token) => ({ ...token, verified: true })), ])); return tokens; }, refetchInterval, staleTime: refetchInterval, }); // Search tokens cache - unverified tokens from search const { data: searchTokens, isLoading: isSearchLoading } = useQuery({ queryKey: [getQueryKey('tokens-search', keyPrefix), search, chainId], queryFn: async ({ queryKey, signal }) => { const [, searchQuery, searchChainId] = queryKey; const chainTypes = [ ChainType.EVM, ChainType.SVM, ChainType.UTXO, ChainType.MVM, ].filter((chainType) => isItemAllowed(chainType, chainsConfig?.types)); const tokensResponse = await getTokens({ chainTypes, orderBy: 'volumeUSD24H', extended: true, search: searchQuery, limit: 1000, }, { signal }); // If the chainId is not provided, try to get it from the search query let _chainId = searchChainId; if (!_chainId) { const chainType = getChainTypeFromAddress(searchQuery); if (chainType) { _chainId = defaultChainIdsByType[chainType]; } } // Fallback: If the main search returned no tokens for the specific chainId, // fetch a single token using the /token endpoint if (_chainId && searchQuery) { const existingTokens = tokensResponse.tokens[_chainId] || []; if (!existingTokens.length) { const token = await getToken(_chainId, searchQuery, { signal }); if (token) { tokensResponse.tokens[_chainId] = [token]; } } } // Mark all search tokens as unverified const tokens = Object.fromEntries(Object.entries(tokensResponse.tokens).map(([chainId, tokens]) => [ chainId, tokens.map((token) => ({ ...token, verified: false })), ])); return tokens; }, enabled: !!search, refetchInterval, staleTime: refetchInterval, }); // Merge tokens at read time - single place where caches are combined const allTokens = useMemo(() => { const merged = mergeVerifiedWithSearchTokens(verifiedTokens, searchTokens); return filterAllowedTokens(merged, configTokens, chainsConfig, formType); }, [verifiedTokens, searchTokens, configTokens, chainsConfig, formType]); return { allTokens, isLoading, isSearchLoading, }; }; //# sourceMappingURL=useTokens.js.map