Some checks are pending
CI/CD Pipeline / Solidity Contracts (push) Waiting to run
CI/CD Pipeline / Security Scanning (push) Waiting to run
CI/CD Pipeline / Lint and Format (push) Waiting to run
CI/CD Pipeline / Terraform Validation (push) Waiting to run
CI/CD Pipeline / Kubernetes Validation (push) Waiting to run
Deploy ChainID 138 / Deploy ChainID 138 (push) Waiting to run
Validation / validate-genesis (push) Waiting to run
Validation / validate-terraform (push) Waiting to run
Validation / validate-kubernetes (push) Waiting to run
Validation / validate-smart-contracts (push) Waiting to run
Validation / validate-security (push) Waiting to run
Validation / validate-documentation (push) Waiting to run
Verify Deployment / Verify Deployment (push) Waiting to run
242 lines
18 KiB
TypeScript
242 lines
18 KiB
TypeScript
/**
|
|
* Canonical token list for GRU base money, W-tokens, asset (ac*), and debt (vdc* / sdc*) tokens.
|
|
* Used for CMC/CoinGecko reporting and token-aggregation indexing.
|
|
* Addresses can be overridden via env (e.g. CUSDC_ADDRESS_138) or filled by indexer.
|
|
*/
|
|
|
|
export type TokenType = 'base' | 'w' | 'asset' | 'debt';
|
|
|
|
export interface CanonicalTokenSpec {
|
|
symbol: string;
|
|
name: string;
|
|
type: TokenType;
|
|
decimals: number;
|
|
currencyCode?: string; // ISO-4217 for base/w
|
|
/** ChainId -> contract address (placeholder or from env) */
|
|
addresses: Partial<Record<number, string>>;
|
|
description?: string;
|
|
websiteUrl?: string;
|
|
logoUrl?: string;
|
|
/** v1 matrix symbol for origin reference only (e.g. cXUSDC when bridged); on Chain 138 symbol is v0 only (no X) */
|
|
v1Symbol?: string;
|
|
/** v0 symbol alias; on ChainID 138 tokens use v0 only (cUSDC, cUSDT), no chain designator */
|
|
v0Alias?: string;
|
|
}
|
|
|
|
const CHAIN_138 = 138;
|
|
const CHAIN_25 = 25; // Cronos
|
|
const CHAIN_651940 = 651940;
|
|
/** L2/mainnet chain IDs for cUSDT/cUSDC multichain (env: CUSDT_ADDRESS_56, CUSDC_ADDRESS_137, etc.) */
|
|
const L2_CHAIN_IDS = [1, 56, 137, 10, 42161, 8453, 43114, 25, 100, 42220, 1111] as const;
|
|
|
|
/** Verified addresses from CHAIN138_TOKEN_ADDRESSES, .env, and deployment summaries */
|
|
const FALLBACK_ADDRESSES: Record<string, Partial<Record<number, string>>> = {
|
|
USDC: {
|
|
[CHAIN_138]: '0x71D6687F38b93CCad569Fa6352c876eea967201b',
|
|
},
|
|
USDT: {
|
|
[CHAIN_138]: '0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1',
|
|
},
|
|
cUSDC: {
|
|
[CHAIN_138]: '0xf22258f57794CC8E06237084b353Ab30fFfa640b',
|
|
[CHAIN_651940]: '0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881', // AUSDC on ALL Mainnet
|
|
[1]: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Ethereum USDC
|
|
[56]: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', // BSC USDC
|
|
[137]: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c1369', // Polygon USDC
|
|
[100]: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83', // Gnosis USDC
|
|
[10]: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // Optimism USDC
|
|
[42161]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', // Arbitrum USDC
|
|
[8453]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // Base USDC
|
|
[43114]: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E', // Avalanche USDC
|
|
[CHAIN_25]: '0xc21223249CA28397B4B6541dfFaEcC539BfF0c59', // Cronos USDC
|
|
[42220]: '0xcebA9300f2b948710d2653dD7B07f33A8B32118C', // Celo USDC
|
|
[1111]: '0xE3F5a90F9cb311505cd691a46596599aA1A0AD7D', // Wemix USDC
|
|
},
|
|
cUSDT: {
|
|
[CHAIN_138]: '0x93E66202A11B1772E55407B32B44e5Cd8eda7f22',
|
|
[CHAIN_651940]: '0x015B1897Ed5279930bC2Be46F661894d219292A6', // AUSDT primary on ALL Mainnet
|
|
[1]: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // Ethereum USDT
|
|
[56]: '0x55d398326f99059fF775485246999027B3197955', // BSC USDT
|
|
[137]: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', // Polygon USDT
|
|
[100]: '0x4ECaBa5870353805a9F068101A40E0f32ed605C6', // Gnosis USDT
|
|
[10]: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', // Optimism USDT
|
|
[42161]: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', // Arbitrum USDT
|
|
[8453]: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2', // Base USDT
|
|
[43114]: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7', // Avalanche USDT
|
|
[CHAIN_25]: '0x66e4286603D22FF153A6547700f37C7Eae42F8E2', // Cronos USDT
|
|
[42220]: '0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e', // Celo USDT
|
|
[1111]: '0xA649325Aa7C5093d12D6F98EB4378deAe68CE23F', // Wemix USDT
|
|
},
|
|
// Compliant Fiat on Chain 138 — from DeployCompliantFiatTokens (2026-02-27)
|
|
cEURC: { [CHAIN_138]: '0x8085961F9cF02b4d800A3c6d386D31da4B34266a' },
|
|
cEURT: { [CHAIN_138]: '0xdf4b71c61E5912712C1Bdd451416B9aC26949d72' },
|
|
cGBPC: { [CHAIN_138]: '0x003960f16D9d34F2e98d62723B6721Fb92074aD2' },
|
|
cGBPT: { [CHAIN_138]: '0x350f54e4D23795f86A9c03988c7135357CCaD97c' },
|
|
cAUDC: { [CHAIN_138]: '0xD51482e567c03899eecE3CAe8a058161FD56069D' },
|
|
cJPYC: { [CHAIN_138]: '0xEe269e1226a334182aace90056EE4ee5Cc8A6770' },
|
|
cCHFC: { [CHAIN_138]: '0x873990849DDa5117d7C644f0aF24370797C03885' },
|
|
cCADC: { [CHAIN_138]: '0x54dBd40cF05e15906A2C21f600937e96787f5679' },
|
|
cXAUC: { [CHAIN_138]: '0x290E52a8819A4fbD0714E517225429aA2B70EC6b' },
|
|
cXAUT: { [CHAIN_138]: '0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E' },
|
|
// ISO-4217W on Cronos (25) — from DeployISO4217WSystem
|
|
USDW: { [CHAIN_25]: '0x948690147D2e50ffe50C5d38C14125aD6a9FA036' },
|
|
EURW: { [CHAIN_25]: '0x58a8D8F78F1B65c06dAd7542eC46b299629A60dd' },
|
|
GBPW: { [CHAIN_25]: '0xFb4B6Cc81211F7d886950158294A44C312abCA29' },
|
|
AUDW: { [CHAIN_25]: '0xf9f5D0ACD71C76F9476F10B3F3d3E201F0883C68' },
|
|
JPYW: { [CHAIN_25]: '0xeE17bB0322383fecCA2784fbE2d4CD7d02b1905B' },
|
|
CHFW: { [CHAIN_25]: '0xc9750828124D4c10e7a6f4B655cA8487bD3842EB' },
|
|
CADW: { [CHAIN_25]: '0x328Cd365Bb35524297E68ED28c6fF2C9557d1363' },
|
|
};
|
|
|
|
function addr(symbol: string, chainId: number): string | undefined {
|
|
if (chainId === CHAIN_138 && symbol === 'USDT') {
|
|
return process.env.USDT_ADDRESS_138 || process.env.OFFICIAL_USDT_ADDRESS || FALLBACK_ADDRESSES[symbol]?.[chainId];
|
|
}
|
|
if (chainId === CHAIN_138 && symbol === 'USDC') {
|
|
return process.env.USDC_ADDRESS_138 || process.env.OFFICIAL_USDC_ADDRESS || FALLBACK_ADDRESSES[symbol]?.[chainId];
|
|
}
|
|
const key = `${symbol.replace(/-/g, '_').toUpperCase()}_ADDRESS_${chainId}`;
|
|
const envVal = process.env[key];
|
|
if (envVal && envVal.trim() !== '') return envVal;
|
|
return FALLBACK_ADDRESSES[symbol]?.[chainId];
|
|
}
|
|
|
|
export const CANONICAL_TOKENS: CanonicalTokenSpec[] = [
|
|
// --- Base (GRU-M1) ---
|
|
// Local Chain 138 quote-side mirror stables used by PMM pools.
|
|
{ symbol: 'USDC', name: 'USD Coin (Official Mirror)', type: 'base', decimals: 6, currencyCode: 'USD', addresses: { [CHAIN_138]: addr('USDC', CHAIN_138) || '' } },
|
|
{ symbol: 'USDT', name: 'Tether USD (Official Mirror)', type: 'base', decimals: 6, currencyCode: 'USD', addresses: { [CHAIN_138]: addr('USDT', CHAIN_138) || '' } },
|
|
// Chain 138 v0 only (no X): cUSDC on 138; cXUSDC used only for bridged/origin reference elsewhere. See ISO4217_COMPLIANT_TOKEN_MATRIX.md
|
|
{ symbol: 'cUSDC', name: 'USD Coin (Compliant)', type: 'base', decimals: 6, currencyCode: 'USD', v0Alias: 'cUSDC', addresses: { [CHAIN_138]: addr('cUSDC', CHAIN_138) || '', [CHAIN_651940]: addr('cUSDC', CHAIN_651940) || '', ...Object.fromEntries(L2_CHAIN_IDS.map((id) => [id, addr('cUSDC', id)])) } },
|
|
// Chain 138 v0 only (no X): cUSDT on 138; cXUSDT used only for bridged/origin reference elsewhere. See ISO4217_COMPLIANT_TOKEN_MATRIX.md
|
|
{ symbol: 'cUSDT', name: 'Tether USD (Compliant)', type: 'base', decimals: 6, currencyCode: 'USD', v0Alias: 'cUSDT', addresses: { [CHAIN_138]: addr('cUSDT', CHAIN_138) || '', [CHAIN_651940]: addr('cUSDT', CHAIN_651940) || '', ...Object.fromEntries(L2_CHAIN_IDS.map((id) => [id, addr('cUSDT', id)])) } },
|
|
{ symbol: 'cEURC', name: 'Euro Coin (Compliant)', type: 'base', decimals: 6, currencyCode: 'EUR', addresses: { [CHAIN_138]: addr('cEURC', CHAIN_138), [CHAIN_651940]: addr('cEURC', CHAIN_651940) } },
|
|
{ symbol: 'cEURT', name: 'Tether EUR (Compliant)', type: 'base', decimals: 6, currencyCode: 'EUR', addresses: { [CHAIN_138]: addr('cEURT', CHAIN_138), [CHAIN_651940]: addr('cEURT', CHAIN_651940) } },
|
|
{ symbol: 'cGBPC', name: 'Pound Sterling (Compliant)', type: 'base', decimals: 6, currencyCode: 'GBP', addresses: { [CHAIN_138]: addr('cGBPC', CHAIN_138), [CHAIN_651940]: addr('cGBPC', CHAIN_651940) } },
|
|
{ symbol: 'cGBPT', name: 'Tether GBP (Compliant)', type: 'base', decimals: 6, currencyCode: 'GBP', addresses: { [CHAIN_138]: addr('cGBPT', CHAIN_138), [CHAIN_651940]: addr('cGBPT', CHAIN_651940) } },
|
|
{ symbol: 'cAUDC', name: 'Australian Dollar (Compliant)', type: 'base', decimals: 6, currencyCode: 'AUD', addresses: { [CHAIN_138]: addr('cAUDC', CHAIN_138), [CHAIN_651940]: addr('cAUDC', CHAIN_651940) } },
|
|
{ symbol: 'cJPYC', name: 'Japanese Yen (Compliant)', type: 'base', decimals: 6, currencyCode: 'JPY', addresses: { [CHAIN_138]: addr('cJPYC', CHAIN_138), [CHAIN_651940]: addr('cJPYC', CHAIN_651940) } },
|
|
{ symbol: 'cCHFC', name: 'Swiss Franc (Compliant)', type: 'base', decimals: 6, currencyCode: 'CHF', addresses: { [CHAIN_138]: addr('cCHFC', CHAIN_138), [CHAIN_651940]: addr('cCHFC', CHAIN_651940) } },
|
|
{ symbol: 'cCADC', name: 'Canadian Dollar (Compliant)', type: 'base', decimals: 6, currencyCode: 'CAD', addresses: { [CHAIN_138]: addr('cCADC', CHAIN_138), [CHAIN_651940]: addr('cCADC', CHAIN_651940) } },
|
|
{
|
|
symbol: 'cXAUC',
|
|
name: 'Gold (Compliant)',
|
|
type: 'base',
|
|
decimals: 6,
|
|
currencyCode: 'XAU',
|
|
description: '1 full token = 1 troy ounce fine gold (10^6 base units = 1 oz).',
|
|
addresses: { [CHAIN_138]: addr('cXAUC', CHAIN_138), [CHAIN_651940]: addr('cXAUC', CHAIN_651940) },
|
|
},
|
|
{
|
|
symbol: 'cXAUT',
|
|
name: 'Tether XAU (Compliant)',
|
|
type: 'base',
|
|
decimals: 6,
|
|
currencyCode: 'XAU',
|
|
description: '1 full token = 1 troy ounce fine gold (10^6 base units = 1 oz).',
|
|
addresses: { [CHAIN_138]: addr('cXAUT', CHAIN_138), [CHAIN_651940]: addr('cXAUT', CHAIN_651940) },
|
|
},
|
|
{ symbol: 'LiXAU', name: 'XAU Liquidity-adjusted', type: 'base', decimals: 6, currencyCode: 'XAU', addresses: { [CHAIN_138]: addr('LiXAU', CHAIN_138), [CHAIN_651940]: addr('LiXAU', CHAIN_651940) } },
|
|
// --- ISO-4217 W ---
|
|
{ symbol: 'USDW', name: 'USD W Token', type: 'w', decimals: 2, currencyCode: 'USD', addresses: { [CHAIN_138]: addr('USDW', CHAIN_138), [CHAIN_25]: addr('USDW', CHAIN_25), [CHAIN_651940]: addr('USDW', CHAIN_651940) } },
|
|
{ symbol: 'EURW', name: 'EUR W Token', type: 'w', decimals: 2, currencyCode: 'EUR', addresses: { [CHAIN_138]: addr('EURW', CHAIN_138), [CHAIN_25]: addr('EURW', CHAIN_25), [CHAIN_651940]: addr('EURW', CHAIN_651940) } },
|
|
{ symbol: 'GBPW', name: 'GBP W Token', type: 'w', decimals: 2, currencyCode: 'GBP', addresses: { [CHAIN_138]: addr('GBPW', CHAIN_138), [CHAIN_25]: addr('GBPW', CHAIN_25), [CHAIN_651940]: addr('GBPW', CHAIN_651940) } },
|
|
{ symbol: 'AUDW', name: 'AUD W Token', type: 'w', decimals: 2, currencyCode: 'AUD', addresses: { [CHAIN_138]: addr('AUDW', CHAIN_138), [CHAIN_25]: addr('AUDW', CHAIN_25), [CHAIN_651940]: addr('AUDW', CHAIN_651940) } },
|
|
{ symbol: 'JPYW', name: 'JPY W Token', type: 'w', decimals: 2, currencyCode: 'JPY', addresses: { [CHAIN_138]: addr('JPYW', CHAIN_138), [CHAIN_25]: addr('JPYW', CHAIN_25), [CHAIN_651940]: addr('JPYW', CHAIN_651940) } },
|
|
{ symbol: 'CHFW', name: 'CHF W Token', type: 'w', decimals: 2, currencyCode: 'CHF', addresses: { [CHAIN_138]: addr('CHFW', CHAIN_138), [CHAIN_25]: addr('CHFW', CHAIN_25), [CHAIN_651940]: addr('CHFW', CHAIN_651940) } },
|
|
{ symbol: 'CADW', name: 'CAD W Token', type: 'w', decimals: 2, currencyCode: 'CAD', addresses: { [CHAIN_138]: addr('CADW', CHAIN_138), [CHAIN_25]: addr('CADW', CHAIN_25), [CHAIN_651940]: addr('CADW', CHAIN_651940) } },
|
|
// --- Asset (ac*) ---
|
|
{ symbol: 'acUSDC', name: 'Deposit cUSDC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acUSDC', CHAIN_138), [CHAIN_651940]: addr('acUSDC', CHAIN_651940) } },
|
|
{ symbol: 'acUSDT', name: 'Deposit cUSDT', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acUSDT', CHAIN_138), [CHAIN_651940]: addr('acUSDT', CHAIN_651940) } },
|
|
{ symbol: 'acEURC', name: 'Deposit cEURC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acEURC', CHAIN_138), [CHAIN_651940]: addr('acEURC', CHAIN_651940) } },
|
|
{ symbol: 'acGBPC', name: 'Deposit cGBPC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acGBPC', CHAIN_138), [CHAIN_651940]: addr('acGBPC', CHAIN_651940) } },
|
|
{ symbol: 'acAUDC', name: 'Deposit cAUDC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acAUDC', CHAIN_138), [CHAIN_651940]: addr('acAUDC', CHAIN_651940) } },
|
|
{ symbol: 'acJPYC', name: 'Deposit cJPYC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acJPYC', CHAIN_138), [CHAIN_651940]: addr('acJPYC', CHAIN_651940) } },
|
|
{ symbol: 'acCHFC', name: 'Deposit cCHFC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acCHFC', CHAIN_138), [CHAIN_651940]: addr('acCHFC', CHAIN_651940) } },
|
|
{ symbol: 'acCADC', name: 'Deposit cCADC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acCADC', CHAIN_138), [CHAIN_651940]: addr('acCADC', CHAIN_651940) } },
|
|
{ symbol: 'acXAUC', name: 'Deposit cXAUC', type: 'asset', decimals: 6, addresses: { [CHAIN_138]: addr('acXAUC', CHAIN_138), [CHAIN_651940]: addr('acXAUC', CHAIN_651940) } },
|
|
// --- Debt (vdc* / sdc*) ---
|
|
{ symbol: 'vdcUSDC', name: 'Debt cUSDC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcUSDC', CHAIN_138), [CHAIN_651940]: addr('vdcUSDC', CHAIN_651940) } },
|
|
{ symbol: 'sdcUSDC', name: 'Debt cUSDC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcUSDC', CHAIN_138), [CHAIN_651940]: addr('sdcUSDC', CHAIN_651940) } },
|
|
{ symbol: 'vdcUSDT', name: 'Debt cUSDT (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcUSDT', CHAIN_138), [CHAIN_651940]: addr('vdcUSDT', CHAIN_651940) } },
|
|
{ symbol: 'sdcUSDT', name: 'Debt cUSDT (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcUSDT', CHAIN_138), [CHAIN_651940]: addr('sdcUSDT', CHAIN_651940) } },
|
|
{ symbol: 'vdcEURC', name: 'Debt cEURC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcEURC', CHAIN_138), [CHAIN_651940]: addr('vdcEURC', CHAIN_651940) } },
|
|
{ symbol: 'sdcEURC', name: 'Debt cEURC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcEURC', CHAIN_138), [CHAIN_651940]: addr('sdcEURC', CHAIN_651940) } },
|
|
{ symbol: 'vdcGBPC', name: 'Debt cGBPC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcGBPC', CHAIN_138), [CHAIN_651940]: addr('vdcGBPC', CHAIN_651940) } },
|
|
{ symbol: 'sdcGBPC', name: 'Debt cGBPC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcGBPC', CHAIN_138), [CHAIN_651940]: addr('sdcGBPC', CHAIN_651940) } },
|
|
{ symbol: 'vdcAUDC', name: 'Debt cAUDC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcAUDC', CHAIN_138), [CHAIN_651940]: addr('vdcAUDC', CHAIN_651940) } },
|
|
{ symbol: 'sdcAUDC', name: 'Debt cAUDC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcAUDC', CHAIN_138), [CHAIN_651940]: addr('sdcAUDC', CHAIN_651940) } },
|
|
{ symbol: 'vdcJPYC', name: 'Debt cJPYC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcJPYC', CHAIN_138), [CHAIN_651940]: addr('vdcJPYC', CHAIN_651940) } },
|
|
{ symbol: 'sdcJPYC', name: 'Debt cJPYC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcJPYC', CHAIN_138), [CHAIN_651940]: addr('sdcJPYC', CHAIN_651940) } },
|
|
{ symbol: 'vdcCHFC', name: 'Debt cCHFC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcCHFC', CHAIN_138), [CHAIN_651940]: addr('vdcCHFC', CHAIN_651940) } },
|
|
{ symbol: 'sdcCHFC', name: 'Debt cCHFC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcCHFC', CHAIN_138), [CHAIN_651940]: addr('sdcCHFC', CHAIN_651940) } },
|
|
{ symbol: 'vdcCADC', name: 'Debt cCADC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcCADC', CHAIN_138), [CHAIN_651940]: addr('vdcCADC', CHAIN_651940) } },
|
|
{ symbol: 'sdcCADC', name: 'Debt cCADC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcCADC', CHAIN_138), [CHAIN_651940]: addr('sdcCADC', CHAIN_651940) } },
|
|
{ symbol: 'vdcXAUC', name: 'Debt cXAUC (variable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('vdcXAUC', CHAIN_138), [CHAIN_651940]: addr('vdcXAUC', CHAIN_651940) } },
|
|
{ symbol: 'sdcXAUC', name: 'Debt cXAUC (stable)', type: 'debt', decimals: 6, addresses: { [CHAIN_138]: addr('sdcXAUC', CHAIN_138), [CHAIN_651940]: addr('sdcXAUC', CHAIN_651940) } },
|
|
];
|
|
|
|
export function getCanonicalTokensByChain(chainId: number): CanonicalTokenSpec[] {
|
|
return CANONICAL_TOKENS.filter(
|
|
(t) => t.addresses[chainId] && String(t.addresses[chainId]).trim() !== ''
|
|
);
|
|
}
|
|
|
|
export function getCanonicalTokenByAddress(chainId: number, address: string): CanonicalTokenSpec | undefined {
|
|
const lower = address.toLowerCase();
|
|
return CANONICAL_TOKENS.find((t) => t.addresses[chainId]?.toLowerCase() === lower);
|
|
}
|
|
|
|
export function getCanonicalTokenBySymbol(chainId: number, symbol: string): CanonicalTokenSpec | undefined {
|
|
const normalized = symbol.trim().toLowerCase();
|
|
return CANONICAL_TOKENS.find(
|
|
(t) => t.symbol.toLowerCase() === normalized && t.addresses[chainId] && String(t.addresses[chainId]).trim() !== ''
|
|
);
|
|
}
|
|
|
|
/** IPFS-hosted logo URLs (Pinata) for Uniswap token list (logoURI).
|
|
* Every token must have logoURI for MetaMask to display icons. getLogoUriForSpec resolves
|
|
* ac-tokens from base (c*), vdc/sdc from base; unknown symbols fall back to ETH_LOGO. */
|
|
const IPFS_GATEWAY = 'https://ipfs.io/ipfs';
|
|
const ETH_LOGO = `${IPFS_GATEWAY}/Qma3FKtLce9MjgJgWbtyCxBiPjJ6xi8jGWUSKNS5Jc2ong`;
|
|
const USDC_LOGO = `${IPFS_GATEWAY}/QmNPq4D5JXzurmi9jAhogVMzhAQRk1PZ1r9H3qQUV9gjDm`;
|
|
const USDT_LOGO = `${IPFS_GATEWAY}/QmRfhPs9DcyFPpGjKwF6CCoVDWUHSxkQR34n9NK7JSbPCP`;
|
|
|
|
const LOGO_BY_SYMBOL: Record<string, string> = {
|
|
USDC: USDC_LOGO,
|
|
USDT: USDT_LOGO,
|
|
cUSDC: USDC_LOGO,
|
|
cUSDT: USDT_LOGO,
|
|
cEURC: USDC_LOGO,
|
|
cEURT: USDT_LOGO,
|
|
cGBPC: `${IPFS_GATEWAY}/QmNQF73WjxU6FwTXNH8PXoDRFaSFKTYQWL7d4Q1kdRVJ4o`,
|
|
cGBPT: `${IPFS_GATEWAY}/QmV4frsJmDTWzLdxdj1z81uMqVXcbGpHZLzwkpj6GvEX4k`,
|
|
cAUDC: `${IPFS_GATEWAY}/QmPh16PY241zNtePyeK7ep1uf1RcARV2ynGAuRU8U7sSqS`,
|
|
cJPYC: `${IPFS_GATEWAY}/Qmb9JmuD9ehaQtTLBBZmAoiAbvE53e3FMjkEty8rvbPf9K`,
|
|
cCHFC: `${IPFS_GATEWAY}/QmPh16PY241zNtePyeK7ep1uf1RcARV2ynGAuRU8U7sSqS`,
|
|
cCADC: `${IPFS_GATEWAY}/QmPh16PY241zNtePyeK7ep1uf1RcARV2ynGAuRU8U7sSqS`,
|
|
cXAUC: ETH_LOGO,
|
|
cXAUT: ETH_LOGO,
|
|
LiXAU: `${IPFS_GATEWAY}/QmUVY5trUM5N1UnS4abReb66fNzGw7kenjU9AjL7TgR3M1`,
|
|
USDW: USDC_LOGO,
|
|
EURW: `${IPFS_GATEWAY}/QmPh16PY241zNtePyeK7ep1uf1RcARV2ynGAuRU8U7sSqS`,
|
|
GBPW: `${IPFS_GATEWAY}/QmT2nJ6WyhYBCsYJ6NfS1BPAqiGKkCEuMxiC8ye93Co1hF`,
|
|
AUDW: `${IPFS_GATEWAY}/Qmb9JmuD9ehaQtTLBBZmAoiAbvE53e3FMjkEty8rvbPf9K`,
|
|
JPYW: `${IPFS_GATEWAY}/Qmb9JmuD9ehaQtTLBBZmAoiAbvE53e3FMjkEty8rvbPf9K`,
|
|
CHFW: `${IPFS_GATEWAY}/Qmb9JmuD9ehaQtTLBBZmAoiAbvE53e3FMjkEty8rvbPf9K`,
|
|
CADW: `${IPFS_GATEWAY}/Qmb9JmuD9ehaQtTLBBZmAoiAbvE53e3FMjkEty8rvbPf9K`,
|
|
};
|
|
|
|
/** Resolve logo URI for a canonical token (Uniswap token list format). */
|
|
export function getLogoUriForSpec(spec: CanonicalTokenSpec): string {
|
|
if (spec.logoUrl) return spec.logoUrl;
|
|
const bySymbol = LOGO_BY_SYMBOL[spec.symbol];
|
|
if (bySymbol) return bySymbol;
|
|
if (spec.symbol.startsWith('ac')) return getLogoUriForSpec(CANONICAL_TOKENS.find((t) => t.symbol === spec.symbol.replace('ac', 'c')) || spec);
|
|
if (spec.symbol.startsWith('vdc') || spec.symbol.startsWith('sdc')) {
|
|
const base = spec.symbol.replace(/^(vd|sd)c/, 'c');
|
|
return getLogoUriForSpec(CANONICAL_TOKENS.find((t) => t.symbol === base) || spec);
|
|
}
|
|
return ETH_LOGO;
|
|
}
|