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 includessendandsendBulkmethods.requestEip1993- this adds an EIP-1993 compatablerequestmethod to the clienteip1993EventEmitter- This adds an EIP-1993 compatable event emitter API to the tevm clienttevmActionsthis adds the core api for tevm such asgetAccount,call,script, and more described more in detail in theactionssection of the learn docsethActionsthis adds actions that correspond to the standard ethereum JSON-RPC api such aseth.blockNumber,eth.getStorageAt,eth.balanceOfand 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
debugwill show a significant amount of internal logs andtraceincludes the EVM logs
It is recomended you also pass in a chain object when forking. This will improve the performance of forking as well as guarantee tevm has all the correct chain information such as which EIPs and hardforks to use. A TevmChain is different from a viem chain in that it extends viem chains with the ethereumjs/common interface.
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 modeinvalidates the cache every block so there isn’t much gained from persisting state in proxy mode - There is currently a known bug where
fork modewill 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 storageconst 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.