Chains
The viem/chains
entrypoint contains references to popular EVM-compatible chains such as: Polygon, Optimism, Avalanche, Base, Zora, and more.
Usage
Import your chain from the entrypoint and use them in the consuming viem code:
import { createPublicClient, http } from 'viem'
import { zora } from 'viem/chains'
const client = createPublicClient({
chain: zora,
transport: http()
})
import { createPublicClient, http } from 'viem'
import { zora } from 'viem/chains'
const client = createPublicClient({
chain: zora,
transport: http()
})
See here for a list of supported chains.
Want to add a chain that's not listed in viem? Read the Contributing Guide, and then open a Pull Request with your chain.
Custom Chains
You can also extend viem to support other EVM-compatible chains by building your own chain object that inherits the Chain
type.
import { defineChain } from 'viem'
export const zora = defineChain({
id: 7777777,
name: 'Zora',
network: 'zora',
nativeCurrency: {
decimals: 18,
name: 'Ether',
symbol: 'ETH',
},
rpcUrls: {
default: {
http: ['https://rpc.zora.energy'],
webSocket: ['wss://rpc.zora.energy'],
},
public: {
http: ['https://rpc.zora.energy'],
webSocket: ['wss://rpc.zora.energy'],
},
},
blockExplorers: {
default: { name: 'Explorer', url: 'https://explorer.zora.energy' },
},
contracts: {
multicall3: {
address: '0xcA11bde05977b3631167028862bE2a173976CA11',
blockCreated: 5882,
},
},
})
import { defineChain } from 'viem'
export const zora = defineChain({
id: 7777777,
name: 'Zora',
network: 'zora',
nativeCurrency: {
decimals: 18,
name: 'Ether',
symbol: 'ETH',
},
rpcUrls: {
default: {
http: ['https://rpc.zora.energy'],
webSocket: ['wss://rpc.zora.energy'],
},
public: {
http: ['https://rpc.zora.energy'],
webSocket: ['wss://rpc.zora.energy'],
},
},
blockExplorers: {
default: { name: 'Explorer', url: 'https://explorer.zora.energy' },
},
contracts: {
multicall3: {
address: '0xcA11bde05977b3631167028862bE2a173976CA11',
blockCreated: 5882,
},
},
})
Chain Configuration
You can optionally pass a second parameter to defineChain
to set configuration such as: fees, formatters, and transaction serializers.
Fees
You can modify how fees are derived by using the fees
property on the Chain.
fees.baseFeeMultiplier
- Type:
number
- Default:
1.2
The fee multiplier to use to account for fee fluctuations. Used in the estimateFeesPerGas
Action against the latest block's base fee per gas to derive a final maxFeePerGas
(EIP-1193), or gas price to derive a final gasPrice
(Legacy).
Parameters
block
: The latest block.client
: The Client instance.request
: The transaction request (if exists).
import { defineChain } from 'viem'
const example = defineChain(
{ /* ... */ },
{
fees: {
baseFeeMultiplier: 1.2,
// or
async baseFeeMultiplier({ block, request }) {
// some async work
return // ...
}
}
}
)
import { defineChain } from 'viem'
const example = defineChain(
{ /* ... */ },
{
fees: {
baseFeeMultiplier: 1.2,
// or
async baseFeeMultiplier({ block, request }) {
// some async work
return // ...
}
}
}
)
fees.defaultPriorityFee
- Type:
number | ((args: FeesFnParameters) => Promise<bigint> | bigint)
The default maxPriorityFeePerGas
to use when a priority fee is not defined upon sending a transaction.
Also overrides the return value in the estimateMaxPriorityFeePerGas
Action and maxPriorityFeePerGas
value in estimateFeesPerGas
.
Parameters
block
: The latest block.client
: The Client instance.request
: The transaction request (if exists).
import { defineChain } from 'viem'
const example = defineChain(
{ /* ... */ },
{
fees: {
defaultPriorityFee: parseGwei('0.01'),
// or
async defaultPriorityFee({ block, request }) {
// some async work
return // ...
}
}
}
)
import { defineChain } from 'viem'
const example = defineChain(
{ /* ... */ },
{
fees: {
defaultPriorityFee: parseGwei('0.01'),
// or
async defaultPriorityFee({ block, request }) {
// some async work
return // ...
}
}
}
)
fees.estimateFeesPerGas
- Type:
(args: FeesFnParameters) => Promise<EstimateFeesPerGasResponse>
Allows customization of fee per gas values (ie. maxFeePerGas
, maxPriorityFeePerGas
, gasPrice
).
Also overrides the return value in estimateFeesPerGas
.
Parameters
block
: The latest block.client
: The Client instance.multiply
: A function to apply thebaseFeeMultiplier
to the provided value.request
: The transaction request (if exists).type
: The transaction type (ie.legacy
oreip1559
).
import { defineChain } from 'viem'
const example = defineChain(
{ /* ... */ },
{
fees: {
async estimateFeesPerGas({ client, multiply, type }) {
const gasPrice = // ...
const baseFeePerGas = // ...
const maxPriorityFeePerGas = // ...
if (type === 'legacy') return { gasPrice: multiply(gasPrice) }
return {
maxFeePerGas: multiply(baseFeePerGas) + maxPriorityFeePerGas,
maxPriorityFeePerGas
}
}
}
}
)
import { defineChain } from 'viem'
const example = defineChain(
{ /* ... */ },
{
fees: {
async estimateFeesPerGas({ client, multiply, type }) {
const gasPrice = // ...
const baseFeePerGas = // ...
const maxPriorityFeePerGas = // ...
if (type === 'legacy') return { gasPrice: multiply(gasPrice) }
return {
maxFeePerGas: multiply(baseFeePerGas) + maxPriorityFeePerGas,
maxPriorityFeePerGas
}
}
}
}
)
Formatters
You can modify how Blocks & Transactions are formatted by using the formatters
property on the Chain.
This is useful for chains that have a different Block or Transaction structure than Mainnet (e.g. Celo & OP Stack chains).
formatters.block
You can modify how Blocks are formatted by using the formatters.block
property on the Chain.
You can either pass in the Block overrides, or the whole Block itself to the format
function of defineBlock
. You can also exclude certain properties with exclude
.
import { defineBlock, defineChain, hexToBigInt } from 'viem'
type RpcBlockOverrides = {
secondaryFee: `0x${string}`
}
type BlockOverrides = {
secondaryFee: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
block: defineBlock({
exclude: ['difficulty'],
format(args: RpcBlockOverrides): BlockOverrides {
return {
secondaryFee: hexToBigInt(args.secondaryFee)
}
}
})
}
}
)
const block = await client.getBlock()
// ^? { ..., difficulty: never, secondaryFee: bigint, ... }
import { defineBlock, defineChain, hexToBigInt } from 'viem'
type RpcBlockOverrides = {
secondaryFee: `0x${string}`
}
type BlockOverrides = {
secondaryFee: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
block: defineBlock({
exclude: ['difficulty'],
format(args: RpcBlockOverrides): BlockOverrides {
return {
secondaryFee: hexToBigInt(args.secondaryFee)
}
}
})
}
}
)
const block = await client.getBlock()
// ^? { ..., difficulty: never, secondaryFee: bigint, ... }
formatters.transaction
You can modify how Transactions are formatted by using the formatters.transaction
property on the Chain.
You can either pass in the Transaction overrides, or the whole Transaction itself to the format
function of defineTransaction
. You can also exclude certain properties with exclude
.
import { defineTransaction, defineChain, hexToBigInt } from 'viem'
type RpcTransactionOverrides = {
mint: `0x${string}`
}
type TransactionOverrides = {
mint: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
transaction: defineTransaction({
exclude: ['gasPrice'],
format(args: RpcTransactionOverrides): TransactionOverrides {
return {
mint: hexToBigInt(args.mint)
}
}
})
}
}
)
const transaction = await client.getTransaction({ hash: '0x...' })
// ^? { ..., gasPrice: never, mint: bigint, ... }
import { defineTransaction, defineChain, hexToBigInt } from 'viem'
type RpcTransactionOverrides = {
mint: `0x${string}`
}
type TransactionOverrides = {
mint: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
transaction: defineTransaction({
exclude: ['gasPrice'],
format(args: RpcTransactionOverrides): TransactionOverrides {
return {
mint: hexToBigInt(args.mint)
}
}
})
}
}
)
const transaction = await client.getTransaction({ hash: '0x...' })
// ^? { ..., gasPrice: never, mint: bigint, ... }
formatters.transactionReceipt
You can modify how Transaction Receipts are formatted by using the formatters.transactionReceipt
property on the Chain.
You can either pass in the Transaction Receipt overrides, or the whole Transaction Receipt itself to the format
function of defineTransactionReceipt
. You can also exclude certain properties with exclude
.
import { defineTransactionReceipt, defineChain, hexToBigInt } from 'viem'
type RpcTransactionReceiptOverrides = {
l1Fee: `0x${string}`
}
type TransactionReceiptOverrides = {
l1Fee: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
transactionReceipt: defineTransactionReceipt({
exclude: ['effectiveGasPrice'],
format(args: RpcTransactionReceiptOverrides):
TransactionReceiptOverrides {
return {
l1Fee: hexToBigInt(args.l1Fee)
}
}
})
}
}
)
const receipt = await client.getTransactionReceipt({ hash: '0x...' })
// ^? { ..., effectiveGasPrice: never, l1Fee: bigint, ... }
import { defineTransactionReceipt, defineChain, hexToBigInt } from 'viem'
type RpcTransactionReceiptOverrides = {
l1Fee: `0x${string}`
}
type TransactionReceiptOverrides = {
l1Fee: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
transactionReceipt: defineTransactionReceipt({
exclude: ['effectiveGasPrice'],
format(args: RpcTransactionReceiptOverrides):
TransactionReceiptOverrides {
return {
l1Fee: hexToBigInt(args.l1Fee)
}
}
})
}
}
)
const receipt = await client.getTransactionReceipt({ hash: '0x...' })
// ^? { ..., effectiveGasPrice: never, l1Fee: bigint, ... }
formatters.transactionRequest
You can modify how Transaction Requests are formatted by using the formatters.transactionRequest
property on the Chain.
You can either pass in the Transaction Request overrides, or the whole Transaction Request itself to the format
function of defineTransactionRequest
. You can also exclude certain properties with exclude
.
import { defineTransactionRequest, defineChain, hexToBigInt } from 'viem'
type RpcTransactionRequestOverrides = {
secondaryFee: `0x${string}`
}
type TransactionRequestOverrides = {
secondaryFee: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
transactionRequest: defineTransactionRequest({
exclude: ['effectiveGasPrice'],
format(args: TransactionRequestOverrides):
RpcTransactionRequestOverrides {
return {
secondaryFee: numberToHex(args.secondaryFee)
}
}
})
}
}
)
const receipt = await client.getTransactionReceipt({ hash: '0x...' })
// ^? { ..., effectiveGasPrice: never, l1Fee: bigint, ... }
import { defineTransactionRequest, defineChain, hexToBigInt } from 'viem'
type RpcTransactionRequestOverrides = {
secondaryFee: `0x${string}`
}
type TransactionRequestOverrides = {
secondaryFee: bigint
}
const example = defineChain(
{ /* ... */ },
{
formatters: {
transactionRequest: defineTransactionRequest({
exclude: ['effectiveGasPrice'],
format(args: TransactionRequestOverrides):
RpcTransactionRequestOverrides {
return {
secondaryFee: numberToHex(args.secondaryFee)
}
}
})
}
}
)
const receipt = await client.getTransactionReceipt({ hash: '0x...' })
// ^? { ..., effectiveGasPrice: never, l1Fee: bigint, ... }
Serializers
serializers.transaction
- Type:
(transaction: Transaction, signature?: Signature) => "0x${string}"
You can modify how Transactions are serialized by using the serializers.transaction
property on the Chain.
Parameters
transaction
: The transaction to serialize.signature
: The transaction signature (if exists).
import { defineChain, serializeTransaction } from 'viem'
const example = defineChain(
{ /* ... */ },
{
serializers: {
transaction(transaction, signature) {
return serializeTransaction(transaction, signature)
}
}
}
)
import { defineChain, serializeTransaction } from 'viem'
const example = defineChain(
{ /* ... */ },
{
serializers: {
transaction(transaction, signature) {
return serializeTransaction(transaction, signature)
}
}
}
)
Utilities
extractChain
: Extracts a type-safe chain by ID.