Skip to main content

Try it Live

Run EventLog examples in the interactive playground
New to event logs? Start with Fundamentals for guided examples on topics, bloom filters, and ABI decoding.

Type Definition

Branded type representing an Ethereum event log with contract address, indexed topics, and event data.
export type EventLogType = {
  address: AddressType;
  topics: readonly HashType[];
  data: Uint8Array;
  blockNumber?: bigint;
  transactionHash?: HashType;
  transactionIndex?: number;
  blockHash?: HashType;
  logIndex?: number;
  removed?: boolean;
} & { readonly __tag: "EventLog" };

API Methods

Constructors

Accessors

Filtering

Utilities

Types

export type EventLogType = {
  /** Contract address that emitted the log */
  address: AddressType;
  /** Event topics (topic0 = signature, topic1-3 = indexed params) */
  topics: readonly HashType[];
  /** Non-indexed event data */
  data: Uint8Array;
  /** Block number where log was emitted */
  blockNumber?: bigint;
  /** Transaction hash that generated the log */
  transactionHash?: HashType;
  /** Transaction index in block */
  transactionIndex?: number;
  /** Block hash */
  blockHash?: HashType;
  /** Log index in block */
  logIndex?: number;
  /** Log removed due to chain reorganization */
  removed?: boolean;
} & { readonly __tag: "EventLog" };
Main branded type with all log metadata.

Usage Patterns

Effect Schema

import { EventLogSchema } from '@tevm/voltaire/EventLog/effect'

// Construct from typed data
const addr = new Uint8Array(20)
const topic0 = new Uint8Array(32)
const log = EventLogSchema.from({ address: addr, topics: [topic0], data: new Uint8Array(0) })

// Filter logs
const filtered = EventLogSchema.filter([log], { address: addr })

ERC-20 Transfer Event Filtering

import { EventLog, Address, Hash } from 'tevm';

// Transfer(address indexed from, address indexed to, uint256 value)
const TRANSFER_SIG = Hash(
  '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
);

// Filter transfers to specific user
const userAddress = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2');
const userAddressHash = Hash(
  new Uint8Array([...new Uint8Array(12).fill(0), ...userAddress])
);

const transfersToUser = EventLog.filterLogs(allLogs, {
  address: usdcAddress,
  topics: [
    TRANSFER_SIG,      // Event signature
    null,              // from: any address
    userAddressHash,   // to: user
  ],
  fromBlock: 18000000n,
  toBlock: 18500000n,
});

// Sort chronologically
const sorted = EventLog.sortLogs(transfersToUser);

// Decode values
for (const log of sorted) {
  const [fromHash, toHash] = log.getIndexedTopics();
  const value = new DataView(log.data.buffer).getBigUint64(24, false);

  console.log(`Transfer: ${value} tokens`);
  console.log(`Block: ${log.blockNumber}`);
}

Multi-Contract Log Parsing

import { EventLog, Address, Hash } from 'tevm';

const TRANSFER_SIG = Hash('0xddf252ad...');
const APPROVAL_SIG = Hash('0x8c5be1e5...');

// Monitor multiple ERC-20 tokens
const tokens = [
  Address('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'), // USDC
  Address('0x6B175474E89094C44Da98b954EedeAC495271d0F'), // DAI
  Address('0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'), // WETH
];

// Get all Transfer and Approval events
const relevantLogs = EventLog.filterLogs(allLogs, {
  address: tokens,
  topics: [[TRANSFER_SIG, APPROVAL_SIG]], // OR: either event type
});

// Process by event type
const transfers = relevantLogs.filter(log => {
  const sig = log.getTopic0();
  return sig && Hash.equals(sig, TRANSFER_SIG);
});

const approvals = relevantLogs.filter(log => {
  const sig = log.getTopic0();
  return sig && Hash.equals(sig, APPROVAL_SIG);
});

console.log(`Found ${transfers.length} transfers, ${approvals.length} approvals`);

Chain Reorganization Handling

import { EventLog } from 'tevm';

// Filter active (non-removed) logs
const activeLogs = allLogs.filter(log => !log.isRemoved());

// Detect reorg events
const removedLogs = allLogs.filter(log => log.wasRemoved());
if (removedLogs.length > 0) {
  console.log(`Chain reorg detected: ${removedLogs.length} logs invalidated`);

  for (const log of removedLogs) {
    console.log(`  Block ${log.blockNumber}, Index ${log.logIndex}`);
  }
}

// Sort remaining logs chronologically
const sorted = EventLog.sortLogs(activeLogs);

Block Range Analysis

import { EventLog } from 'tevm';

// Group logs by block
const byBlock = new Map<bigint, typeof allLogs>();

const sorted = EventLog.sortLogs(allLogs);
for (const log of sorted) {
  const blockNum = log.blockNumber ?? 0n;
  if (!byBlock.has(blockNum)) {
    byBlock.set(blockNum, []);
  }
  byBlock.get(blockNum)!.push(log);
}

// Analyze each block
for (const [blockNumber, blockLogs] of byBlock) {
  console.log(`\nBlock ${blockNumber}: ${blockLogs.length} logs`);

  // Count by contract
  const byContract = new Map<string, number>();
  for (const log of blockLogs) {
    const addr = Address.toHex(log.address);
    byContract.set(addr, (byContract.get(addr) || 0) + 1);
  }

  console.log('  Events per contract:', byContract);
}

Bundle Size

EventLog uses optimized APIs for efficient imports and tree-shaking support.

Core Documentation

  • Fundamentals - Learn event structure, topics, and bloom filters
  • Abi - ABI encoding/decoding for event data
  • Transaction - Transaction logs and receipts
  • BloomFilter - Bloom filter for efficient log filtering
  • Address - Ethereum address handling
  • Keccak256 - Keccak256 hashing for event signatures

Specification