From 25c85e2974452be5015cda0b9d298c3fa0e3ec76 Mon Sep 17 00:00:00 2001 From: "Petros G. Sideris" Date: Tue, 18 Nov 2025 13:47:00 +0000 Subject: [PATCH] Autodetect tokens and fix tokens being added on demand. --- src/actions/getAccountTokens.ts | 28 ++++++++++++++++++++++++---- src/hooks/useAccountTokens.ts | 21 ++++++++++++--------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/actions/getAccountTokens.ts b/src/actions/getAccountTokens.ts index fda733a..7157a7b 100644 --- a/src/actions/getAccountTokens.ts +++ b/src/actions/getAccountTokens.ts @@ -1,5 +1,6 @@ import { type Address, parseAbiItem } from 'abitype' import type { GetLogsParameters } from 'viem' +import { erc20Abi } from 'viem' import { getLogsQueryOptions } from '~/hooks/useGetLogs' import { queryClient } from '~/react-query' @@ -17,6 +18,8 @@ export async function getAccountTokens( toBlock: GetLogsParameters['toBlock'] }, ) { + console.log('getAccountTokens params:', { address, fromBlock, toBlock }) + const [transfersFrom, transfersTo] = await Promise.all([ queryClient.fetchQuery( getLogsQueryOptions(client, { @@ -43,13 +46,30 @@ export async function getAccountTokens( }), ), ]) - - // TODO: Check if log addresses are ERC20 tokens. - - return [ + // console.log(transfersFrom, transfersTo, 'transfers'); + const potentialTokens = [ ...new Set([ ...(transfersFrom?.map((t) => t.address) || []), ...(transfersTo?.map((t) => t.address) || []), ]), ] + + const erc20Tokens = await Promise.all( + potentialTokens.map(async (tokenAddress) => { + try { + const decimals = await client.readContract({ + address: tokenAddress, + abi: erc20Abi, + functionName: 'decimals', + }) + return typeof decimals === 'number' && decimals >= 0 && decimals <= 255 + ? tokenAddress + : null + } catch { + return null + } + }), + ) + + return erc20Tokens.filter((token): token is Address => token !== null) } diff --git a/src/hooks/useAccountTokens.ts b/src/hooks/useAccountTokens.ts index cf5d5ac..e04c91f 100644 --- a/src/hooks/useAccountTokens.ts +++ b/src/hooks/useAccountTokens.ts @@ -97,19 +97,22 @@ export function useAccountTokens({ address }: UseAccountTokensParameters) { [address, network.rpcUrl, tokensStore.removeToken], ) - const tokens = useMemo( + const tokensKey = useMemo( () => address - ? tokensStore.tokens[ - getTokensKey({ - accountAddress: address, - rpcUrl: network.rpcUrl, - }) - ] - : [], - [address, network.rpcUrl, tokensStore.tokens], + ? getTokensKey({ + accountAddress: address, + rpcUrl: network.rpcUrl, + }) + : undefined, + [address, network.rpcUrl], ) + const tokens = useMemo(() => { + if (!tokensKey) return [] + return tokensStore.tokens[tokensKey] ?? [] + }, [tokensKey, tokensStore.tokens]) + return Object.assign(useQuery(queryOptions), { addToken, hideToken,