feat(migration): second backup acknowledgement + confirm Discard and Sweep

Migrate-to-seed is irreversible and fund-moving, so its gates are strengthened
(UI only — the sweep/adopt/wipe logic, z_mergetoaddress args, amounts and
destination are byte-identical):
- Continue now requires a second, consequence-stating acknowledgement checkbox
  (funds move and are recoverable only via the seed phrase), not just "I wrote
  it down".
- Discard, Sweep-all and Sweep-remaining each take a second confirming click
  (stating the amount being moved) instead of firing on one click; the confirm
  body runs verbatim only after confirmation, and arming never survives a
  close/reopen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 23:20:32 -05:00
co-authored by Claude Opus 4.8
parent 3f1838cfdd
commit 89d3975eb3
4 changed files with 110 additions and 35 deletions
+6
View File
@@ -927,6 +927,8 @@ private:
// curve on every failed path (a PIN RPC failure used to skip it).
void applyUnlockSuccess(const std::string& passphrase, int timeout);
void applyUnlockFailure(const std::string& errorMessage);
// Restore the persisted unlock-failure count + lockout (once per lock-screen session, per wallet).
void restoreLockoutState();
// Non-credential failure (busy node, unknown error): message only, no attempt counted.
void applyUnlockNotCounted(const std::string& errorMessage);
// Clear all rescan + witness-rebuild progress/accumulator state. Shared by the four
@@ -1453,6 +1455,9 @@ private:
std::string seed_migration_dest_; // new shielded z-address (Phase 2 sweep target)
std::string seed_migration_temp_dir_; // temp datadir root holding the new wallet (kept)
bool seed_migration_backed_up_ = false; // "I've written it down" confirmation
bool seed_migration_understood_ = false; // 2nd ack: funds recoverable only via the phrase
bool seed_migration_confirm_discard_ = false; // inline "are you sure" gate for Discard (never persisted)
bool seed_migration_confirm_sweep_ = false; // inline "are you sure" gate for Sweep (never persisted)
std::string seed_migration_status_; // main-thread display (progress / error text)
double seed_migration_balance_ = 0.0; // legacy total to sweep (shown on the Sweep step)
std::string seed_migration_sweep_txid_; // the z_mergetoaddress sweep transaction id
@@ -1973,6 +1978,7 @@ private:
int lock_attempts_ = 0;
float lock_lockout_timer_ = 0.0f;
std::chrono::steady_clock::time_point lock_timer_armed_at_{}; // when lock_error/lockout timers were last armed
bool lock_state_restored_ = false; // one-shot: persisted lockout restored for this lock-screen session
bool lock_unlock_in_progress_ = false;
// Encrypt wallet dialog state