Skip to content

mettadata/wallet-checker

Repository files navigation

wallet-checker

A Rust CLI tool that derives wallet addresses from a BIP-39 mnemonic across all major blockchains, checks balances via free public APIs, and persists results to SQLite.

Supported Chains (27 chains)

EVM Chains (scan + sweep)

Chain Symbol Chain ID Derivation
Ethereum ETH 1 secp256k1, m/44'/60'/a'/0/i
Polygon MATIC 137 secp256k1, m/44'/60'/a'/0/i
Arbitrum ETH 42161 secp256k1, m/44'/60'/a'/0/i
BSC BNB 56 secp256k1, m/44'/60'/a'/0/i
Avalanche AVAX 43114 secp256k1, m/44'/60'/a'/0/i
Optimism ETH 10 secp256k1, m/44'/60'/a'/0/i
Base ETH 8453 secp256k1, m/44'/60'/a'/0/i
Cronos CRO 25 secp256k1, m/44'/60'/a'/0/i
Mantle MNT 5000 secp256k1, m/44'/60'/a'/0/i
Ethereum Classic ETC 61 secp256k1, m/44'/60'/a'/0/i

Bitcoin & UTXO Chains

Chain Symbol Address Types Derivation Sweep
Bitcoin BTC Legacy, SegWit, Native SegWit, Taproot secp256k1, m/44,49,84,86'/0'/a'/0,1/i Yes
Litecoin LTC Legacy (L...), Native SegWit (ltc1q...) secp256k1, m/44,84'/2'/a'/0,1/i Yes
Dogecoin DOGE P2PKH (D...) secp256k1, m/44'/3'/a'/0/i Yes
Bitcoin Cash BCH P2PKH (1...) secp256k1, m/44'/145'/a'/0/i Yes
Zcash ZEC Transparent (t1...) secp256k1, m/44'/133'/a'/0/i Scan only
Kaspa KAS Bech32 (kaspa1...) secp256k1, m/44'/111111'/a'/0/i Yes

Cosmos SDK Chains (scan + sweep)

Chain Symbol Prefix Derivation
Cosmos Hub ATOM cosmos1 secp256k1, m/44'/118'/a'/0/i
Osmosis OSMO osmo1 secp256k1, m/44'/118'/a'/0/i
THORChain RUNE thor1 secp256k1, m/44'/931'/a'/0/i

Ed25519 Chains

Chain Symbol Address Format Derivation Sweep
Solana SOL Base58 SLIP-0010, m/44'/501'/a'/0' Yes
NEAR NEAR Hex implicit SLIP-0010, m/44'/397'/a' Yes
Aptos APT Hex (0x...) SLIP-0010, m/44'/637'/a'/0'/i' Yes
SUI SUI Hex (0x...) SLIP-0010, m/44'/784'/a'/0'/i' Yes
Stellar XLM StrKey (G...) SLIP-0010, m/44'/148'/a' Scan only
Algorand ALGO Base32 SLIP-0010, m/44'/283'/a' Scan only
Hedera HBAR Hex pubkey SLIP-0010, m/44'/3030'/a' Scan only
TON TON Base64url v4R2 SLIP-0010, m/44'/607'/a' Yes
Polkadot DOT SS58 SLIP-0010, m/44'/354'/a'/0'/i' Yes
Bittensor TAO SS58 (5...) SLIP-0010, m/44'/354'/a'/0'/i' Scan only

Special Derivation

Chain Symbol Address Format Derivation Sweep
Cardano ADA Bech32 Shelley (addr1...) Ed25519-BIP32 Icarus, m/1852'/1815'/a'/0/i Yes
Monero XMR Monero Base58 (4...) SLIP-0010 + CryptoNote, m/44'/128'/a' Scan only
XRP XRP Base58 (r...) secp256k1, m/44'/144'/a'/0/i Yes
TRON TRX Base58Check (T...) secp256k1, m/44'/195'/a'/0/i Yes

Install

cargo build --release

The binary will be at target/release/wallet-checker.

Usage

Scan wallets

# Scan all enabled chains (mnemonic is entered hidden)
wallet-checker scan

# Scan specific chains only
wallet-checker scan --chains ethereum,bitcoin,solana

# Custom gap limit and max accounts
wallet-checker scan --gap-limit 30 --max-accounts 10

# Output as JSON
wallet-checker scan --json

Test mnemonic

For testing, you can use the standard BIP-39 test vector (all-zero entropy):

abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about

Do not use this mnemonic for real funds — it is publicly known and used by every wallet library for testing.

The scan uses a gap-limit algorithm (BIP-44 standard): it iterates derivation indices and stops after N consecutive empty addresses (default 20). It also scans multiple account indices (default 5) and change addresses for Bitcoin/Litecoin.

View results

# Show detailed results from the latest scan
wallet-checker results

# Show results from a specific scan
wallet-checker results <scan-id>

# Output as JSON
wallet-checker results --json

View history

# List all previous scans
wallet-checker history

# Show summary table of a specific scan
wallet-checker show <scan-id>

# Show as JSON
wallet-checker show <scan-id> --json

Configuration

Copy config.example.toml to config.toml and customize:

[general]
database_path = "wallet_checker.db"

[scan]
gap_limit = 20
max_accounts = 5

[chains.ethereum]
enabled = true
api_key = "YOUR_ETHERSCAN_KEY"  # optional, increases rate limit
rate_limit_per_second = 5

[chains.bitcoin]
enabled = true
rate_limit_per_second = 3

[chains.solana]
enabled = true
rate_limit_per_second = 2

All chains are enabled by default. API URLs and rate limits are configurable per chain. Most chains use free public APIs that require no keys.

Architecture

Clean/hexagonal architecture with strict separation of concerns:

src/
  domain/         # Pure domain logic, zero infra dependencies
    ports.rs      # Trait definitions (AddressDeriver, BalanceFetcher, etc.)
    scanner.rs    # Gap-limit scanning algorithm
    types.rs      # WalletAddress, BalanceResult, ScanResult, etc.
  crypto/         # Pure cryptography, no I/O
    mnemonic.rs   # BIP-39 seed derivation
    derivation.rs # BIP-32/44 and SLIP-0010 key derivation
  adapters/       # Infrastructure implementations
    chains/       # AddressDeriver implementations (one per blockchain)
    providers/    # BalanceFetcher/TokenFetcher/NftFetcher (API clients)
    storage/      # SQLite persistence
  cli.rs          # Clap CLI definitions
  config.rs       # TOML config loading
  output/         # Terminal table rendering

Adding a new chain requires implementing AddressDeriver and BalanceFetcher traits, with no changes to the scanner or domain logic.

Testing

cargo test

345 unit tests covering address derivation, API response parsing (via wiremock), transaction building, CBOR/SCALE/Borsh encoding, gap-limit scanning, and SQLite storage.

Security

  • Mnemonic input is hidden (not echoed to terminal)
  • Private keys are derived in memory and never stored
  • Only public addresses are persisted to SQLite
  • No network calls are made with private key material

License

MIT

About

wallet-checker to find lost funds onchain

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors