fix(sync): empty wallet save must not wipe the synced copy on relays

Data-loss bug: on a fresh device the user opened the Wallet pane (field empty,
wallet not yet restored), clicked Save, and the "removed" branch called
walletSync.disable() — publishing a {cleared:true} note that destroyed the good
encrypted copy another device relied on. (Confirmed in logs: a kind-30078
"bitvid:nwc" {cleared:true} event signed right after login.)

An empty save happens routinely (saving before hydration/restore), so treating it
as a deliberate disconnect-that-wipes-the-remote is wrong. Removed the auto-clear
from the empty-save branch: the remote synced note is now changed ONLY via the
explicit sync toggle (enable/disable) or a successful save (push). An empty save
clears just the LOCAL wallet.

tests/wallet-sync-no-clobber.test.mjs: empty save does not call disable/push; a
real save still pushes. Mutation-verified (re-adding the disable fails the test).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-21 20:52:20 -04:00
1 parent 234f57e009
commit c26ef89a93
2 files changed
+93 -12

No files matched your search

+7 -12
View File
@@ -631,18 +631,13 @@ export class ProfileWalletController {
finalVariant = "info";
this.mainController.showStatus("Wallet connection removed.");
context.reason = "cleared";
// Don't leave a now-removed spending URI lingering (encrypted) on relays.
const sync = this.getWalletSyncService();
if (sync.isEnabled(normalizedActive)) {
try {
await sync.disable(normalizedActive);
} catch (syncError) {
devLogger.warn(
"[ProfileModal] Wallet sync clear after disconnect failed:",
syncError
);
}
}
// NOTE: deliberately do NOT clear the remote synced note here. An empty
// save happens routinely (e.g. saving before the wallet has hydrated /
// been restored on a fresh device), and wiping the encrypted note on
// relays would destroy a good copy that another device relies on. The
// remote note is only ever changed via the explicit sync toggle
// (enable/disable) or a successful save (push). Toggling sync off is the
// single, deliberate way to clear the remote.
}
context.success = true;
} catch (error) {