Add GetPockets method
ADD
WalletWasabi.Fluent/Helpers/CoinPocketHelper.cs
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Blockchain.Analysis.Clustering;
+using WalletWasabi.Blockchain.TransactionOutputs;
+
+namespace WalletWasabi.Fluent.Helpers
+{
+ public static class CoinPocketHelper
+ {
+ public static IEnumerable<(string Labels, ICoinsView Coins)> GetPockets(ICoinsView allCoins)
+ {
+ var clusters = allCoins.GroupBy(x => x.HdPubKey.Cluster.Labels);
+
+ List<(string Labels, ICoinsView Coins)> pockets = new();
+
+ foreach (var cluster in clusters)
+ {
+ string allLabels = cluster.Key.ToString();
+ SmartCoin[] coins = cluster.ToArray();
+
+ if (string.IsNullOrWhiteSpace(allLabels))
+ {
+ // If the Label is empty then add every coin as a separate pocket
+ foreach (var coin in coins)
+ {
+ pockets.Add(new("", new CoinsView(new[] { coin })));
+ }
+ }
+ else
+ {
+ pockets.Add(new(allLabels, new CoinsView(coins)));
+ }
+ }
+ return pockets;
+ }
+ }
+}

MODIFY
WalletWasabi.Tests/UnitTests/Transactions/TransactionProcessorTests.cs
WalletWasabi.Tests/UnitTests/Transactions/TransactionProcessorTests.cs
@@ -9,6 +9,7 @@ using WalletWasabi.Blockchain.Keys;
using WalletWasabi.Blockchain.TransactionOutputs;
using WalletWasabi.Blockchain.TransactionProcessing;
using WalletWasabi.Blockchain.Transactions;
+using WalletWasabi.Fluent.Helpers;
using WalletWasabi.Models;
using WalletWasabi.Tests.Helpers;
using Xunit;
@@ -1069,6 +1070,32 @@ namespace WalletWasabi.Tests.UnitTests.Transactions
Assert.NotEmpty(changeCoin.HdPubKey.Cluster.Labels);
}
+ [Fact]
+ public async Task GetPocketsAsync()
+ {
+ var transactionProcessor = await CreateTransactionProcessorAsync();
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("A").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("A").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("A").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("B").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("C").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("C").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("A, B").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("").P2wpkhScript, Money.Coins(1.0m)));
+ transactionProcessor.Process(CreateCreditingTransaction(transactionProcessor.NewKey("").P2wpkhScript, Money.Coins(1.0m)));
+
+ IEnumerable<(string Labels, ICoinsView Coins)> pockets = CoinPocketHelper.GetPockets(transactionProcessor.Coins);
+ (string Labels, ICoinsView Coins) aPocket = pockets.Single(x => x.Labels == "A");
+ Assert.Equal(3, aPocket.Coins.Count());
+ Assert.Equal(Money.Coins(3.0m), aPocket.Coins.TotalAmount());
+ Assert.Single(pockets.Single(x => x.Labels == "B").Coins);
+ Assert.Equal(2, pockets.Single(x => x.Labels == "C").Coins.Count());
+ Assert.Single(pockets.Single(x => x.Labels == "A, B").Coins);
+ Assert.Equal(4, pockets.Count(x => x.Labels == ""));
+ }
+
private static SmartTransaction CreateSpendingTransaction(Coin coin, Script? scriptPubKey = null, int height = 0)
{
var tx = Network.RegTest.CreateTransaction();

Add GetPockets method