Skip to content

Commit

Permalink
Merge branch 'master' into pr/12456
Browse files Browse the repository at this point in the history
  • Loading branch information
molnard committed Feb 16, 2024
2 parents 0ae9356 + a50e243 commit 862336b
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 44 deletions.
2 changes: 1 addition & 1 deletion WalletWasabi.Fluent.Desktop/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static async Task<int> Main(string[] args)

var exitCode = await app.RunAsGuiAsync();

if (exitCode == ExitCode.Ok && (Services.UpdateManager?.DoUpdateOnClose ?? false))
if (exitCode == ExitCode.Ok && Services.UpdateManager.DoUpdateOnClose)
{
Services.UpdateManager.StartInstallingNewVersion();
}
Expand Down
2 changes: 1 addition & 1 deletion WalletWasabi.Fluent/Controls/Dialog.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)

if (this.GetVisualRoot() is TopLevel topLevel)
{
topLevel.AddHandler(PointerPressedEvent, CancelPointerPressed, RoutingStrategies.Tunnel);
topLevel.AddHandler(PointerPressedEvent, CancelPointerPressed, RoutingStrategies.Bubble);
topLevel.AddHandler(KeyDownEvent, CancelKeyDown, RoutingStrategies.Tunnel);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace WalletWasabi.Fluent.ViewModels.Login.PasswordFinder;

[NavigationMetaData(Title = "Password Finder")]
[NavigationMetaData(Title = "Password Finder", NavigationTarget = NavigationTarget.DialogScreen)]
public partial class PasswordFinderIntroduceViewModel : RoutableViewModel
{
private PasswordFinderIntroduceViewModel(IWalletModel wallet)
Expand Down
11 changes: 8 additions & 3 deletions WalletWasabi.Fluent/ViewModels/Wallets/Buy/BuyViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,18 @@ protected override void OnNavigatedTo(bool inHistory, CompositeDisposable dispos
base.OnNavigatedTo(inHistory, disposables);

// Mark Conversation as read for selected order
this.WhenAnyValue(x => x.SelectedOrder)
this.WhenAnyValue(x => x.SelectedOrder, x => x.SelectedOrder.Workflow.Conversation, (order, _) => order)
.WhereNotNull()
.DoAsync(async order => await order.MarkAsReadAsync())
.DoAsync(order => order.MarkAsReadAsync())
.Subscribe()
.DisposeWith(disposables);

MarkNewMessagesFromSelectedOrderAsRead().DisposeWith(disposables);
}

protected override void OnNavigatedFrom(bool isInHistory)
{
base.OnNavigatedFrom(isInHistory);

SelectNewOrderIfAny();
}
Expand Down Expand Up @@ -167,7 +172,7 @@ private async Task InitializeAsync()
EmptyOrder = NewEmptyOrder();
}

SelectedOrder = _orders.FirstOrDefault();
SelectNewOrderIfAny();
}
catch (Exception exception)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@ public partial class AssistantMessageViewModel : MessageViewModel
{
public AssistantMessageViewModel(ChatMessage message) : base(message)
{
UiMessage = message.Text;
string uiMessage = ParseRawMessage(message);
UiMessage = uiMessage;
}

private string ParseRawMessage(ChatMessage message)
{
string raw = message.Text;

// Check if the string starts with '@'
if (raw.StartsWith('@'))
{
// Find the index of the second '@'
int secondAt = raw.IndexOf('@', 1);

if (secondAt != -1 && long.TryParse(raw[1..secondAt], out _))
{
// Take the substring starting after the second '@'
raw = raw[(secondAt + 1)..];
}
}

return raw;
}
}
17 changes: 0 additions & 17 deletions WalletWasabi.Fluent/ViewModels/Wallets/Buy/OrderViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public partial class OrderViewModel : ViewModelBase
[AutoNotify] private bool _isBusy;
[AutoNotify] private bool _isCompleted;
[AutoNotify] private bool _hasUnreadMessages;
[AutoNotify] private bool _isSelected;

private CancellationTokenSource _cts;

Expand Down Expand Up @@ -77,12 +76,6 @@ public OrderViewModel(UiContext uiContext, IWalletModel wallet, Workflow workflo
// TODO: Remove this once we use newer version of DynamicData
HasUnreadMessagesObs.BindTo(this, x => x.HasUnreadMessages);

// Update file on disk
this.WhenAnyValue(x => x.HasUnreadMessages).Where(x => x == false).ToSignal()
.Merge(_messagesList.Connect().ToSignal())
.DoAsync(async _ => await UpdateConversationLocallyAsync(cancellationToken))
.Subscribe();

this.WhenAnyValue(x => x.Workflow.Conversation)
.Do(conversation =>
{
Expand Down Expand Up @@ -186,16 +179,6 @@ private void RefreshMessageList(Conversation conversation)

private void ClearMessageList() => _messagesList.Edit(x => x.Clear());

private Task UpdateConversationLocallyAsync(CancellationToken cancellationToken)
{
if (ConversationId == ConversationId.Empty)
{
return Task.CompletedTask;
}

return _buyAnythingManager.UpdateConversationOnlyLocallyAsync(Workflow.Conversation, cancellationToken);
}

private MessageViewModel CreateMessageViewModel(ChatMessage message)
{
if (message.IsMyMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public CountryStep(Conversation conversation, IReadOnlyList<Country> countries,
protected override IEnumerable<string> BotMessages(Conversation conversation)
{
// Assistant greeting, min order limit
yield return $"Hello, I am your chosen {GetAssistantName(conversation)}.\nFor now we only accept requests for legal goods or services of at least $1,000 USD.";
yield return $"Hello, I am your {GetAssistantName(conversation)}.\nFor now, the MINIMUM ORDER VALUE is $1,000 USD and we only accept requests for LEGAL goods or services.";

// Ask for Location
yield return "If your order involves shipping, provide the destination country. For non-shipping orders, specify your nationality.";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Threading;
using ReactiveUI;
using WalletWasabi.BuyAnything;

namespace WalletWasabi.Fluent.ViewModels.Wallets.Buy.Workflows;
Expand All @@ -12,12 +14,18 @@ public class RequestedItemStep : WorkflowStep<string>
public RequestedItemStep(Conversation conversation, CancellationToken token) : base(conversation, token)
{
Watermark = "Describe here...";

this.WhenAnyValue(x => x.Value)
.Select(text => text?.Length >= MinCharLimit)
.BindTo(this, x => x.IsInputLengthValid);
}

public override int MinCharLimit => 60;

protected override IEnumerable<string> BotMessages(Conversation conversation)
{
// Ask for item to buy
yield return "What do you exactly need? Be as precise as possible for a faster response.";
yield return $"What do you exactly need? Describe it with at least {MinCharLimit} characters and be as precise as possible for a faster response.";
}

protected override Conversation PutValue(Conversation conversation, string value) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -104,6 +105,11 @@ public async Task MarkConversationAsReadAsync(CancellationToken cancellationToke

try
{
if (!Conversation.ChatMessages.Any(x => x.IsUnread))
{
return;
}

Conversation = Conversation.MarkAsRead();

if (Conversation.Id == ConversationId.Empty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public abstract partial class WorkflowStep<TValue> : ReactiveObject, IWorkflowSt
[AutoNotify] private TValue? _value;
[AutoNotify] private bool _isValid;
[AutoNotify] private bool _isBusy;
[AutoNotify] private bool _isInputLengthValid = true;
protected bool _ignored;

public WorkflowStep(Conversation conversation, CancellationToken token, bool isEditing = false)
Expand All @@ -76,12 +77,14 @@ public WorkflowStep(Conversation conversation, CancellationToken token, bool isE
.BindTo(this, x => x.IsValid);

var canExecuteSendCommand =
this.WhenAnyValue(x => x.IsValid, x => x.IsBusy)
.Select(t => t.Item1 && !t.Item2);
this.WhenAnyValue(x => x.IsValid, x => x.IsBusy, x => x.IsInputLengthValid)
.Select(t => t.Item1 && !t.Item2 && t.Item3);

SendCommand = ReactiveCommand.Create(Send, canExecuteSendCommand);
}

public virtual int MinCharLimit => 0;

public bool IsEditing { get; }

public ICommand SendCommand { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ private async Task OnPasteAsync(bool pasteIfInvalid = true)
Uri.IsWellFormedUriString(endPoint, UriKind.Absolute))
{
var payjoinEndPointUri = new Uri(endPoint);
if (!Services.PersistentConfig.UseTor)
if (!Services.Config.UseTor)
{
if (payjoinEndPointUri.DnsSafeHost.EndsWith(".onion", StringComparison.OrdinalIgnoreCase))
{
Expand Down
11 changes: 4 additions & 7 deletions WalletWasabi.Fluent/ViewModels/Wallets/WalletViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,16 @@ protected override void OnNavigatedTo(bool isInHistory, CompositeDisposable disp

private bool GetIsBuyButtonVisible(bool hasBalance, bool hasNonEmptyOrder)
{
var network = UiContext.ApplicationSettings.Network;
#if DEBUG
return true;
#endif

var network = UiContext.ApplicationSettings.Network;
if (network == Network.Main && (hasBalance || hasNonEmptyOrder))
{
return true;
}

#if DEBUG
if (hasBalance || hasNonEmptyOrder)
{
return true;
}
#endif
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@
<Style Selector="ComboBox:pointerover /template/ Border#Background">
<Setter Property="Background" Value="{DynamicResource ChatInputBackground}" />
</Style>
<Style Selector="TextBlock.minLimit">
<Setter Property="Foreground" Value="{DynamicResource WarningMessageForeground}" />
<Setter Property="Opacity" Value="1" />
</Style>
<Style Selector="TextBlock.fade">
<Setter Property="Opacity" Value="0.4" />
</Style>
</ContentControl.Styles>
<ContentControl.DataTemplates>
<!-- Default views for steps that don't require user interaction -->
Expand Down Expand Up @@ -107,10 +114,18 @@

<!-- RequestedItemStep -->
<DataTemplate DataType="vm:RequestedItemStep">
<TextBox VerticalAlignment="Center"
<TextBox Name="RequestTextBox"
VerticalAlignment="Center"
Text="{Binding Value}"
MaxLength="5000"
Watermark="{Binding Watermark}">
<TextBox.InnerRightContent>
<StackPanel ToolTip.Tip="{Binding MinCharLimit, StringFormat={}The minimum character limit is {0}.}" VerticalAlignment="Center" Margin="0 0 15 0" Orientation="Horizontal" Spacing="2">
<TextBlock Classes.fade="{Binding IsInputLengthValid}" Classes.minLimit="{Binding !IsInputLengthValid}" Text="{Binding #RequestTextBox.Text.Length, FallbackValue=0}" />
<TextBlock Classes="fade" Text="/" />
<TextBlock Classes="fade" Text="{Binding #RequestTextBox.MaxLength}" />
</StackPanel>
</TextBox.InnerRightContent>
<i:Interaction.Behaviors>
<behaviors:FocusOnAttachedBehavior />
</i:Interaction.Behaviors>
Expand Down Expand Up @@ -151,6 +166,13 @@
x:Name="TextBox"
MaxLength="5000"
Watermark="{Binding Watermark}">
<TextBox.InnerRightContent>
<StackPanel VerticalAlignment="Center" Margin="0 0 15 0" Orientation="Horizontal" Spacing="2">
<TextBlock Classes="fade" Text="{Binding #TextBox.Text.Length, FallbackValue=0}" />
<TextBlock Classes="fade" Text="/" />
<TextBlock Classes="fade" Text="{Binding #TextBox.MaxLength}" />
</StackPanel>
</TextBox.InnerRightContent>
<i:Interaction.Behaviors>
<behaviors:FocusOnAttachedBehavior />
<DataTriggerBehavior Binding="{Binding IsBusy}" Value="False">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,19 @@ public void TryParseTests()
Assert.Equal("mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP", result.Address.ToString());
Assert.Equal("bolt11_example", result.Label);
Assert.Equal(Money.Coins(0.02m), result.Amount);

// Handling of unknown parameters.
Assert.True(Bip21UriParser.TryParse("bitcoin:mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP?amount=0.02&label=unknown_params&unknown1=1&unknown2=true&unknown3=someValue", Network.TestNet, out result, out error));
Assert.Null(error);
Assert.Equal("mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP", result.Address.ToString());
Assert.Equal("unknown_params", result.Label);
Assert.Equal(Money.Coins(0.02m), result.Amount);
Assert.True(result.UnknownParameters.TryGetValue("unknown1", out string? unknown1));
Assert.Equal("1", unknown1);
Assert.True(result.UnknownParameters.TryGetValue("unknown2", out string? unknown2));
Assert.Equal("true", unknown2);
Assert.True(result.UnknownParameters.TryGetValue("unknown3", out string? unknown3));
Assert.Equal("someValue", unknown3);
}

/// <summary>
Expand Down
8 changes: 1 addition & 7 deletions WalletWasabi/Helpers/HardwareWalletOperationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,7 @@ public static async Task<KeyManager> GenerateWalletAsync(HwiEnumerateEntry devic
KeyManager.GetAccountKeyPath(network, ScriptPubKeyType.Segwit),
genCts.Token).ConfigureAwait(false);

var taprootExtPubKey = await client.GetXpubAsync(
device.Model,
device.Path,
KeyManager.GetAccountKeyPath(network, ScriptPubKeyType.TaprootBIP86),
genCts.Token).ConfigureAwait(false);

return KeyManager.CreateNewHardwareWalletWatchOnly(fingerPrint, segwitExtPubKey, taprootExtPubKey, network, walletFilePath);
return KeyManager.CreateNewHardwareWalletWatchOnly(fingerPrint, segwitExtPubKey, null, network, walletFilePath);
}

public static async Task InitHardwareWalletAsync(HwiEnumerateEntry device, Network network, CancellationToken cancelToken)
Expand Down
4 changes: 4 additions & 0 deletions WalletWasabi/Userfacing/Bip21/Bip21UriParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ public static bool TryParse(string input, Network network, [NotNullWhen(true)] o
error = ErrorUnsupportedReqParameter with { Details = parameterName };
return false;
}
else
{
unknownParameters.Add(parameterName, value);
}
}

result = new(Uri: parsedUri, network, address, amount, Label: label, Message: message, unknownParameters);
Expand Down
6 changes: 6 additions & 0 deletions WalletWasabi/WabiSabi/Client/CoinJoinManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using WalletWasabi.Extensions;
using WalletWasabi.Helpers;
using WalletWasabi.Logging;
using WalletWasabi.WabiSabi.Backend.Models;
using WalletWasabi.WabiSabi.Client.Banning;
using WalletWasabi.WabiSabi.Client.CoinJoinProgressEvents;
using WalletWasabi.WabiSabi.Client.RoundStateAwaiters;
Expand Down Expand Up @@ -544,6 +545,11 @@ private async Task HandleCoinJoinFinalizationAsync(CoinJoinTracker finishedCoinJ
// The fix is already done but the clients have to upgrade.
wallet.LogInfo($"{nameof(CoinJoinClient)} failed with exception: '{e}'");
}
catch (WabiSabiProtocolException wpe) when (wpe.ErrorCode == WabiSabiProtocolErrorCode.WrongPhase)
{
// This can happen when the coordinator aborts the round in Signing phase because of detected double spend.
wallet.LogInfo($"{nameof(CoinJoinClient)} failed with: '{wpe.Message}'");
}
catch (Exception e)
{
wallet.LogError($"{nameof(CoinJoinClient)} failed with exception: '{e}'");
Expand Down

0 comments on commit 862336b

Please sign in to comment.