#33043 [POC] wallet: Enable non-electronic (paper-based) wallet backup with codex32
https://github.com/bitcoin/bitcoin/pull/33043 · · +1437/-46 in 31 files, 5 commits · labels: Needs rebase · draft
Goal
- Enable non-electronic paper backup and recovery for wallets using codex32
- Help users back up and restore wallets without needing to manage raw descriptor strings
This proof-of-concept PR ports the codex32 implementation from Core Lightning to C++ and adds support for non-electronic (paper-based) wallet backups. It persists master seeds in the wallet database, introduces a new WALLET_FLAG_SEEDS_STORED flag, and exposes exposesecret and recoverwalletfromseed RPCs.
Problem: Bitcoin Core descriptor wallets do not retain or export an overarching seed or paper backup phrase, making non-electronic seed backup and recovery difficult for users who do not want to manage raw descriptor strings.
Category: Wallet (#67 of 84)
P3 · new feature
- P3 because it fulfills an enduring user request for non-electronic paper backups
- Backing up raw seeds without descriptor metadata or timestamps offers incomplete wallet recovery
Enables non-electronic paper backups for wallets using the BIP 93 codex32 format, addressing an enduring user request. However, raw seed recovery without descriptor metadata or timestamps offers incomplete wallet recovery, keeping this in the worthwhile exploratory tier.
Membership: Touches wallet database structures, wallet flags, descriptor setup, and adds wallet backup/recovery RPCs.
Factors: security/stability 1, bug 0, performance 0, user value 2, leverage 0
Reviewability: Stale: Needs rebase
- Draft proof of concept needs a rebase and has been inactive for over a year
The PR has merge conflicts across 8 open PRs, is marked as a draft POC, and has seen no author activity in over 400 days.
Author status: silent since 2025-07-24
Open concerns:
- apoelstra noted that codex32 has no notion of passphrases or encryption, correcting the author's assumption that an encrypted wallet's passphrase protects exported seeds from an attacker.
- Sjors noted that paper backups must account for output descriptors and timestamps, arguing key material import should go through addhdkey (#32652) rather than creating custom seed-recovery wallet flows.
- BenWestgate pointed out that seed recovery requires wallet birthtime timestamps and suggested supporting codex32 Shamir shares rather than only bare secrets.
Resolved concerns:
- Author acknowledged that passphrases do not deterministically protect BIP32 master keys in the way originally assumed.
Agreement: Mild
- Concept approval for the broad idea of paper backups (rkrux)
- Unaddressed objection: backing up keys without descriptors or timestamps is insufficient (Sjors)
- Warning that exported seeds bypass wallet encryption and grant full spending access (apoelstra)
- Suggested requiring wallet birth timestamps and supporting Shamir shares (BenWestgate)
General concept support for paper backups, but reviewers questioned the design and reliance on raw seeds without descriptors.
Reviewers support the broad idea of paper backups, but architectural concerns from Sjors and apoelstra about separating descriptors, timestamps, and seed derivation remain unanswered on this inactive POC.
- apoelstra noted codex32 seeds are unencrypted and give full spending access regardless of wallet passphrases.
- Sjors recommended using addhdkey (#32652) and emphasized that backing up keys without descriptors is insufficient for modern wallets.
- rkrux offered concept ACK for the high-level idea of non-electronic backups.
Review verdicts (DrahtBot): 0
Files
484 lines under test/bench/ci.
- src/wallet/codex32.cpp +420/-0
- src/wallet/test/codex32_tests.cpp +366/-0
- src/wallet/rpc/backup.cpp +263/-0
- src/wallet/wallet.cpp +82/-15
- test/functional/wallet_codex32.py +92/-0
- src/wallet/walletdb.cpp +85/-0
- src/wallet/codex32.h +63/-0
- src/wallet/wallet.h +20/-7
- src/bech32.cpp +5/-5
- src/wallet/rpc/wallet.cpp +7/-1
- src/bench/wallet_create_tx.cpp +2/-2
- src/wallet/interfaces.cpp +2/-2
- src/wallet/test/util.cpp +2/-2
- src/wallet/walletdb.h +4/-0
- test/functional/wallet_avoidreuse.py +2/-2
- src/bech32.h +3/-0
- src/rpc/client.cpp +3/-0
- src/wallet/walletutil.h +3/-0
- src/bench/wallet_balance.cpp +1/-1
- src/bench/wallet_create.cpp +1/-1
- src/interfaces/wallet.h +1/-1
- src/qt/test/addressbooktests.cpp +1/-1
- src/qt/test/wallettests.cpp +1/-1
- src/qt/walletcontroller.cpp +1/-1
- src/wallet/load.cpp +1/-1
- src/wallet/test/coinselector_tests.cpp +1/-1
- src/wallet/test/group_outputs_tests.cpp +1/-1
- src/wallet/wallettool.cpp +1/-1
- src/wallet/CMakeLists.txt +1/-0
- src/wallet/test/CMakeLists.txt +1/-0
- test/functional/test_runner.py +1/-0
Card
This draft POC introduces non-electronic wallet backup and recovery via codex32 (BIP 93) by storing seed material in the wallet database and adding exposesecret and recoverwalletfromseed RPCs. It addresses a long-standing request for paper backups, though reviewers caution that raw seed backups omit necessary output descriptor and timestamp metadata. The PR is stale, conflicting with multiple open wallet changes, and has been inactive since July 2025.