fix(lite): sort lite transactions newest-first to match the UI panels

The lite backend lists transactions oldest-first, but every consumer of
the transaction list assumes newest-first and takes a prefix of it, so
the Recent Transactions / Recent Sends / Recent Received panels and the
CSV export showed the oldest records instead of the latest.

- The UI copy is now sorted pending (0-conf) first, then newest-first by
  timestamp, the same order as the History tab's default.
- The sort is stable, so several records that share a txid (a send entry
  plus its per-note entries, or same-block transactions) keep a
  deterministic order across refreshes. That keeps the order-sensitive
  change check reporting "unchanged" and avoids bumping the transaction
  revision every couple of seconds.

Tests: a new case covers the pending-first, newest-first ordering, a
stable order within one txid, and the revision staying unchanged when
the identical model is re-applied.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 21:42:22 -05:00
co-authored by Claude Opus 4.8
parent e7f084e3eb
commit 5ae5e5213b
2 changed files with 68 additions and 0 deletions
+11
View File
@@ -402,6 +402,17 @@ void applyLiteRefreshModelToWalletState(const LiteWalletAppRefreshModel& model,
}
nextTransactions.push_back(std::move(tx));
}
// The backend lists oldest-first; every consumer of state.transactions (Recent Transactions / Recent Sends /
// Recent Received, CSV export) assumes newest-first. Same key as the History tab's default: pending (0-conf)
// on top, then newest. STABLE: one txid yields several records with the same datetime (send entry + per-note
// entries, same-block txs), and stability keeps their order deterministic across refreshes, so the
// order-sensitive sameTransactionList() still reports "unchanged" and tx_revision is not bumped every 2 s.
std::stable_sort(nextTransactions.begin(), nextTransactions.end(),
[](const TransactionInfo& a, const TransactionInfo& b) {
const bool ap = a.confirmations == 0, bp = b.confirmations == 0;
if (ap != bp) return ap;
return a.timestamp > b.timestamp;
});
state.setTransactionsIfChanged(std::move(nextTransactions));
}