Files
cryptowallet/docs/plans/2026-03-18-add-tokens-and-bsc.md
2026-04-14 13:30:26 +03:00

18 KiB

Add Tokens + BSC Chain Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

Goal: Add new tokens to ETH/SOL swap+balance+send, add BNB Smart Chain as a new EVM network with PancakeSwap V2 swap.

Architecture: Extend existing multi-chain config-driven architecture. BSC reuses ETH's EVM signing logic (same derivation path, same ethers.Wallet). BSC swap via PancakeSwap V2 Router (Uniswap V2 fork) through a new API proxy. All new SOL tokens go through Jupiter (existing proxy). All new ETH tokens go through Uniswap (existing flow).

Tech Stack: ethers.js v5, Next.js, Express, PancakeSwap V2 ABI, Jupiter API, Uniswap V3/V4 SDK


Token Reference

New ETH Tokens (Uniswap swap)

Symbol Contract (checksummed) Decimals CoinGecko ID
stETH 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84 18 staked-ether
SHIB 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE 18 shiba-inu
LINK 0x514910771AF9Ca656af840dff83E8264EcF986CA 18 chainlink
POL 0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6 18 polygon-ecosystem-token
WLFI 0x66f85e3865D0cFDc009aCF6280A8621f12e46CCf 18 world-liberty-financial
AAVE 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9 18 aave

New SOL Tokens (Jupiter swap)

Symbol Mint Decimals CoinGecko ID
WIF EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm 6 dogwifcoin
POPCAT 7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr 9 popcat
TRUMP 6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN 6 official-trump
PYTH HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3 6 pyth-network
JTO jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL 9 jito-governance-token
W 85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ 6 wormhole
BONK DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263 5 bonk
ORCA orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE 6 orca
PENGU 2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv 6 pudgy-penguins
RAY 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R 6 raydium

BSC Chain Config

Property Value
ChainId 56
Native BNB (18 decimals)
WBNB 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
DOGE (BEP-20) 0xbA2aE424d960c26247Dd6c32edC70B295c744C43 (8 decimals)
PancakeSwap V2 Router 0x10ED43C718714eb63d5aA57B78B54704E256024E
Derivation Same as ETH: m/44'/60'/0'/0/0
RPC https://bsc-dataseed.binance.org + fallbacks
Explorer https://bscscan.com/tx/

Task 1: Add new ETH tokens to swap constants

Files:

  • Modify: apps/web/src/lib/swap/constants.ts

Steps:

  1. Add 6 new Token instances after PEPE:
const STETH = new Token(ETHEREUM_CHAIN_ID, '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84', 18, 'stETH', 'Lido Staked Ether');
const SHIB = new Token(ETHEREUM_CHAIN_ID, '0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE', 18, 'SHIB', 'Shiba Inu');
const LINK = new Token(ETHEREUM_CHAIN_ID, '0x514910771AF9Ca656af840dff83E8264EcF986CA', 18, 'LINK', 'Chainlink');
const POL = new Token(ETHEREUM_CHAIN_ID, '0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6', 18, 'POL', 'Polygon');
const WLFI = new Token(ETHEREUM_CHAIN_ID, '0x66f85e3865D0cFDc009aCF6280A8621f12e46CCf', 18, 'WLFI', 'World Liberty Financial');
const AAVE_TOKEN = new Token(ETHEREUM_CHAIN_ID, '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', 18, 'AAVE', 'Aave');
  1. Update SwapTokenSymbol type to include new symbols:
export type SwapTokenSymbol = 'ETH' | 'USDT' | 'USDC' | 'XAUT' | 'UNI' | 'PEPE' | 'stETH' | 'SHIB' | 'LINK' | 'POL' | 'WLFI' | 'AAVE';
  1. Add entries to SWAP_TOKENS record for each new token (same pattern as existing).

  2. Update SWAP_TOKEN_OPTIONS and SWAP_TOKEN_OPTIONS_BY_CHAIN.ETH to include new symbols.

  3. Add V3 pool candidates for new tokens (WETH pairs with MEDIUM/HIGH fees):

// stETH
{ tokenA: WETH, tokenB: STETH, fee: FeeAmount.LOW },
{ tokenA: WETH, tokenB: STETH, fee: FeeAmount.MEDIUM },
// SHIB
{ tokenA: WETH, tokenB: SHIB, fee: FeeAmount.MEDIUM },
{ tokenA: WETH, tokenB: SHIB, fee: FeeAmount.HIGH },
// LINK
{ tokenA: WETH, tokenB: LINK, fee: FeeAmount.LOW },
{ tokenA: WETH, tokenB: LINK, fee: FeeAmount.MEDIUM },
// POL
{ tokenA: WETH, tokenB: POL, fee: FeeAmount.MEDIUM },
{ tokenA: WETH, tokenB: POL, fee: FeeAmount.HIGH },
// WLFI
{ tokenA: WETH, tokenB: WLFI, fee: FeeAmount.MEDIUM },
{ tokenA: WETH, tokenB: WLFI, fee: FeeAmount.HIGH },
// AAVE
{ tokenA: WETH, tokenB: AAVE_TOKEN, fee: FeeAmount.LOW },
{ tokenA: WETH, tokenB: AAVE_TOKEN, fee: FeeAmount.MEDIUM },
  1. Add V4 pool key candidates similarly.

  2. Update getSlippageBps to include new volatile tokens:

const volatileTokens: SwapTokenSymbol[] = ['PEPE', 'XAUT', 'UNI', 'SHIB', 'WLFI', 'stETH', 'LINK', 'POL', 'AAVE'];

Task 2: Add new ETH tokens to balance fetcher

Files:

  • Modify: apps/web/src/lib/balances/eth-balances.ts

Steps:

  1. Add 6 new entries to ETH_TOKENS array (after PEPE):
{ chain: 'ETH', symbol: 'stETH', decimals: 18, contractAddress: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84', coinGeckoId: 'staked-ether', isNative: false },
{ chain: 'ETH', symbol: 'SHIB', decimals: 18, contractAddress: '0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE', coinGeckoId: 'shiba-inu', isNative: false },
{ chain: 'ETH', symbol: 'LINK', decimals: 18, contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA', coinGeckoId: 'chainlink', isNative: false },
{ chain: 'ETH', symbol: 'POL', decimals: 18, contractAddress: '0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6', coinGeckoId: 'polygon-ecosystem-token', isNative: false },
{ chain: 'ETH', symbol: 'WLFI', decimals: 18, contractAddress: '0x66f85e3865D0cFDc009aCF6280A8621f12e46CCf', coinGeckoId: 'world-liberty-financial', isNative: false },
{ chain: 'ETH', symbol: 'AAVE', decimals: 18, contractAddress: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', coinGeckoId: 'aave', isNative: false },

Task 3: Add new ETH tokens to send constants

Files:

  • Modify: apps/web/src/lib/send/constants.ts

Steps:

  1. Add 6 new token entries under SEND_CHAINS.ETH.tokens:
stETH: { symbol: 'stETH', contractAddress: '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84', decimals: 18 },
SHIB: { symbol: 'SHIB', contractAddress: '0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE', decimals: 18 },
LINK: { symbol: 'LINK', contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA', decimals: 18 },
POL: { symbol: 'POL', contractAddress: '0x455e53CBB86018Ac2B8092FdCd39d8444aFFC3F6', decimals: 18 },
WLFI: { symbol: 'WLFI', contractAddress: '0x66f85e3865D0cFDc009aCF6280A8621f12e46CCf', decimals: 18 },
AAVE: { symbol: 'AAVE', contractAddress: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', decimals: 18 },
  1. Add corresponding CONTRACT_TO_SYMBOL entries (lowercase addresses).

Task 4: Add new SOL tokens to swap constants

Files:

  • Modify: apps/web/src/lib/swap/constants.ts

Steps:

  1. Add new entries to SOL_TOKEN_MINTS:
WIF: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm',
POPCAT: '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr',
TRUMP: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN',
PYTH: 'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3',
JTO: 'jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL',
W: '85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ',
BONK: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
ORCA: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE',
PENGU: '2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv',
RAY: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R',
  1. Add entries to SOL_TOKEN_DECIMALS:
WIF: 6, POPCAT: 9, TRUMP: 6, PYTH: 6, JTO: 9, W: 6, BONK: 5, ORCA: 6, PENGU: 6, RAY: 6,
  1. Update SWAP_TOKEN_OPTIONS_BY_CHAIN.SOL:
SOL: ['SOL', 'USDT', 'USDC', 'PUMP', 'JUP', 'WIF', 'POPCAT', 'TRUMP', 'PYTH', 'JTO', 'W', 'BONK', 'ORCA', 'PENGU', 'RAY'],

Task 5: Add new SOL tokens to balance fetcher + Jupiter whitelist

Files:

  • Modify: apps/web/src/lib/balances/sol-balances.ts
  • Modify: apps/api/src/routes/sol-swap-proxy.routes.ts

Steps:

  1. Add 10 new entries to SOL_TOKENS array in sol-balances.ts:
{ chain: 'SOL', symbol: 'WIF', decimals: 6, contractAddress: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', coinGeckoId: 'dogwifcoin', isNative: false },
{ chain: 'SOL', symbol: 'POPCAT', decimals: 9, contractAddress: '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr', coinGeckoId: 'popcat', isNative: false },
{ chain: 'SOL', symbol: 'TRUMP', decimals: 6, contractAddress: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', coinGeckoId: 'official-trump', isNative: false },
{ chain: 'SOL', symbol: 'PYTH', decimals: 6, contractAddress: 'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3', coinGeckoId: 'pyth-network', isNative: false },
{ chain: 'SOL', symbol: 'JTO', decimals: 9, contractAddress: 'jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL', coinGeckoId: 'jito-governance-token', isNative: false },
{ chain: 'SOL', symbol: 'W', decimals: 6, contractAddress: '85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ', coinGeckoId: 'wormhole', isNative: false },
{ chain: 'SOL', symbol: 'BONK', decimals: 5, contractAddress: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', coinGeckoId: 'bonk', isNative: false },
{ chain: 'SOL', symbol: 'ORCA', decimals: 6, contractAddress: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE', coinGeckoId: 'orca', isNative: false },
{ chain: 'SOL', symbol: 'PENGU', decimals: 6, contractAddress: '2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv', coinGeckoId: 'pudgy-penguins', isNative: false },
{ chain: 'SOL', symbol: 'RAY', decimals: 6, contractAddress: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', coinGeckoId: 'raydium', isNative: false },
  1. Add all 10 new mint addresses to ALLOWED_MINTS in sol-swap-proxy.routes.ts:
const ALLOWED_MINTS = new Set([
  'So11111111111111111111111111111111111111112',   // SOL
  'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', // USDT
  'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
  'pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn',  // PUMP
  'JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN',  // JUP
  'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', // WIF
  '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr', // POPCAT
  '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', // TRUMP
  'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3', // PYTH
  'jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL',  // JTO
  '85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ', // W
  'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', // BONK
  'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE',  // ORCA
  '2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv', // PENGU
  '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', // RAY
]);

Task 6: Add new SOL tokens to send constants

Files:

  • Modify: apps/web/src/lib/send/constants.ts

Steps:

  1. Add 10 new token entries under SEND_CHAINS.SOL.tokens (same mint addresses as balance fetcher).

  2. Add corresponding CONTRACT_TO_SYMBOL entries for the new SOL mints.


Task 7: Add BSC chain — wallet derivation

Files:

  • Modify: apps/web/src/lib/crypto/derive-keys.ts
  • Modify: apps/web/src/lib/balances/types.ts

Steps:

  1. In derive-keys.ts, update Chain type:
export type Chain = 'ETH' | 'BTC' | 'SOL' | 'TRX' | 'BSC';
  1. Add BSC derivation path (same as ETH):
BSC: "m/44'/60'/0'/0/0",
  1. In deriveWalletsFromMnemonic, add BSC wallet. Since BSC uses the same key as ETH:
const bsc = deriveEthWallet(mnemonic); // same key derivation
// ...
{ chain: 'BSC', address: bsc.address, privateKey: bsc.privateKey, derivationPath: DERIVATION_PATHS.BSC },
  1. In types.ts, update BalanceChain:
export type BalanceChain = 'ETH' | 'BTC' | 'SOL' | 'TRX' | 'BSC';

Task 8: Add BSC chain — environment + balance fetcher

Files:

  • Modify: apps/web/src/lib/env.ts
  • Create: apps/web/src/lib/balances/bsc-balances.ts
  • Modify: apps/web/src/lib/balances/index.ts

Steps:

  1. Add BSC RPC to env.ts:
bscRpcUrl: readUrlEnv('NEXT_PUBLIC_BSC_RPC_URL', 'https://bsc-dataseed.binance.org'),
  1. Create bsc-balances.ts — copy eth-balances.ts pattern with:

    • BSC_CHAIN_ID = 56
    • BSC_RPC_CANDIDATES: webEnv.bscRpcUrl, https://bsc-dataseed1.defibit.io, https://bsc-dataseed1.ninicoin.io
    • BSC_TOKENS: BNB native (18 dec, coinGeckoId binancecoin) + DOGE BEP-20 (8 dec, 0xbA2aE424d960c26247Dd6c32edC70B295c744C43, coinGeckoId dogecoin)
    • fetchBscBalances(address) — same logic as fetchEthBalances but with BSC provider
    • All internal references use chain: 'BSC'
  2. Register in balances/index.ts:

import { fetchBscBalances } from './bsc-balances';
// ...
const SUPPORTED_CHAINS: BalanceChain[] = ['ETH', 'BTC', 'SOL', 'TRX', 'BSC'];
// ...
BSC: fetchBscBalances,

Task 9: Add BSC chain — swap via PancakeSwap V2 API proxy

Files:

  • Create: apps/api/src/routes/bsc-swap-proxy.routes.ts
  • Modify: apps/api/src/app.ts

Steps:

  1. Create bsc-swap-proxy.routes.ts — PancakeSwap V2 swap proxy (same pattern as tron-swap-proxy.routes.ts but simpler since it's EVM):
Router endpoints:
  GET  /quote  — calls PancakeSwap V2 Router getAmountsOut via BSC RPC
  POST /build  — builds swap calldata (approve + swap tx)

Key constants:
  PANCAKE_ROUTER = '0x10ED43C718714eb63d5aA57B78B54704E256024E'
  WBNB = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'
  DOGE = '0xbA2aE424d960c26247Dd6c32edC70B295c744C43'
  BSC_RPC = 'https://bsc-dataseed.binance.org'

Quote logic:
  - Create ethers provider with BSC RPC
  - Call router.getAmountsOut(amountIn, [fromToken, toToken])
  - Return { amountIn, amountOut, from, to }

Build logic:
  - For BNB->Token: encode swapExactETHForTokensSupportingFeeOnTransferTokens calldata
  - For Token->BNB: check/build approve tx + encode swapExactTokensForETHSupportingFeeOnTransferTokens calldata
  - Return { calldata, to, value, approveTx? }
  1. Register in app.ts:
import bscSwapProxyRoutes from './routes/bsc-swap-proxy.routes';
// ...
app.use('/api/bsc/swap', bscSwapProxyRoutes);

Task 10: Add BSC to swap constants + UI

Files:

  • Modify: apps/web/src/lib/swap/constants.ts

Steps:

  1. Update SwapChain:
export type SwapChain = 'ETH' | 'SOL' | 'TRX' | 'BSC';
  1. Add BSC token configs:
export const BSC_TOKEN_ADDRESSES: Record<string, string> = {
  BNB: 'native',
  DOGE: '0xbA2aE424d960c26247Dd6c32edC70B295c744C43',
};

export const BSC_TOKEN_DECIMALS: Record<string, number> = {
  BNB: 18,
  DOGE: 8,
};
  1. Add BSC to SWAP_TOKEN_OPTIONS_BY_CHAIN:
BSC: ['BNB', 'DOGE'],
  1. Add BSC to CHAIN_DEFAULT_TOKENS:
BSC: { from: 'BNB', to: 'DOGE' },
  1. Update getSlippageBpsForChain to handle BSC:
if (chain === 'BSC') return 50; // 0.50%
  1. Update getExplorerTxUrl:
case 'BSC': return `https://bscscan.com/tx/${txHash}`;

Task 11: Add BSC swap execution (client-side)

Files:

  • Create: apps/web/src/lib/swap/bsc/execute.ts
  • Modify: swap UI hooks/page to add BSC chain option

Steps:

  1. Create bsc/execute.ts:
// Similar to TRX swap execute but using ethers.Wallet directly
// 1. Fetch quote from /api/bsc/swap/quote
// 2. Build tx from /api/bsc/swap/build
// 3. If approve needed: sign and send approve tx, wait for confirmation
// 4. Sign and send swap tx via ethers.Wallet connected to BSC RPC
// 5. Return { hash, explorerUrl }
  1. Update swap page CHAINS array:
const CHAINS: SwapChain[] = ['ETH', 'SOL', 'TRX', 'BSC'];
  1. Update useSwap hook to handle BSC chain (dispatch to executeBscSwap).

Task 12: Add BSC to send/receive

Files:

  • Modify: apps/web/src/lib/send/constants.ts
  • Modify: apps/web/src/lib/send/execute.ts
  • Modify: apps/web/src/lib/send/validate.ts
  • Modify: apps/web/src/lib/qr/generate.ts
  • Modify: apps/web/src/lib/qr/parse.ts

Steps:

  1. In send/constants.ts:

    • Update SendChain: 'ETH' | 'SOL' | 'TRX' | 'BTC' | 'BSC'
    • Add BSC config:
    BSC: {
      key: 'BSC',
      label: 'BNB Smart Chain',
      walletChain: 'BSC',
      tokens: {
        BNB: { symbol: 'BNB', contractAddress: null, decimals: 18 },
        DOGE: { symbol: 'DOGE', contractAddress: '0xbA2aE424d960c26247Dd6c32edC70B295c744C43', decimals: 8 },
      },
      explorerTxUrl: 'https://bscscan.com/tx/',
    },
    
    • Add to SEND_CHAIN_OPTIONS
  2. In send/execute.ts:

    • Add BSC case — same as ETH but with BSC provider:
    case 'BSC':
      return executeBscSend(params);
    
    • executeBscSend: create ethers.providers.StaticJsonRpcProvider(bscRpcUrl, 56), use ethers.Wallet for native BNB or BEP-20 transfer (identical to ETH logic).
  3. In send/validate.ts:

    • BSC uses same address format as ETH — add case 'BSC': return validateEthAddress(address);
    • Update detectChainFromAddress — BSC can't be auto-detected (same format as ETH)
  4. In qr/generate.ts:

    • Add BSC case using ethereum: URI scheme with @56 chain discriminator:
    case 'BSC':
      return generateBscUri(address, token, amount);
    
    • generateBscUri: ethereum:${address}@56 for native, ethereum:${contract}@56/transfer?address=${to} for BEP-20
  5. In qr/parse.ts:

    • Handle @56 chain discriminator in ethereum: URIs to distinguish BSC from ETH

Task 13: Run typecheck and verify

Steps:

  1. Run pnpm typecheck from monorepo root
  2. Fix any TypeScript errors
  3. Verify all imports resolve correctly

Commit Strategy

  • After Tasks 1-3 (ETH tokens): commit "feat: add stETH, SHIB, LINK, POL, WLFI, AAVE tokens to ETH swap/balance/send"
  • After Tasks 4-6 (SOL tokens): commit "feat: add WIF, POPCAT, TRUMP, PYTH, JTO, W, BONK, ORCA, PENGU, RAY to SOL swap/balance/send"
  • After Tasks 7-12 (BSC chain): commit "feat: add BNB Smart Chain with PancakeSwap V2 swap, BNB + DOGE tokens"
  • After Task 13: commit "fix: resolve typecheck errors" (if needed)