diff options
| author | Adam Soltys <[email protected]> | 2026-06-24 15:13:19 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-24 15:13:19 -0700 |
| commit | 31268770ce5d824eb598b51f0fa159d21239ce2b (patch) | |
| tree | 34c63c2aca2dd961b7b052eb3d0289751ea16ffd /src | |
| parent | bdc5779b425151f47a4f5c93566a9f40f952428d (diff) | |
| download | coinosv3-31268770ce5d824eb598b51f0fa159d21239ce2b.tar.gz coinosv3-31268770ce5d824eb598b51f0fa159d21239ce2b.zip | |
Fix confirmed txs stuck showing "pending"
Two paths left a tx's confirmed flag stale once the balance had already
reconciled:
- The frontier poll re-fetched an address's txs but only appended new
ones (`if (!txs.some(...))`), so a tx that moved from mempool to a
block kept its old pending status. Now it refreshes the record in place.
- On reload, scan() skipped the history re-pull when the cached balance
already matched on-chain, so a stale-pending cached tx never updated.
scan() now also re-pulls history whenever any tx is still pending.
Verified: a cached pending tx that is confirmed on-chain flips to
confirmed (and pending balance clears) after a scan.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/wallet.js | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/src/wallet.js b/src/wallet.js index 4098087..9e7bb32 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -341,7 +341,12 @@ export class Wallet { } const list = await this.api.addressTxs(a.address); for (const tx of list) { - if (!this.txs.some((t) => t.txid === tx.txid)) this.txs.push(this._txSummary(tx)); + const summary = this._txSummary(tx); + const at = this.txs.findIndex((t) => t.txid === tx.txid); + // Refresh in place so a tx that has since confirmed loses its pending + // status — not just append new ones (which left confirmations stale). + if (at >= 0) this.txs[at] = summary; + else this.txs.push(summary); } } @@ -445,7 +450,11 @@ export class Wallet { // balance/addresses actually changed. Idle polls stay /address-only. const balanceChanged = `${this.confirmed}|${this.pending}|${this.nextReceiveIndex}|${this.nextChangeIndex}` !== prevBal; - if (!silent || balanceChanged || !this.loaded) { + // Always re-pull history while any tx is still pending, so confirmations + // get reconciled even when the balance itself hasn't changed (e.g. a + // received coin that simply moved from mempool to a block). + const hasPending = this.txs.some((t) => !t.confirmed); + if (!silent || balanceChanged || !this.loaded || hasPending) { // Balance + receive address are already known from the chain_stats above. // Show them right away so the wallet looks ready, then keep loading the // heavier UTXO set and full history in the background. |
