Skip to content

MemoryClient

MemoryClient<TChain, TAccountOrAddress>: Prettify<Client<TevmTransport, TChain, TAccountOrAddress extends Account ? Account : undefined, TevmRpcSchema, TevmActions & PublicActions<TevmTransport, TChain, TAccountOrAddress extends Account ? Account : undefined> & WalletActions<TChain, TAccountOrAddress extends Account ? Account : undefined> & TestActions>>

Represents a TEVM-enhanced viem client with an in-memory Ethereum client as its transport. The MemoryClient comes preloaded with all wallet, test, public, and TEVM actions, and supports both manual and auto mining modes.

This client allows for extensive interaction with the EVM, including making JSON-RPC requests, managing accounts, forking networks, and handling state persistence.

Type Parameters

TChain extends Chain | undefined = Chain | undefined

TAccountOrAddress extends Account | Address | undefined = Account | Address | undefined

Example

import { createMemoryClient } from "tevm";
const client = createMemoryClient({
fork: {
transport: http("https://mainnet.optimism.io")({}),
},
});
const blockNumber = await client.getBlockNumber();
console.log(blockNumber);

See

Actions API

MemoryClient supports the following viem actions:

import { createMemoryClient } from "tevm";
const tevm = createMemoryClient();
await tevm.setAccount({ address: `0x${'01'.repeat(20)}`, balance: 100n });
import { createMemoryClient } from "tevm";
const tevm = createMemoryClient();
const bn = await tevm.getBlockNumber();
import { createMemoryClient } from "tevm";
const tevm = createMemoryClient();
await tevm.setBalance({ address: `0x${'01'.repeat(20)}`, balance: 100n });

Forking

To fork an existing network, pass an EIP-1193 transport to the fork.transport option with an optional block tag. When you fork, TEVM will pin the block tag and lazily cache state from the fork transport. It’s highly recommended to pass in a common object that matches the chain. This will increase the performance of forking with known values.

import { createMemoryClient, http } from "tevm";
import { optimism } from "tevm/common";
const forkedClient = createMemoryClient({
fork: {
transport: http("https://mainnet.optimism.io")({}),
blockTag: '0xa6a63cd70fbbe396321ca6fe79e1b6735760c03538208b50d7e3a5dac5226435',
},
common: optimism,
});

The common object extends the viem chain interface with EVM-specific information. When using TEVM, you should also use tevm/common rather than viem/chains or use createCommon and pass in a viem chain.

Viem clients, including MemoryClient, are themselves EIP-1193 transports. This means you can fork a client with another client.

Mining Modes

TEVM supports two mining modes:

  • Manual: Using tevm.mine()
  • Auto: Automatically mines a block after every transaction.

TEVM state does not update until blocks are mined.

Using TEVM over HTTP

TEVM can be run as an HTTP server using @tevm/server to handle JSON-RPC requests.

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

This allows you to use any Ethereum client to communicate with it, 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());

State Persistence (Experimental)

It is possible to persist the TEVM client to a synchronous source using the persister option.

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 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. More official chain support will be added in the near future.

Note: Optimism deposit transactions are not currently supported but will be in a future release. TEVM filters out these transactions from blocks.

Network and Hardfork Support

TEVM supports enabling and disabling different EIPs, but the following EIPs are always turned on:

  • 1559
  • 4895
  • 4844
  • 4788

Currently, only EIP-1559 Fee Market transactions are supported.

Tree Shakeable Actions

TEVM supports tree-shakeable actions using createTevmNode() and the tevm/actions package. If you are building a UI, you should use tree-shakeable actions to optimize bundle size. These are described in detail in the actions API guide.

Composing with TEVM Contracts and Bundler

MemoryClient can compose with TEVM contracts and the TEVM bundler. For more information, see the TEVM contracts guide and the TEVM Solidity imports guide.

import { createMemoryClient } from "tevm";
import { MyERC721 } from './MyERC721.sol';
const tevm = createMemoryClient({
fork: {
transport: http("https://mainnet.optimism.io")({}),
},
});
const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045';
await tevm.runContractCall(
MyERC721.write.mint({
caller: address,
}),
);
const balance = await tevm.runContractCall(
MyERC721.read.balanceOf({
caller: address,
}),
);
console.log(balance); // 1n

Defined in

packages/memory-client/src/MemoryClient.ts:193