Overview
ChainId is a branded number type representing an EIP-155 chain identifier. Used for replay protection and identifying which network a transaction targets.
import * as ChainId from '@voltaire/primitives/ChainId'
const mainnet = ChainId.from(1)
const sepolia = ChainId.from(11155111)
if (ChainId.isMainnet(1)) {
console.log('Using Ethereum mainnet')
}
Type Definition
type ChainIdType = number & { readonly [brand]: "ChainId" }
The branded type prevents accidentally mixing chain IDs with other numbers.
Creating ChainId
from
Create from a non-negative integer.
const mainnet = ChainId.from(1)
const arbitrum = ChainId.from(42161)
const base = ChainId.from(8453)
Validation: Throws InvalidFormatError if value is not a non-negative integer.
ChainId.from(-1) // Error: must be non-negative
ChainId.from(1.5) // Error: must be integer
Constants
Pre-defined chain IDs for common networks:
import { MAINNET, SEPOLIA, HOLESKY, OPTIMISM, ARBITRUM, BASE, POLYGON } from '@voltaire/primitives/ChainId'
// Ethereum
const mainnet = MAINNET // 1
const sepolia = SEPOLIA // 11155111
const holesky = HOLESKY // 17000
// Layer 2s
const optimism = OPTIMISM // 10
const arbitrum = ARBITRUM // 42161
const base = BASE // 8453
const polygon = POLYGON // 137
GOERLI (5) is deprecated. Use SEPOLIA or HOLESKY for testnet development.
Methods
toNumber
Convert to plain number.
const n = ChainId.toNumber(42161) // 42161
equals
Compare two chain IDs.
const same = ChainId.equals(1, 1) // true
const different = ChainId.equals(1, 10) // false
isMainnet
Check if chain ID is Ethereum mainnet.
ChainId.isMainnet(1) // true
ChainId.isMainnet(10) // false (Optimism)
ChainId.isMainnet(42161) // false (Arbitrum)
Common Chain IDs
| Chain | ID | Type |
|---|
| Ethereum | 1 | Mainnet |
| Sepolia | 11155111 | Testnet |
| Holesky | 17000 | Testnet |
| Optimism | 10 | L2 |
| Arbitrum One | 42161 | L2 |
| Base | 8453 | L2 |
| Polygon | 137 | Sidechain |
| Avalanche | 43114 | L1 |
| BSC | 56 | L1 |
EIP-155 Replay Protection
Chain ID is embedded in transaction signatures to prevent replay attacks across chains:
import * as ChainId from '@voltaire/primitives/ChainId'
const tx = {
chainId: ChainId.from(1), // Mainnet only
to: "0x...",
value: 1000000000000000000n,
// ... other fields
}
// This transaction can only be valid on Ethereum mainnet
// Submitting to Arbitrum would fail signature verification
Namespace Usage
import { ChainId } from '@voltaire/primitives/ChainId'
// Using namespace object
const id = ChainId.from(1)
const isMain = ChainId.isMainnet(1)
const equal = ChainId.equals(1, 1)
See Also