From affeaccae899c94c7c3e055c5970af0230881dc0 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Sun, 21 Jun 2026 22:28:28 +0200 Subject: [PATCH] feat(ui): password-gated private key reveal in address detail overlay Replace the direct private-key display in the address detail overlay with a two-step reveal flow: - Unencrypted wallet: clicking Show reveals the WIF key immediately. - Encrypted wallet: clicking Show opens a modal password-prompt overlay; the key is displayed only if the entered password matches the wallet file password; a wrong password shows an inline error without closing the prompt. Hiding the key (Hide button) clears the revealed state. Closing the address overlay or opening a different one always resets both the reveal state and the password prompt, so no sensitive material lingers between sessions. --- .../ViewModels/MainWindowViewModel.Receive.cs | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/App/ViewModels/MainWindowViewModel.Receive.cs b/src/App/ViewModels/MainWindowViewModel.Receive.cs index eda680a..c4f5c2e 100644 --- a/src/App/ViewModels/MainWindowViewModel.Receive.cs +++ b/src/App/ViewModels/MainWindowViewModel.Receive.cs @@ -68,11 +68,81 @@ public partial class MainWindowViewModel [ObservableProperty] private AddressInfo? addressInfo; + [ObservableProperty] + private bool isAddressPrivKeyRevealed; + + // ---- private key password prompt ---- + + [ObservableProperty] + private bool isPrivKeyPromptOpen; + + [ObservableProperty] + private string privKeyPromptPassword = ""; + + [ObservableProperty] + private string privKeyPromptError = ""; + + partial void OnAddressInfoChanged(AddressInfo? value) + { + IsAddressPrivKeyRevealed = false; + ClosePrivKeyPromptInternal(); + } + + private void ClosePrivKeyPromptInternal() + { + IsPrivKeyPromptOpen = false; + PrivKeyPromptPassword = ""; + PrivKeyPromptError = ""; + } + public void ShowAddressInfo(AddressRow row) => AddressInfo = new AddressInfo(Loc, row.Indirizzo, row.DerivPath, row.PubKey, row.PrivKey); [RelayCommand] - private void CloseAddressInfo() => AddressInfo = null; + private void CloseAddressInfo() + { + ClosePrivKeyPromptInternal(); + AddressInfo = null; + } + + [RelayCommand] + private void RequestPrivKeyReveal() + { + if (AddressInfo is null || !AddressInfo.HasPrivKey) return; + if (string.IsNullOrEmpty(_password)) + { + // No encryption: reveal directly + IsAddressPrivKeyRevealed = true; + } + else + { + // Encrypted: open password prompt + PrivKeyPromptPassword = ""; + PrivKeyPromptError = ""; + IsPrivKeyPromptOpen = true; + } + } + + [RelayCommand] + private void ConfirmPrivKeyPassword() + { + if (PrivKeyPromptPassword != _password) + { + PrivKeyPromptError = Loc.Tr("msg.wrongpassword"); + return; + } + IsAddressPrivKeyRevealed = true; + ClosePrivKeyPromptInternal(); + } + + [RelayCommand] + private void CancelPrivKeyPrompt() => ClosePrivKeyPromptInternal(); + + [RelayCommand] + private void HideAddressPrivKey() + { + IsAddressPrivKeyRevealed = false; + } // ---- transaction detail overlay ----