feat(wallet): give new full-node wallets a BIP39 seed phrase + backup UI

New full-node wallets now get a real 24-word recovery phrase, and users can
reveal/back it up from Settings.

- Pass -usemnemonic=1 to dragonxd. The daemon reads it only inside
  GenerateNewSeed() when a wallet has no seed yet, so it is inert on existing
  wallets (safe to pass unconditionally) and makes every freshly-created
  wallet mnemonic-backed — its phrase is then exportable via z_exportmnemonic
  and portable to SDXLite/ObsidianDragonLite. (Existing/legacy wallets are
  unaffected and keep using the chat identity's z_exportkey fallback.)
- App::exportSeedPhrase() wraps z_exportmnemonic on the RPC worker with
  sodium_memzero wiping on every path; it flags the daemon's "not derived
  from a mnemonic" error as a legacy wallet rather than a failure.
- New "Back up seed phrase" modal (Settings -> Backup & Data, full-node
  gated): reveals the phrase in a numbered word grid, copy (45s clipboard
  auto-clear) + save-to-file (0600), wipes the secret on every close path
  incl. dismiss-mid-fetch. Shared ui/windows/seed_display.h grid helper.
- One-time nudge (settings flag seed_backup_reminded) toasts mnemonic-wallet
  users to back up their phrase; legacy wallets are not nagged.
- 15 new strings translated into all 8 languages (additive, 957->972 keys);
  CJK subset font rebuilt for the new glyphs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-07 10:49:03 -05:00
parent 036199a011
commit 403e145b30
18 changed files with 394 additions and 2 deletions

View File

@@ -233,6 +233,22 @@ void I18n::loadBuiltinEnglish()
strings_["chat_toast_compose_failed"] = "Could not compose the message (too long?).";
strings_["chat_toast_request_compose_failed"] = "Could not compose the contact request (invalid address / text?).";
strings_["chat_toast_request_queued"] = "Contact request queued.";
// Seed-phrase backup (full-node)
strings_["seed_backup_button"] = "Seed phrase";
strings_["tt_seed_backup"] = "Show and back up your wallet's 24-word recovery seed phrase";
strings_["seed_backup_title"] = "Back up seed phrase";
strings_["seed_backup_intro"] = "These words are the master backup of your wallet. Anyone who has them controls your funds.";
strings_["seed_backup_warning"] = "Write them down in order, store them offline, and never share or photograph them. If you lose them, your funds cannot be recovered.";
strings_["seed_backup_loading"] = "Loading your seed phrase…";
strings_["seed_backup_locked"] = "Unlock your wallet to reveal its seed phrase.";
strings_["seed_backup_none"] = "This wallet predates seed phrases, so it has no 24-word phrase. Back it up with \"Backup wallet\" or by exporting your private keys instead.";
strings_["seed_backup_load_failed"] = "Could not load the seed phrase.";
strings_["seed_backup_copy"] = "Copy";
strings_["seed_backup_save"] = "Save to file…";
strings_["seed_backup_saved"] = "Saved to ";
strings_["seed_backup_save_failed"] = "Could not write ";
strings_["seed_backup_close"] = "Close";
strings_["seed_backup_reminder"] = "Your wallet has a 24-word recovery seed phrase. Back it up now in Settings → Node & Security.";
strings_["contacts_search_placeholder"] = "Search contacts...";
strings_["contacts_search_no_match"] = "No matching contacts";
strings_["address_book_confirm_delete"] = "Confirm delete?";