#33043 [POC] wallet: Enable non-electronic (paper-based) wallet backup with codex32
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #33043 [POC] wallet: Enable non-electronic (paper-based) wallet backup with codex32 | Waiting on author | 0 | Mild | 965 + 472 tests | |||
|
|
|
|
| |||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
This pull request adds support for persisting wallet seeds and introduces codex32 (BIP 93) encoding to enable paper-based backup and recovery. It ports the codex32 implementation from Core Lightning into C++ and adds two new RPCs: exposesecret to export seeds in codex32 format, and recoverwalletfromseed to restore a wallet from a codex32 string.
Problem: Bitcoin Core descriptor wallets do not retain the original seed material after generating descriptors, preventing users from backing up or restoring wallets using physical, human-verifiable paper backups like codex32 without retaining raw database files or long descriptor strings.
Evidence of importance:
- The author states in the PR description: 'Because Bitcoin Core wallets currently do not store the seed material by default, this PR adds support for doing so, along with a new wallet flag to explicitly indicate when this feature is enabled.'
- Author notes the POC status: 'This PR is intended as a proposal for feedback—to assess whether this functionality is desirable, and to explore how it might evolve further.'
Scope: Includes a port of external code (codex32.{c,h} from Core Lightning) adapted into C++ (wallet/codex32.cpp and tests). It also introduces new persistent wallet database keys (WALLETSEEDKEY and WALLETSEEDCKEY) and a new wallet flag WALLET_FLAG_SEEDS_STORED.
Reviewability
Paused · Waiting on author
Open objections from BenWestgate, Sjors with no author reply for 207 days; review would repeat what has been asked.
Agreement
Mild
objection that needs an answer has none yet (Sjors, BenWestgate)
Thread notes: Initial record for the POC PR. Reviewers support the concept of paper backups in principle, but open objections remain regarding the architecture: Sjors and BenWestgate noted that seed recovery without descriptors and birth timestamps is incomplete for modern descriptor wallets, and Sjors prefers integration via addhdkey.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| apoelstra (contributor) | objection, safety | a raw codex32 seed allows an attacker to sweep funds without needing the wallet passphrase | answered · v1, not yet re-checked | answered | yes | 2025-07-23: 'the seed is the seed -- once an attacker has it, it's game over. He doesn't need the passphrase or any other part of the wallet to sweep coins' Status from: 2025-07-23: w0xlt: 'Yes, you're right. I thought the passphrase deterministically modified the seed to create the BIP 32 Extended Key, but that's not the case.' |
| Sjors (member) | objection, approach | backing up raw keys in custom seed RPCs bypasses descriptor backups needed for complex wallets and fragments key import logic away from addhdkey | open · v1, not yet re-checked | answered | no | 2025-07-25: 'It seems to me that codex32 only plays a role in (1). And so importing it should be done with `addhdkey`. Exporting could be done with `gethdkeys`.' |
| BenWestgate (contributor) | objection, interface | restoring solely from seed lacks wallet birth timestamps needed for efficient rescanning and lacks descriptor associations | open · v1, not yet re-checked | answered | no | 2025-10-13: 'we need the timestamp no? Other approaches made the import/restore command require a corresponding descriptor to function and that seems more robust for existing wallets.' |
Support:
- rkrux (contributor) (Concept ACK, 2026-04-08): paper-based backups are a ubiquitous industry standard and timely now that legacy wallets are removed
Participants:
- apoelstra (contributor, objection, 1 statements 2025-07-23 to 2025-07-23): pointed out that codex32 seeds are unencrypted and bypass wallet passphrases
- Sjors (member, objection, 2 statements 2025-07-24 to 2025-07-25): argued key material import/export should use addhdkey/gethdkeys and must account for descriptors
- BenWestgate (contributor, objection, 3 statements 2025-08-21 to 2025-10-13): pointed out missing timestamps for rescans and urged support for share sets and descriptors
- rkrux (contributor, support, 1 statements 2026-04-08 to 2026-04-08): Concept ACK for introducing paper-based wallet backups
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
The short text the ranking pass compares across PRs.
This pull request adds the ability to back up and restore Bitcoin Core wallets using paper-based codex32 (BIP 93) seeds. Bitcoin Core descriptor wallets currently do not store seed material or provide paper backup workflows, forcing users to rely on electronic descriptor or file backups. The PR ports codex32 logic from Core Lightning, stores encrypted/plaintext seeds in the wallet database under a new wallet flag, and adds exposesecret and recoverwalletfromseed RPCs. The work is submitted as a proof of concept to gather feedback on seed storage in Core.
Data
thread read through 2026-04-08 (10 statements), head 14f3342262
Discussion read under schema 1 rules: suggestions and questions may be missing, and an objection may combine several harms (schema history).
labels: Needs rebase · draft
Categories
Wallet
P3 · new feature (assessed alone as P2; Lowered from P2: an explicit proof of concept seeking feedback on whether Core should store seeds at all; value is speculative until that is settled.)
Addresses the inability of descriptor wallets to support standard human-verifiable paper backups without preserving raw databases or descriptor strings. As noted in the discussion, paper backups are an industry standard whose absence in descriptor wallets is a notable gap following legacy wallet removal.
Membership: Adds codex32 (BIP 93) seed persistence, database keys, and recovery RPCs across src/wallet/.
Factors: security/stability 1, bug 0, performance 0, user value 2, leverage 1