wallet (epic): BIP32/39/44 HD wallets — primitives in tree, no wiring #35

Open
opened 2026-06-15 23:14:25 +00:00 by dobbscoin · 0 comments
dobbscoin commented 2026-06-15 23:14:25 +00:00

Goal

Wire OFF's wallet to use the BIP32 hierarchical-deterministic key-derivation primitives that already sit in the codebase, add BIP39 mnemonic-seed import/export, and standardize derivation paths via BIP44. Replace the legacy "100-key keypool, refill when low" model inherited from Bitcoin Core 0.10.

This is a multi-PR epic, not a single change. Tracked here as the umbrella for future scoped sub-issues. No fork height needed — wallet-only, no consensus change.

Flagged by @9019x on 2026-06-14: "framework already mostly in place on 0.10 — but not used."

Current state

What exists in tree but is unused:

  • src/key.h:267-306 — CExtKey, CExtPubKey classes with Derive() / Neuter() methods. BIP32 primitives, fully implemented.
  • src/base58.h:156-157 — CBitcoinExtKey / CBitcoinExtPubKey (xprv/xpub base58 encodings).

What's missing:

  • Wallet integration. Zero calls to CExtKey::Derive() in src/wallet.cpp. Wallet still uses the legacy CKeyPool random-key model.
  • HDChain record format. No HDChain struct in wallet.{h,cpp}, no wallet record-version bump, no seed storage path.
  • BIP39 mnemonic encoding. No wordlist (need to import the 2048-word English BIP39 list), no MnemonicToSeed() PBKDF2 helper, no UI for restore-from-phrase.
  • BIP44 path standardization. OFF has no SLIP-0044 coin-type registered. Needs PR to https://github.com/satoshilabs/slips before the path format is canonical.
  • Backward compatibility. Existing wallets are legacy-keypool format. Need either auto-migration to HD on next open, or coexistence (legacy keys remain visible, new keys are HD).

Why this is NOT in the v2.0.x consensus-fork bundle

Wallet feature, not consensus. No fork height, no chain-split risk, no activation coordination. Different release cadence (v2.1.x or v2.2.x, not v2.0.x). Different test surface (wallet upgrade tests, mnemonic round-trip tests — not consensus regression vectors). Different failure mode (one user's wallet has issues vs the chain forks).

Folding it into the BIP66 / BIP65 / COINBASE_MATURITY release would couple unrelated risks. Kept explicitly separate per discussion 2026-06-15.

Scope breakdown (future sub-issues)

This epic should fan out into roughly:

  1. wallet: SLIP-0044 registration for OFF coin-type — upstream PR to satoshilabs/slips picking an OFF coin-type number. Blocking dependency for BIP44.
  2. wallet: HDChain record + auto-migration on wallet open — wire CExtKey::Derive() into CWallet. Wallet record-version bump. Backward-compat handling for legacy keypool. ~500 LoC.
  3. wallet: BIP39 mnemonic encode/decode — import 2048-word English list (~6 KB), PBKDF2 seed derivation, RPC dumpmnemonic + CLI restore. ~300 LoC.
  4. wallet: BIP44 path enforcement — use m/44'/<OFF-coin-type>'/0'/{0,1}/i. Depends on (1).
  5. wallet: HD backup / restore UI in Qt — dialogs for seed display, restore-from-phrase, optional passphrase second factor.
  6. wallet: gap-limit handling — standard 20-key gap for receive chain on restore.
  7. wallet: tests — round-trip seed → tree → addresses → sign → spend. Cross-validate against an independent BIP39 reference (Trezor's Python lib is the standard).

Design questions for later discussion

  • Passphrase-protected seed: optional or required?
  • Gap limit default: 20 (BIP44 standard) or higher to account for OFF's lighter use?
  • Coexistence with legacy keys: keep them visible forever, or sweep into HD on first open?
  • Mnemonic wordlist languages: English-only at first, or seed-from-day-one with the full BIP39 set (English, Spanish, Japanese, etc.)?
  • Watch-only HD via xpub-only import: in scope here or follow-on?

References

Community chat: https://23skidoo.info/discord

## Goal Wire OFF's wallet to use the BIP32 hierarchical-deterministic key-derivation primitives that already sit in the codebase, add BIP39 mnemonic-seed import/export, and standardize derivation paths via BIP44. Replace the legacy "100-key keypool, refill when low" model inherited from Bitcoin Core 0.10. This is a **multi-PR epic**, not a single change. Tracked here as the umbrella for future scoped sub-issues. **No fork height needed — wallet-only, no consensus change.** Flagged by @9019x on 2026-06-14: "framework already mostly in place on 0.10 — but not used." ## Current state What exists in tree but is unused: - `src/key.h:267-306` — `CExtKey`, `CExtPubKey` classes with `Derive()` / `Neuter()` methods. BIP32 primitives, fully implemented. - `src/base58.h:156-157` — `CBitcoinExtKey` / `CBitcoinExtPubKey` (xprv/xpub base58 encodings). What's missing: - **Wallet integration.** Zero calls to `CExtKey::Derive()` in `src/wallet.cpp`. Wallet still uses the legacy `CKeyPool` random-key model. - **HDChain record format.** No `HDChain` struct in `wallet.{h,cpp}`, no wallet record-version bump, no seed storage path. - **BIP39 mnemonic encoding.** No wordlist (need to import the 2048-word English BIP39 list), no `MnemonicToSeed()` PBKDF2 helper, no UI for restore-from-phrase. - **BIP44 path standardization.** OFF has no SLIP-0044 coin-type registered. Needs PR to https://github.com/satoshilabs/slips before the path format is canonical. - **Backward compatibility.** Existing wallets are legacy-keypool format. Need either auto-migration to HD on next open, or coexistence (legacy keys remain visible, new keys are HD). ## Why this is NOT in the v2.0.x consensus-fork bundle Wallet feature, not consensus. No fork height, no chain-split risk, no activation coordination. Different release cadence (`v2.1.x` or `v2.2.x`, not `v2.0.x`). Different test surface (wallet upgrade tests, mnemonic round-trip tests — not consensus regression vectors). Different failure mode (one user's wallet has issues vs the chain forks). Folding it into the BIP66 / BIP65 / COINBASE_MATURITY release would couple unrelated risks. Kept explicitly separate per discussion 2026-06-15. ## Scope breakdown (future sub-issues) This epic should fan out into roughly: 1. **wallet: SLIP-0044 registration for OFF coin-type** — upstream PR to `satoshilabs/slips` picking an OFF coin-type number. Blocking dependency for BIP44. 2. **wallet: HDChain record + auto-migration on wallet open** — wire `CExtKey::Derive()` into `CWallet`. Wallet record-version bump. Backward-compat handling for legacy keypool. ~500 LoC. 3. **wallet: BIP39 mnemonic encode/decode** — import 2048-word English list (~6 KB), PBKDF2 seed derivation, RPC `dumpmnemonic` + CLI restore. ~300 LoC. 4. **wallet: BIP44 path enforcement** — use `m/44'/<OFF-coin-type>'/0'/{0,1}/i`. Depends on (1). 5. **wallet: HD backup / restore UI in Qt** — dialogs for seed display, restore-from-phrase, optional passphrase second factor. 6. **wallet: gap-limit handling** — standard 20-key gap for receive chain on restore. 7. **wallet: tests** — round-trip seed → tree → addresses → sign → spend. Cross-validate against an independent BIP39 reference (Trezor's Python lib is the standard). ## Design questions for later discussion - Passphrase-protected seed: optional or required? - Gap limit default: 20 (BIP44 standard) or higher to account for OFF's lighter use? - Coexistence with legacy keys: keep them visible forever, or sweep into HD on first open? - Mnemonic wordlist languages: English-only at first, or seed-from-day-one with the full BIP39 set (English, Spanish, Japanese, etc.)? - Watch-only HD via xpub-only import: in scope here or follow-on? ## References - BIP32: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki - BIP39: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki - BIP44: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki - SLIP-0044 (coin-type registry): https://github.com/satoshilabs/slips/blob/master/slip-0044.md - `src/key.h:267-306` — existing `CExtKey` / `CExtPubKey` primitives - `src/base58.h:156-157` — existing extended-key base58 wrappers - `src/wallet.cpp` — legacy keypool model (no HD calls) Community chat: https://23skidoo.info/discord
Sign in to join this conversation.
No labels
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SubGeniusFinance/Offerings-to-Cthulhu#35
No description provided.