Skip to content

amanusk/snbeat

Repository files navigation

snbeat

snbeat is a local, terminal based, Block explorer for the Starknet Blockchain. It supports multiple data sources, to give the best experience, while prioritizing privacy, recency and caching.

Block Detail
Block detail view
Transaction Detail
Transaction detail view
Address Info
Address info view
Class Info
Class info view
  • Privacy first: snbeat works best with a local RPC node, and can connect directly to the Pathfinder DB. Fully local. External APIs (Dune/Voyager) can be used but are optional. It is open source. Hack any feature you need.
  • Cache first: Every fetched data is cached. Any data visited is cached for subsequent queries. No unnecessary indexing of data that is never used.
  • Recency first: See recent txs first, stream incoming txs, wait longer for full data fetch.
  • Vim!

Features

  • Data backends - RPC, WS, Pathfinder query service, Dune and Voyager can be used simultaneously to fetch data
  • ABI-aware decoding - decodes calldata, events, and multicalls using on-chain class ABIs
  • Persistent local cache - SQLite; blocks, transactions, receipts, and ABIs are cached for instant fetch on subsequent visits
  • Live feed - Stream new blocks, transactions, and events as they happen (requires WebSocket support from the RPC)
  • Custom labels - tag addresses and transactions with human-readable names and searchable tags
  • Fast search - prefix/substring search over labelled addresses; navigate by hash or block number
  • Nonce-based and Block based navigation - jump to the next/previous transaction by account, by index, or jump to the next block

Installation

Prerequisites

  • Rust 1.85+ (edition 2024)
  • A Starknet RPC endpoint

Install from crates.io

cargo install snbeat

Install from git

cargo install --git https://github.com/amanusk/snbeat

Then place your config in ~/.config/snbeat/ (see Configuration below).

Build from source

git clone https://github.com/amanusk/snbeat
cd snbeat
cargo build --release

The binary is at target/release/snbeat.

Run

# From the repo (uses local .env)
cp .env.example .env
cargo run --release

# Or directly
./target/release/snbeat

snbeat reads environment variables directly, so you can also export them in your shell or pass them inline:

APP_RPC_URL=https://api.zan.top/public/starknet-mainnet/rpc/v0_10 snbeat

Configuration

snbeat looks for configuration files in two locations, with local files taking priority:

  1. Current working directory - for development or per-project setups
  2. ~/.config/snbeat/ - for system-wide installs (e.g. cargo install)

This applies to both .env and labels.toml. If a file exists in the current directory it is used; otherwise snbeat falls back to ~/.config/snbeat/.

Quick setup (cargo install)

mkdir -p ~/.config/snbeat
cp .env.example ~/.config/snbeat/.env
# Edit ~/.config/snbeat/.env with your settings

Environment variables

All variables are optional except APP_RPC_URL.

Variable Default Description
APP_RPC_URL (required) Starknet JSON-RPC endpoint
APP_WS_URL - WebSocket endpoint for new-block subscriptions
APP_PATHFINDER_SERVICE_URL - URL of a running pf-query instance
VOYAGER_API_KEY - Voyager API key for address metadata
DUNE_API_KEY - Dune Analytics API key
APP_USER_LABELS labels.toml Path to your custom labels file
APP_LOG_LEVEL info trace / debug / info / warn / error
APP_LOG_DIR ~/.config/snbeat/logs Log file directory

Custom Labels

Create a labels.toml file to tag addresses and transactions with names and searchable tags. Place it in the current directory or in ~/.config/snbeat/labels.toml for a global install.

[addresses]
# Simple name
"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" = "ETH"

# Name + tags (tags are searchable in the / search bar)
"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" = { name = "My Wallet", tags = ["defi", "nft"] }

[transactions]
# Optional transaction labels
"0xabc123..." = "Initial deploy"

User labels take priority over the built-in known address registry (tokens, DEXes, bridges, etc.). The file is loaded at startup; a malformed file prints a warning but does not prevent startup.


ABI Decoding

snbeat fetches the class ABI for every contract it encounters and decodes:

  • Calldata - function arguments with named parameters and typed values (u256, structs, enums, arrays, …)
  • Multicalls - account transactions that bundle multiple inner calls are unpacked individually
  • Events - keys and data fields are matched against the ABI and rendered with parameter names

Decoded ABIs are stored in the local SQLite cache (~/.config/snbeat/cache.db) and are never re-fetched.

Press d in a transaction detail view to toggle between raw and decoded calldata.


Local Cache

All fetched data is persisted to ~/.config/snbeat/cache.db (SQLite). The cache stores:

  • Block headers
  • Transactions and receipts
  • Per-address event and transaction lists
  • Parsed ABIs (keyed by class hash)

On subsequent visits to the same block or address, data is served from disk with no network round-trip.


Keybindings

Navigation

Key Action
j / Move down
k / Move up
l / / Enter Drill in / navigate forward
h / / Esc Go back
Ctrl+O Jump back (vim-style)
] Jump forward
g Jump to top
G Jump to bottom
Ctrl+U / PgUp Next block or transaction
Ctrl+D / PgDn Previous block or transaction
n Next transaction by same sender
N Previous transaction by same sender
Tab Cycle tabs (Address Info view)
q Jump to home / quit
Ctrl+C Quit

Search

Press / to open the search bar. You can search by:

  • Address, transaction hash, or class hash (0x…)
  • Block number
  • Label name or tag

Arrow keys to navigate suggestions; Enter confirms; Tab fills in the highlighted suggestion; Esc closes.

Transaction Detail

Key Action
c Toggle raw calldata
d Toggle ABI-decoded calldata
v Enter visual mode (highlight addresses / block refs)
r Refresh
? Toggle help overlay

Visual Mode

Press v in a Transaction or Block detail view to enter visual mode. Use j/k to cycle through addresses and block references, then Enter to navigate to the highlighted item. Esc exits.


Data Backends

snbeat can draw data from multiple sources simultaneously. Configure only the ones you have access to.

Data source matrix

Each cell shows the fetch priority when multiple sources provide the same data (1 = primary, 2 = fallback, etc.). A dash means the source cannot provide this data.

Data point RPC WS PF-query Dune Voyager
Blocks
Latest block number 1 (poll) 1 (push) - - -
Block header 1 - - - -
Block transactions 1 - 1 - -
Transactions
Transaction by hash 1 - - - -
Transaction receipt (fee, status) 1 - - - -
Tx hash → block + index lookup - - 1 - -
Calldata 1 - - - -
Multicall decoding 1 - - - -
Address - Account history
Account tx history 3 (events) - 1 2 -
Nonce history (timeline) - - 1 - -
Current nonce 1 - - - -
Address - Contract history
Contract call history 2 (events) - - 1 -
Contract events 1 - 1 - -
Activity range probe - - - 1 -
Address - General
Class hash at address 1 - - - -
Token balances (ETH, STRK, …) 1 (call) - - - -
Address label / metadata - - - - 1
Deploy tx detection 1 - - - -
Classes & ABIs
Class definition (Sierra ABI) 1 - - - -
Selector → function/event name 1 (via ABI) - - - -
Class declaration block - - 1 2 -
Declare tx info 1 (block scan) - 1 (block lookup) 2 -
Contracts deployed with class - - 1 - -
Class upgrade history - - 1 - -
WebSocket subscriptions
New block headers (live) - 1 - - -
Live events for address - 1 - - -
Live transactions from address - 1 - - -
Search
Block number lookup 1 - - - -
Transaction hash search 1 - - - -
Address resolution 1 - - - -
Class hash search 1 - - - -
Block hash search 1 - - - -
Label / tag search - - - - -

Note: All fetched data is cached locally in SQLite. Subsequent visits serve from cache with no network round-trip. Label/tag search is powered by the local registry (labels.toml + built-in known addresses) with no external data source.

RPC (required)

All data fetching starts here. Set APP_RPC_URL to any Starknet JSON-RPC v0.7+ endpoint (local node or hosted).

APP_RPC_URL=http://localhost:9545/rpc/v0_10

An optional WebSocket URL enables push-based block, txs and events

APP_WS_URL=ws://localhost:9545/ws

Pathfinder Query Service (optional, recommended for local nodes)

If you run a Pathfinder node, the bundled pf-query service exposes its SQLite database over HTTP. This unlocks fast data lookups, which power the address timeline.

See Setting up pf-query below.

APP_PATHFINDER_SERVICE_URL=http://localhost:8234

Dune Analytics (optional)

A Dune API key enables additional address history features:

  • Account transaction history - full transaction list for an account, used as a fallback when Pathfinder is unavailable
  • Contract call history - the Calls tab on an address shows all transactions that called that contract
  • Activity range probe - detects the active block range for an address
DUNE_API_KEY=your_key_here

Voyager API (optional)

Connect to Voyager API to optionally get Voyager tags for addresses, classes etc

VOYAGER_API_KEY=your_key_here

Setting up pf-query

pf-query is a lightweight HTTP service that exposes the Pathfinder SQLite database for fast nonce-history queries. It lives in crates/pf-query/.

Build and run locally

# Build
cargo build --release --manifest-path crates/pf-query/Cargo.toml

# Run (point it at your Pathfinder database)
PF_DB_PATH=/var/lib/pathfinder/pathfinder.db ./target/release/pf-query
# Listening on 0.0.0.0:8234 by default
Variable Default Description
PF_DB_PATH (required) Path to the Pathfinder SQLite database
PF_PORT 8234 Port to listen on
PF_HOST 127.0.0.1 Host address to bind to

Run on a remote server

If your Pathfinder node is on a different machine, run pf-query on that machine and set APP_PATHFINDER_SERVICE_URL in your snbeat .env to point at it:

APP_PATHFINDER_SERVICE_URL=http://192.168.1.10:8234

API

Endpoint Description
GET /health Returns { "latest_block": N }
GET /nonce-history/{address}?limit=N Returns ordered nonce update history (max 2000 entries)
GET /class-history/{address} Returns class hash history for a contract
GET /contracts-by-class/{class_hash} Returns contracts deployed with a given class hash
GET /class-declaration/{class_hash} Returns declaration info for a class hash
GET /tx-by-hash/{hash} Looks up a transaction by hash
GET /block-txs/{block_number} Returns decoded transactions in a block
GET /sender-txs/{address} Returns transactions sent by an address
GET /contract-events/{address} Returns events emitted by a contract

Testing

# Unit and integration tests (no network required)
cargo test

# RPC-dependent integration tests (requires APP_RPC_URL in .env)
cargo test -- --ignored

License

This project is licensed under the MIT License.


Contributing

  1. Fork the repository and create a feature branch.
  2. Run cargo fmt and cargo clippy before opening a PR.
  3. Add tests for new behaviour where practical.
  4. Keep PRs focused; one feature or fix per PR.

Please open an issue first for significant changes to discuss the approach.

About

Terminal based Starknet Block Explorer

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors