Refs: offline install via vendored wheels and test verification workflow (see README/playbook updates)
This commit is contained in:
207
README.md
207
README.md
@@ -1,151 +1,172 @@
|
||||
# hdwalletpy – Setup & Usage Guide
|
||||
# pyhdwallet – Secure HD Wallet Tool
|
||||
|
||||
This project provides a Python-based HD Wallet tool with optional Docker-based build automation for fast, reproducible environments.
|
||||
A Python command-line tool for generating and recovering BIP39 HD wallets with support for Ethereum, Solana, and Bitcoin. Designed for offline operation with optional PGP encryption and AES-encrypted ZIP artifacts.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation Options
|
||||
## 📦 Installation
|
||||
|
||||
### **Option 1: Standard Python Setup (Host Machine)**
|
||||
### **Quick Start (macOS/Linux with Internet)**
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/<your-username>/hdwalletpy.git
|
||||
cd hdwalletpy
|
||||
|
||||
# Install using automated script
|
||||
./install_offline.sh
|
||||
```
|
||||
|
||||
The script automatically:
|
||||
|
||||
- Creates Python 3.12 virtual environment
|
||||
- Installs from vendored wheels (offline-capable)
|
||||
- Verifies installation with test suite
|
||||
- Leaves you in activated venv
|
||||
|
||||
---
|
||||
|
||||
### **Air-Gapped Installation (No Internet)**
|
||||
|
||||
This repository includes pre-built Python wheels for offline use.
|
||||
|
||||
**Supported platforms:**
|
||||
|
||||
- macOS ARM64 (M1/M2/M3) - Python 3.12
|
||||
- Linux x86_64 (Ubuntu/Tails) - Python 3.12
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. On an online machine, clone and verify:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/<your-username>/hdwalletpy.git
|
||||
cd hdwalletpy
|
||||
|
||||
# Verify checksums
|
||||
cd vendor/linux-x86_64 # or macos-arm64
|
||||
sha256sum -c SHA256SUMS # Linux
|
||||
shasum -a 256 -c SHA256SUMS # macOS
|
||||
```
|
||||
|
||||
2. Create a virtual environment:
|
||||
2. Transfer entire repo to USB drive
|
||||
|
||||
3. On air-gapped machine:
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
cd hdwalletpy
|
||||
./install_offline.sh
|
||||
```
|
||||
|
||||
3. Install dependencies:
|
||||
4. Generate wallet:
|
||||
|
||||
```bash
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r requirements.txt
|
||||
python src/pyhdwallet.py gen --off-screen --file
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **Option 2: Fast Setup Using Docker + Makefile**
|
||||
### **Developer Installation (with Docker)**
|
||||
|
||||
This method avoids installing compilers on your host and speeds up dependency builds.
|
||||
|
||||
#### **Step 1: Build Docker Image**
|
||||
For development or building wheels for other platforms:
|
||||
|
||||
```bash
|
||||
# Build Docker image
|
||||
make build-image
|
||||
```
|
||||
|
||||
Creates a reusable image `python-build-env:3.11` with build tools and `python3-venv`.
|
||||
# Build wheels for all platforms
|
||||
make vendor-all
|
||||
|
||||
#### **Step 2: Compile Wheels in Container**
|
||||
# Install development environment
|
||||
make install
|
||||
|
||||
```bash
|
||||
make wheels
|
||||
```
|
||||
|
||||
Builds all dependency wheels into `./wheelhouse` for fast installs.
|
||||
|
||||
#### **Step 3: Create Host Virtual Environment**
|
||||
|
||||
```bash
|
||||
make venv-host
|
||||
source .venv_host/bin/activate
|
||||
```
|
||||
|
||||
Installs dependencies from `wheelhouse` (no compilation needed).
|
||||
|
||||
#### **Optional: Work Inside a Warm Container**
|
||||
|
||||
```bash
|
||||
make up # Start container
|
||||
make shell # Open shell inside container
|
||||
make venv-container # Create container-only venv at /opt/venv
|
||||
```
|
||||
|
||||
#### **Cleanup**
|
||||
|
||||
```bash
|
||||
make clean # Remove host venv and wheelhouse
|
||||
make down # Stop/remove container
|
||||
# Run tests
|
||||
make test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Basic Usage
|
||||
|
||||
Run the tool with subcommands. For help, use `-h` (e.g., `gen -h`, `recover -h`).
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
# Generate mnemonic (prints to stdout; for debug/test)
|
||||
python ./src/pyhdwallet.py gen
|
||||
# Generate wallet (prints mnemonic - debug mode)
|
||||
python src/pyhdwallet.py gen
|
||||
|
||||
# Generate and save AES-encrypted ZIP artifact into ./.wallet (password prompted)
|
||||
python ./src/pyhdwallet.py gen --file
|
||||
# Generate with off-screen mode + encrypted ZIP
|
||||
python src/pyhdwallet.py gen --off-screen --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
|
||||
# Generate with PGP encryption + ZIP
|
||||
python src/pyhdwallet.py gen \
|
||||
--pgp-pubkey-file pubkeys/mykey.asc \
|
||||
--expected-fingerprint A27B96F2B169B5491013D2DA892B822C14A9AA18 \
|
||||
--off-screen \
|
||||
--file
|
||||
|
||||
# Recover from mnemonic (prefer --interactive to avoid shell history)
|
||||
python ./src/pyhdwallet.py recover --interactive
|
||||
# Recover wallet from mnemonic
|
||||
python src/pyhdwallet.py recover --interactive --file
|
||||
|
||||
# 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
|
||||
# Fetch PGP public key (requires internet)
|
||||
python src/pyhdwallet.py fetchkey "https://example.com/key.asc" --out mykey.asc
|
||||
|
||||
# Run tests
|
||||
python ./src/pyhdwallet.py test
|
||||
python src/pyhdwallet.py test
|
||||
pytest -v tests/test_vectors.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Notes on `--file`, AES ZIP, and PGP
|
||||
## 🔐 Security Features
|
||||
|
||||
- `--file` writes **only** an AES-encrypted ZIP (no raw `.json`/`.asc` left on disk), using `pyzipper`.
|
||||
- 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(...)`.
|
||||
- **Offline-first**: Network access blocked during key generation/recovery
|
||||
- **Test suite**: Regression tests with frozen vectors ensure derivation logic integrity
|
||||
- **PGP fingerprint pinning**: Prevents key substitution attacks
|
||||
- **TTY safety guard**: Refuses to print secrets when stdout is piped/redirected
|
||||
- **AES-encrypted outputs**: Wallet artifacts encrypted with `pyzipper`
|
||||
- **No shell history leaks**: Use `--interactive` or `--mnemonic-stdin` for recovery
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ About `--force`
|
||||
## 🛠️ Makefile Targets
|
||||
|
||||
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:
|
||||
**Vendoring (for air-gapped deployment):**
|
||||
|
||||
```bash
|
||||
python ./src/pyhdwallet.py gen > out.txt # likely refused (non-TTY)
|
||||
python ./src/pyhdwallet.py gen --force > out.txt # allowed
|
||||
make vendor-macos # Build macOS ARM64 wheels
|
||||
make vendor-linux # Build Linux x86_64 wheels (Docker)
|
||||
make vendor-all # Build for both platforms
|
||||
make verify-vendor # Test offline installation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Why Use Makefile?
|
||||
|
||||
- **Speed:** Avoid repeated `apt-get` installs; wheels cached locally.
|
||||
- **Reproducibility:** Same Docker image for builds; no environment drift.
|
||||
- **Convenience:** One-liner tasks (`make wheels`, `make venv-host`, `make shell`).
|
||||
- **Separation:** Host venv vs container venv for clean workflows.
|
||||
|
||||
---
|
||||
|
||||
## Common Makefile Targets
|
||||
**Development:**
|
||||
|
||||
```bash
|
||||
make build-image # Build Docker image with build tools
|
||||
make wheels # Compile wheels into ./wheelhouse
|
||||
make venv-host # Host venv install from wheelhouse
|
||||
make up # Start warm container
|
||||
make shell # Shell into warm container
|
||||
make venv-container # Container venv at /opt/venv
|
||||
make down # Stop/remove container
|
||||
make clean # Remove .venv_host and wheelhouse
|
||||
make install # Create venv and install dependencies
|
||||
make test # Run test suite
|
||||
make build-image # Build Docker image
|
||||
make shell # Open shell in Docker container
|
||||
make clean # Remove venvs and build artifacts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Full Documentation
|
||||
|
||||
- **[playbook.md](playbook.md)** - Complete command reference and operational guide
|
||||
- **[tests/](tests/)** - Regression test suite documentation
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Recommended Air-Gapped Setup
|
||||
|
||||
For maximum security when generating production wallets:
|
||||
|
||||
1. Use fresh Ubuntu Live USB or Tails OS
|
||||
2. Never connect to network after booting
|
||||
3. Transfer this repository via separate USB
|
||||
4. Run `./install_offline.sh`
|
||||
5. Generate wallet: `python src/pyhdwallet.py gen --off-screen --file`
|
||||
6. Write mnemonic to paper/metal backup
|
||||
7. Transfer encrypted ZIP to secure storage
|
||||
8. Wipe USB drives securely
|
||||
|
||||
See [playbook.md](playbook.md) for detailed air-gapped procedures.
|
||||
|
||||
Reference in New Issue
Block a user