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 viemBatteries-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.

