# 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: ```ts 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'); ``` 2. Update `SwapTokenSymbol` type to include new symbols: ```ts export type SwapTokenSymbol = 'ETH' | 'USDT' | 'USDC' | 'XAUT' | 'UNI' | 'PEPE' | 'stETH' | 'SHIB' | 'LINK' | 'POL' | 'WLFI' | 'AAVE'; ``` 3. Add entries to `SWAP_TOKENS` record for each new token (same pattern as existing). 4. Update `SWAP_TOKEN_OPTIONS` and `SWAP_TOKEN_OPTIONS_BY_CHAIN.ETH` to include new symbols. 5. Add V3 pool candidates for new tokens (WETH pairs with MEDIUM/HIGH fees): ```ts // 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 }, ``` 6. Add V4 pool key candidates similarly. 7. Update `getSlippageBps` to include new volatile tokens: ```ts 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): ```ts { 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`: ```ts 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 }, ``` 2. 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`: ```ts WIF: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', POPCAT: '7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr', TRUMP: '6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN', PYTH: 'HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3', JTO: 'jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL', W: '85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ', BONK: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263', ORCA: 'orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE', PENGU: '2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv', RAY: '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R', ``` 2. Add entries to `SOL_TOKEN_DECIMALS`: ```ts WIF: 6, POPCAT: 9, TRUMP: 6, PYTH: 6, JTO: 9, W: 6, BONK: 5, ORCA: 6, PENGU: 6, RAY: 6, ``` 3. Update `SWAP_TOKEN_OPTIONS_BY_CHAIN.SOL`: ```ts 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`: ```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 }, ``` 2. Add all 10 new mint addresses to `ALLOWED_MINTS` in `sol-swap-proxy.routes.ts`: ```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: ```ts export type Chain = 'ETH' | 'BTC' | 'SOL' | 'TRX' | 'BSC'; ``` 2. Add BSC derivation path (same as ETH): ```ts BSC: "m/44'/60'/0'/0/0", ``` 3. In `deriveWalletsFromMnemonic`, add BSC wallet. Since BSC uses the same key as ETH: ```ts const bsc = deriveEthWallet(mnemonic); // same key derivation // ... { chain: 'BSC', address: bsc.address, privateKey: bsc.privateKey, derivationPath: DERIVATION_PATHS.BSC }, ``` 4. In `types.ts`, update `BalanceChain`: ```ts 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`: ```ts bscRpcUrl: readUrlEnv('NEXT_PUBLIC_BSC_RPC_URL', 'https://bsc-dataseed.binance.org'), ``` 2. 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'` 3. Register in `balances/index.ts`: ```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? } ``` 2. Register in `app.ts`: ```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`: ```ts export type SwapChain = 'ETH' | 'SOL' | 'TRX' | 'BSC'; ``` 2. Add BSC token configs: ```ts export const BSC_TOKEN_ADDRESSES: Record = { BNB: 'native', DOGE: '0xbA2aE424d960c26247Dd6c32edC70B295c744C43', }; export const BSC_TOKEN_DECIMALS: Record = { BNB: 18, DOGE: 8, }; ``` 3. Add BSC to `SWAP_TOKEN_OPTIONS_BY_CHAIN`: ```ts BSC: ['BNB', 'DOGE'], ``` 4. Add BSC to `CHAIN_DEFAULT_TOKENS`: ```ts BSC: { from: 'BNB', to: 'DOGE' }, ``` 5. Update `getSlippageBpsForChain` to handle BSC: ```ts if (chain === 'BSC') return 50; // 0.50% ``` 6. Update `getExplorerTxUrl`: ```ts 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`: ```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 } ``` 2. Update swap page `CHAINS` array: ```ts const CHAINS: SwapChain[] = ['ETH', 'SOL', 'TRX', 'BSC']; ``` 3. 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: ```ts 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: ```ts 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: ```ts 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)