Tevm Node Methods
Reference for the main API methods on a Tevm Node instance: EVM interaction, state management, execution control.
Core Methods
Initialization
import { createTevmNode, http } from 'tevm'
const rpcUrl = process.env.MAINNET_RPC_URL
if (!rpcUrl) {
throw new Error('MAINNET_RPC_URL is required for fork mode')
}
const node = createTevmNode({
fork: {
transport: http(rpcUrl)({})
}
})
await node.ready()Virtual Machine
import { createImpersonatedTx } from 'tevm/tx'
import { Block } from 'tevm/block'
import { createAddress } from 'tevm/address'
const vm = await node.getVm()
const block = new Block()
const tx = createImpersonatedTx({
impersonatedAddress: createAddress('0x1234567890123456789012345678901234567890'),
nonce: 0n,
gasLimit: 21064n,
maxFeePerGas: 8n,
maxPriorityFeePerGas: 1n,
to: createAddress('0x5678901234567890123456789012345678901234'),
value: 1000000000000000000n, // 1 ETH
})
const result = await vm.runTx({ tx, block, skipNonce: true, skipBalance: true })
if (!result.execResult.exceptionError) {
console.log('Gas used:', result.totalGasSpent)
}Transaction Pool
const txPool = await node.getTxPool()
await txPool.add({
from: '0x1234...',
to: '0x5678...',
value: 1000000000000000000n,
})
// Sorted by gas price and nonce
const pending = await txPool.txsByPriceAndNonce()
// Raw access
const allPending = txPool.getPendingTransactions()
// Pending nonce for an address
const nextNonce = txPool.getPendingNonce('0x1234...')Receipts & Logs
import { hexToBytes } from 'tevm/utils'
const receipts = await node.getReceiptsManager()
const vm = await node.getVm()
const fromBlock = await vm.blockchain.getBlock(0n)
const toBlock = fromBlock
const receipt = await receipts.getReceiptByTxHash(
hexToBytes('0x1234567890123456789012345678901234567890123456789012345678901234'),
)
const logs = await receipts.getLogs(
fromBlock,
toBlock,
[hexToBytes('0x1234567890123456789012345678901234567890')],
[hexToBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef')],
)The logs API mirrors Ethereum's JSON-RPC pattern (filter by address, topics, block range).
State Management
Account Impersonation
// Impersonate (fork mode only)
node.setImpersonatedAccount('0x1234...')
const impersonated = node.getImpersonatedAccount()
// Stop
node.setImpersonatedAccount(undefined)Event Filtering
node.setFilter({
id: '0x1',
fromBlock: 0n,
toBlock: 'latest',
address: '0x1234...',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef', // Transfer
],
})
const filters = node.getFilters()
node.removeFilter('0x1')
const logs = await node.request({
method: 'eth_getFilterChanges',
params: ['0x1']
})Topic 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef is keccak256 of Transfer(address,address,uint256).
Node Properties
Status
console.log(node.status)
// 'INITIALIZING' | 'READY' | 'SYNCING' | 'MINING' | 'STOPPED'
const waitForReady = async () => {
while (node.status !== 'READY') {
await new Promise(resolve => setTimeout(resolve, 100))
}
}Mode
console.log(node.mode) // 'fork' or 'normal'
if (node.mode === 'fork') {
// fork-specific features like impersonation
} else {
// local-only features
}Logger
node.logger.trace('Extremely detailed information')
node.logger.debug('Detailed debugging information')
node.logger.info('General information')
node.logger.warn('Warning messages')
node.logger.error('Error information')
node.logger.fatal('Critical errors that stop execution')
node.logger.info('Transaction processed', {
hash: '0x1234...',
from: '0x5678...',
to: '0x9abc...',
value: '1 ETH'
})Advanced Actions
The tevm-prefixed actions provide direct EVM execution with debugging hooks.
tevmCall
Low-level EVM call with execution tracing:
import { tevmCall } from 'tevm/actions'
import { encodeFunctionData } from 'viem'
import { createMemoryClient } from 'tevm'
const client = createMemoryClient()
const result = await tevmCall(client, {
to: '0x1234...',
data: encodeFunctionData({ abi, functionName: 'myFunction', args: [arg1, arg2] }),
onStep: (step, next) => {
console.log(`Opcode: ${step.opcode.name}, PC: ${step.pc}`)
next?.()
},
onNewContract: (data, next) => {
console.log(`New contract at: ${data.address.toString()}`)
next?.()
},
onBeforeMessage: (message, next) => {
console.log(`Call to: ${message.to?.toString()}`)
next?.()
},
onAfterMessage: (result, next) => {
console.log(`Return: ${result.execResult.returnValue.toString('hex')}`)
next?.()
}
})tevmContract
High-level contract interaction with event monitoring:
import { tevmContract } from 'tevm/actions'
import { createMemoryClient } from 'tevm'
const client = createMemoryClient()
const result = await tevmContract(client, {
abi,
address: '0x1234...',
functionName: 'myFunction',
args: [arg1, arg2],
onStep: (step, next) => {
console.log(`Opcode: ${step.opcode.name}, Stack: ${step.stack.length}`)
next?.()
},
onNewContract: (data, next) => {
console.log(`New contract: ${data.address.toString()}`)
next?.()
}
})tevmDeploy
Contract deployment with execution monitoring:
import { tevmDeploy } from 'tevm/actions'
import { createMemoryClient } from 'tevm'
const client = createMemoryClient()
const deployResult = await tevmDeploy(client, {
abi,
bytecode,
args: [constructorArg1, constructorArg2],
onStep: (step, next) => {
console.log(`Executing: ${step.opcode.name}`)
next?.()
},
onNewContract: (data, next) => {
console.log(`Deployed at: ${data.address.toString()}`)
next?.()
}
})
console.log('Deployed:', deployResult.address)
console.log('Gas used:', deployResult.gasUsed)Debug use cases: gas profiling, contract testing, security auditing, educational EVM visualizers.
Extensibility
Custom Methods
const enhancedNode = node.extend((baseNode) => ({
async getBalance(address: string) {
const vm = await baseNode.getVm()
const account = await vm.stateManager.getAccount(address)
return account.balance
},
}))
const balance = await enhancedNode.getBalance('0x1234...')State Cloning
// Deep copy with independent state
const nodeCopy = await node.deepCopy()
// Fork from another node
const forkedNode = createTevmNode({
fork: { transport: node }
})
await nodeCopy.sendTransaction({ ... })
// Original state unchangedState copying is useful for test scenarios, alternative execution paths, and state snapshots.
JSON-RPC Support
Tevm Node implements standard Ethereum JSON-RPC methods.
EIP-1193 Interface
import { requestEip1193 } from 'tevm/decorators'
const node = createTevmNode().extend(requestEip1193())
const blockNumber = await node.request({ method: 'eth_blockNumber', params: [] })
const balance = await node.request({
method: 'eth_getBalance',
params: ['0x1234...', 'latest']
})The EIP-1193 interface is compatible with libraries like Ethers.js.
Action Methods
import { ethActions } from 'tevm/decorators'
const node = createTevmNode().extend(ethActions())
const blockNumber = await node.eth.getBlockNumber()
const balance = await node.eth.getBalance('0x1234...')
const hash = await node.eth.sendTransaction({
from: '0x1234...',
to: '0x5678...',
value: 1000000000000000000n
})Action methods provide ergonomic TypeScript-typed alternatives to raw JSON-RPC.
Common JSON-RPC Methods
For the exhaustive list, see the JSON-RPC Guide.
State Accesseth_getBalanceeth_getCodeeth_getStorageAteth_getTransactionCount
eth_blockNumbereth_getBlockByHasheth_getBlockByNumber
eth_sendTransactioneth_sendRawTransactioneth_getTransactionByHasheth_getTransactionReceipt
anvil_impersonateAccountanvil_stopImpersonatingAccountanvil_mineanvil_setBalance
tevm_snapshottevm_reverttevm_minetevm_setAccount
whatsabi[Coming Soon] Analyze contract bytecode, discover function selectors, resolve proxy implementations, and determine ABIs even for unverified contracts.

