Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Using with Ethers.js v6

Tevm works with Ethers.js through Tevm's EIP-1193 provider interface. Use Tevm for local chain control, state setup, and mining; use ethers for providers, wallets, and contract instances.

Install

npm
npm install tevm ethers

Create a Provider

Create a memory client, extend its underlying Tevm node with the EIP-1193 request interface, then pass that node to ethers' BrowserProvider.

import { createMemoryClient } from 'tevm'
import { requestEip1193 } from 'tevm/decorators'
import { BrowserProvider } from 'ethers'
 
const client = createMemoryClient()
client.transport.tevm.extend(requestEip1193())
await client.tevmReady()
 
const provider = new BrowserProvider(client.transport.tevm, undefined, {
  // Ethers caches JSON-RPC reads briefly by default. Disable for
  // deterministic local tests where you manually mine blocks.
  cacheTimeout: -1,
})
 
console.log(`Connected to block ${await provider.getBlockNumber()}`)

Fund a Wallet

import { Wallet, formatEther, parseEther } from 'ethers'
 
const signer = Wallet.createRandom().connect(provider)
 
await client.setBalance({ address: signer.address, value: parseEther('10') })
 
const balance = await provider.getBalance(signer.address)
console.log(`Wallet balance: ${formatEther(balance)} ETH`)

Deploy and Call a Contract

Deploys a small compiled counter contract, mines the deployment, then calls it through an ethers Contract instance.

import { ContractFactory } from 'ethers'
 
const counterAbi = [
  'function number() view returns (uint256)',
  'function increment() public',
] as const
 
const counterBytecode =
  '0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220d5fb46adf6ce0cfd90fa4324ffd8c48b0fc6fb6c4cac9ca2c69c97e25f355c9d64736f6c63430008110033'
 
const factory = new ContractFactory(counterAbi, counterBytecode, signer)
const deployment = await factory.deploy()
 
await client.mine({ blocks: 1 })
 
const counter = await deployment.waitForDeployment()
console.log(`Counter deployed at ${await counter.getAddress()}`)
console.log(`Initial count: ${await counter.number()}`)

Send a Transaction

Transactions sent by ethers go through eth_sendRawTransaction and enter Tevm's mempool. Mine a block before waiting for the receipt.

const tx = await counter.increment()
 
await client.mine({ blocks: 1 })
await tx.wait()
 
console.log(`Updated count: ${await counter.number()}`)

Complete Example

import { createMemoryClient } from 'tevm'
import { requestEip1193 } from 'tevm/decorators'
import { BrowserProvider, ContractFactory, Wallet, formatEther, parseEther } from 'ethers'
 
const client = createMemoryClient()
client.transport.tevm.extend(requestEip1193())
await client.tevmReady()
 
const provider = new BrowserProvider(client.transport.tevm, undefined, { cacheTimeout: -1 })
 
const signer = Wallet.createRandom().connect(provider)
await client.setBalance({ address: signer.address, value: parseEther('10') })
 
console.log(`Wallet balance: ${formatEther(await provider.getBalance(signer.address))} ETH`)
 
const counterAbi = [
  'function number() view returns (uint256)',
  'function increment() public',
] as const
 
const counterBytecode =
  '0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220d5fb46adf6ce0cfd90fa4324ffd8c48b0fc6fb6c4cac9ca2c69c97e25f355c9d64736f6c63430008110033'
 
const factory = new ContractFactory(counterAbi, counterBytecode, signer)
const deployment = await factory.deploy()
await client.mine({ blocks: 1 })
 
const counter = await deployment.waitForDeployment()
console.log(`Counter deployed at ${await counter.getAddress()}`)
console.log(`Initial count: ${await counter.number()}`)
 
const tx = await counter.increment()
await client.mine({ blocks: 1 })
await tx.wait()
 
console.log(`Updated count: ${await counter.number()}`)

Notes

  • Use client.setBalance(), client.setStorageAt(), client.mine(), and other Tevm test actions to control the local chain.
  • Use ethers providers, wallets, factories, and contracts for application code that already depends on ethers.
  • Tevm does not mine ethers transactions until you call client.mine() unless you configure automining.