Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Forking Mainnet Example

Basic Fork Setup

Unknown accounts/contracts fetch from the remote on demand and cache locally.

import { createTevmNode, http } from 'tevm'
 
const rpcUrl = process.env.MAINNET_RPC_URL
if (!rpcUrl) throw new Error('MAINNET_RPC_URL is required')
 
const node = createTevmNode({
  fork: {
    transport: http(rpcUrl)({}),
  },
  loggingLevel: 'debug',
})
 
await node.ready()

Account Impersonation

import { callHandler } from 'tevm/actions'
 
const result = await callHandler(node)({
  from: '0x28C6c06298d514Db089934071355E5743bf21d60',
  to: '0x1234567890123456789012345678901234567890',
  value: 1000000000000000000n, // 1 ETH
  skipBalance: true,
  throwOnFail: false,
})

Working with Forked Contracts

import { callHandler } from 'tevm/actions'
import { encodeFunctionData, parseAbi } from 'viem'
 
const USDC_ADDRESS = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
const HOLDER_ADDRESS = '0x47ac0fb4f2d84898e4d9e7b4dab3c24507a6d503'
const RECIPIENT_ADDRESS = '0x1234567890123456789012345678901234567890'
const ERC20_ABI = parseAbi([
  'function balanceOf(address) view returns (uint256)',
  'function transfer(address to, uint256 amount) returns (bool)',
])
 
const balance = await callHandler(node)({
  to: USDC_ADDRESS,
  data: encodeFunctionData({
    abi: ERC20_ABI,
    functionName: 'balanceOf',
    args: [HOLDER_ADDRESS],
  }),
})
 
// Simulate a local write; the remote chain is not affected.
const transfer = await callHandler(node)({
  from: HOLDER_ADDRESS,
  to: USDC_ADDRESS,
  data: encodeFunctionData({
    abi: ERC20_ABI,
    functionName: 'transfer',
    args: [RECIPIENT_ADDRESS, 1n],
  }),
  skipBalance: true,
  throwOnFail: false,
})

Fork at Specific Block

const node = createTevmNode({
  fork: {
    transport: http(rpcUrl)({}),
    blockTag: 23_483_670n,
  },
})
 
const vm = await node.getVm()
const block = await vm.blockchain.getBlock(23_483_670n)

Multiple Network Support

const optimismNode = createTevmNode({
  fork: { transport: http(process.env.OPTIMISM_RPC_URL!)({}) },
})
 
const arbitrumNode = createTevmNode({
  fork: { transport: http(process.env.ARBITRUM_RPC_URL!)({}) },
})
Related