npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

eth-trace-inspector

v2.3.6

Published

A zero-config TypeScript library for automatically decoding, tracing, and debugging EVM transactions. Provides human-readable call stacks, event logs, and state changes for any transaction hash across all major EVM networks, even without the contract ABI.

Readme

eth-trace-inspector

A zero-config TypeScript library for automatically decoding, tracing, and debugging EVM transactions. Provides human-readable call stacks, event logs, and state changes for any transaction hash across all major EVM networks, even without the contract ABI.

Features

  • 🔍 Automatic ABI Discovery: Fetches contract ABIs from block explorer APIs (Etherscan, Polygonscan, etc.)
  • 🧩 ABI Inference: Falls back to 4-byte signature database when official ABIs aren't available
  • 📊 Human-Readable Output: Converts raw EVM traces into structured, hierarchical call stacks
  • 🎯 Multi-Chain Support: Works with Ethereum, Polygon, BSC, Arbitrum, Optimism, Avalanche, Base, and more
  • 🐛 Debug-Friendly: Identifies exactly where transactions revert and provides error messages
  • 📝 Flexible Output: Structured JSON for programmatic use or pretty-print for CLI debugging

Installation

npm install eth-trace-inspector

Environment Variables

The library supports environment variables for configuration. Copy .env.example to .env and fill in your values:

cp .env.example .env

Available environment variables:

  • TEST_TX_HASH - Transaction hash for testing
  • ETHERSCAN_API_KEY - Etherscan API key (recommended to avoid rate limits)
  • POLYGONSCAN_API_KEY - Polygonscan API key
  • BSCSCAN_API_KEY - BSCscan API key
  • ARBISCAN_API_KEY - Arbiscan API key
  • OPTIMISTIC_ETHERSCAN_API_KEY - Optimistic Etherscan API key
  • SNOWTRACE_API_KEY - Snowtrace API key
  • BASESCAN_API_KEY - Basescan API key
  • ETH_RPC_URL - Custom Ethereum RPC URL
  • POLYGON_RPC_URL - Custom Polygon RPC URL
  • BSC_RPC_URL - Custom BSC RPC URL
  • ARBITRUM_RPC_URL - Custom Arbitrum RPC URL
  • OPTIMISM_RPC_URL - Custom Optimism RPC URL
  • AVALANCHE_RPC_URL - Custom Avalanche RPC URL
  • BASE_RPC_URL - Custom Base RPC URL

Note: The .env file is gitignored. Use .env.example as a template.

Quick Start

import { inspectTransaction, prettyPrint } from 'eth-trace-inspector';

const report = await inspectTransaction('0x...', {
 chainId: 1, // Ethereum mainnet
 apiKey: 'your-api-key', // Optional, but recommended for rate limits
});

prettyPrint(report);

const json = JSON.stringify(report, null, 2);
console.log(json);

Usage

Basic Usage

import { inspectTransaction } from 'eth-trace-inspector';

const report = await inspectTransaction('0x1234...', {
 chainId: 1,
});

With Custom RPC Provider

import { JsonRpcProvider } from 'ethers';
import { inspectTransaction } from 'eth-trace-inspector';

const provider = new JsonRpcProvider('https://your-rpc-url.com');
const report = await inspectTransaction('0x1234...', {
 provider,
});

With Custom ABIs

const report = await inspectTransaction('0x1234...', {
 chainId: 1,
 customABIs: {
 '0xContractAddress': [
 ],
 },
});

Options

interface InspectorOptions {
 rpcUrl?: string; // Custom RPC URL
 provider?: Provider; // Custom ethers provider
 chainId?: number; // Chain ID (auto-detected if not provided)
 apiKey?: string; // Block explorer API key
 includeGasDetails?: boolean; // Include gas usage (default: true)
 includeStorageChanges?: boolean; // Include storage changes (default: false)
 customABIs?: Record<string, any[]>; // Custom ABIs by address
 fetchABI?: boolean; // Attempt ABI fetching (default: true)
 useSignatureDatabase?: boolean; // Use 4-byte signature DB (default: true)
}

Output Format

The inspectTransaction function returns a TransactionReport object:

interface TransactionReport {
 txHash: string;
 blockNumber: number;
 transactionIndex: number;
 from: string;
 to: string | null;
 value: bigint;
 gasPrice: bigint;
 gasLimit: bigint;
 gasUsed: bigint;
 status: boolean;
 callStack: DecodedCall[];
 events: DecodedEvent[];
 revertReason?: string;
 chainId: number;
 timestamp?: number;
}

Decoded Call Structure

interface DecodedCall {
 to: string;
 functionName: string;
 args: any[];
 calldata: string;
 signature: string;
 inferred?: boolean; // true if function name was inferred
 gasUsed?: bigint;
 value?: bigint;
 calls?: DecodedCall[]; // Nested calls
 reverted?: boolean;
 revertReason?: string;
}

Decoded Event Structure

interface DecodedEvent {
 address: string;
 eventName: string;
 args: any[];
 data: string;
 topics: string[];
 signature: string;
 inferred?: boolean;
 blockNumber: number;
 transactionIndex: number;
 logIndex: number;
}

Supported Networks

  • Ethereum Mainnet (1)
  • Ethereum Sepolia (11155111)
  • Polygon (137)
  • BNB Smart Chain (56)
  • Arbitrum One (42161)
  • Optimism (10)
  • Avalanche (43114)
  • Base (8453)

Requirements

  • Node.js 18+
  • An RPC provider that supports debug_traceTransaction (required for full trace analysis)
  • Full nodes (Geth, Erigon, etc.)
  • Alchemy
  • Infura (with tracing enabled)
  • Other providers with tracing support

Limitations

  1. RPC Provider Support: The library requires an RPC provider that supports debug_traceTransaction. Public RPC endpoints often don't support this method. Consider using:
  • A local full node
  • Alchemy (supports tracing)
  • Infura (with tracing enabled)
  • Other specialized providers
  1. ABI Availability: While the library attempts to fetch ABIs automatically, not all contracts have verified source code on block explorers.

  2. Signature Database: The built-in 4-byte signature database is limited. For better coverage, the library attempts to fetch from 4byte.directory, but this requires internet connectivity.

Examples

Inspect a Failed Transaction

const report = await inspectTransaction('0x...', { chainId: 1 });

if (!report.status) {
 console.log('Transaction failed!');
 console.log('Revert reason:', report.revertReason);
 
 const findRevertedCall = (calls: DecodedCall[]): DecodedCall | null => {
 for (const call of calls) {
 if (call.reverted) return call;
 if (call.calls) {
 const nested = findRevertedCall(call.calls);
 if (nested) return nested;
 }
 }
 return null;
 };
 
 const revertedCall = findRevertedCall(report.callStack);
 if (revertedCall) {
 console.log('Reverted in:', revertedCall.functionName);
 }
}

Analyze Event Logs

const report = await inspectTransaction('0x...', { chainId: 1 });

const transfers = report.events.filter(e => e.eventName === 'Transfer');
console.log(`Found ${transfers.length} Transfer events`);

const eventNames = new Set(report.events.map(e => e.eventName));
console.log('Event types:', Array.from(eventNames));

Pretty Print Output

import { inspectTransaction, prettyPrint } from 'eth-trace-inspector';

const report = await inspectTransaction('0x...', { chainId: 1 });
prettyPrint(report);

This will output a formatted, human-readable report to the console.

API Reference

inspectTransaction(txHash: string, options?: InspectorOptions): Promise<TransactionReport>

Main function to inspect a transaction.

Parameters:

  • txHash: Transaction hash to inspect
  • options: Optional configuration (see InspectorOptions)

Returns: Promise resolving to TransactionReport

prettyPrint(report: TransactionReport): void

Pretty print a transaction report to the console.

toJSON(report: TransactionReport, pretty?: boolean): string

Convert a transaction report to JSON string.

Parameters:

  • report: Transaction report to convert
  • pretty: Whether to format JSON with indentation (default: true)

getSummary(report: TransactionReport): string

Get a one-line summary of the transaction report.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT