aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-03 20:15:16 -0700
committerAdam Soltys <[email protected]>2026-08-03 20:15:16 -0700
commitd59d667d3e4c6edb42b8a42fd120a1bdd96a58db (patch)
tree0df9efb0d83b805bf284eef3868719426074f214 /src
parenta7c45156fb49e26f06a359d79240d328d88a00d5 (diff)
downloadcoinosv3-d59d667d3e4c6edb42b8a42fd120a1bdd96a58db.tar.gz
coinosv3-d59d667d3e4c6edb42b8a42fd120a1bdd96a58db.zip
Gift records belong to one wallet, not to the browser
giftRecords() caches the parsed blob on the wallet object, but the app runs a single Wallet for its lifetime and load() never dropped that cache. Switching wallets carried the old wallet's gift links into the new one, where they all rendered as claimed — none of their outpoints are live in a wallet that never issued them — and the first save wrote them back under the new wallet's key. Clear the cache on load alongside the other two gift caches, and forget records whose funding tx isn't in this wallet's own history, to clean up what earlier builds already misfiled. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
Diffstat (limited to 'src')
-rw-r--r--src/features/gifts-wallet.js21
-rw-r--r--src/wallet.js1
2 files changed, 22 insertions, 0 deletions
diff --git a/src/features/gifts-wallet.js b/src/features/gifts-wallet.js
index 93ef268..bf8a82d 100644
--- a/src/features/gifts-wallet.js
+++ b/src/features/gifts-wallet.js
@@ -94,6 +94,26 @@ export function installGiftWallet(wallet) {
_saveGiftRecords() { try { localStorage.setItem(this._giftRecordsKey(), JSON.stringify(this.giftRecords())); } catch {} },
+ // We fund a gift from our own coins, so the funding tx is always in our own
+ // history. A record whose tx isn't means it was never issued here — an
+ // earlier build let a wallet keep the previous wallet's records in memory
+ // and then write them back under its own key. Forget those rather than
+ // show someone another wallet's gifts.
+ _pruneForeignGifts() {
+ const recs = this.giftRecords();
+ const ids = Object.keys(recs);
+ if (!ids.length) return;
+ const ours = new Set(this.txs.map((t) => t.txid));
+ let changed = false;
+ for (const id of ids) {
+ const outs = recs[id].outpoints || [];
+ if (outs.some((o) => ours.has(String(o).split(':')[0]))) continue;
+ delete recs[id];
+ changed = true;
+ }
+ if (changed) this._saveGiftRecords();
+ },
+
// Remember which tx claimed a gift (resolved lazily via outspend) so the
// history can merge the gift row with its claim transaction.
setGiftClaimTx(id, txid) {
@@ -125,6 +145,7 @@ export function installGiftWallet(wallet) {
// once scanned, so an un-synced wallet doesn't mislabel everything as claimed.)
claimedGifts() {
if (!this.loaded) return [];
+ this._pruneForeignGifts();
const live = new Set(this.utxos.map((u) => utxoId(u)));
return Object.values(this.giftRecords())
.filter((r) => !r.revoked && r.outpoints && !r.outpoints.some((o) => live.has(o)))
diff --git a/src/wallet.js b/src/wallet.js
index 9502700..d94b56f 100644
--- a/src/wallet.js
+++ b/src/wallet.js
@@ -192,6 +192,7 @@ export class Wallet {
this._addrCache.clear();
this._reserved = null; // gift coins set aside from spending (lazy-loaded)
this._reclaimed = null; // gift coins freed for spending but link still live
+ this._giftRecords = null; // gift links this wallet issued (lazy-loaded)
this._savedAt = 0;
try {
for (const fn of this._loadHooks) { try { fn({ spFresh, netName, offline }); } catch {} }