> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Chain Metadata

> Accessing chain properties and network information

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=primitives/chain.ts">
  Run Chain examples in the interactive playground
</Card>

# Metadata

Accessing chain configuration properties including network details, RPC endpoints, explorers, and native currency information.

## Overview

Chain objects contain comprehensive network metadata following the [Chain List](https://chainlist.org/) standard. All properties are accessed directly on the chain object.

```typescript theme={null}
import { Chain } from 'tevm'

const quai = Chain.fromId(9)!

// Network identification
console.log(quai.name)        // "Quai Mainnet"
console.log(quai.chainId)     // 9
console.log(quai.shortName)   // "quai"

// Native currency
console.log(quai.nativeCurrency.symbol)   // "QUAI"
console.log(quai.nativeCurrency.decimals) // 18

// RPC endpoints
console.log(quai.rpc[0])      // First RPC URL

// Explorer
console.log(quai.explorers?.[0]?.url)  // Block explorer URL
```

## Core Properties

### Network Identification

#### `chain.name`

Full network name.

```typescript theme={null}
const quai = Chain.fromId(9)!
console.log(quai.name) // "Quai Mainnet"

const flare = Chain.fromId(14)!
console.log(flare.name) // "Flare Mainnet"

const ronin = Chain.fromId(2020)!
console.log(ronin.name) // "Ronin Mainnet"
```

**Type:** `string`

#### `chain.chainId`

EIP-155 chain identifier. Unique numeric ID for the network.

```typescript theme={null}
const quai = Chain.fromId(9)!
console.log(quai.chainId) // 9

const flare = Chain.fromId(14)!
console.log(flare.chainId) // 14

const ronin = Chain.fromId(2020)!
console.log(ronin.chainId) // 2020
```

**Type:** `number`

**Note:** Chain IDs are defined by [EIP-155](https://eips.ethereum.org/EIPS/eip-155) to prevent replay attacks across chains.

#### `chain.shortName`

Short identifier for the chain.

```typescript theme={null}
const quai = Chain.fromId(9)!
console.log(quai.shortName) // "quai"

const flare = Chain.fromId(14)!
console.log(flare.shortName) // "flr"

const ronin = Chain.fromId(2020)!
console.log(ronin.shortName) // "ron"
```

**Type:** `string`

#### `chain.chain`

Chain family or network type identifier.

```typescript theme={null}
const quai = Chain.fromId(9)!
console.log(quai.chain) // "Quai"

const flare = Chain.fromId(14)!
console.log(flare.chain) // "FLR"
```

**Type:** `string`

#### `chain.networkId`

Network ID (optional). May differ from chain ID on some networks.

```typescript theme={null}
const chain = Chain.fromId(9)!
console.log(chain.networkId) // number | undefined
```

**Type:** `number | undefined`

**Note:** Most modern networks use the same value for chain ID and network ID, making this property often redundant.

## Native Currency

### `chain.nativeCurrency`

Native currency details including name, symbol, and decimals.

```typescript theme={null}
const quai = Chain.fromId(9)!

console.log(quai.nativeCurrency.name)     // "Quai"
console.log(quai.nativeCurrency.symbol)   // "QUAI"
console.log(quai.nativeCurrency.decimals) // 18

const flare = Chain.fromId(14)!
console.log(flare.nativeCurrency.name)    // "Flare"
console.log(flare.nativeCurrency.symbol)  // "FLR"
console.log(flare.nativeCurrency.decimals) // 18
```

**Type:** `NativeCurrency`

```typescript theme={null}
interface NativeCurrency {
  name: string
  symbol: string
  decimals: number
  [key: string]: any
}
```

#### `nativeCurrency.name`

Full name of native currency.

**Type:** `string`

#### `nativeCurrency.symbol`

Currency symbol (ticker).

**Type:** `string`

**Common symbols:**

* ETH - Ethereum and many L2s
* QUAI - Quai Network
* FLR - Flare
* RON - Ronin

#### `nativeCurrency.decimals`

Number of decimal places for the currency. Almost always 18 for EVM chains.

**Type:** `number`

**Note:** 18 decimals is the standard for EVM-compatible chains (1 token = 10^18 wei).

## RPC Endpoints

### `chain.rpc`

Array of RPC endpoint URLs for connecting to the network.

```typescript theme={null}
const quai = Chain.fromId(9)!

// Access all RPC endpoints
console.log(quai.rpc) // string[]

// Use first endpoint
const rpcUrl = quai.rpc[0]
console.log(rpcUrl) // "https://..."

// Fallback through multiple endpoints
function connectToChain(chain: Chain) {
  for (const rpc of chain.rpc) {
    try {
      // Attempt connection to RPC
      console.log(`Trying ${rpc}...`)
      // ... connection logic
      break
    } catch {
      console.log(`Failed, trying next RPC...`)
    }
  }
}

connectToChain(quai)
```

**Type:** `string[]`

**Note:** Multiple RPC endpoints provide redundancy. If one fails, try the next.

## Block Explorers

### `chain.explorers`

Array of block explorer configurations (optional).

```typescript theme={null}
const quai = Chain.fromId(9)!

// Check if explorers exist
if (quai.explorers && quai.explorers.length > 0) {
  const explorer = quai.explorers[0]

  console.log(explorer.name)     // Explorer name
  console.log(explorer.url)      // "https://..."
  console.log(explorer.standard) // "EIP3091" (optional)
}

// Safe access pattern
const explorerUrl = quai.explorers?.[0]?.url
if (explorerUrl) {
  console.log(`View on ${explorerUrl}`)
}
```

**Type:** `Explorer[] | undefined`

```typescript theme={null}
interface Explorer {
  name: string
  url: string
  standard?: string
  [key: string]: any
}
```

#### `explorer.name`

Human-readable name of the block explorer.

**Type:** `string`

**Examples:**

* "Quai Explorer"
* "Flarescan"
* "Ronin Explorer"

#### `explorer.url`

Base URL of the block explorer.

**Type:** `string`

**Use cases:**

* Link to transactions: `${url}/tx/${txHash}`
* Link to addresses: `${url}/address/${address}`
* Link to blocks: `${url}/block/${blockNumber}`

#### `explorer.standard`

Explorer API standard (optional).

**Type:** `string | undefined`

**Common values:**

* `"EIP3091"` - Standard for generating explorer URLs
* `"none"` - Non-standard explorer

## Additional Information

### `chain.infoURL`

Official website or information URL (optional).

```typescript theme={null}
const quai = Chain.fromId(9)!

if (quai.infoURL) {
  console.log(quai.infoURL) // "https://..."
}
```

**Type:** `string | undefined`

### Custom Properties

Chain objects support additional custom properties via index signature.

```typescript theme={null}
const chain = Chain.fromId(9)!

// Access any additional properties
const customProp = chain.someCustomProperty
```

**Type:** `[key: string]: any`

## Usage Examples

### Display Chain Info

```typescript theme={null}
function displayChainInfo(chainId: number) {
  const chain = Chain.fromId(chainId)

  if (!chain) {
    console.log('Chain not found')
    return
  }

  console.log('='.repeat(50))
  console.log(`Chain: ${chain.name}`)
  console.log(`ID: ${chain.chainId}`)
  console.log(`Symbol: ${chain.nativeCurrency.symbol}`)
  console.log(`RPC: ${chain.rpc[0]}`)

  if (chain.explorers?.[0]) {
    console.log(`Explorer: ${chain.explorers[0].url}`)
  }

  if (chain.infoURL) {
    console.log(`Info: ${chain.infoURL}`)
  }
  console.log('='.repeat(50))
}

displayChainInfo(9)
```

### Generate Explorer Links

```typescript theme={null}
function generateExplorerLink(
  chain: Chain,
  type: 'tx' | 'address' | 'block',
  value: string
): string | null {
  const explorer = chain.explorers?.[0]

  if (!explorer) {
    return null
  }

  return `${explorer.url}/${type}/${value}`
}

const quai = Chain.fromId(9)!

const txLink = generateExplorerLink(
  quai,
  'tx',
  '0x1234567890abcdef...'
)

const addressLink = generateExplorerLink(
  quai,
  'address',
  '0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e'
)

console.log(txLink)
console.log(addressLink)
```

### RPC Connection with Fallback

```typescript theme={null}
async function connectWithFallback(chain: Chain) {
  for (let i = 0; i < chain.rpc.length; i++) {
    const rpcUrl = chain.rpc[i]

    try {
      console.log(`Attempting connection to ${rpcUrl}...`)

      // Try to connect (pseudo-code)
      // const provider = new JsonRpcProvider(rpcUrl)
      // await provider.getBlockNumber()

      console.log(`✓ Connected to ${chain.name} via ${rpcUrl}`)
      return rpcUrl
    } catch (error) {
      console.log(`✗ Failed to connect to ${rpcUrl}`)

      if (i === chain.rpc.length - 1) {
        throw new Error(`Could not connect to ${chain.name}`)
      }
    }
  }
}

const quai = Chain.fromId(9)!
await connectWithFallback(quai)
```

### Currency Formatting

```typescript theme={null}
function formatNativeAmount(
  chain: Chain,
  weiAmount: bigint
): string {
  const decimals = chain.nativeCurrency.decimals
  const symbol = chain.nativeCurrency.symbol

  // Convert wei to token amount
  const divisor = 10n ** BigInt(decimals)
  const tokenAmount = Number(weiAmount) / Number(divisor)

  return `${tokenAmount.toFixed(6)} ${symbol}`
}

const quai = Chain.fromId(9)!
const amount = 1500000000000000000n // 1.5 QUAI in wei

console.log(formatNativeAmount(quai, amount))
// "1.500000 QUAI"
```

### Chain Comparison

```typescript theme={null}
function compareChains(chainId1: number, chainId2: number) {
  const chain1 = Chain.fromId(chainId1)
  const chain2 = Chain.fromId(chainId2)

  if (!chain1 || !chain2) {
    console.log('One or both chains not found')
    return
  }

  console.log('Chain 1:', chain1.name)
  console.log('Chain 2:', chain2.name)
  console.log()

  console.log('Same currency?',
    chain1.nativeCurrency.symbol === chain2.nativeCurrency.symbol)

  console.log('Same decimals?',
    chain1.nativeCurrency.decimals === chain2.nativeCurrency.decimals)

  console.log('RPC count:',
    `${chain1.rpc.length} vs ${chain2.rpc.length}`)

  console.log('Has explorer?',
    `${!!chain1.explorers?.[0]} vs ${!!chain2.explorers?.[0]}`)
}

compareChains(9, 14) // Compare Quai and Flare
```

### Multi-Chain Dashboard

```typescript theme={null}
interface ChainSummary {
  id: number
  name: string
  symbol: string
  rpcCount: number
  hasExplorer: boolean
}

function summarizeChain(chain: Chain): ChainSummary {
  return {
    id: chain.chainId,
    name: chain.name,
    symbol: chain.nativeCurrency.symbol,
    rpcCount: chain.rpc.length,
    hasExplorer: !!chain.explorers?.[0],
  }
}

function createDashboard(chainIds: number[]): ChainSummary[] {
  return chainIds
    .map(id => Chain.fromId(id))
    .filter((chain): chain is Chain => chain !== undefined)
    .map(summarizeChain)
}

const dashboard = createDashboard([9, 14, 1776, 2020])
console.table(dashboard)
```

## Related

* [Constructors](/primitives/chain/constructors) - Creating Chain instances
* [Chain Lookup](/primitives/chain/chain-lookup) - Looking up chains by ID
* [BrandedChain](/primitives/chain/branded-chain) - Functional API
