Chains
popularChains, customChain() and arranging the Networks tab with chainOrder.
Networks are defined in code, so every user sees the same set in the order you choose. Mix Wyllet's presets, any chain from viem/chains, and your own chains built with customChain().
import { sepolia } from 'viem/chains'
import { customChain, getDefaultConfig, popularChains } from 'wyllet'
const myChain = customChain({
id: 424242,
name: 'My Chain',
rpcUrl: 'https://rpc.mychain.xyz',
explorerUrl: 'https://scan.mychain.xyz',
nativeCurrency: { name: 'My Token', symbol: 'MYT', decimals: 18 },
icon: '/mychain.svg',
nativeIcon: '/myt.svg',
})
export const config = getDefaultConfig({
appName: 'My dApp',
chains: [myChain, ...popularChains, sepolia],
})Chain order
The order of chains is the priority order, and the first chain is the default. The Networks tab lists chains in the same order unless you set chainOrder (see below).
getDefaultConfig uses each chain's public RPC by default. Use your own RPC in production with transports:
import { http } from 'wagmi'
getDefaultConfig({
appName: 'My dApp',
chains: [mainnet, base],
transports: { [base.id]: http('https://base.my-rpc.xyz') },
})Chains you leave out of transports keep the public RPC.
Presets
popularChains and popularTestnets are arrays of viem chains, ready to spread into chains.
| Preset | Chains, in order |
|---|---|
popularChains | Ethereum, Base, OP Mainnet, Arbitrum One, Polygon, BNB Smart Chain, Avalanche, ZKsync Era, Linea Mainnet, Scroll |
popularTestnets | Sepolia, Base Sepolia, OP Sepolia, Arbitrum Sepolia, Polygon Amoy |
Spread a preset and add to it, or pick individual chains from viem/chains instead. Nothing in Wyllet requires the presets.
Custom chains
customChain() defines any EVM chain in one call, such as your own L2, an appchain or a devnet. It returns a viem Chain that works anywhere wagmi and viem expect one, and it carries Wyllet's icon metadata.
| Field | Type | Required | Description |
|---|---|---|---|
id | number | Yes | Chain ID |
name | string | Yes | Display name |
rpcUrl | string | Yes | HTTPS JSON-RPC endpoint |
nativeCurrency | { name: string; symbol: string; decimals: number } | No | Defaults to Ether, ETH, 18 decimals |
explorerUrl | string | No | Block explorer base URL. Enables explorer links for addresses and transactions |
testnet | boolean | No | Shows a Testnet tag in the Networks tab |
icon | string | No | Chain logo URL or data URI |
color | string | No | Brand color for the generated monogram. Setting it skips the built-in icon for that chain ID |
nativeIcon | string | No | Icon for the native currency in the Tokens tab |
Wyllet stores icon, color and nativeIcon on the chain under custom.wyllet (the ChainExtras type). You can add the same field to a viem chain to give it a native currency icon:
import { base } from 'viem/chains'
const baseWithIcons = { ...base, custom: { wyllet: { nativeIcon: '/eth.svg' } } }Chain icons
Wyllet bundles official logos for these networks and their testnets: Ethereum (including Sepolia and Holesky), OP, Arbitrum, Base, Polygon, Avalanche, ZKsync, Linea, Scroll, Gnosis, Zora and Blast. Local dev chains with ID 31337 (Hardhat, Anvil) get a generic developer mark.
Any other chain gets a monogram: the first letter of its name on a color derived from the name. This includes BNB Smart Chain, which is in popularChains but has no bundled artwork.
Icons resolve in this order:
- The
chainIconsprop onWylletProvider iconfromcustomChain()- The built-in logo for the chain ID
- A monogram, using
colorwhen you set one
Override any chain's icon by ID with chainIcons:
<WylletProvider chainIcons={{ 56: '/brand/bnb.svg', 424242: '/mychain.svg' }}>
{children}
</WylletProvider>Arranging the Networks tab
chainOrder moves chain IDs to the front of the Networks tab, in the order given. The remaining chains follow in config order. It does not change the default chain.
<WylletProvider chainOrder={[8453, 424242]}>
{children}
</WylletProvider>This shows Base, then My Chain, then everything else.
Switching networks
The Networks tab switches with wagmi's switchChain. If an injected wallet reports that it does not know the chain, wagmi asks it to add the network using the name, RPC URL, explorer and native currency from your chain definition. The user approves the new network in their wallet, and the switch continues. No extra setup is needed for custom chains.
When the wallet is on a chain that is not in your config, Wyllet shows the wrong-network state. See Account panel.
useWylletChains
Returns your configured chains, arranged by chainOrder. Use it to build your own network picker.
import { ChainIcon, useWylletChains } from 'wyllet'
import { useSwitchChain } from 'wagmi'
function NetworkList() {
const { chains } = useWylletChains()
const { mutate: switchChain } = useSwitchChain()
return chains.map((chain) => (
<button key={chain.id} onClick={() => switchChain({ chainId: chain.id })}>
<ChainIcon chainId={chain.id} size={20} />
{chain.name}
</button>
))
}ChainIcon
Renders a chain's icon as an img, using the resolution order above. It must be rendered inside WylletProvider.
| Prop | Type | Default | Description |
|---|---|---|---|
chainId | number | Chain to show | |
size | number | 20 | Width and height in pixels |
className | string | Extra class name |
The image's alt text is the chain name when the chain is in your config.