Comprehensive event listening, filtering, and querying capabilities. Supports real-time event monitoring and historical event queries with automatic ABI decoding and rich event objects.
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()}`);
});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();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();
}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;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();
});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");
});/** 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>;
}