Skip to content

Tevm clients guide

Tevm Clients

Tevm clients provide a JavaScript api for interacting with the Tevm API. This api provides a uniform API for interacting with Tevm whether interacting with a MemoryClient directly or remotely interacting via an HttpCLient. Tevm clients share the same actions based interface along with a request method for handling JSON-RPC requests.

The following in-memory clients are available

  • MemoryClient - An in memory instance of the EVM that can run in Node.js, bun or the browser
  • TevmProvider - For ethers users

Viem API

Tevm is built on top of viem and supports an ever-growing list of the viem API. 100% support for viem is release criteria for Tevm 1.0.0 stable.

MemoryClient

The default client most folks will want to use is MemoryClient. It comes with the following additional functionality added to the BaseClient

  • tevmSend - This decorator allows issuing JSON-RPC requests. This includes send and sendBulk methods.
  • requestEip1993 - this adds an EIP-1993 compatable request method to the client
  • eip1993EventEmitter - This adds an EIP-1993 compatable event emitter API to the tevm client
  • tevmActions this adds the core api for tevm such as getAccount, call, script, and more described more in detail in the actions section of the learn docs
  • ethActions this adds actions that correspond to the standard ethereum JSON-RPC api such as eth.blockNumber, eth.getStorageAt, eth.balanceOf and more.

To create a memoryclient simply initialize it with createMemoryClient.

import { createMemoryClient } from "tevm";
const client = createMemoryClient({
fork: { url: "https://mainnet.optimism.io" },
});

Options

Notable options include:

  • fork.url to fork a network
  • fork.blockTag to specify a specific block tag to fork
  • loggingLevel defaults to warning. Setting to debug will show a significant amount of internal logs and trace includes the EVM logs

See BaseClientOptions docs for information about all individual options.

Mining modes

Currently only manual mining using tevm.mine() is supported.

Using tevm over http

A common use case is wanting to use a client over http. This can be done via using @tevm/server to run tevm as an HTTP server.

import { createServer } from "tevm/server";
import { createMemoryClient } from "tevm";
const memoryClient = createMemoryClient();
const server = createServer({
request: tevm.request,
});
server.listen(8545, () => console.log("listening on 8545"));

Once you are running it as a server you can use any ethereum client to communicate with it with no special modifications including a viem public client

import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
const publicClient = createPublicClient({
chain: mainnet,
transport: http("https://localhost:8545"),
});
console.log(await publicClient.getChainId());

Tevm also supports a growing list of the anvil/hardhat test api.

For viem users you can also use the custom tevm actions such as tevmSetAccount even over http via extending any viem client with tevmViemExtension.

import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
import { tevmViemExtension } from "tevm/viem";
const publicClient = createPublicClient({
chain: mainnet,
transport: http("https://localhost:8545"),
}).extend(tevmViemExtension());
console.log(await publicClient.setAccount({ address: `0x${"00".repeat(20)}` }));
console.log(await publicClient.getAccount({ address: `0x${"00".repeat(20)}` }));

This works because all tevm actions are implemented both in memory and as JSON-RPC handlers. This means whether using tevm in memory with MemoryProvider or over http the api is the same.

State persistence (experimental)

It is possible to persist the tevm client to a syncronous source using the persister option. This will initialize the state with with the persisted storage if it exists and back up the state to this storage after state updates happen.

  • Note that proxy mode invalidates the cache every block so there isn’t much gained from persisting state in proxy mode
  • There is currently a known bug where fork mode will not persist the block tag and thus will be fetching state from a newer block when reinitialized.
  • The memory client still keeps the state in memory as source of truth even with state persistence. It is simply backing up the state to storage so it can rehydrate itself on future initializations
import { createMemoryClient, createSyncPersister } from "tevm";
import { createMemoryClient } from "tevm/sync-storage-persister";
// Client state will be hydrated and persisted from/to local storage
const clientWithLocalStoragePersistence = createMemoryClient({
persister: createSyncPersister({
storage: localStorage,
}),
});

Network support

Tevm network compatability will grow over time. Check back here for updates. At this moment tevm guarantees support for the following networks:

  • Ethereum mainnet
  • Standard OP Stack chains

Other EVM chains are likely to work but do not officially carry support.

Note: At this time Optimism deposit transactions are not supported by At this time Optimism deposit transactions are not supported by tevm but will be in a future release. Currently Tevm filters out these tx from blocks.

Network and hardfork support and tx support

Tevm experimentally supports enabling and disabling different EIPs but the following EIPs are always turned on.

  • 1559
  • 4895,
  • 4844,
  • 4788

Tevm plans on supporting many types of tx in future but at this moment only EIP-1559 Fee Market tx are supported.