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.
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
cargo build --releaseThe binary will be at target/release/wallet-checker.
# 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 --jsonFor 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.
# 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# 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> --jsonCopy 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 = 2All chains are enabled by default. API URLs and rate limits are configurable per chain. Most chains use free public APIs that require no keys.
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.
cargo test345 unit tests covering address derivation, API response parsing (via wiremock), transaction building, CBOR/SCALE/Borsh encoding, gap-limit scanning, and SQLite storage.
- 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
MIT