Skip to main content

Add a custom network

Dapps on networks Core doesn't ship by default — an Avalanche L1, a new EVM chain — can register the network and switch to it in two calls.

Switch first, add on failure

The polite pattern: try to switch (the user may already have the network), and only ask to add it when the wallet reports the chain as unknown (error 4902):

const FUJI = {
chainId: '0xa869', // 43113
chainName: 'Avalanche Fuji Testnet',
nativeCurrency: { name: 'AVAX', symbol: 'AVAX', decimals: 18 },
rpcUrls: ['https://api.avax-test.network/ext/bc/C/rpc'],
blockExplorerUrls: ['https://testnet.snowtrace.io/'],
};

async function ensureNetwork(provider) {
try {
await provider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: FUJI.chainId }],
});
} catch (error) {
if (error.code === 4902) {
// Unknown chain: ask the user to add it, which also switches.
await provider.request({
method: 'wallet_addEthereumChain',
params: [FUJI],
});
} else if (error.code !== 4001) {
throw error;
}
}
}

Both calls open approval screens: wallet_addEthereumChain shows the full network definition, wallet_switchEthereumChain a switch confirmation.

Field notes

  • chainId is hex, and Core verifies it against the RPC endpoint's own eth_chainId — a mismatch rejects the request, so you can't typo a chain id onto the wrong RPC.
  • nativeCurrency.decimals must be 18.
  • Use your network's canonical public RPC in rpcUrls. Users can edit the endpoint later in Core's network settings.

After the switch

chainChanged fires — if you followed the connection guide, your dapp reloads and reads the new chain cleanly.

For Avalanche L1s

An L1's C-style EVM chain works exactly like this. If you operate the L1, publishing your network definition (chain id, RPC, explorer) lets any EIP-3085 wallet onboard users — nothing here is Core-specific.