Add FeeTargetAvarageTimeFrameHours
MODIFY
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/CoinJoinProfileViewModel.cs
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/CoinJoinProfileViewModel.cs
using Avalonia.Media;
-using WalletWasabi.Fluent.Helpers;
+using WalletWasabi.Blockchain.Keys;
namespace WalletWasabi.Fluent.ViewModels.CoinJoinProfiles;
-public class CoinJoinProfileViewModel : ViewModelBase
+public abstract class CoinJoinProfileViewModel : ViewModelBase
{
- public string Title { get; }
- public string Description { get; }
- public IImage Icon { get; }
+ public abstract string Title { get; }
+ public abstract string Description { get; }
+ public abstract IImage Icon { get; }
- public CoinJoinProfileViewModel(string title, string description)
- {
- Title = title;
- Description = description;
- Icon = AssetHelpers.GetBitmapAsset($"avares://WalletWasabi.Fluent/Assets/PasswordFinder/{ThemeHelper.CurrentTheme}/numbers.png");
- }
+ public virtual int MinAnonScoreTarget { get; } = 5;
+
+ public virtual int MaxAnonScoreTarget { get; } = 10;
+ public abstract int FeeTargetAvarageTimeFrameHours { get; }
}

MODIFY
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/CoinJoinProfilesViewModel.cs
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/CoinJoinProfilesViewModel.cs
using ReactiveUI;
+using System.Collections.Generic;
using System.Reactive.Disposables;
using WalletWasabi.Blockchain.Keys;
using WalletWasabi.Fluent.ViewModels.AddWallet;
@@ -9,14 +10,34 @@ namespace WalletWasabi.Fluent.ViewModels.CoinJoinProfiles;
[NavigationMetaData(Title = "CoinJoin Profiles")]
public partial class CoinJoinProfilesViewModel : RoutableViewModel
{
+ [AutoNotify] private CoinJoinProfileViewModel _selectedProfile;
+
public CoinJoinProfilesViewModel(KeyManager keyManager)
{
NextCommand = ReactiveCommand.Create(() => OnNext(keyManager));
EnableBack = true;
+
+ var privateProfile = new PrivateCoinJoinProfile();
+
+ Profiles = new()
+ {
+ new SpeedyCoinJoinProfile(),
+ new EconomyCoinJoinProfile(),
+ privateProfile
+ };
+
+ _selectedProfile = privateProfile;
}
+ public List<CoinJoinProfileViewModel> Profiles { get; }
+
private void OnNext(KeyManager keyManager)
{
+ var selected = SelectedProfile;
+
+ keyManager.SetAnonScoreTargets(selected.MinAnonScoreTarget, selected.MaxAnonScoreTarget, toFile: false);
+ keyManager.SetFeeTargetAvarageTimeFrame(selected.FeeTargetAvarageTimeFrameHours, toFile: false);
+
Navigate().To(new AddedWalletPageViewModel(keyManager));
}

ADD
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/EconomyCoinJoinProfile.cs
+using Avalonia.Media;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Fluent.Helpers;
+
+namespace WalletWasabi.Fluent.ViewModels.CoinJoinProfiles;
+
+internal class EconomyCoinJoinProfile : CoinJoinProfileViewModel
+{
+ public override string Title => "Speedy";
+
+ public override string Description => "very speedy";
+
+ public override IImage Icon => AssetHelpers.GetBitmapAsset($"avares://WalletWasabi.Fluent/Assets/PasswordFinder/{ThemeHelper.CurrentTheme}/numbers.png");
+
+ public override int FeeTargetAvarageTimeFrameHours => 168; // One week avarage.
+}

ADD
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/PrivateCoinJoinProfile.cs
+using Avalonia.Media;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Fluent.Helpers;
+
+namespace WalletWasabi.Fluent.ViewModels.CoinJoinProfiles;
+
+internal class PrivateCoinJoinProfile : CoinJoinProfileViewModel
+{
+ public override string Title => "Speedy";
+
+ public override string Description => "very speedy";
+
+ public override IImage Icon => AssetHelpers.GetBitmapAsset($"avares://WalletWasabi.Fluent/Assets/PasswordFinder/{ThemeHelper.CurrentTheme}/numbers.png");
+ public override int MinAnonScoreTarget => 50;
+ public override int MaxAnonScoreTarget => 100;
+
+ public override int FeeTargetAvarageTimeFrameHours => 0;
+}

ADD
WalletWasabi.Fluent/ViewModels/CoinJoinProfiles/SpeedyCoinJoinProfile.cs
+using Avalonia.Media;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WalletWasabi.Fluent.Helpers;
+
+namespace WalletWasabi.Fluent.ViewModels.CoinJoinProfiles;
+
+internal class SpeedyCoinJoinProfile : CoinJoinProfileViewModel
+{
+ public override string Title => "Speedy";
+
+ public override string Description => "very speedy";
+
+ public override IImage Icon => AssetHelpers.GetBitmapAsset($"avares://WalletWasabi.Fluent/Assets/PasswordFinder/{ThemeHelper.CurrentTheme}/numbers.png");
+
+ public override int FeeTargetAvarageTimeFrameHours => 0;
+}

MODIFY
WalletWasabi.Fluent/Views/CoinJoinProfiles/CoinJoinProfilesView.axaml
WalletWasabi.Fluent/Views/CoinJoinProfiles/CoinJoinProfilesView.axaml
xmlns:vm="using:WalletWasabi.Fluent.ViewModels.CoinJoinProfiles"
xmlns:c="using:WalletWasabi.Fluent.Controls"
xmlns:conv="using:WalletWasabi.Fluent.Converters"
+ xmlns:prof="clr-namespace:WalletWasabi.Fluent.Views.CoinJoinProfiles"
mc:Ignorable="d" d:DesignWidth="428" d:DesignHeight="371"
x:DataType="vm:CoinJoinProfilesViewModel"
x:CompileBindings="True"
EnableBack="{Binding EnableBack}"
NextContent="Continue" EnableNext="True"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
+ <ListBox Items="{Binding Profiles}" SelectedItem="{Binding SelectedProfile}">
+ <ListBox.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapPanel Orientation="Horizontal" />
+ </ItemsPanelTemplate>
+ </ListBox.ItemsPanel>
+ <ListBox.DataTemplates>
+ <DataTemplate DataType="vm:CoinJoinProfileViewModel">
+ <c:SuggestionItem>
+ <prof:CoinJoinProfileControl />
+ </c:SuggestionItem>
+ </DataTemplate>
+ </ListBox.DataTemplates>
+ </ListBox>
</c:ContentArea>
</UserControl>

MODIFY
WalletWasabi/Blockchain/Keys/KeyManager.cs
WalletWasabi/Blockchain/Keys/KeyManager.cs
@@ -26,6 +26,7 @@ public class KeyManager
public const int DefaultMinAnonScoreTarget = 5;
public const int DefaultMaxAnonScoreTarget = 10;
public const bool DefaultAutoCoinjoin = false;
+ public const int DefaultFeeTargetAvarageTimeFrameHours = 24;
public const int AbsoluteMinGapLimit = 21;
public const int MaxGapLimit = 10_000;
@@ -162,6 +163,9 @@ public class KeyManager
[JsonProperty(Order = 14, PropertyName = "MaxAnonScoreTarget")]
public int MaxAnonScoreTarget { get; private set; } = DefaultMaxAnonScoreTarget;
+ [JsonProperty(Order = 15, PropertyName = "FeeTargetAvarageTimeFrameHours")]
+ public int FeeTargetAvarageTimeFrameHours { get; private set; } = DefaultFeeTargetAvarageTimeFrameHours;
+
[JsonProperty(Order = 999)]
private List<HdPubKey> HdPubKeys { get; }
@@ -695,7 +699,7 @@ public class KeyManager
SetIcon(type.ToString());
}
- public void SetAnonScoreTargets(int minAnonScoreTarget, int maxAnonScoreTarget)
+ public void SetAnonScoreTargets(int minAnonScoreTarget, int maxAnonScoreTarget, bool toFile = true)
{
if (maxAnonScoreTarget <= minAnonScoreTarget)
{
@@ -704,8 +708,20 @@ public class KeyManager
MinAnonScoreTarget = minAnonScoreTarget;
MaxAnonScoreTarget = maxAnonScoreTarget;
+ if (toFile)
+ {
ToFile();
}
+ }
+
+ public void SetFeeTargetAvarageTimeFrame(int hours, bool toFile = true)
+ {
+ FeeTargetAvarageTimeFrameHours = hours;
+ if (toFile)
+ {
+ ToFile();
+ }
+ }
public void AssertNetworkOrClearBlockState(Network expectedNetwork)
{

Add FeeTargetAvarageTimeFrameHours