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.

110 lines (100 loc) 3.31 kB
import { ChainType, getTokens } from '@lifi/sdk' import { useQuery } from '@tanstack/react-query' import { useMemo } from 'react' import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js' import type { TokenAmount } from '../types/token.js' import { getQueryKey } from '../utils/queries.js' import { useChains } from './useChains.js' export const useTokens = (selectedChainId?: number) => { const { tokens: configTokens, keyPrefix } = useWidgetConfig() const { data, isLoading } = useQuery({ queryKey: [getQueryKey('tokens', keyPrefix)], queryFn: () => getTokens({ chainTypes: [ ChainType.EVM, ChainType.SVM, ChainType.UTXO, ChainType.MVM, ], }), refetchInterval: 300_000, staleTime: 300_000, }) const { chains, isLoading: isSupportedChainsLoading, getChainById, } = useChains() const filteredData = useMemo(() => { if (isSupportedChainsLoading || !data) { return } const chain = getChainById(selectedChainId, chains) const chainAllowed = selectedChainId && chain if (!chainAllowed) { return } let filteredTokens = data.tokens?.[selectedChainId] || [] const includedTokens = configTokens?.include?.filter( (token) => token.chainId === selectedChainId ) if (includedTokens?.length) { filteredTokens = [...includedTokens, ...filteredTokens] } const filteredTokensMap = new Map( filteredTokens.map((token) => [token.address, token]) ) const [popularTokens, featuredTokens] = ( ['popular', 'featured'] as ('popular' | 'featured')[] ).map((tokenType) => { const typedConfigTokens = configTokens?.[tokenType]?.filter( (token) => token.chainId === selectedChainId ) const populatedConfigTokens = typedConfigTokens?.map((token) => { // Mark token as popular ;(token as TokenAmount)[tokenType] = true // Check if this token exists in the filteredTokensMap and add priceUSD if it does const matchingFilteredToken = filteredTokensMap.get(token.address) if (matchingFilteredToken?.priceUSD) { ;(token as TokenAmount).priceUSD = matchingFilteredToken.priceUSD } if (!token.logoURI && matchingFilteredToken) { ;(token as TokenAmount).logoURI = matchingFilteredToken.logoURI } return token }) as TokenAmount[] if (populatedConfigTokens?.length) { const configTokenAddresses = new Set( populatedConfigTokens?.map((token) => token.address) ) filteredTokens = filteredTokens.filter( (token) => !configTokenAddresses.has(token.address) ) populatedConfigTokens.push(...filteredTokens) filteredTokens = populatedConfigTokens } return populatedConfigTokens }) return { tokens: filteredTokens, featuredTokens, popularTokens, chain, } }, [ chains, configTokens, data, getChainById, isSupportedChainsLoading, selectedChainId, ]) return { tokens: filteredData?.tokens, featuredTokens: filteredData?.featuredTokens, popularTokens: filteredData?.popularTokens, chain: filteredData?.chain, isLoading, } }