A multi-chain wallet needs an abstraction over chain-specific details (RPC endpoints, gas token, address format, block explorer URL) so screens don't hardcode assumptions about a single network.
interface ChainConfig {
id: number;
name: string;
rpcUrl: string;
nativeSymbol: string;
explorerUrl: string;
}
const CHAINS: Record<number, ChainConfig> = {
1: { id: 1, name: "Ethereum", rpcUrl: "https://eth.llamarpc.com", nativeSymbol: "ETH", explorerUrl: "https://etherscan.io" },
8453: { id: 8453, name: "Base", rpcUrl: "https://mainnet.base.org", nativeSymbol: "ETH", explorerUrl: "https://basescan.org" },
};
function txUrl(chainId: number, hash: string) {
return `${CHAINS[chainId].explorerUrl}/tx/${hash}`;
}Keeping chain config data-driven (rather than scattered `if (chainId === 1)` checks) makes adding a new supported chain a config change, not a re-architecture.