Skip to main content

NetworkId

Type-safe Ethereum network identifiers for peer-to-peer network discovery.

Overview

Branded number type representing Ethereum network IDs. Network IDs are used for peer-to-peer network identification and discovery, distinct from Chain IDs which are used for transaction replay protection.
NetworkId vs ChainId: These are different concepts!
  • NetworkId: Used for P2P network discovery (devp2p protocol)
  • ChainId: Used for transaction replay protection (EIP-155)
For most public networks they happen to be the same value, but they serve different purposes.

Quick Start

import * as NetworkId from '@tevm/voltaire/NetworkId'

// Create network ID
const mainnet = NetworkId.from(1)
const sepolia = NetworkId.from(11155111)

// Convert to number
NetworkId.toNumber(mainnet)  // 1
NetworkId.toNumber(sepolia)  // 11155111

// Compare network IDs
NetworkId.equals(mainnet, mainnet)  // true
NetworkId.equals(mainnet, sepolia)  // false

Network Constants

ConstantValueNetwork
MAINNET1Ethereum Mainnet
SEPOLIA11155111Sepolia Testnet
HOLESKY17000Holesky Testnet
GOERLI5Goerli Testnet (deprecated)

API Reference

Constructors

import * as NetworkId from '@tevm/voltaire/NetworkId'

// From number
const networkId = NetworkId.from(1)

// From pre-defined constant
import { MAINNET, SEPOLIA } from '@tevm/voltaire/NetworkId'

Methods

import * as NetworkId from '@tevm/voltaire/NetworkId'

const networkId = NetworkId.from(1)

// Convert to number
NetworkId.toNumber(networkId)  // 1

// Equality check
NetworkId.equals(networkId, NetworkId.from(1))  // true

NetworkId vs ChainId

Understanding the difference:
AspectNetworkIdChainId
PurposeP2P network discoveryTransaction replay protection
Protocoldevp2pEIP-155
RPC Methodnet_versioneth_chainId
Used InPeer handshakeTransaction signing
For most public networks, NetworkId and ChainId have the same value:
import * as NetworkId from '@tevm/voltaire/NetworkId'
import * as Chain from '@tevm/voltaire/Chain'

// Mainnet: both are 1
const networkId = NetworkId.from(1)
const chainId = Chain.from(1)

// Sepolia: both are 11155111
const sepoliaNetworkId = NetworkId.from(11155111)
const sepoliaChainId = Chain.from(11155111)
However, private networks or some L2s may use different values for each.

Use Cases

Network Detection

import * as NetworkId from '@tevm/voltaire/NetworkId'
import { MAINNET, SEPOLIA, HOLESKY } from '@tevm/voltaire/NetworkId'

function getNetworkName(networkId: number): string {
  const id = NetworkId.from(networkId)

  if (NetworkId.equals(id, MAINNET)) return 'Ethereum Mainnet'
  if (NetworkId.equals(id, SEPOLIA)) return 'Sepolia Testnet'
  if (NetworkId.equals(id, HOLESKY)) return 'Holesky Testnet'

  return `Unknown Network (${NetworkId.toNumber(id)})`
}

Multi-Network Support

import * as NetworkId from '@tevm/voltaire/NetworkId'
import { MAINNET, SEPOLIA } from '@tevm/voltaire/NetworkId'

const RPC_URLS: Record<number, string> = {
  1: 'https://eth.llamarpc.com',
  11155111: 'https://rpc.sepolia.org'
}

function getRpcUrl(networkId: number): string {
  const url = RPC_URLS[networkId]
  if (!url) {
    throw new Error(`Unsupported network: ${networkId}`)
  }
  return url
}

Node Connection Validation

import * as NetworkId from '@tevm/voltaire/NetworkId'

async function validateNetwork(
  rpcUrl: string,
  expectedNetworkId: number
): Promise<boolean> {
  const response = await fetch(rpcUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'net_version',
      params: [],
      id: 1
    })
  })
  const { result } = await response.json()
  const actualNetworkId = NetworkId.from(parseInt(result))
  const expected = NetworkId.from(expectedNetworkId)

  return NetworkId.equals(actualNetworkId, expected)
}

// Ensure connected to mainnet
const isMainnet = await validateNetwork('https://eth.llamarpc.com', 1)
  • Chain - Chain configuration with ChainId
  • PeerId - Peer identifiers for P2P
  • NodeInfo - Node information structure

References