@pulsadev/token-list
v0.1.0
Published
On-chain ERC-20/721/1155 token metadata resolver — batch queries, standard detection, token list validation. Zero dependencies, pure RPC.
Readme
@pulsadev/token-list
On-chain ERC-20/721/1155 token metadata resolver — batch queries, standard detection, token list validation. Zero dependencies, pure RPC.
Resolve any token's name, symbol, decimals, and supply from the chain. No etherscan, no external APIs.
Features
- On-chain token resolution — fetch name, symbol, decimals, totalSupply via
eth_call - Token standard detection — auto-detect ERC-20 vs ERC-721 vs ERC-1155 via ERC-165
- Batch resolution — resolve multiple tokens in parallel
- Balance & allowance queries —
balanceOf,allowancefor any holder/spender - Token list parsing — parse and validate Uniswap-standard token list JSON
- Token list utilities — filter, search, merge, deduplicate token lists
- Well-known tokens — built-in registry of major tokens across 7 chains
- Stablecoin & native helpers —
getStablecoinsByChain,getWrappedNative - bytes32 string decoding — handles old tokens (MKR, SAI) that return bytes32 instead of string
- Zero dependencies — ~29 KB bundled, ESM + CJS, pure TypeScript
Install
npm install @pulsadev/token-listQuick Start
Resolve token metadata
import { resolveToken } from '@pulsadev/token-list'
const usdc = await resolveToken('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', {
rpcUrl: 'https://ethereum-rpc.publicnode.com',
})
console.log(usdc.name) // 'USD Coin'
console.log(usdc.symbol) // 'USDC'
console.log(usdc.decimals) // 6
console.log(usdc.totalSupply) // 26000000000000n
console.log(usdc.standard) // 'ERC-20'Batch resolve
import { resolveTokens } from '@pulsadev/token-list'
const tokens = await resolveTokens(
['0xA0b8...', '0xdAC1...', '0x6B17...'],
{ rpcUrl: 'https://ethereum-rpc.publicnode.com', chainId: 1 }
)
tokens.forEach(t => console.log(`${t.symbol}: ${t.decimals} decimals`))Get balances
import { getBalance, getBalances } from '@pulsadev/token-list'
const balance = await getBalance(
'0xA0b8...', // token
'0xd8dA...', // holder
{ rpcUrl: 'https://ethereum-rpc.publicnode.com' }
)
console.log(`${balance.balance} (${balance.decimals} decimals)`)
// Batch
const balances = await getBalances(
['0xA0b8...', '0xdAC1...', '0x6B17...'],
'0xd8dA...',
{ rpcUrl: 'https://ethereum-rpc.publicnode.com' }
)Check allowance
import { getAllowance } from '@pulsadev/token-list'
const allowance = await getAllowance(
'0xA0b8...', // token
'0xd8dA...', // owner
'0x7a25...', // spender (e.g. Uniswap router)
{ rpcUrl: 'https://ethereum-rpc.publicnode.com' }
)Parse token lists
import { parseTokenList, filterByChain, findBySymbol, mergeTokenLists } from '@pulsadev/token-list'
const list = parseTokenList(jsonString)
// Filter by chain
const ethTokens = filterByChain(list, 1)
// Find by symbol
const usdc = findBySymbol(list, 'USDC', 1)
// Merge multiple lists (deduplicates by chainId + address)
const merged = mergeTokenLists(list1, list2, list3)Well-known tokens
import {
getWellKnownToken,
getWellKnownTokensByChain,
getStablecoinsByChain,
getWrappedNative,
} from '@pulsadev/token-list'
getWellKnownToken(1, 'WETH') // { address, name, symbol, decimals, chainId }
getWellKnownToken(1, '0xA0b8..') // find by address too
getWellKnownTokensByChain(1) // all known tokens on Ethereum
getStablecoinsByChain(1) // [USDC, USDT, DAI]
getWrappedNative(56) // WBNB on BSCAPI
Token Resolution
| Function | Description |
|----------|-------------|
| resolveToken(address, options) | Resolve single token metadata from chain |
| resolveTokens(addresses, options) | Batch resolve multiple tokens |
| getBalance(token, holder, options) | Get ERC-20 balance for holder |
| getBalances(tokens, holder, options) | Batch get balances for multiple tokens |
| getAllowance(token, owner, spender, options) | Get ERC-20 allowance |
| detectStandard(rpcUrl, address, decimals) | Auto-detect token standard |
Token List Utilities
| Function | Description |
|----------|-------------|
| parseTokenList(json) | Parse and validate token list JSON |
| validateTokenList(data) | Validate token list object |
| filterByChain(list, chainId) | Filter tokens by chain |
| findBySymbol(list, symbol, chainId?) | Find token by symbol |
| findByAddress(list, address, chainId?) | Find token by address |
| mergeTokenLists(...lists) | Merge lists with deduplication |
| tokenListToMap(list) | Convert to Map<"chainId:address", entry> |
Well-Known Tokens
| Function | Description |
|----------|-------------|
| getWellKnownToken(chainId, symbolOrAddress) | Find well-known token |
| getWellKnownTokensByChain(chainId) | All known tokens for a chain |
| getStablecoinsByChain(chainId) | Stablecoins on a chain |
| getWrappedNative(chainId) | Wrapped native token (WETH, WBNB, etc.) |
Supported Chains (Well-Known Registry)
Ethereum (1), BSC (56), Polygon (137), Arbitrum (42161), Optimism (10), Base (8453), Avalanche (43114)
TokenInfo
interface TokenInfo {
address: Address
chainId: number
standard: 'ERC-20' | 'ERC-721' | 'ERC-1155' | 'unknown'
name: string | null
symbol: string | null
decimals: number | null
totalSupply: bigint | null
}License
MIT © Yuto Nakamura
