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

Getting Started

These docs target tevm@1.0.0-rc.151.

Install

npm
npm install tevm@1.0.0-rc.151 viem

Tevm re-exports the viem helpers used by the examples. Install viem separately only when your application imports directly from viem.

Run a Local Transaction

import {
  createMemoryClient,
  parseEther,
  PREFUNDED_ACCOUNTS,
} from 'tevm'
 
const client = createMemoryClient({
  miningConfig: { type: 'manual' },
})
 
const sender = PREFUNDED_ACCOUNTS[0].address
const recipient = '0x1111111111111111111111111111111111111111'
 
const { txHash } = await client.tevmCall({
  from: sender,
  to: recipient,
  value: parseEther('1'),
  addToMempool: true,
})
 
if (!txHash) throw new Error('transaction was not added to the txpool')
 
await client.tevmMine({ blockCount: 1 })
 
const receipt = await client.getTransactionReceipt({ hash: txHash })
const balance = await client.getBalance({ address: recipient })
 
console.log(receipt.status, balance)

createMemoryClient() is synchronous. The first action initializes the node lazily. Use await client.tevmReady() when initialization itself should finish before a measurement or forked read.

What Just Happened?

  1. createMemoryClient created an in-process Ethereum chain and a viem-compatible client.
  2. tevmCall({ addToMempool: true }) executed the transfer and added its transaction to the txpool.
  3. tevmMine({ blockCount: 1 }) built a canonical block.
  4. viem actions read the receipt and final balance.

Without addToMempool, tevmCall is a simulation and does not change canonical state.

Install Contract Code

Use viem test actions to prepare state and public actions to query it.

import { createMemoryClient } from 'tevm'
import { SimpleContract } from 'tevm/contract'
 
const client = createMemoryClient()
const contract = SimpleContract.withAddress(
  '0x2222222222222222222222222222222222222222',
)
 
await client.setCode({
  address: contract.address,
  bytecode: contract.deployedBytecode,
})
 
const value = await client.readContract({
  address: contract.address,
  abi: contract.abi,
  functionName: 'get',
})
 
console.log(value)

Fork an Existing Chain

The fork transport must be an EIP-1193 request function. Invoke the viem HTTP transport factory with ({}) when passing it directly.

import { createMemoryClient, http } from 'tevm'
import { mainnet } from 'tevm/common'
 
const client = createMemoryClient({
  common: mainnet,
  fork: {
    transport: http('https://ethereum-rpc.publicnode.com')({}),
    blockTag: 20_000_000n,
  },
})
 
await client.tevmReady()
 
const balance = await client.getBalance({
  address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
  blockNumber: 20_000_000n,
})
 
console.log(balance)

Pin blockTag for reproducible tests. Local writes are stored in an overlay and never sent upstream.

Choose an API Surface

Next: Architecture Overview · Mining Modes · Local Testing