encrypt manager menuitem is wallet independent
MODIFY
WalletWasabi.Gui/Shell/Commands/ToolCommands.cs
WalletWasabi.Gui/Shell/Commands/ToolCommands.cs
@@ -25,15 +25,10 @@ namespace WalletWasabi.Gui.Shell.Commands
commandIconService.GetCompletionKindImage("WalletManager"),
ReactiveCommand.Create(OnWalletManager));
- var isWalletLoaded = Global.WhenPropertyChanged
- .Where(x => x.PropertyName == nameof(WalletService)) //looking for the wallet is loaded
- .Select(ws => ws != null) //if it is not null -> wallet is loaded
- .ObserveOn(RxApp.MainThreadScheduler); //syncronize with the UI
-
EncryptionManagerCommand = new CommandDefinition(
"Encryption Manager",
commandIconService.GetCompletionKindImage("EncryptionManager"),
- ReactiveCommand.Create(OnEncryptionManager, isWalletLoaded));
+ ReactiveCommand.Create(OnEncryptionManager));
SettingsCommand = new CommandDefinition(
"Settings",

MODIFY
WalletWasabi.Gui/Tabs/EncryptionManager/SignMessageView.xaml
WalletWasabi.Gui/Tabs/EncryptionManager/SignMessageView.xaml
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
- <controls:ExtendedTextBox Grid.Row="0" Text="{Binding Message}" Watermark="Message" TextWrapping="Wrap" AcceptsReturn="True" Height="400" />
- <controls:ExtendedTextBox Grid.Row="1" Text="{Binding Address}" Watermark="Address" />
+ <controls:ExtendedTextBox Grid.Row="0" Text="{Binding Message}" Watermark="Message" UseFloatingWatermark="True" TextWrapping="Wrap" AcceptsReturn="True" />
+ <controls:ExtendedTextBox Grid.Row="1" Text="{Binding Address}" Watermark="Address" UseFloatingWatermark="True" />
<controls:NoparaPasswordBox Grid.Row="2" Password="{Binding Password}" Watermark="Password" />
- <controls:ExtendedTextBox Grid.Row="3" Text="{Binding Signature}" Watermark="Signature" TextWrapping="Wrap" AcceptsReturn="True" Height="400" />
+ <controls:ExtendedTextBox Grid.Row="3" Text="{Binding Signature}" Watermark="Signature" UseFloatingWatermark="True" TextWrapping="Wrap" AcceptsReturn="True" Height="400" />
<Grid Grid.Row="4">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Text="{Binding WarningMessage}" />

MODIFY
WalletWasabi.Gui/Tabs/EncryptionManager/SignMessageViewModel.cs
WalletWasabi.Gui/Tabs/EncryptionManager/SignMessageViewModel.cs
@@ -3,6 +3,7 @@ using NBitcoin;
using ReactiveUI;
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
using WalletWasabi.Gui.Tabs.EncryptionManager;
using WalletWasabi.Gui.Tabs.WalletManager;
@@ -100,14 +101,18 @@ namespace WalletWasabi.Gui.Tabs.EncryptionManager
{
//https://programmingblockchain.gitbook.io/programmingblockchain/bitcoin_transfer/proof_of_ownership_as_an_authentication_method
password = Guard.Correct(password);
- BitcoinSecret bitcoinPrivateKey = Global.WalletService.KeyManager.EncryptedSecret.GetSecret(password);
- string signature = bitcoinPrivateKey.PrivateKey.SignMessage(message);
+ ExtKey result = Global.WalletService.KeyManager.GetSecrets(password, BitcoinAddress.Create(address, Global.Network)).FirstOrDefault();
+ if (result is null)
+ {
+ throw new InvalidOperationException("Address not found.");
+ }
+ string signature = result.PrivateKey.SignMessage(message);
return signature;
}
private static bool VerifyMessage(string address, string message, string signature)
{
- BitcoinPubKeyAddress addr = new BitcoinPubKeyAddress(address, Global.Network);
+ BitcoinPubKeyAddress addr = new BitcoinPubKeyAddress(address, Global.Network);//TODO: only works for addresses beginning with 1
return addr.VerifyMessage(message, signature);
}
}

MODIFY
WalletWasabi/KeyManagement/KeyManager.cs
WalletWasabi/KeyManagement/KeyManager.cs
@@ -319,6 +319,44 @@ namespace WalletWasabi.KeyManagement
}
}
+ public IEnumerable<ExtKey> GetSecrets(string password, params BitcoinAddress[] addresses)
+ {
+ return GetSecretsAndPubKeyPairs(password, addresses).Select(x => x.secret);
+ }
+
+ public IEnumerable<(ExtKey secret, HdPubKey pubKey)> GetSecretsAndPubKeyPairs(string password, params BitcoinAddress[] addresses)
+ {
+ Key secret;
+ try
+ {
+ secret = EncryptedSecret.GetKey(password);
+ }
+ catch (SecurityException ex)
+ {
+ throw new SecurityException("Invalid password.", ex);
+ }
+ var extKey = new ExtKey(secret, ChainCode);
+ var extKeysAndPubs = new List<(ExtKey secret, HdPubKey pubKey)>();
+
+ var networks = addresses.Select(a => a.Network).Distinct();
+
+ lock (HdPubKeysLock)
+ {
+ foreach (var network in networks)
+ {
+ foreach (HdPubKey key in HdPubKeys.Where(x =>
+ addresses.Contains(x.GetP2wpkhAddress(network))
+ || addresses.Contains(x.GetP2shOverP2wpkhAddress(network))
+ || addresses.Contains(x.GetP2pkhAddress(network))))
+ {
+ ExtKey ek = extKey.Derive(key.FullKeyPath);
+ extKeysAndPubs.Add((ek, key));
+ }
+ }
+ return extKeysAndPubs;
+ }
+ }
+
/// <summary>
/// Make sure there's always clean keys generated and indexed.
/// </summary>

encrypt manager menuitem is wallet independent