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
chainIdis hex, and Core verifies it against the RPC endpoint's owneth_chainId— a mismatch rejects the request, so you can't typo a chain id onto the wrong RPC.nativeCurrency.decimalsmust be18.- 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.