pyhdwallet v1.0.5

A secure, offline-first command-line tool for generating and recovering BIP39 HD wallets with support for Ethereum, Solana, and Bitcoin. It supports optional PGP-encrypted payloads (ASCII-armored .asc) and deterministic AES-encrypted ZIP wallet artifacts written under a local .wallet/ folder.

Purpose

pyhdwallet helps create new wallets or recover from existing mnemonics/seeds with offline operation, auditable derivation, and optional encryption for safer storage. PGP encryption produces an ASCII-armored PGP message suitable for saving as .asc.[3]

Repository layout

  • src/pyhdwallet.py — main CLI script
  • .wallet/ — generated wallet artifacts (recommend adding to .gitignore)
  • requirements.in, requirements.txt
  • README.md, playbook.md, LICENSE

Installation

  1. Ensure Python 3.11+ is installed.
  2. Clone/download the repo.
  3. Create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activate
  1. Install dependencies:
python -m pip install -r requirements.txt

Basic usage

Run the tool with a subcommand. For help, use -h (e.g., gen -h, recover -h).

# Generate (prints mnemonic by default; intended for debug/test)
python ./src/pyhdwallet.py gen

# Generate and save an AES-encrypted ZIP artifact into ./.wallet (password prompted)
python ./src/pyhdwallet.py gen --file

# Generate with PGP encryption + ZIP artifact (ZIP contains only encrypted .asc payload)
python ./src/pyhdwallet.py gen --pgp-pubkey-file pubkeys/mykey.asc --file

# Recover from mnemonic (prefer --interactive to avoid shell history)
python ./src/pyhdwallet.py recover --interactive

# Recover and save AES ZIP artifact
python ./src/pyhdwallet.py recover --interactive --file

# Fetch PGP public key (online)
python ./src/pyhdwallet.py fetchkey "https://example.com/key.asc" --out mykey.asc

# Run tests
python ./src/pyhdwallet.py test

Notes on --file, AES ZIP, and PGP

  • --file writes only an AES-encrypted ZIP (no raw .json/.asc is left on disk), using pyzipper.[4]
  • If --pgp-pubkey-file is set, the ZIP contains a single ASCII-armored PGP message (.asc) created with PGPy-style PGPMessage.new(...) then pubkey.encrypt(...).[3]

About --force

The tool includes a safety guard: if stdout is piped/redirected (non-TTY), it refuses to print sensitive output unless --force is set. Checking whether stdout is a terminal is commonly done via isatty().

Example:

python ./src/pyhdwallet.py gen > out.txt          # likely refused (non-TTY)
python ./src/pyhdwallet.py gen --force > out.txt  # forced (dangerous)

Security

  • Designed to run offline; gen, recover, and test block network access in-process.
  • Use --off-screen to suppress printing sensitive data to stdout.
  • Prefer --file (AES ZIP) and optionally combine with --pgp-pubkey-file for stronger at-rest security.
  • For detailed examples and operational guidance, see playbook.md.
Description
HD wallets Gen/Recover/Encrypt
Readme MIT 48 MiB
Languages
Python 74.9%
Shell 12.3%
Makefile 12.2%
Dockerfile 0.6%