Find which derivation path a wallet used
Everything below runs inside the sealed container through sealed-run (the agent sees addresses and paths only) or, for a human at the terminal, via…
Everything below runs inside the sealed container through sealed-run (the agent sees
addresses and paths only) or, for a human at the terminal, via ./blocktools reveal.
Flags carry public parameters only; the seed phrase arrives on stdin.
1. See the plan first (no keys involved)
derive --explain --preset recovery --chain all
derive --list-presets
2. "Which path produces this address?"
Put the public addresses you know the wallet had in targets.txt, one per line:
seed-repair < /in/seed.txt | seed-to-master | derive --preset exhaustive --chain all --match /in/targets.txt
Only hits are printed, each with chain, kind and path. If nothing matches,
{"status":"no_candidates","count":N} says how many derivations were tried.
3. Common one-liners
| Want | Flags |
|---|---|
| First 200 native-segwit receive + change | --chain btc --address-type p2wpkh --change 0,1 --index 0..199 |
| A custom path | --chain btc --path "m/0'/0'/{i}'" --both |
| BIP44 paths encoded as bech32 | --chain btc --purpose 44 --address-type p2wpkh |
| Litecoin with a non-standard coin type | --chain ltc --coin-type 0 |
| Ledger Live ETH accounts 0..9 | --chain eth --preset ledger-live --index 0..9 |
| TronLink | --chain tron --preset tronlink |
| Public addresses only (no key field in the JSON) | --public-only |
| Solana only | --curve ed25519 --chain sol |
| Keep scanning while hits continue | --match targets.txt --gap-limit 20 |
| Stop at first known address | --match targets.txt --stop-on-match |
| Uncompressed (2011-era) keys | --chain btc --address-type p2pkh --uncompressed |
Ranges are inclusive: 0..9, 2-4, 0,1,5, 0..2,7.
4. A plain address list (SwapChan SCAN_JS layout)
--preset scan-js is the same wallet path table as SwapChan's SCAN_JS script: the same wallet
names, paths and order, 20 addresses each, over eth, tron, sol, btc, ltc, doge, bch and btg.
--address-list prints one label<TAB>path<TAB>address line per address and no key material
(status lines go to stderr). To also try passphrases, put one per line in a file:
./blocktools run 'seed-repair < /in/seed.txt | seed-to-master --passphrase-file /in/passphrases.txt | derive --preset scan-js --chain btc --address-list'
The empty passphrase is tried first, then each non-empty line; rows from line N get
[passphrase #N] after the path, as SCAN_JS prints them. Without --chain the preset uses all
eight chains above; with --chain it keeps only the rows for those chains.
Through the sealed boundary this works as is, so addresses.txt can be written on the host:
./blocktools run 'seed-repair < /in/seed.txt | seed-to-master | derive --preset scan-js --address-list'
(add > addresses.txt on the host to keep the list).
The boundary passes a non-JSON line only if it is exactly label<TAB>path<TAB>address with a short
label, a BIP32 path (optionally [passphrase #N]) and an address, and it passes the same leak
check as JSON lines; any other line is dropped. The last line is the boundary's own
{"tool":"redact",...} count; strip it with grep -v '"tool":"redact"'.
5. A typed BIP39 passphrase
A BIP39 passphrase is typed with seed-to-master --passphrase-prompt (built: it reads /dev/tty, not echoed, empty = none; checked on a pty 2026-10-26). It cannot be combined with --passphrase-file or a stdin passphrase.
Electrum 1.x old seed
seed-to-master prints such a seed as "scheme":"electrum-old" (hex seed, no xprv); derive walks the non-BIP32
keys m/{change}/{i} (change 0 and 1), uncompressed p2pkh, btc only. --preset electrum-old names the same plan and
refuses an xprv line (unsupported). See input-electrum.md.
Planned (not built yet)
- TON addresses from
derive(derive --chain tongivesno_candidates).
Tested examples
--public-only keeps the JSON rows but drops the key field entirely (not even [REDACTED]):
./blocktools run 'seed-repair < /in/seed.txt | seed-to-master | derive --chain btc --count 1 --public-only'
./blocktools run 'seed-repair < /in/seed.txt | seed-to-master | derive --preset exhaustive --chain btc --match /in/targets.txt'
./blocktools run 'derive --list-presets'