6.3 KiB
Below is a practical playbook you can save as PLAYBOOK.md next to hdwallet_recovery.py.
Purpose (what this tool does)
- Derive addresses (ETH/SOL/BTC) from either a BIP39 mnemonic (+ optional passphrase) or a raw 64‑byte BIP39 seed hex.
- Optionally encrypt a payload to a PGP public key (ASCII armored) so secrets are not shown in plaintext on screen.
fetchkeymode is the only mode that touches the network (downloads a PGP public key).
Prerequisites (software + packages)
OS / Python
- Use Python 3.12 (recommended for compatibility with
bip_utils,PGPy, etc.). - macOS: install Python 3.12 via Homebrew and create a clean venv.
Python packages
Install into a venv:
Base (derive addresses + encrypt payload):
bip-utilsPGPy
Only needed if you use --export-private and include solana:
PyNaClbase58
Example:
python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install bip-utils PGPy
pip install PyNaCl base58 # only if exporting Solana private keys
Files you need
hdwallet_recovery.py(the script)kccleoc.asc(or any*.asc) = ASCII-armored PGP public key used to encrypt the payload
Operating modes
Mode A — fetchkey (online, no secrets allowed)
Use this to download a PGP public key from a URL and verify it.
Command:
python hdwallet_recovery.py fetchkey "https://github.com/<user>.gpg" --out key.asc
What to check:
- The script prints SHA256 of the downloaded key and the PGP fingerprint.
- Independently verify the fingerprint matches the intended owner (don’t trust only the URL).
Safety rule:
- Never pass mnemonic/seed/passphrase flags together with
fetchkey. The script should refuse.
Mode B — derive (offline, addresses only)
Derives addresses and prints them to stdout.
Command (addresses only):
python hdwallet_recovery.py \
--mnemonic '... your words ...' \
--passphrase '' \
--chains ethereum solana bitcoin \
--addresses 10
Notes:
- This prints addresses (safe) but still requires you to supply the mnemonic (sensitive) on the command line unless you use
--interactive.
Preferred (avoid shell history):
python hdwallet_recovery.py --interactive --chains ethereum solana bitcoin --addresses 10
Mode C — derive + PGP encrypt payload (recommended)
Derives addresses, prints addresses, and prints an encrypted PGP block containing recovery material.
Command (include mnemonic + passphrase):
python hdwallet_recovery.py \
--interactive \
--chains ethereum solana bitcoin \
--addresses 10 \
--pgp-pubkey-file key.asc
Decrypt later:
- Use your PGP private key (on a safe machine) to decrypt the PGP message.
Mode D — derive + export private keys (encrypted only)
This is for when you need to import per-account keys into hot wallets (e.g., Phantom) but don’t want to type the seed phrase into the app.
Behavior (as implemented):
- Still prints addresses to stdout.
- Produces a PGP-encrypted payload that includes:
- the mnemonic (so you can fully recover later)
- a note that a passphrase was used (but not the passphrase)
- Ethereum private keys (hex) for indices
0..--addresses-1 - Solana Phantom-compatible private keys (base58 64-byte secret key) for indices
0..--addresses-1 - Bitcoin: addresses only (no BTC private keys)
Command:
python hdwallet_recovery.py \
--interactive \
--chains ethereum solana bitcoin \
--addresses 10 \
--export-private \
--passphrase 'YOUR_PASSPHRASE' \
--passphrase-hint 'memory hint here' \
--pgp-pubkey-file key.asc
Hot wallet import guidance:
- Import only the specific derived account key you plan to treat as “hot”.
- Fund only that account/address.
- Assume the device/app is compromised eventually; rotate keys.
Verification checklist (before trusting results)
- Confirm you’re using the expected Python and venv:
which python python -V pip show bip-utils PGPy - Confirm the PGP public key fingerprint is correct (out-of-band verified).
- Confirm derived addresses match known wallet UI for the same mnemonic/passphrase (test with a small index range first).
Security warnings (read this every time)
- Never run derive mode on a machine you don’t trust.
- Avoid passing mnemonics on the command line (
--mnemonic '...') because:- shell history may capture it
- process lists can expose arguments
- Prefer
--interactiveso the mnemonic is hidden input. - The encrypted payload printed to screen can still be:
- copied into scrollback logs
- captured by screen recording / monitoring
- saved by terminal multiplexer logs
Treat it as sensitive, even if encrypted.
- If
--export-privateis used, the encrypted payload contains a bundle of hot private keys. Anyone who decrypts it controls those accounts. Keep it offline and limit distribution. - If a passphrase was used, losing it makes recovery impossible even with mnemonic and derived-address list. Store the passphrase separately and securely; the payload only stores a hint/reminder.
- Consider using a dedicated “hot” seed (separate mnemonic) for accounts intended for hot-wallet import, rather than exporting keys derived from your main long-term seed.
Quick command recipes
1) Download and pin a key:
python hdwallet_recovery.py fetchkey "https://github.com/<user>.gpg" --out key.asc
2) Offline derive addresses (no encryption):
python hdwallet_recovery.py --interactive --chains ethereum solana bitcoin --addresses 10
3) Offline derive + encrypt payload (no private key export):
python hdwallet_recovery.py --interactive --chains ethereum solana bitcoin --addresses 10 --pgp-pubkey-file key.asc
4) Offline derive + encrypt payload + export ETH/SOL private keys:
python hdwallet_recovery.py --interactive --chains ethereum solana bitcoin --addresses 10 --export-private --passphrase-hint '...' --pgp-pubkey-file key.asc
If you want, the playbook can be turned into a Makefile (targets: venv, fetchkey, derive, export) so you don’t have to remember flags.