288 lines
8.5 KiB
Markdown
288 lines
8.5 KiB
Markdown
# pyhdwallet v1.0.2
|
|
|
|
A command-line tool for generating and recovering HD wallets (BIP39) with support for Ethereum, Solana, and Bitcoin. Features offline operation, PGP encryption, and multi-chain address derivation.
|
|
|
|
## Table of Contents
|
|
|
|
- [Features](#features)
|
|
- [Installation](#installation)
|
|
- [Quick Start](#quick-start)
|
|
- [Commands](#commands)
|
|
- [fetchkey](#fetchkey)
|
|
- [gen](#gen)
|
|
- [recover](#recover)
|
|
- [test](#test)
|
|
- [Examples](#examples)
|
|
- [Security](#security)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [Changelog](#changelog)
|
|
|
|
## Features
|
|
|
|
- **Offline-first**: Generate and recover wallets without internet access.
|
|
- **Multi-chain support**: Derive addresses for Ethereum, Solana, and Bitcoin.
|
|
- **PGP encryption**: Securely encrypt sensitive data (mnemonics, private keys) to PGP public keys.
|
|
- **Flexible input**: Accept BIP39 mnemonics or hex seeds.
|
|
- **BIP39 passphrase support**: Optional passphrase for additional security.
|
|
- **Private key export**: Export derived private keys in encrypted payloads.
|
|
- **Solana profiles**: Multiple derivation paths for Solana compatibility.
|
|
- **Self-testing**: Built-in tests to verify functionality.
|
|
- **Secure mode**: Optional paranoid mode with memory zeroing, temp files, and no output printing for high-security use.
|
|
|
|
## Installation
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.11 or higher
|
|
- Virtual environment (recommended)
|
|
|
|
### Setup
|
|
|
|
1. Clone or download the repository.
|
|
2. Create a virtual environment:
|
|
|
|
```bash
|
|
python -m venv .venv
|
|
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
|
```
|
|
|
|
3. Install dependencies:
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
### Dependencies
|
|
|
|
- `bip-utils`: BIP39 and derivation logic
|
|
- `PGPy`: PGP encryption
|
|
- `PyNaCl` & `base58`: Solana private key handling (optional for Solana private key export)
|
|
|
|
## Quick Start
|
|
|
|
1. Generate a new wallet:
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py gen --chains ethereum solana --addresses 3
|
|
```
|
|
|
|
2. Recover from a mnemonic:
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py recover --mnemonic "abandon abandon ... about" --chains bitcoin
|
|
```
|
|
|
|
3. Fetch a PGP key:
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py fetchkey "https://example.com/key.asc" --out mykey.asc
|
|
```
|
|
|
|
4. Use secure mode for high-security operations:
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py gen --secure-mode --pgp-pubkey-file key.asc --chains ethereum --addresses 1
|
|
```
|
|
|
|
5. Run tests:
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py test
|
|
```
|
|
|
|
## Commands
|
|
|
|
### fetchkey
|
|
|
|
Download and verify a PGP public key from a URL.
|
|
|
|
**Usage:**
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py fetchkey <url> [--out FILE] [--timeout SECONDS]
|
|
```
|
|
|
|
**Options:**
|
|
|
|
- `url`: URL to the ASCII-armored PGP key
|
|
- `--out FILE`: Save the key to a file
|
|
- `--timeout SECONDS`: Request timeout (default: 15)
|
|
- `--secure-mode`: Enable secure mode (temp files, no extra output)
|
|
|
|
**Example:**
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py fetchkey "https://keys.openpgp.org/pks/lookup?op=get&search=user@example.com" --out key.asc
|
|
```
|
|
|
|
### gen
|
|
|
|
Generate a new BIP39 mnemonic and derive addresses.
|
|
|
|
**Usage:**
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py gen [options]
|
|
```
|
|
|
|
**Options:**
|
|
|
|
- `--words {12,15,18,21,24}`: Number of mnemonic words (default: 12)
|
|
- `--dice-rolls "1 2 3 ..."`: Space-separated dice rolls for entropy
|
|
- `--passphrase PASSPHRASE`: BIP39 passphrase
|
|
- `--passphrase-hint HINT`: Hint for the passphrase
|
|
- `--chains {ethereum,solana,bitcoin}`: Chains to derive (default: all)
|
|
- `--addresses N`: Number of addresses per chain (default: 5)
|
|
- `--sol-profile {phantom_bip44change,phantom_bip44,phantom_deprecated,solana_bip39_first32}`: Solana derivation profile
|
|
- `--output {text,json}`: Output format (default: text)
|
|
- `--file FILE`: Save output to file
|
|
- `--pgp-pubkey-file FILE`: Encrypt payload to PGP key
|
|
- `--pgp-ignore-usage-flags`: Ignore PGP key usage flags
|
|
- `--export-private`: Include private keys in encrypted payload
|
|
- `--include-source`: Include mnemonic in encrypted payload
|
|
- `--unsafe-print`: Print mnemonic even when encrypting
|
|
- `--secure-mode`: Enable secure mode (no printing, temp files, memory zeroing)
|
|
|
|
**Examples:**
|
|
|
|
```bash
|
|
# Basic generation
|
|
python ./src/pyhdwallet.py gen
|
|
|
|
# With secure mode
|
|
python ./src/pyhdwallet.py gen --secure-mode --pgp-pubkey-file key.asc
|
|
|
|
# With passphrase and encryption
|
|
python ./src/pyhdwallet.py gen --passphrase "mysecret" --pgp-pubkey-file key.asc --export-private
|
|
|
|
# JSON output to file
|
|
python ./src/pyhdwallet.py gen --chains ethereum --addresses 10 --output json --file wallet.json
|
|
```
|
|
|
|
### recover
|
|
|
|
Derive addresses from an existing mnemonic or seed.
|
|
|
|
**Usage:**
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py recover [options]
|
|
```
|
|
|
|
**Options:** Same as `gen`, plus:
|
|
|
|
- `--mnemonic MNEMONIC`: BIP39 mnemonic phrase
|
|
- `--seed HEX_SEED`: 128-character hex seed
|
|
- `--interactive`: Prompt for mnemonic/seed interactively
|
|
- `--secure-mode`: Enable secure mode (no printing, temp files, memory zeroing)
|
|
|
|
**Examples:**
|
|
|
|
```bash
|
|
# From mnemonic
|
|
python ./src/pyhdwallet.py recover --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" --chains ethereum solana
|
|
|
|
# Interactive input
|
|
python ./src/pyhdwallet.py recover --interactive --chains bitcoin
|
|
|
|
# From seed
|
|
python ./src/pyhdwallet.py recover --seed "0123456789abcdef..." --chains solana
|
|
```
|
|
|
|
### test
|
|
|
|
Run minimal self-tests to verify functionality.
|
|
|
|
**Usage:**
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py test [--secure-mode]
|
|
```
|
|
|
|
**Options:**
|
|
|
|
- `--secure-mode`: Enable secure mode (no extra output)
|
|
|
|
**Output:** Success/failure messages for derivation tests.
|
|
|
|
## Examples
|
|
|
|
### 1. Generate and Encrypt a New Wallet
|
|
|
|
```bash
|
|
# Generate with encryption
|
|
python ./src/pyhdwallet.py gen --pgp-pubkey-file key.asc --include-source --export-private --chains ethereum solana --addresses 5
|
|
|
|
# Decrypt the output later with GPG
|
|
echo "-----BEGIN PGP MESSAGE-----..." | gpg -d
|
|
```
|
|
|
|
### 2. Recover from Mnemonic with Passphrase
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py recover --mnemonic "word1 word2 ... word12" --passphrase "mypass" --chains ethereum --addresses 10 --output json
|
|
```
|
|
|
|
### 3. Fetch and Use PGP Key
|
|
|
|
```bash
|
|
# Fetch key
|
|
python ./src/pyhdwallet.py fetchkey "https://example.com/pubkey.asc" --out mykey.asc
|
|
|
|
# Use in secure mode
|
|
python ./src/pyhdwallet.py fetchkey --secure-mode "https://example.com/pubkey.asc"
|
|
```
|
|
|
|
### 4. High-Security Operations with Secure Mode
|
|
|
|
```bash
|
|
# Generate without printing sensitive data
|
|
python ./src/pyhdwallet.py gen --secure-mode --pgp-pubkey-file key.asc --chains ethereum --addresses 1
|
|
|
|
# Recover in secure mode
|
|
python ./src/pyhdwallet.py recover --secure-mode --interactive --pgp-pubkey-file key.asc --export-private
|
|
```
|
|
|
|
# Use in recovery
|
|
|
|
python ./src/pyhdwallet.py recover --interactive --pgp-pubkey-file mykey.asc --export-private
|
|
|
|
```
|
|
|
|
### 4. Solana-Specific Derivation
|
|
|
|
```bash
|
|
python ./src/pyhdwallet.py gen --chains solana --sol-profile phantom_bip44change --addresses 3
|
|
```
|
|
|
|
## Security
|
|
|
|
- **Offline operation**: `gen`, `recover`, and `test` commands block network access.
|
|
- **No plaintext secrets**: Mnemonics and private keys are never printed unless encrypted or `--unsafe-print` is used.
|
|
- **PGP encryption**: Use for secure storage of sensitive data.
|
|
- **Secure mode**: Use `--secure-mode` for paranoid operations—suppresses output, uses temp files with auto-deletion, and zeros memory.
|
|
- **Passphrase handling**: Passphrases are not stored; only hints are included.
|
|
- **Private key export**: Only export what's needed; treat encrypted payloads as sensitive.
|
|
- **File permissions**: Output files are set to owner-only (0o600) for security.
|
|
- **Memory zeroing**: In secure mode, sensitive variables are cleared after use.
|
|
- **Best practices**:
|
|
- Use `--interactive` to avoid command-line history exposure.
|
|
- Use `--secure-mode` for high-risk operations.
|
|
- Verify PGP fingerprints out-of-band.
|
|
- Run on trusted, offline machines.
|
|
|
|
## Troubleshooting
|
|
|
|
- **Missing dependencies**: Run `pip install -r requirements.txt`
|
|
- **Network errors in offline modes**: Ensure no internet access; the tool blocks it.
|
|
- **Invalid mnemonic**: Check word count and spelling.
|
|
- **PGP decryption fails**: Ensure you have the correct private key.
|
|
- **Secure mode issues**: Ensure temp files are deleted; check permissions on output files.
|
|
- **Version check**: Run `python ./src/pyhdwallet.py --version`
|
|
|
|
## Changelog
|
|
|
|
- **v1.0.2**: Security patches - added --secure-mode, memory zeroing, file permission fixes, auto-deletion in secure mode, sanitized errors.
|
|
- **v1.0.1**: Renamed to pyhdwallet, added --version flag, updated documentation, excluded _toDelete in .gitignore.
|
|
- **v1.0.0**: Initial release with gen, recover, fetchkey, and test commands.
|