@yodlpay/tokenlists
v1.6.0
Published
Chains, tokens, and router ABIs for the Yodl Web3 Payment Network
Downloads
3,660
Keywords
Readme
@yodlpay/tokenlists
Chains, tokens, and router ABIs for the Yodl Web3 Payment Network.
Installation
npm install @yodlpay/tokenlistsEverything is exported from the package root. The @yodlpay/tokenlists/tokens, @yodlpay/tokenlists/chains and @yodlpay/tokenlists/abis subpaths export each domain on its own.
Usage
Chains
Every per-chain fact lives on the chain entry: the router, the fee treasury, the wrapped native token, the user-facing name, and whether Yodl sponsors gas there. Read it from here rather than keeping a list of chain ids beside it.
import {
chains,
mainnetChains,
testnetChains,
getChainById,
getChainDisplayName,
getShortNames,
getNativeToken,
getRouter,
getRouterByAddress,
isSponsoredChain,
type YodlChain,
type YodlChainId,
type MainnetChainId,
type RouterConfig,
type YodlChainExtension
} from '@yodlpay/tokenlists';
// Every chain in the table, test networks included
const allChains = chains;
// Just the chains Yodl operates on in production
const production = mainnetChains;
// Get chain by ID
const arbitrum = getChainById(42161);
// Get router config for a chain
const router = getRouter(1);
// { address: '0x...', version: '0.8', fee: '0.002' }
// Get native token symbol
const symbol = getNativeToken(1); // 'ETH'
// User-facing name: the entry's own where it has one, else viem's
getChainDisplayName(10); // 'Optimism' (viem calls it 'OP Mainnet')
getChainDisplayName(11155111); // 'Chain 11155111' for anything off the table
// Whether Yodl sponsors gas there
isSponsoredChain(8453); // true
isSponsoredChain(1); // false — mainnet gas is bundled into the paymentgetNativeCoinGeckoId(chainId) sits with the token helpers below: it answers
which symbol a rates service prices the chain's gas coin under, and undefined
where the list carries no priced entry for that coin.
isYodlChainId and isMainnetChainId are the non-throwing membership checks,
narrowing to YodlChainId and MainnetChainId; getChainById throws instead.
Endpoints
The URLs Yodl serves per chain. Each takes the deployment origin as an argument,
defaulting to YODL_BASE_URL, so a staging build derives its own table from the
same chain list.
import {
YODL_BASE_URL,
getChainRpcUrl,
getBundlerUrl,
getChainExplorerUrl,
getChainRpcConfig,
getPaymasterUrl
} from '@yodlpay/tokenlists';
getChainRpcUrl(8453); // https://lite.yodl.me/api/rpc-proxy?chainId=8453
getBundlerUrl(8453); // https://lite.yodl.me/api/pimlico-boosted?chainId=8453
getChainExplorerUrl(8453); // https://basescan.org/tx
// All three at once
getChainRpcConfig(8453, 'https://staging.example');
// The paymaster to attach to a payment, or undefined where the wallet pays.
// Same URL as getBundlerUrl; this one asks whether Yodl covers the gas first.
getPaymasterUrl(8453); // the paymaster URL
getPaymasterUrl(1); // undefined — mainnet is not sponsoredTokens
import {
tokenlist,
getTokens,
getTokenByAddress,
getTokenBySymbol,
getFeaturedTokenBySymbol,
getNativeWrappedToken,
type TokenInfo
} from '@yodlpay/tokenlists';
// Get all tokens
const allTokens = tokenlist;
// Get tokens for a specific chain
const ethereumTokens = getTokens(1);
// Find token by address
const usdc = getTokenByAddress('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', 1);
// Find token by symbol
const dai = getTokenBySymbol('DAI', 1);
// Get wrapped native token
const weth = getNativeWrappedToken(1);Stablecoins
Stablecoin peg information is stored directly in token extensions via the peggedTo field:
import {
getTokenBySymbol,
type FiatCurrency,
type TokenInfo
} from '@yodlpay/tokenlists';
// Get a token and check if it's a stablecoin
const usdc = getTokenBySymbol('USDC', 1);
// Check the peggedTo field in extensions
if (usdc.extensions?.peggedTo) {
console.log(`${usdc.symbol} is pegged to ${usdc.extensions.peggedTo}`);
// "USDC is pegged to USD"
}
// Filter tokens by peg currency
import { tokenlist } from '@yodlpay/tokenlists';
const eurStablecoins = tokenlist.filter(
(token) => token.extensions?.peggedTo === 'EUR'
);Supported fiat currencies: USD, EUR, CHF, BRL, IDR, GBP, JPY, KRW, SGD, AUD, MXN, CNY, TRY
Router ABIs
import {
getRouterAbi,
YODL_ROUTER_ABIS,
type AbiVersion
} from '@yodlpay/tokenlists';
// Get ABI for a specific version
const abiV08 = getRouterAbi('0.8');
// Use with viem
import { getContract } from 'viem';
const router = getContract({
address: '0x...',
abi: getRouterAbi('0.8'),
client,
});Supported Chains
Yodl sponsors gas on every mainnet except Ethereum, where the fee is bundled into the payment instead. Test networks carry the router deployments but no paymaster.
Mainnets
| Chain | ID | Gas sponsored | | --- | --- | --- | | Ethereum | 1 | No | | Arbitrum | 42161 | Yes | | Optimism | 10 | Yes | | Base | 8453 | Yes | | Polygon | 137 | Yes | | Gnosis | 100 | Yes | | BSC | 56 | Yes | | Robinhood Chain | 4663 | Yes |
Robinhood Chain carries metadata and tokens only; no Yodl router is deployed there.
Testnets
- Arbitrum Sepolia (421614)
- BSC Testnet (97)
Development
This package lives in the yodl-sdk workspace. From packages/tokenlists:
pnpm test # unit tests
pnpm build # tsdown build to dist/
pnpm typecheck
pnpm lint
pnpm update:tokens # refresh the generated token list
pnpm validate:schema # validate both lists against the Uniswap schemaToken List Update Process
The package maintains these data files:
- Featured (
tokenlist-featured.json) - Manually curated tokens with metadata updated from on-chain data - Generated (
tokenlist-generated.json) - Auto-fetched tokens from external sources, derived fromtokenlist-generated.source.json(the last fetch) withtokenlist-overrides.jsonapplied
Stablecoin peg information is stored directly in token extensions via the peggedTo field (e.g., "peggedTo": "USD").
How pnpm update:tokens Works
- Fetch tokens from Relay Link API - Discovers tokens across all supported chains
- Fetch stablecoin data - Gets stablecoin categories from CoinGecko to determine
peggedTovalues - Match CoinGecko IDs - Links tokens to CoinGecko for market data and adds
peggedTofor stablecoins (tokens without a match are excluded) - Filter by market data - Removes low-quality tokens based on the defaults in
DEFAULT_MARKET_FILTER_CONFIG:- Market cap rank (must be ≤ 5,000)
- 24h volume (must be ≥ $7,000,000)
- Volume/market cap ratio (must be ≥ 0.1%)
- Circulating/max supply ratio (must be ≥ 0.1%)
- Remove duplicates - Tokens with duplicate symbols on the same chain are removed
- Write the source list - Updates
tokenlist-generated.source.json, then re-derivestokenlist-generated.jsonfrom it and the overrides
On-chain verification of name, symbol and decimals (scripts/lib/onchain.ts) exists but is currently not called by the pipeline.
If Relay or CoinGecko fails or returns nothing, the run aborts before writing, so an outage cannot replace the list with an empty or partial one.
Note: Steps 2, 3, and 4 use the CoinGecko Pro API and require a
COINGECKO_API_KEYenvironment variable with a valid Pro API key.
Featured Token Overrides
Some tokens intentionally have duplicates (e.g., native USDC + bridged USDC on the same chain). These are defined in FEATURED_TOKEN_OVERRIDES in src/tokens/index.ts:
FEATURED_TOKEN_OVERRIDES: Array<{
symbol: string; // Token symbol (e.g., 'USDC')
chainId: number; // Chain ID where duplicates exist
primary: string; // Default address returned by getTokenBySymbol()
addresses: string[]; // All valid addresses for this token
}>When querying by symbol, the primary address is returned. Use getTokenByAddress() to get a specific variant.
Symbol-Based Overrides
The tokenlist-overrides.json file allows you to customize generated tokens without modifying the auto-generated list. Overrides are applied by symbol (uppercase) and affect all tokens with that symbol across all chains. The published tokenlist-generated.json is always derived from tokenlist-generated.source.json plus the overrides, so a _deleted override hides tokens without losing them, and removing the override restores them.
{
"name": "Yodl Token Overrides",
"timestamp": "2024-01-01T00:00:00.000Z",
"version": { "major": 2, "minor": 0, "patch": 0 },
"overrides": {
"USDC": {
"logoURI": "https://example.com/usdc.png",
"extensions": {
"peggedTo": "USD"
}
},
"SPAM": {
"_deleted": true
}
}
}Override fields:
name- Override the token namelogoURI- Override the logo URLtags- Override tags arrayextensions- Merge additional extension fields_deleted- Set totrueto hide all tokens with this symbol
Overrides are automatically re-applied after running pnpm update:tokens. Editing a generated token in the token manager saves only the fields that differ from the source as an override, merged into the symbol's existing override; setting a field back to its source value clears that override.
Token Manager UI
A web-based UI for managing tokens is available:
pnpm tool:tokensThis starts a local server at http://localhost:3456 where you can:
- Browse featured and generated tokens
- Filter by chain, source, and search
- Add/edit overrides for generated tokens
- Mark tokens as deleted
- Validate token lists against the Uniswap schema
Token Logo Management
Token logos are stored in Vercel Blob storage. Run:
pnpm update:logosThis downloads logos from external URLs, converts them to optimized WebP format, and uploads them to Vercel Blob storage.
Requires the BLOB_READ_WRITE_TOKEN environment variable (set in .env or export). Downloaded logos land in logos/tokens/, which is not committed: the Vercel Blob store is the source of truth for token logos, and only the hand-drawn chain logos in logos/chains/ are kept in git.
Releases
Versions are managed with Changesets at the workspace root: add a changeset with a user-visible change, and the workspace release publishes the package. See the workspace README.
License
Licensed under the Business Source License 1.1 © Yodl Verein, like the rest of the yodl-sdk workspace. Production use requires prior written approval from Yodl; each version converts to MIT four years after its first public release.
