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 with Viem

createMemoryClient is a viem client backed by an in-process Tevm node. It includes viem public, wallet, and Anvil-compatible test actions plus Tevm-specific actions.

Install

npm install tevm@1.0.0-rc.151 viem

Batteries-Included Client

import { createMemoryClient } from 'tevm'
 
const client = createMemoryClient()
 
const chainId = await client.getChainId()
const block = await client.getBlock({ blockTag: 'latest' })
const balance = await client.getBalance({
  address: '0x1111111111111111111111111111111111111111',
})
 
console.log(chainId, block.number, balance)

Client construction is synchronous. await client.tevmReady() is optional for local clients and useful before the first forked read.

Public, Wallet, Test, and Tevm Actions

import { createMemoryClient, PREFUNDED_ACCOUNTS } from 'tevm'
 
const client = createMemoryClient({
  account: PREFUNDED_ACCOUNTS[0],
  miningConfig: { type: 'manual' },
})
 
// viem test action
await client.setBalance({
  address: PREFUNDED_ACCOUNTS[0].address,
  value: 10n ** 18n,
})
 
// viem wallet action
const hash = await client.sendTransaction({
  to: '0x1111111111111111111111111111111111111111',
  value: 1n,
})
 
// viem test action
await client.mine({ blocks: 1 })
 
// viem public action
const receipt = await client.getTransactionReceipt({ hash })
 
// Tevm action
const account = await client.tevmGetAccount({
  address: '0x1111111111111111111111111111111111111111',
})
 
console.log(receipt.status, account.balance)

The viem mine action uses { blocks }. The Tevm equivalent uses client.tevmMine({ blockCount }).

Call a Contract

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',
})
 
const simulation = await client.tevmContract({
  to: contract.address,
  abi: contract.abi,
  functionName: 'get',
})
 
console.log(value, simulation.data)

Use viem contract actions for familiar reads and writes. Use tevmContract when a call needs Tevm-only options such as opcode hooks, state overrides, createTrace, or createAccessList.

Fork Through a Viem Transport

import { createMemoryClient, http } from 'tevm'
import { optimism } from 'tevm/common'
 
const client = createMemoryClient({
  common: optimism,
  fork: {
    transport: http('https://mainnet.optimism.io')({}),
    blockTag: 130_000_000n,
  },
})
 
await client.tevmReady()
console.log(await client.getBlockNumber())

The value passed as fork.transport is an EIP-1193 request function, so invoke http(url) with ({}).

Tree-Shakable Client

For smaller application bundles, construct a plain viem client with the Tevm transport and import actions individually.

import {
  createTevmTransport,
  tevmCall,
  tevmDumpState,
} from 'tevm'
import { createClient } from 'viem'
import { getBlockNumber } from 'viem/actions'
 
const client = createClient({
  transport: createTevmTransport(),
})
 
const blockNumber = await getBlockNumber(client)
const call = await tevmCall(client, {
  deployedBytecode: '0x6001600055',
  createTrace: true,
})
const state = await tevmDumpState(client)
 
console.log(blockNumber, call.executionGasUsed, state.state)

Standalone Tevm action functions come from tevm; tevm/actions contains lower-level handler factories and types.

Raw EIP-1193 Requests

The transport also supports the EIP-1193 request shape:

import { createMemoryClient } from 'tevm'
 
const client = createMemoryClient()
 
const chainId = await client.request({ method: 'eth_chainId' })
const balance = await client.request({
  method: 'eth_getBalance',
  params: ['0x1111111111111111111111111111111111111111', 'latest'],
})
 
console.log(chainId, balance)

Do not add JSON-RPC envelope fields (id and jsonrpc) to request.

Related