Skip to content

Frodrinos/wallet-activity-reporter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wallet-activity-reporter

A CLI to investigate Ethereum wallets: transfer history, top tokens, and activity patterns in one command.

Example output

About

I started this project while learning on-chain forensics. Etherscan is great for inspecting one transaction at a time, but it doesn't answer the questions I actually care about: across a window of time, what did this wallet do? How much volume in each token? What patterns are visible? I wanted a tool that runs in seconds, in a terminal, and gives me a summary I can actually read.

wallet-activity-reporter takes an Ethereum address and a block range, fetches every ERC-20 Transfer event where that address is either the sender or the receiver, decodes amounts with the correct decimals, and presents the activity chronologically alongside a top-tokens summary. Internally it paginates eth_getLogs calls to fit within free-tier RPC limits, and caches token metadata so repeat tokens don't trigger redundant RPC reads.

It also shows what most wallet trackers don't. Tools like Zerion or DeBank give you a snapshot of a wallet's current holdings. This one shows you the process - every transfer in a defined window, including exotic tokens you've never heard of, with exact amounts and direction. The built-in summary surfaces the top sent and received tokens by transfer count, total volumes per token, and a count of unique tokens involved. You pick the time window. The tool does the rest.

Features

  • Bidirectional scanning - fetches both incoming and outgoing transfers in parallel, merged into a single chronological view.
  • Pagination built-in - automatically splits large block ranges into chunks that fit free-tier RPC limits (10 blocks per eth_getLogs call on Alchemy free).
  • Token-aware output - resolves symbols and decimals on the fly via readContract, converts raw bigint amounts to human-readable values.
  • Smart caching - token metadata is cached per address, so repeat tokens (like USDT appearing 50 times) trigger only one RPC roundtrip.
  • Built-in summary - top sent and received tokens, total event counts, unique token count, and approximate time range.
  • Etherscan links - every transaction includes a direct Etherscan URL for quick verification.
  • Modular architecture - logic split across fetcher, tokens, formatters, and aggregator modules for clarity and reusability.

Quickstart

Prerequisites

  • Node.js 18 or higher
  • An Ethereum RPC endpoint (e.g. Alchemy or Infura)

Installation

git clone https://github.com/Frodrinos/wallet-activity-reporter.git
cd wallet-activity-reporter
npm install

Configuration

Copy the example environment file and add your RPC URL:

cp .env.example .env

Edit .env:

RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY

Run

Scan an address with default range (100 blocks):

node main.js 0x28C6c06298d514Db089934071355E5743bf21d60

Or specify a custom block range:

node main.js 0x28C6c06298d514Db089934071355E5743bf21d60 500

Examples

Detecting phishing and address poisoning

node main.js 0x[VICTIM_ADDRESS] 500

Address poisoning attacks send many tiny transfers (often $0.00 or fractional cents) from spoofed addresses that look visually similar to the victim's real counterparties. The goal: trick the victim into copy-pasting a wrong address from their transaction history.

The summary section makes this pattern obvious - look for dozens of incoming transfers with negligible amounts in the top received tokens. A clean wallet shows a handful of meaningful transfers. A poisoned wallet shows a flood of spam.

Analyzing exchange behavior

node main.js 0x28C6c06298d514Db089934071355E5743bf21d60 50

This is Binance's hot wallet, scanned across 50 blocks (~10 minutes). A typical centralized exchange shows:

  • Heavy USDT inflows from user deposits.
  • Smaller, batched outflows to withdrawal addresses.
  • 49+ unique tokens active simultaneously.
  • Incoming count significantly higher than outgoing - confirming the deposit-heavy direction.

Useful for monitoring exchange health, spotting unusual volume changes, or comparing flows across different exchanges.

Spotting sybil patterns across wallets

Run the tool on multiple suspected wallets and compare their outputs:

node main.js 0xWALLET_A 100
node main.js 0xWALLET_B 100
node main.js 0xWALLET_C 100

Sybil farms - multiple wallets controlled by one operator - leave distinctive fingerprints. Look for matching activity across wallets:

  • Same tokens transferred in same amounts during overlapping block ranges.
  • Identical transfer counts within a short window.
  • Same counterparty addresses receiving funds.

If three "different" wallets show 12 USDC transfers of identical amounts to the same address within the same 100 blocks - you've likely found a coordinated cluster. This is the foundation of sybil detection work for airdrops and grants programs.

Project structure

wallet-activity-reporter/
├── main.js                      # CLI entry point - argv parsing, orchestration, output
├── src/
│   ├── fetcher.js               # fetchAllLogs - paginated getLogs with progress
│   ├── tokens.js                # getTokenInfo with in-memory cache
│   ├── formatters.js            # formatAmount, formatLargeNumber, shortHash
│   └── aggregator.js            # aggregateByToken, printTopTokens
├── .env.example                 # Template for environment variables
├── package.json
└── README.md

The architecture follows a clear separation of concerns: fetcher handles RPC pagination, tokens handles ERC-20 metadata with caching, formatters are pure utility functions, and aggregator builds the summary. The main file is intentionally thin - it parses CLI arguments, orchestrates module calls, and renders output. Each module takes the client instance as a parameter (dependency injection) rather than reaching for a global, making the code easier to test and reuse.

Roadmap

The current version handles single-address analysis well, but there's room to grow:

  • Multi-address comparison mode - pass multiple addresses in one command, automatically detect overlapping transfer patterns (foundation for built-in sybil detection).
  • Native ETH transfers - currently only ERC-20 events are decoded; native transfers via eth_getBlockByNumber would complete the picture.
  • ERC-721 / NFT support - Transfer event signature is identical to ERC-20, but indexed parameters differ; needs separate handling.
  • CSV / JSON export - for piping output into spreadsheets or further analysis pipelines.
  • Block-to-timestamp resolution - show real dates instead of approximate "~10 minutes" estimates.
  • Pattern detection helpers - automated flags for common forensics signals (mass outflows, address poisoning floods, matching cluster activity).
  • Dune / Flipside integration - for larger datasets that exceed RPC practical limits.

If any of these would be useful for your work, open an issue or contribute a PR.

Tech stack

  • viem - Ethereum library for RPC calls, ABI parsing, and unit conversions.
  • Node.js - runtime, using native ES modules and top-level await.
  • dotenv - environment variable management.

License

MIT

About

A CLI tool that fetches and analyzes ERC-20 transfer activity for any Ethereum address.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors