Using with Viem
Tevm integrates with viem as a local Ethereum environment with viem's familiar API surface.
Integration Options
Two approaches:
Tree-shakable (Recommended)
// For production frontends — minimize bundle size
import { createTevmTransport, tevmDumpState } from 'tevm'
import { createClient } from 'viem'
import { getBlockNumber } from 'viem/actions'
const tevmTransport = createTevmTransport()
const client = createClient({ transport: tevmTransport })
// Import viem actions individually
await getBlockNumber(client)
// Import tevm actions individually
await tevmDumpState(client)Core Functionality
- Public Actions — read blockchain state, query contracts, estimate gas (below)
- Wallet Actions — send transactions, sign messages (below)
- Test Actions — manipulate state for testing (below)
- Tevm Actions — Tevm-specific EVM extensions (below)
Public Actions
Use viem's public actions to read from your local Tevm environment:
import { createMemoryClient } from "tevm";
import { ERC20 } from "tevm/contract";
import { parseAbi } from "viem";
const client = createMemoryClient();
const tokenAddress = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
const holderAddress = "0x1234567890123456789012345678901234567890";
const block = await client.getBlock();
console.log(`Block number: ${block.number}`);
const balance = await client.getBalance({
address: holderAddress,
});
const nonce = await client.getTransactionCount({
address: holderAddress,
});
await client.setCode({
address: tokenAddress,
bytecode: ERC20.deployedBytecode,
});
const result = await client.readContract({
address: tokenAddress,
abi: parseAbi(["function balanceOf(address) view returns (uint256)"]),
functionName: "balanceOf",
args: [holderAddress],
});Wallet Actions
Tevm supports all viem wallet actions with prefunded accounts:
import { createMemoryClient, PREFUNDED_ACCOUNTS } from "tevm";
import { parseEther } from "viem";
const client = createMemoryClient({
account: PREFUNDED_ACCOUNTS[0], // 10000 ETH
});
const hash = await client.sendTransaction({
to: "0x1234567890123456789012345678901234567890",
value: parseEther("1"),
});
const receipt = await client.waitForTransactionReceipt({ hash });
const { contractAddress } = await client.deployContract({
abi: parseAbi([
"function greet() view returns (string)",
"function setGreeting(string) returns ()",
]),
bytecode: "0x608060405234801561...",
});Working with Custom Accounts
import { createMemoryClient } from "tevm";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
);
const client = createMemoryClient({ account });
await client.setBalance({ address: account.address, value: parseEther("10") });
const hash = await client.sendTransaction({
to: "0x1234567890123456789012345678901234567890",
value: parseEther("1"),
});Test Actions
All viem test actions are supported (Anvil/Hardhat compatible):
import { createMemoryClient } from "tevm";
import { parseEther } from "viem";
const client = createMemoryClient();
await client.mine({ blocks: 5 });
await client.setBalance({
address: "0x1234567890123456789012345678901234567890",
value: parseEther("100"),
});
await client.setNextBlockTimestamp(1695311333n);
await client.mine({ blocks: 1 });
// Snapshot and revert
const snapshotId = await client.snapshot();
await client.setBalance({
address: "0x1234567890123456789012345678901234567890",
value: parseEther("999"),
});
await client.revert({ id: snapshotId });
const balance = await client.getBalance({
address: "0x1234567890123456789012345678901234567890",
});Tevm Actions
Tevm-specific actions for enhanced EVM control.
Contract Interactions
import { createMemoryClient } from "tevm";
import { ERC20 } from "tevm/contract";
import { parseAbi } from "viem";
const client = createMemoryClient();
const tokenAddress = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
const holderAddress = "0x1234567890123456789012345678901234567890";
const result = await client.tevmContract({
abi: parseAbi(["function balanceOf(address) view returns (uint256)"]),
address: tokenAddress,
deployedBytecode: ERC20.deployedBytecode,
functionName: "balanceOf",
args: [holderAddress],
});
// Low-level call
const callResult = await client.tevmCall({
to: tokenAddress,
deployedBytecode: ERC20.deployedBytecode,
data:
"0x70a08231000000000000000000000000" +
holderAddress.slice(2),
});Account Management
import { createMemoryClient } from "tevm";
import { parseEther } from "viem";
const client = createMemoryClient();
const account = await client.tevmGetAccount({
address: "0x1234567890123456789012345678901234567890",
});
// Set complex account state (EOA or contract)
await client.tevmSetAccount({
address: "0xabcdef1234567890abcdef1234567890abcdef12",
balance: parseEther("100"),
nonce: 5n,
deployedBytecode: "0x6080604052348015600e575f80fd5b00",
state: {
"0x0000000000000000000000000000000000000000000000000000000000000000":
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000001":
"0x0000000000000000000000000000000000000000000000000000000000000002",
},
});
// Native ETH
await client.tevmDeal({
account: "0x1234567890123456789012345678901234567890",
amount: parseEther("10"),
});
// ERC20
await client.tevmDeal({
erc20: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
account: "0x1234567890123456789012345678901234567890",
amount: 1000000n, // 1 USDC (6 decimals)
});State Management
import { createMemoryClient } from "tevm";
const client = createMemoryClient();
const state = await client.tevmDumpState();
const savedState = await client.tevmDumpState();
await client.setBalance({
address: "0x1234567890123456789012345678901234567890",
value: 123456789n,
});
await client.tevmLoadState({ state: savedState });
await client.tevmMine({ blocks: 5 });Inside the Memory Client
A MemoryClient is a viem client with Tevm functionality. Build one from scratch:
import { createTevmNode } from "tevm";
import { requestEip1193 } from "tevm/decorators";
import { tevmViemActions } from "tevm/memory-client";
import { http, custom, createClient, publicActions, testActions, walletActions } from "viem";
const rpcUrl = process.env.OPTIMISM_RPC_URL ?? "https://mainnet.optimism.io";
const forkTransport = http(rpcUrl)({});
const node = createTevmNode({
fork: { transport: forkTransport },
}).extend(requestEip1193());
const memoryClient = createClient({ transport: custom(node) })
.extend(tevmViemActions())
.extend(publicActions)
.extend(walletActions)
.extend(testActions({ mode: "anvil" }));Key architectural components:
- EIP-1193 Compatibility Layer — standard Ethereum provider interface
- In-Memory EVM — full Ethereum Virtual Machine locally
- Viem Integration — extends viem with EVM-specific capabilities
Complete Action Reference
Public Actions — Read blockchain state
Contract Interactions
call— Call without sending a transactionreadContract— Read a constant/view methodsimulateContract— Simulate a write without executingestimateContractGas— Estimate gas for a contract callestimateGas— Estimate gas for a transactiongetBytecode— Get a contract's bytecode
Block & Transaction
getBlock— Get a block by number or hashgetBlockNumber— Latest block numbergetBlockTransactionCount— Tx count for a blockgetTransaction— Tx details by hashgetTransactionCount— Tx count (nonce) for addressgetTransactionReceipt— Receipt by hashwaitForTransactionReceipt— Wait for mining
Account & Chain
getBalance— Balance of an addressgetChainId— Chain IDgetGasPrice— Current gas priceestimateFeesPerGas— Estimate fees per gas unitgetStorageAt— Storage slot value
Test Actions — Manipulate blockchain state
Block & Mining
mine— Mine blockssetAutomine— Enable/disable automatic miningsetIntervalMining— Mine at intervalssetBlockGasLimit— Block gas limitsetBlockTimestampInterval— Timestamp incrementsetNextBlockBaseFeePerGas— Next block base feesetNextBlockTimestamp— Next block timestamp
Account & State
setBalance— Set address balancesetCode— Set contract bytecodesetNonce— Set noncesetStorageAt— Set storage slotsetCoinbase— Set miner addresssetMinGasPrice— Minimum gas price
State Management
Wallet Actions — Send transactions, interact with accounts
Account Management
getAddresses— Get available addressesrequestAddresses— Request address permission
Transaction Operations
prepareTransactionRequest— Prepare txsendTransaction— Send txsendRawTransaction— Send signed txsignTransaction— Sign tx
Signing
signMessage— Sign a messagesignTypedData— Sign typed data (EIP-712)
Chain Management
addChain— Add a chainswitchChain— Switch chain
Permissions & Assets
getPermissions— Get permissionsrequestPermissions— Request permissionswatchAsset— Add a token
Tevm Actions — Enhanced EVM capabilities
tevmCall— Low-level EVM calltevmContract— Contract call with detailed EVM infotevmDeploy— Deploy with detailed resultstevmGetAccount— Detailed account infotevmSetAccount— Set complex account statetevmDeal— Add native ETH or ERC20 tokenstevmDumpState— Export complete EVM statetevmLoadState— Import complete EVM statetevmMine— Mine blocks with options

