This guide explains how to add a new EVM-compatible blockchain to The Extension Wallet.
The wallet uses ethereum-lists/chains as the primary source of truth for EVM chain configurations, available at chainid.network.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ethereum-lists/chains β
β https://chainid.network/chains.json β
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββ΄βββββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β BUILD TIME β β RUNTIME β
β sync-evm- β β evm-registry-client.ts β
β registry.ts β β β
βββββββββββ¬ββββββββββββ β β’ Fetch on-demand β
β β β’ Cache in chrome.storage β
βΌ β β’ 24-hour TTL β
βββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β evm-registry.ts β
β (pre-bundled) β
βββββββββββββββββββββββ
The wallet has partial EVM support - read operations work, but sending is not yet implemented:
| Feature | Status | Notes |
|---|---|---|
| Key derivation (BIP44) | β Supported | m/44'/60'/0'/0/index path |
| Address generation | β Supported | EIP-55 checksummed addresses |
| Native token balance | β Supported | Via eth_getBalance |
| EIP-1559 gas estimation | β Supported | Via eth_gasPrice + block base fee |
| Native token transfers | β³ Planned | Transaction signing not implemented |
| Transaction signing | β Not implemented | Required for any send operation |
| ERC-20 tokens | β Not implemented | No contract interaction support |
| ERC-721/1155 NFTs | β Not implemented | No contract interaction support |
- View balances - Native token balances display correctly
- Receive tokens - Addresses are valid and can receive tokens
- Network switching - Multiple EVM networks supported
If the chain is not already in the registry, contribute to the upstream source:
- Fork ethereum-lists/chains
- Add chain data following their schema
- Submit PR to the main repository
- Wait for merge and data propagation to chainid.network
- Update wallet by running
npm run sync:evm
This approach ensures the chain is available to the entire ecosystem.
For chains already in the registry but not pre-bundled:
import { evmRegistryClient } from '@/lib/networks';
// Fetch a specific chain by ID
const chain = await evmRegistryClient.fetchChain(137); // Polygon
// Search for chains
const results = await evmRegistryClient.searchChains('polygon');
// Get popular chains
const popular = await evmRegistryClient.getPopularChains();The runtime client:
- Fetches chain data from chainid.network
- Caches results in
browser.storage.localfor 24 hours - Filters out deprecated chains and invalid RPC endpoints
For chains not in the registry, or when you need full control:
Add the network configuration in src/lib/networks/evm.ts:
export const NEWCHAIN_MAINNET: EvmNetworkConfig = {
id: 'newchain-mainnet',
name: 'New Chain',
type: 'evm',
enabled: true,
symbol: 'NEW',
decimals: 18, // Usually 18 for EVM chains
coinType: 60, // Always 60 for EVM (Ethereum derivation)
chainId: 12345, // EVM chain ID
rpcUrls: [
// Multiple URLs for failover (in order of preference)
'https://rpc.newchain.io',
'https://rpc2.newchain.io',
'https://rpc.ankr.com/newchain',
],
nativeCurrency: {
name: 'New Token',
symbol: 'NEW',
decimals: 18,
},
explorerUrl: 'https://explorer.newchain.io',
explorerAccountPath: '/address/{address}',
explorerTxPath: '/tx/{txHash}',
};Add to the EVM_NETWORKS array:
export const EVM_NETWORKS: EvmNetworkConfig[] = [
ETHEREUM_MAINNET,
BASE_MAINNET,
// ... existing networks
NEWCHAIN_MAINNET,
];In src/lib/assets/chainRegistry.ts, add to evmAssets:
const evmAssets: Record<string, RegistryAsset[]> = {
// ... existing assets
'newchain-mainnet': [
{
symbol: 'NEW',
name: 'New Token',
denom: 'wei', // Base unit (always 'wei' for EVM)
decimals: 18,
coingeckoId: 'newtoken', // For price data
},
],
};interface EvmNetworkConfig {
id: string; // Unique internal identifier
name: string; // Human-readable name
type: 'evm'; // Network type
enabled: boolean; // Whether enabled by default
symbol: string; // Native token symbol
decimals: number; // Native token decimals (usually 18)
coinType: number; // BIP44 coin type (always 60 for EVM)
chainId: number; // EVM chain ID
rpcUrls: string[]; // JSON-RPC endpoints (array for failover)
nativeCurrency: {
name: string;
symbol: string;
decimals: number;
};
explorerUrl?: string; // Block explorer base URL
explorerAccountPath?: string; // Path for addresses (use {address})
explorerTxPath?: string; // Path for transactions (use {txHash})
}The registry adds extra fields:
interface EvmRegistryConfig extends EvmNetworkConfig {
shortName: string; // Registry short name for lookups
infoUrl?: string; // Chain info URL
isTestnet?: boolean; // Whether this is a testnet
}# Sync default popular chains (~25 chains)
npm run sync:evm
# Sync all chains with valid RPC endpoints
npm run sync:evm:all
# Sync specific chains by ID
npx ts-node --esm scripts/sync-evm-registry.ts --chains 1,56,137,8453The following chains are pre-bundled by default:
| Chain | Chain ID | Enabled |
|---|---|---|
| Ethereum | 1 | β |
| OP Mainnet | 10 | β |
| BNB Smart Chain | 56 | β |
| Polygon | 137 | β |
| Base | 8453 | β |
| Arbitrum One | 42161 | β |
| Cronos | 25 | β |
| Gnosis | 100 | β |
| Fantom | 250 | β |
| zkSync Era | 324 | β |
| Polygon zkEVM | 1101 | β |
| Moonbeam | 1284 | β |
| Mantle | 5000 | β |
| Avalanche C-Chain | 43114 | β |
| Linea | 59144 | β |
| Blast | 81457 | β |
| Scroll | 534352 | β |
| Zora | 7777777 | β |
| Sepolia (testnet) | 11155111 | β |
| Base Sepolia | 84532 | β |
- ChainList: https://chainlist.org/
- Chainid.network: https://chainid.network/
- Chain Registry: https://github.com/ethereum-lists/chains
For production use, consider these providers:
- Alchemy (https://www.alchemy.com/)
- Infura (https://infura.io/)
- QuickNode (https://www.quicknode.com/)
- Ankr (https://www.ankr.com/)
The EVM implementation consists of:
| File | Purpose |
|---|---|
src/lib/networks/evm.ts |
Manual network configurations |
src/lib/networks/evm-registry.ts |
Auto-generated from chain registry |
src/lib/networks/evm-registry-client.ts |
Runtime client for dynamic fetching |
src/lib/evm/client.ts |
JSON-RPC client (read ops + raw broadcast) |
src/lib/crypto/evm.ts |
Key derivation and address generation |
src/lib/assets/chainRegistry.ts |
Asset definitions (native tokens only) |
scripts/sync-evm-registry.ts |
Build-time sync script |
The EvmClient class provides:
// Read operations (implemented)
getBalance(address); // Get native token balance
getGasPrice(); // Get current gas price
getFeeData(); // Get EIP-1559 fee data
getTransactionCount(address); // Get nonce
estimateGas(tx); // Estimate gas for transaction
getTransaction(txHash); // Get transaction by hash
getTransactionReceipt(txHash); // Get transaction receipt
getBlockNumber(); // Get current block number
getChainId(); // Get chain ID
// Write operations (partially implemented)
sendRawTransaction(signedTx); // Broadcast pre-signed transactionNote: sendRawTransaction requires an already-signed transaction. Transaction building and signing are not yet implemented.
All EVM chains use the same derivation path: m/44'/60'/0'/0/index
This means the same private key/address works across all EVM chains. The wallet derives keys using:
- BIP39 mnemonic β seed
- BIP32 derivation with coin type 60
- Keccak256 hash of public key β address
- EIP-55 checksum formatting
ERC-20 tokens are not currently supported. The wallet only displays native EVM tokens (ETH, BNB, etc.).
To implement ERC-20 support, the following would be required:
- Token Registry - Contract addresses per chain
- Balance Fetching -
eth_callwithbalanceOfselector - Token Transfers - ABI encoding for
transferfunction - Transaction Signing - Full transaction building/signing
| Component | Effort | Notes |
|---|---|---|
| Balance fetching | Low | Simple eth_call |
| Token registry | Medium | Need curated token lists |
| Transfer UI | Medium | Token selection, approval flows |
| Transaction signing | High | ABI encoding, gas estimation for contracts |
| Token approvals | High | ERC-20 approve/allowance pattern |
- Verify RPC URL is accessible
- Check that RPC supports required methods
- Ensure rate limits are not exceeded
- Try alternative endpoints from the failover list
If transactions fail or show wrong network, verify the chain ID matches the registry.
All EVM chains use the same address format (0x...). If addresses look wrong, check the BIP44 derivation.
If a chain isn't in ethereum-lists/chains:
- Check if it's a new chain (may take time to be added)
- Submit a PR to add it
- Use manual configuration as a temporary workaround