/** * Test suite for chain configuration utilities * Run with: bun run test-chain-config.ts */ import { getChainConfig, getMultipleChainConfigs, getCustomizedChains, withCustomRpc, withCustomRpcs, getChainByName, getAllChainsWithOverrides, ChainId, ChainName } from "./chain-config"; import { DefaultChains } from "./constant"; import { EVMVM, EVMChainWallet } from "./evm"; import { SVMVM, SVMChainWallet } from "./svm"; // Test 1: Single chain override const testSingleChainOverride = () => { console.log("\n========== Test 1: Single Chain Override =========="); const customRpcUrl = "https://eth-mainnet.g.alchemy.com/v2/CUSTOM_KEY"; const ethConfig = getChainConfig(ChainId.ETHEREUM, { rpcUrl: customRpcUrl }); console.log("✓ Chain ID:", ethConfig.chainId); console.log("✓ Chain Name:", ethConfig.name); console.log("✓ Custom RPC:", ethConfig.rpcUrl); console.log("✓ Native Token:", ethConfig.nativeToken.symbol); console.log("✓ VM Type:", ethConfig.vmType); // Verify override worked if (ethConfig.rpcUrl === customRpcUrl) { console.log("✅ RPC URL override successful"); } else { console.error("❌ RPC URL override failed"); } // Verify other fields are preserved if (ethConfig.name === "Ethereum" && ethConfig.chainId === 1) { console.log("✅ Other fields preserved"); } else { console.error("❌ Other fields not preserved"); } }; // Test 2: Multiple chain overrides const testMultipleChainOverrides = () => { console.log("\n========== Test 2: Multiple Chain Overrides =========="); const chains = getMultipleChainConfigs([ { chainId: ChainId.ETHEREUM, overrides: { rpcUrl: "https://eth.custom.com" } }, { chainId: ChainId.BSC, overrides: { rpcUrl: "https://bsc.custom.com" } }, { chainId: ChainId.BASE, overrides: { rpcUrl: "https://base.custom.com" } } ]); console.log("✓ Configured chains:", chains.length); chains.forEach(chain => { console.log(` - ${chain.name} (${chain.chainId}): ${chain.rpcUrl}`); }); if (chains.length === 3) { console.log("✅ Multiple chain override successful"); } else { console.error("❌ Multiple chain override failed"); } }; // Test 3: Quick RPC override helpers const testQuickRpcOverride = () => { console.log("\n========== Test 3: Quick RPC Override =========="); // Single chain const ethConfig = withCustomRpc(ChainId.ETHEREUM, "https://eth.quick.com"); console.log("✓ Single:", ethConfig.name, "->", ethConfig.rpcUrl); // Multiple chains const chains = withCustomRpcs({ [ChainId.ETHEREUM]: "https://eth.quick.com", [ChainId.BASE]: "https://base.quick.com", [ChainId.SOLANA]: "https://sol.quick.com" }); console.log("✓ Multiple chains:", chains.length); chains.forEach(chain => { console.log(` - ${chain.name}: ${chain.rpcUrl}`); }); console.log("✅ Quick RPC override successful"); }; // Test 4: Get chain by name const testGetChainByName = () => { console.log("\n========== Test 4: Get Chain by Name =========="); const ethConfig = getChainByName("Ethereum", { rpcUrl: "https://eth.byname.com" }); console.log("✓ By exact name:", ethConfig.name); // Test case-insensitive const baseConfig = getChainByName("base", { rpcUrl: "https://base.byname.com" }); console.log("✓ By lowercase:", baseConfig.name); // Test with ChainName constant const solConfig = getChainByName(ChainName.SOLANA, { rpcUrl: "https://sol.byname.com" }); console.log("✓ With constant:", solConfig.name); console.log("✅ Get by name successful"); }; // Test 5: Customized chains (selective overrides) const testCustomizedChains = () => { console.log("\n========== Test 5: Customized Chains (Selective) =========="); const chains = getCustomizedChains({ [ChainId.ETHEREUM]: { rpcUrl: "https://eth.selective.com" }, [ChainId.BASE]: { rpcUrl: "https://base.selective.com" } // Other chains will use defaults }); console.log("✓ Total chains:", chains.length); console.log("✓ Should equal DefaultChains:", DefaultChains.length); const ethChain = chains.find(c => c.chainId === ChainId.ETHEREUM); const baseChain = chains.find(c => c.chainId === ChainId.BASE); const bscChain = chains.find(c => c.chainId === ChainId.BSC); console.log("✓ Ethereum RPC (custom):", ethChain?.rpcUrl); console.log("✓ Base RPC (custom):", baseChain?.rpcUrl); console.log("✓ BSC RPC (default):", bscChain?.rpcUrl); if (chains.length === DefaultChains.length) { console.log("✅ Selective override successful"); } else { console.error("❌ Selective override failed"); } }; // Test 6: Get all chains with/without overrides const testGetAllChains = () => { console.log("\n========== Test 6: Get All Chains =========="); const allChains = getAllChainsWithOverrides(); console.log("✓ All chains (no override):", allChains.length); // Verify it's a copy, not reference const defaultChain = DefaultChains[0]; const copiedChain = allChains[0]; if (defaultChain !== copiedChain) { console.log("✅ Returns copies, not references"); } else { console.error("❌ Returns references instead of copies"); } }; // Test 7: Error handling const testErrorHandling = () => { console.log("\n========== Test 7: Error Handling =========="); try { getChainConfig(999999); // Invalid chain ID console.error("❌ Should have thrown error for invalid chain ID"); } catch (error) { if (error instanceof Error) { console.log("✓ Error message:", error.message); console.log("✅ Proper error handling for invalid chain ID"); } } try { getChainByName("InvalidChain"); console.error("❌ Should have thrown error for invalid chain name"); } catch (error) { if (error instanceof Error) { console.log("✓ Error message:", error.message); console.log("✅ Proper error handling for invalid chain name"); } } }; // Test 8: Integration with EVMChainWallet const testIntegrationWithWallet = () => { console.log("\n========== Test 8: Integration with Wallet =========="); const mnemonic = "test test test test test test test test test test test junk"; const vm = EVMVM.fromMnemonic(mnemonic); const { privateKey } = vm.generatePrivateKey(0); const ethConfig = withCustomRpc( ChainId.ETHEREUM, "https://eth-mainnet.g.alchemy.com/v2/demo" ); const wallet = new EVMChainWallet(ethConfig, privateKey, 0); console.log("✓ Wallet created successfully"); console.log("✓ Wallet address:", wallet.address); console.log("✓ Chain ID:", wallet.config.chainId); console.log("✓ RPC URL:", wallet.config.rpcUrl); console.log("✅ Integration with wallet successful"); // Clean up vm.dispose(); }; // Test 9: Integration with SVMChainWallet const testIntegrationWithSVMWallet = () => { console.log("\n========== Test 9: Integration with SVM Wallet =========="); const mnemonic = "test test test test test test test test test test test junk"; const vm = SVMVM.fromMnemonic(mnemonic); const { privateKey } = vm.generatePrivateKey(0); const solConfig = getChainConfig(ChainId.SOLANA, { rpcUrl: "https://api.mainnet-beta.solana.com" }); const wallet = new SVMChainWallet(solConfig, privateKey, 0); console.log("✓ SVM Wallet created successfully"); console.log("✓ Wallet address:", wallet.address.toBase58()); console.log("✓ Chain ID:", wallet.config.chainId); console.log("✓ RPC URL:", wallet.config.rpcUrl); console.log("✅ Integration with SVM wallet successful"); // Clean up vm.dispose(); }; // Test 10: Complex override (AA support) const testComplexOverride = () => { console.log("\n========== Test 10: Complex Override (AA Support) =========="); const baseConfig = getChainConfig(ChainId.BASE, { rpcUrl: "https://base-mainnet.g.alchemy.com/v2/CUSTOM", aaSupport: { enabled: true, bundlerUrl: "https://bundler.custom.com", paymasterUrl: "https://paymaster.custom.com", entryPoints: [ { address: "0x0000000071727De22E5E9d8BAf0edAc6f37da032", version: "0.7" } ], kernelImplementations: [ { address: "0xCustomAddress", version: 3 } ] } }); console.log("✓ Chain:", baseConfig.name); console.log("✓ RPC URL:", baseConfig.rpcUrl); console.log("✓ AA Enabled:", baseConfig.aaSupport?.enabled); console.log("✓ Bundler URL:", baseConfig.aaSupport?.bundlerUrl); console.log("✓ Paymaster URL:", baseConfig.aaSupport?.paymasterUrl); if (baseConfig.aaSupport?.enabled) { console.log("✅ Complex override successful"); } else { console.error("❌ Complex override failed"); } }; // Run all tests const runAllTests = () => { console.log("\n╔════════════════════════════════════════════╗"); console.log("║ Chain Configuration Utilities Test Suite ║"); console.log("╚════════════════════════════════════════════╝"); testSingleChainOverride(); testMultipleChainOverrides(); testQuickRpcOverride(); testGetChainByName(); testCustomizedChains(); testGetAllChains(); testErrorHandling(); testIntegrationWithWallet(); testIntegrationWithSVMWallet(); testComplexOverride(); console.log("\n╔════════════════════════════════════════════╗"); console.log("║ All Tests Completed! ✅ ║"); console.log("╚════════════════════════════════════════════╝\n"); }; // Export for use as module or run directly if (require.main === module) { runAllTests(); } export { testSingleChainOverride, testMultipleChainOverrides, testQuickRpcOverride, testGetChainByName, testCustomizedChains, testGetAllChains, testErrorHandling, testIntegrationWithWallet, testIntegrationWithSVMWallet, testComplexOverride, runAllTests };