Wire up event chain
MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
@@ -165,6 +165,7 @@ public class CoinJoinManager : BackgroundService
}
var coinJoinTracker = coinJoinTrackerFactory.CreateAndStart(walletToStart, coinCandidates, startCommand.RestartAutomatically);
+ coinJoinTracker.WalletCoinJoinProgressChanged += CoinJoinTracker_WalletCoinJoinProgressChanged;
trackedCoinJoins.AddOrUpdate(walletToStart.WalletName, _ => coinJoinTracker, (_, cjt) => cjt);
var registrationTimeout = TimeSpan.MaxValue;
@@ -260,6 +261,7 @@ public class CoinJoinManager : BackgroundService
}
else
{
+ finishedCoinJoin.WalletCoinJoinProgressChanged -= CoinJoinTracker_WalletCoinJoinProgressChanged;
finishedCoinJoin.Dispose();
}
@@ -354,6 +356,11 @@ public class CoinJoinManager : BackgroundService
_ => CompletionStatus.Unknown,
}));
+ private void NotifyCoinJoinStatusChanged(Wallet wallet, CoinJoinProgressEventArgs coinJoinProgressEventArgs) =>
+ StatusChanged.SafeInvoke(this, new CoinJoinStatusEventArgs(
+ wallet,
+ coinJoinProgressEventArgs));
+
private ImmutableDictionary<string, Wallet> GetMixableWallets() =>
WalletManager.GetWallets()
.Where(x => x.State == WalletState.Started // Only running wallets
@@ -410,4 +417,14 @@ public class CoinJoinManager : BackgroundService
}
}
}
+
+ private void CoinJoinTracker_WalletCoinJoinProgressChanged(object? sender, CoinJoinProgressEventArgs e)
+ {
+ if (sender is not Wallet wallet)
+ {
+ throw new InvalidOperationException("Sender must be a wallet.");
+ }
+
+ NotifyCoinJoinStatusChanged(wallet, e);
+ }
}

MODIFY
WalletWasabi/WabiSabi/Client/CoinJoinTracker.cs
WalletWasabi/WabiSabi/Client/CoinJoinTracker.cs
@@ -19,12 +19,16 @@ public class CoinJoinTracker : IDisposable
{
Wallet = wallet;
CoinJoinClient = coinJoinClient;
+ CoinJoinClient.CoinJoinClientProgress += CoinJoinClient_CoinJoinClientProgress;
+
CoinCandidates = coinCandidates;
RestartAutomatically = restartAutomatically;
CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
CoinJoinTask = coinJoinClient.StartCoinJoinAsync(coinCandidates, CancellationTokenSource.Token);
}
+ public event EventHandler<CoinJoinProgressEventArgs>? WalletCoinJoinProgressChanged;
+
private CoinJoinClient CoinJoinClient { get; }
private CancellationTokenSource CancellationTokenSource { get; }
@@ -43,12 +47,18 @@ public class CoinJoinTracker : IDisposable
CancellationTokenSource.Cancel();
}
+ private void CoinJoinClient_CoinJoinClientProgress(object? sender, CoinJoinProgressEventArgs coinJoinProgressEventArgs)
+ {
+ WalletCoinJoinProgressChanged?.Invoke(Wallet, coinJoinProgressEventArgs);
+ }
+
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
+ CoinJoinClient.CoinJoinClientProgress -= CoinJoinClient_CoinJoinClientProgress;
CancellationTokenSource.Dispose();
}

ADD
WalletWasabi/WabiSabi/Client/Events/CoinJoinStatusEventArgs.cs
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Wallets;
+
+namespace WalletWasabi.WabiSabi.Client.Events;
+
+internal class CoinJoinStatusEventArgs : StatusChangedEventArgs
+{
+ public CoinJoinStatusEventArgs(Wallet wallet, CoinJoinProgressEventArgs coinJoinProgressEventArgs) : base(wallet)
+ {
+ CoinJoinProgressEventArgs = coinJoinProgressEventArgs;
+ }
+
+ public CoinJoinProgressEventArgs CoinJoinProgressEventArgs { get; }
+}

Wire up event chain