diff options
| author | Adam Soltys <[email protected]> | 2026-08-03 20:15:16 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-03 20:15:16 -0700 |
| commit | d59d667d3e4c6edb42b8a42fd120a1bdd96a58db (patch) | |
| tree | 0df9efb0d83b805bf284eef3868719426074f214 /src | |
| parent | a7c45156fb49e26f06a359d79240d328d88a00d5 (diff) | |
| download | coinosv3-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.js | 21 | ||||
| -rw-r--r-- | src/wallet.js | 1 |
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 {} } |
