9a83c9b80541

App.tsx onMount: on native, treat unconfirmed-recovery + locked + vault-exists as a failed creation — wipe vault slots + recovery-pending flag and restart onboarding. Per user spec: vault creation is atomic with recovery-words confirmation, partial creations don't strand the user behind a password screen. Desktop keeps the resume-via-unlock flow (closing a popup is too easy to do accidentally)

time
2026-05-07 03:38 UTC · 5 months ago
machine
koh2
parent
f23a453c4bda
1 file src/popup/App.tsx+23 −0
src/popup/App.tsx+23 −0
@@ -341,6 +341,29 @@341341       recoveryPending = (out as { peach_recovery_pending?: string })?.peach_recovery_pending === "1";342342     } catch { /* best-effort */ }343343 344+    // Native: closing the app before recovery-words confirmation means the345+    // user didn't finish vault creation. Throw the partial vault away and346+    // restart onboarding rather than asking them to unlock a vault they347+    // never finished creating. Desktop keeps the existing "unlock to348+    // resume" flow because closing the popup there is much more casual.349+    if (recoveryPending && !unlocked && vaultExists && isNativePlatform()) {350+      try {351+        await chrome.storage.local?.remove([352+          "peach_vault_a",353+          "peach_vault_b",354+          "peach_recovery_pending",355+          "peach_onboarded",356+          "peach_vault_history",357+        ]);358+      } catch { /* best-effort */ }359+      setHasVault(false);360+      setOnboarded(false);361+      setView("lock");362+      setBootState("ready");363+      document.getElementById("pre-lock")?.setAttribute("hidden", "true");364+      return;365+    }366+344367     if (recoveryPending && unlocked) {345368       // forceRecoveryWords overrides LockView's hasVault gate so the346369       // recovery surface renders even though the vault now exists.

view file