From 9734402d7bec2047d664f9a7b47ae572d62b790b Mon Sep 17 00:00:00 2001 From: DanS Date: Sun, 23 Aug 2026 07:01:22 +0200 Subject: [PATCH] wallet: create new wallets from a BIP39 seed phrase by default New wallets now get an exportable 24-word phrase instead of a random seed that no phrase can ever reproduce. Only wallets with no seed yet are affected; GenerateNewSeed is reachable from one place, under !HaveHDSeed(), and all three key stores refuse to replace an existing seed. This is safe to default on now that the storage form is backwards compatible: the expanded 64-byte BIP39 seed is what gets stored, so a binary predating any of this reads it and derives the same keys. Verified on an isolated chain before flipping: - a new-format wallet reopened with the tagged v1.1.0 binary, which has no knowledge of the entropy record, listed identical addresses; - restoring only the 24 words into a fresh datadir recovered every address. Note this changes what a new wallet is, not what an existing one is: the same entropy yields a different key tree depending on which side of this commit created the wallet. Nothing migrates, and nothing needs to. Co-Authored-By: Claude Opus 5 (1M context) --- src/init.cpp | 2 +- src/wallet/rpcdump.cpp | 6 ++++-- src/wallet/wallet.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 7384ebf1c..2aa86dc46 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -471,7 +471,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-hdtransparent", strprintf(_("Derive transparent addresses from the HD seed so they can be recovered from it (default: %u)"), 1)); strUsage += HelpMessageOpt("-hdseed=", _("Restore a fresh/empty wallet from a 32- or 64-byte HD seed hex (the value shown in z_exportwallet's '# HDSeed=' line). WARNING: exposes the seed to your shell history and process list.")); strUsage += HelpMessageOpt("-mnemonic=", _("Restore/create a fresh/empty wallet from a BIP39 seed phrase, compatible with SilentDragonXLite (English, no passphrase; cross-wallet restore parity is mainnet-only -- testnet/regtest derive a different HD coin_type). WARNING: exposes the phrase to your shell history and process list; prefer DRAGONX.conf with tight permissions.")); - strUsage += HelpMessageOpt("-usemnemonic", strprintf(_("Create new wallets from a fresh BIP39 seed phrase so the 24 words can be exported (z_exportmnemonic) and used in SilentDragonXLite (default: %u)"), 0)); + strUsage += HelpMessageOpt("-usemnemonic", strprintf(_("Create new wallets from a fresh BIP39 seed phrase so the 24 words can be exported (z_exportmnemonic) and used in SilentDragonXLite. Set to 0 for a raw random seed with no recovery phrase; existing wallets are never changed (default: %u)"), 1)); strUsage += HelpMessageOpt("-hdtransparentgaplimit=", strprintf(_("On -mnemonic/-hdseed restore, pre-derive this many HD transparent keys so a rescan can find coinbase paid to them (default: %u)"), 1000)); strUsage += HelpMessageOpt("-mnemonicsaplinggap=", strprintf(_("On -mnemonic/-hdseed restore, pre-derive this many shielded (Sapling) addresses so a rescan can find notes sent to them (default: %u)"), 100)); strUsage += HelpMessageOpt("-consolidation", _("Enable auto Sapling note consolidation (default: false)")); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 14b0dacc7..9b72f008d 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -1039,8 +1039,10 @@ UniValue z_exportmnemonic(const UniValue& params, bool fHelp, const CPubKey& myp "\nReveal the wallet's BIP39 seed phrase (24 words).\n" "The phrase is byte-compatible with SilentDragonXLite: the same words\n" "restore the same transparent and shielded addresses in either wallet.\n" - "Only works for wallets created or restored from a mnemonic (see the\n" - "-mnemonic and -usemnemonic options). Requires the wallet be unlocked.\n" + "New wallets get a seed phrase by default (-usemnemonic=0 opts out);\n" + "wallets restored with -mnemonic have one too. Wallets created before\n" + "this feature, or from a raw -hdseed, have no phrase -- use\n" + "z_exportwallet for those. Requires the wallet be unlocked.\n" "\nResult:\n" "{\n" " \"mnemonic\" : \"word1 ... word24\", (string) the BIP39 seed phrase\n" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1b902f156..81df81e1e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2476,7 +2476,7 @@ void CWallet::GenerateNewSeed() // (z_exportmnemonic refuses non-mnemonic wallets, rpcdump.cpp:1031+) and // that no seed phrase can restore. A user who asked for -usemnemonic must // get that or a hard failure. - if (GetBoolArg("-usemnemonic", false)) { + if (GetBoolArg("-usemnemonic", true)) { RawHDSeed entropy; if (!GenerateMnemonicEntropy(256, entropy)) throw std::runtime_error(std::string(__func__) + ": -usemnemonic entropy generation failed");