From 08217e53065665eb8a1de6d770d0eb586e530d81 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Thu, 11 Jun 2026 11:27:28 +0200 Subject: [PATCH] feat(spv): per-address balance and tx count in sync result --- src/Core/Spv/WalletSynchronizer.cs | 18 ++++++++++++++++++ src/Core/Storage/WalletDocument.cs | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Core/Spv/WalletSynchronizer.cs b/src/Core/Spv/WalletSynchronizer.cs index d84a766..5ab741b 100644 --- a/src/Core/Spv/WalletSynchronizer.cs +++ b/src/Core/Spv/WalletSynchronizer.cs @@ -24,6 +24,7 @@ public sealed class SyncResult public required IReadOnlyList History { get; init; } public required IReadOnlyList Utxos { get; init; } public required IReadOnlyList Addresses { get; init; } + public required IReadOnlyList AddressRows { get; init; } public required IReadOnlyDictionary Transactions { get; init; } } @@ -145,6 +146,22 @@ public sealed class WalletSynchronizer(HdAccount account, ElectrumClient client, return hb.CompareTo(ha); }); + // Saldo e numero di transazioni per singolo indirizzo (vista indirizzi). + var balanceByAddress = utxos + .GroupBy(u => u.Address) + .ToDictionary(g => g.Key, g => g.Sum(u => u.ValueSats)); + var addressRows = tracked + .OrderBy(t => t.IsChange).ThenBy(t => t.Index) + .Select(t => new CachedAddress + { + Address = t.Address.ToString(), + IsChange = t.IsChange, + Index = t.Index, + BalanceSats = balanceByAddress.GetValueOrDefault(t.Address.ToString()), + TxCount = historyByAddress.TryGetValue(t.ScriptHash, out var h) ? h.Count : 0, + }) + .ToList(); + return new SyncResult { TipHeight = tip.Height, @@ -155,6 +172,7 @@ public sealed class WalletSynchronizer(HdAccount account, ElectrumClient client, History = history, Utxos = utxos, Addresses = tracked, + AddressRows = addressRows, Transactions = transactions, }; } diff --git a/src/Core/Storage/WalletDocument.cs b/src/Core/Storage/WalletDocument.cs index 2139f9a..63c0ff8 100644 --- a/src/Core/Storage/WalletDocument.cs +++ b/src/Core/Storage/WalletDocument.cs @@ -79,6 +79,17 @@ public sealed class SyncCache public int NextChangeIndex { get; set; } public List History { get; set; } = []; public List Utxos { get; set; } = []; + public List Addresses { get; set; } = []; +} + +/// Indirizzo scansionato con saldo proprio e numero di transazioni (vista indirizzi). +public sealed class CachedAddress +{ + public required string Address { get; set; } + public bool IsChange { get; set; } + public int Index { get; set; } + public long BalanceSats { get; set; } + public int TxCount { get; set; } } public sealed class CachedTx