diff --git a/src/app.cpp b/src/app.cpp index d890ebb..521ea28 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1277,13 +1277,24 @@ void App::render() if (gradient_tex_ != 0) { sbStatus.gradientTexID = gradient_tex_; } - // Count unconfirmed transactions (pending in mempool, not conflicted/orphaned) + // Count unconfirmed transactions (pending in mempool, not conflicted/orphaned). + // A transaction can appear as multiple legs sharing one txid (e.g. an autoshield send+receive), + // and a leg parsed from z_viewtransaction may carry confirmations=0 even when the transaction is + // long confirmed (the other leg holds the real count). So: a txid with ANY confirmed leg is + // confirmed, and we count UNIQUE unconfirmed txids — otherwise the badge sticks on stale 0-conf + // legs of already-confirmed transactions and double-counts multi-leg ones. { - int unconf = 0; + std::unordered_set confirmedTxids; for (const auto& tx : state_.transactions) { - if (tx.confirmations == 0) ++unconf; + if (tx.confirmations >= 1) confirmedTxids.insert(tx.txid); } - sbStatus.unconfirmedTxCount = unconf; + std::unordered_set unconfirmedTxids; + for (const auto& tx : state_.transactions) { + if (tx.confirmations == 0 && confirmedTxids.find(tx.txid) == confirmedTxids.end()) { + unconfirmedTxids.insert(tx.txid); + } + } + sbStatus.unconfirmedTxCount = static_cast(unconfirmedTxids.size()); } // Sidebar margins from ui.toml schema (DPI-scaled like all sidebar values)