or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

contract-deployment.mdcontract-interaction.mdevent-management.mdindex.mdtransaction-handling.md
tile.json

event-management.mddocs/

Event Management

Comprehensive event listening, filtering, and querying capabilities. Supports real-time event monitoring and historical event queries with automatic ABI decoding and rich event objects.

Capabilities

Event Listening

Add event listeners for real-time contract event monitoring.

/**
 * Add persistent event listener
 * @param event - Event name, signature, or EventFilter
 * @param listener - Callback function to handle events
 * @returns Contract instance for chaining
 */
on(event: EventFilter | string, listener: Listener): this;

/**
 * Add one-time event listener (automatically removed after first event)
 * @param event - Event name, signature, or EventFilter
 * @param listener - Callback function to handle events
 * @returns Contract instance for chaining
 */
once(event: EventFilter | string, listener: Listener): this;

Usage Examples:

import { Contract } from "@ethersproject/contracts";

const contract = new Contract(address, abi, provider);

// Listen for specific event by name
contract.on("Transfer", (from, to, value, event) => {
  console.log(`Transfer: ${from} -> ${to}: ${value.toString()}`);
  console.log("Block number:", event.blockNumber);
  console.log("Transaction hash:", event.transactionHash);
});

// Listen for event once
contract.once("Approval", (owner, spender, value, event) => {
  console.log(`Approval granted: ${owner} -> ${spender}: ${value.toString()}`);
});

// Listen for all events using wildcard
contract.on("*", (event) => {
  console.log("Event:", event.event);
  console.log("Args:", event.args);
});

// Listen using event filter
const filter = contract.filters.Transfer("0x...", null); // Transfer from specific address
contract.on(filter, (from, to, value, event) => {
  console.log(`Transfer from ${from}: ${to} received ${value.toString()}`);
});

Event Listener Management

Remove event listeners and manage listener lifecycle.

/**
 * Remove specific event listener
 * @param eventName - Event name, signature, or EventFilter
 * @param listener - Specific listener function to remove
 * @returns Contract instance for chaining
 */
off(eventName: EventFilter | string, listener: Listener): this;

/**
 * Remove specific event listener (alias for off)
 * @param eventName - Event name, signature, or EventFilter  
 * @param listener - Specific listener function to remove
 * @returns Contract instance for chaining
 */
removeListener(eventName: EventFilter | string, listener: Listener): this;

/**
 * Remove all listeners for specific event or all events
 * @param eventName - Event name, signature, or EventFilter (optional)
 * @returns Contract instance for chaining
 */
removeAllListeners(eventName?: EventFilter | string): this;

/**
 * Get count of listeners for specific event or all events
 * @param eventName - Event name, signature, or EventFilter (optional)
 * @returns Number of active listeners
 */
listenerCount(eventName?: EventFilter | string): number;

/**
 * Get array of listeners for specific event or all events
 * @param eventName - Event name, signature, or EventFilter (optional)
 * @returns Array of listener functions
 */
listeners(eventName?: EventFilter | string): Array<Listener>;

Usage Examples:

// Store listener reference for later removal
const transferListener = (from, to, value, event) => {
  console.log(`Transfer: ${from} -> ${to}: ${value.toString()}`);
};

contract.on("Transfer", transferListener);

// Remove specific listener
contract.off("Transfer", transferListener);

// Remove all Transfer listeners
contract.removeAllListeners("Transfer");

// Remove all listeners for all events
contract.removeAllListeners();

// Check listener counts
console.log("Transfer listeners:", contract.listenerCount("Transfer"));
console.log("Total listeners:", contract.listenerCount());

// Get all listeners
const allListeners = contract.listeners();

Historical Event Queries

Query historical events from the blockchain with flexible filtering options.

/**
 * Query historical events from blockchain
 * @param event - Event name, signature, or EventFilter
 * @param fromBlockOrBlockhash - Starting block number/tag or block hash
 * @param toBlock - Ending block number/tag (ignored if using block hash)
 * @returns Promise resolving to array of Event objects
 */
queryFilter(
  event: EventFilter | string,
  fromBlockOrBlockhash?: BlockTag | string,
  toBlock?: BlockTag
): Promise<Array<Event>>;

Usage Examples:

// Query all Transfer events from latest 1000 blocks
const recentTransfers = await contract.queryFilter("Transfer", -1000);

// Query events between specific blocks
const transfers = await contract.queryFilter("Transfer", 12000000, 12001000);

// Query events from specific block hash
const transfersInBlock = await contract.queryFilter(
  "Transfer", 
  "0x1234567890abcdef..."
);

// Query with event filter for specific parameters
const filter = contract.filters.Transfer("0x...", null); // From specific address
const filteredTransfers = await contract.queryFilter(filter, -1000);

// Process historical events
for (const event of transfers) {
  console.log("Transfer:", event.args);
  console.log("Block:", event.blockNumber);
  console.log("Gas used:", event.gasUsed);
  
  // Get additional transaction details
  const block = await event.getBlock();
  const transaction = await event.getTransaction();
}

Event Emission

Manually emit events (for testing or custom event handling).

/**
 * Manually emit event to listeners
 * @param eventName - Event name, signature, or EventFilter
 * @param args - Event arguments
 * @returns True if any listeners were called
 */
emit(eventName: EventFilter | string, ...args: Array<any>): boolean;

Event Objects

Rich event objects provided to listeners and queries.

/**
 * Enhanced event object with decoded data and utility methods
 */
interface Event extends Log {
  /** Decoded event name */
  event?: string;
  /** Event signature hash */
  eventSignature?: string;
  /** Decoded event arguments */
  args?: Result;
  /** Error if event decoding failed */
  decodeError?: Error;
  /** Function to manually decode event data */
  decode?: (data: string, topics?: Array<string>) => any;
  /** Remove the listener that received this event */
  removeListener: () => void;
  /** Get block containing this event */
  getBlock: () => Promise<Block>;
  /** Get transaction containing this event */
  getTransaction: () => Promise<TransactionResponse>;
  /** Get transaction receipt containing this event */
  getTransactionReceipt: () => Promise<TransactionReceipt>;
}

Usage Examples:

contract.on("Transfer", async (from, to, value, event) => {
  // Event object properties
  console.log("Event name:", event.event);
  console.log("Event signature:", event.eventSignature);
  console.log("Raw log:", event);
  console.log("Decoded args:", event.args);
  
  // Get additional blockchain data
  const block = await event.getBlock();
  console.log("Block timestamp:", block.timestamp);
  
  const transaction = await event.getTransaction();
  console.log("Transaction from:", transaction.from);
  
  const receipt = await event.getTransactionReceipt();
  console.log("Gas used:", receipt.gasUsed);
  
  // Remove this listener after handling
  event.removeListener();
});

Event Filters

Create and use event filters for targeted event monitoring.

/**
 * Event filter specification for targeted event monitoring
 */
type EventFilter = {
  /** Contract address (optional, defaults to contract address) */
  address?: string;
  /** Event topic filters (indexed parameters) */
  topics?: Array<string | Array<string>>;
};

Usage Examples:

// Access contract's filter generators
const filters = contract.filters;

// Create filters for specific events
const transferFilter = contract.filters.Transfer();
const transferFromFilter = contract.filters.Transfer("0x...", null);
const transferToFilter = contract.filters.Transfer(null, "0x...");
const specificTransferFilter = contract.filters.Transfer("0x...", "0x...");

// Use filters with event listeners
contract.on(transferFromFilter, (from, to, value, event) => {
  console.log(`Outgoing transfer: ${to} received ${value.toString()}`);
});

// Use filters with queries
const incomingTransfers = await contract.queryFilter(transferToFilter, -1000);

// Manual filter creation
const customFilter: EventFilter = {
  address: contract.address,
  topics: [
    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", // Transfer event signature
    "0x000000000000000000000000" + "1234567890123456789012345678901234567890".substring(2), // from address
    null // to address (any)
  ]
};

contract.on(customFilter, (from, to, value, event) => {
  console.log("Custom filtered transfer");
});

Types

/** Event listener callback function */
type Listener = (...args: Array<any>) => void;

/** Enhanced transaction receipt with decoded events */
interface ContractReceipt extends TransactionReceipt {
  /** Array of decoded contract events */
  events?: Array<Event>;
}

/** Enhanced transaction response with contract-specific wait method */
interface ContractTransaction extends TransactionResponse {
  /** Wait for confirmation with event decoding */
  wait(confirmations?: number): Promise<ContractReceipt>;
}