diff --git a/src/hooks/useTokenLists.test.ts b/src/hooks/useTokenLists.test.ts index 4a5b1ee9..d76e996e 100644 --- a/src/hooks/useTokenLists.test.ts +++ b/src/hooks/useTokenLists.test.ts @@ -4,7 +4,7 @@ import type { ReactNode } from 'react' import { createElement } from 'react' import { zeroAddress } from 'viem' import { beforeEach, describe, expect, it, vi } from 'vitest' -import type { Token } from '@/src/types/token' +import { type Token, tokenSchema } from '@/src/types/token' import tokenListsCache, { updateTokenListsCache } from '@/src/utils/tokenListsCache' vi.mock('@/src/utils/tokenListsCache', () => { @@ -155,6 +155,29 @@ describe('fetchTokenList', () => { expect(result.tokens).toEqual([]) warnSpy.mockRestore() }) + + describe("'default' bundled token list", () => { + it('returns a non-empty tokens array', async () => { + const result = await fetchTokenList('default') + + expect(result.tokens.length).toBeGreaterThan(0) + expect(mockFetch).not.toHaveBeenCalled() + }) + + it('every EVM token conforms to tokenSchema', async () => { + const result = await fetchTokenList('default') + + // The bundled list includes non-EVM tokens (e.g. Solana with base58 addresses) + // alongside EVM tokens. Non-EVM entries are filtered out downstream by useTokenLists + // via safeParse. Here we validate only the EVM-addressable subset. + const evmTokens = result.tokens.filter(({ address }) => /^0x[a-fA-F0-9]{40}$/.test(address)) + expect(evmTokens.length).toBeGreaterThan(0) + for (const token of evmTokens) { + expect(() => tokenSchema.parse(token)).not.toThrow() + } + expect(mockFetch).not.toHaveBeenCalled() + }) + }) }) describe('useTokenLists', () => { diff --git a/src/hooks/useTokenLists.ts b/src/hooks/useTokenLists.ts index fe57ed64..57ddc697 100644 --- a/src/hooks/useTokenLists.ts +++ b/src/hooks/useTokenLists.ts @@ -98,7 +98,10 @@ function combineTokenLists(results: Array>): T new Map( results .flatMap((result) => result.data.tokens) - // ensure that only valid tokens are consumed in runtime + // tokenSchema enforces EVM address format (0x + 40 hex chars), so non-EVM entries + // (e.g. Solana tokens from @uniswap/default-token-list v18+) are silently dropped here. + // Supporting non-EVM chains would require changes to the address schema, chain config, + // wallet integration, and contract lookup -- out of scope for this EVM-focused starter kit. .filter((token) => { const result = tokenSchema.safeParse(token)