diff --git a/.changeset/full-points-stand.md b/.changeset/full-points-stand.md new file mode 100644 index 000000000..1ec7491c7 --- /dev/null +++ b/.changeset/full-points-stand.md @@ -0,0 +1,6 @@ +--- +'@relayprotocol/relay-sdk': patch +'@relayprotocol/relay-kit-ui': patch +--- + +Refactor token selector currency metadata fetching diff --git a/packages/sdk/src/types/RelayChain.ts b/packages/sdk/src/types/RelayChain.ts index 9967da927..04715de19 100644 --- a/packages/sdk/src/types/RelayChain.ts +++ b/packages/sdk/src/types/RelayChain.ts @@ -45,6 +45,7 @@ export type RelayChain = { depositEnabled?: boolean blockProductionLagging?: boolean erc20Currencies?: RelayAPIChain['erc20Currencies'] + solverCurrencies?: RelayAPIChain['solverCurrencies'] featuredTokens?: RelayAPIChain['featuredTokens'] tags?: RelayAPIChain['tags'] iconUrl?: string | null diff --git a/packages/ui/src/components/common/TokenSelector/TokenSelector.tsx b/packages/ui/src/components/common/TokenSelector/TokenSelector.tsx index d0557b7d8..8af824a60 100644 --- a/packages/ui/src/components/common/TokenSelector/TokenSelector.tsx +++ b/packages/ui/src/components/common/TokenSelector/TokenSelector.tsx @@ -20,13 +20,17 @@ import useRelayClient from '../../../hooks/useRelayClient.js' import { type Address } from 'viem' import { useDebounceState, useDuneBalances } from '../../../hooks/index.js' import { useMediaQuery } from 'usehooks-ts' -import { useTokenList } from '@relayprotocol/relay-kit-hooks' +import { + type Currency, + useTokenList, + useTrendingCurrencies +} from '@relayprotocol/relay-kit-hooks' import { EventNames } from '../../../constants/events.js' import { UnverifiedTokenModal } from '../UnverifiedTokenModal.js' import { useEnhancedTokensList } from '../../../hooks/useEnhancedTokensList.js' import { TokenList } from './TokenList.js' import { UnsupportedDepositAddressChainIds } from '../../../constants/depositAddresses.js' -import { getRelayUiKitData } from '../../../utils/localStorage.js' +import { getRelayUiKitData, getStarredChainIds } from '../../../utils/localStorage.js' import { isValidAddress as isValidAddressUtil } from '../../../utils/address.js' import { AccessibleList, @@ -43,6 +47,7 @@ import { bitcoinDeadAddress, evmDeadAddress, solDeadAddress, + ASSETS_RELAY_API, type ChainVM } from '@relayprotocol/relay-sdk' import { @@ -50,8 +55,6 @@ import { sortChains } from '../../../utils/tokenSelector.js' import { useInternalRelayChains } from '../../../hooks/index.js' -import { useTrendingCurrencies } from '@relayprotocol/relay-kit-hooks' -import { getStarredChainIds } from '../../../utils/localStorage.js' export type TokenSelectorProps = { token?: Token @@ -217,13 +220,52 @@ const TokenSelector: FC = ({ }, [duneTokens?.balances, configuredChainIds]) const userTokensQuery = useMemo(() => { + if (depositAddressOnly) { + return undefined + } + if (filteredDuneTokenBalances && filteredDuneTokenBalances.length > 0) { - return filteredDuneTokenBalances.map( + const sortedBalances = [...filteredDuneTokenBalances] + .sort((a, b) => (b.value_usd ?? 0) - (a.value_usd ?? 0)) + .slice(0, 100) + + return sortedBalances.map( (balance) => `${balance.chain_id}:${balance.address}` ) } return undefined - }, [filteredDuneTokenBalances]) + }, [filteredDuneTokenBalances, depositAddressOnly]) + + const solverUserTokens = useMemo(() => { + if (!depositAddressOnly) { + return undefined + } + + const tokenMap = new Map() + + configuredChains.forEach((chain) => { + chain.solverCurrencies?.forEach((currency) => { + if (!currency.address || !currency.symbol || !currency.name) return + const tokenKey = `${chain.id}:${currency.address.toLowerCase()}` + const logoId = currency.id ?? currency.symbol.toLowerCase() + + tokenMap.set(tokenKey, { + chainId: chain.id, + address: currency.address, + symbol: currency.symbol, + name: currency.name, + decimals: currency.decimals ?? 18, + vmType: chain.vmType, + metadata: { + verified: true, + logoURI: `${ASSETS_RELAY_API}/icons/currencies/${logoId}.png` + } + }) + }) + }) + + return Array.from(tokenMap.values()) + }, [depositAddressOnly, configuredChains]) // Get user's tokens from currencies api const { data: userTokens, isLoading: isLoadingUserTokens } = useTokenList( @@ -232,15 +274,20 @@ const TokenSelector: FC = ({ ? { tokens: userTokensQuery, limit: 100, - depositAddressOnly, + depositAddressOnly: false, referrer: relayClient?.source } : undefined, { - enabled: !!filteredDuneTokenBalances + enabled: !depositAddressOnly && !!userTokensQuery } ) + const resolvedUserTokens = depositAddressOnly ? solverUserTokens : userTokens + const isLoadingResolvedUserTokens = depositAddressOnly + ? !allRelayChains + : isLoadingUserTokens + const isSearchTermValidAddress = isValidAddressUtil( chainFilter.vmType, debouncedTokenSearchValue, @@ -303,7 +350,7 @@ const TokenSelector: FC = ({ }, [tokenList, externalTokenList, debouncedTokenSearchValue]) const sortedUserTokens = useEnhancedTokensList( - userTokens, + resolvedUserTokens, tokenBalances, context, multiWalletSupportEnabled, @@ -774,7 +821,7 @@ const TokenSelector: FC = ({ { title: 'Your Tokens', tokens: sortedUserTokens, - isLoading: isLoadingUserTokens, + isLoading: isLoadingResolvedUserTokens, show: sortedUserTokens.length > 0 }, {