feat(wallet): persist history and surface pending sends

Add an encrypted SQLite transaction history cache with cached tip metadata and
per-address shielded scan progress so startup and full refreshes avoid
re-scanning every z-address while still invalidating on wallet/address/rescan
changes.

Improve wallet history loading by paging transparent transactions, preserving
cached shielded and sent rows, keeping recent/unconfirmed activity visible, and
classifying mining-address receives. Show z_sendmany opid sends immediately in
History and Overview, pin pending rows through refreshes, and apply optimistic
address/balance debits until opids resolve.

Add timestamped RPC console tracing by source/method without logging params or
results, reduce redundant refresh/RPC calls, and cache Explorer recent block
summaries in SQLite.

Expand focused tests for transaction cache encryption, scan-progress
persistence/invalidation, history preservation, operation-status parsing,
pending send visibility, and Explorer/RPC refresh behavior.
This commit is contained in:
2026-05-05 03:22:14 -05:00
parent 948ef419ac
commit 975743f754
43 changed files with 3732 additions and 702 deletions

View File

@@ -482,6 +482,12 @@ void I18n::loadBuiltinEnglish()
strings_["fee_normal"] = "Normal";
strings_["fee_high"] = "High";
strings_["submitting_transaction"] = "Submitting transaction...";
strings_["processing_transaction"] = "Processing transaction...";
strings_["tx_progress_submitting"] = "Submitting transaction to daemon";
strings_["tx_progress_waiting_ops"] = "Waiting for operation (%d)";
strings_["tx_progress_balances"] = "Refreshing balances";
strings_["tx_progress_history"] = "Refreshing history";
strings_["tx_progress_finalizing"] = "Finalizing transaction";
strings_["transaction_sent_msg"] = "Transaction sent!";
strings_["copy_error"] = "Copy Error";
strings_["dismiss"] = "Dismiss";
@@ -509,6 +515,12 @@ void I18n::loadBuiltinEnglish()
// Transactions tab
strings_["no_transactions"] = "No transactions found";
strings_["loading_transactions"] = "Loading transactions";
strings_["tx_loading_queued"] = "Queued transaction refresh";
strings_["tx_loading_enriching_sends"] = "Checking sent transaction details (%d)";
strings_["tx_loading_scanning_shielded"] = "Scanning shielded history (%d addresses)";
strings_["tx_loading_refreshing_cached"] = "Refreshing wallet history (%d cached)";
strings_["tx_loading_fetching_transparent"] = "Fetching transparent history";
strings_["no_matching"] = "No matching transactions";
strings_["transaction_id"] = "TRANSACTION ID";
strings_["search_placeholder"] = "Search...";
@@ -539,6 +551,9 @@ void I18n::loadBuiltinEnglish()
strings_["txs_count"] = "%d txs";
strings_["conf_count"] = "%d conf";
strings_["confirmations_display"] = "%d confirmations | %s";
strings_["mark_mining_address"] = "Mark as mining address";
strings_["unmark_mining_address"] = "Unmark mining address";
strings_["mining_tag"] = " · Mining";
// Balance Tab
strings_["summary"] = "Summary";
@@ -846,11 +861,13 @@ void I18n::loadBuiltinEnglish()
strings_["console_no_daemon"] = "No daemon";
strings_["console_not_connected"] = "Error: Not connected to daemon";
strings_["console_rpc_reference"] = "RPC Command Reference";
strings_["console_rpc_trace"] = "RPC";
strings_["console_search_commands"] = "Search commands...";
strings_["console_select_all"] = "Select All";
strings_["console_show_daemon_output"] = "Show daemon output";
strings_["console_show_errors_only"] = "Show errors only";
strings_["console_show_rpc_ref"] = "Show RPC command reference";
strings_["console_show_rpc_trace"] = "Show app RPC calls";
strings_["console_showing_lines"] = "Showing %zu of %zu lines";
strings_["console_starting_node"] = "Starting node...";
strings_["console_status_error"] = "Error";