From 6072f6d31a0699ccd2de10d69e54dba5004a8677 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Wed, 29 Nov 2023 10:25:40 +0200 Subject: [PATCH] add master fingerprint to passphrase entry dialog in terminal --- .../sparrow/terminal/PassphraseDialog.java | 77 +++++++++++++++++++ .../terminal/TerminalInteractionServices.java | 7 +- .../sparrow/terminal/wallet/LoadWallet.java | 1 + 3 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/sparrowwallet/sparrow/terminal/PassphraseDialog.java diff --git a/src/main/java/com/sparrowwallet/sparrow/terminal/PassphraseDialog.java b/src/main/java/com/sparrowwallet/sparrow/terminal/PassphraseDialog.java new file mode 100644 index 00000000..92329640 --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/PassphraseDialog.java @@ -0,0 +1,77 @@ +package com.sparrowwallet.sparrow.terminal; + +import com.googlecode.lanterna.TerminalSize; +import com.googlecode.lanterna.gui2.*; +import com.googlecode.lanterna.gui2.dialogs.DialogWindow; +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.wallet.Keystore; +import com.sparrowwallet.drongo.wallet.MnemonicException; + +import java.util.Collections; + +public class PassphraseDialog extends DialogWindow { + private final Label masterFingerprint; + private final TextBox passphrase; + private String result; + + public PassphraseDialog(String walletName, Keystore keystore) { + super("Passphrase for " + walletName); + + setHints(Collections.singleton(Window.Hint.CENTERED)); + + this.masterFingerprint = new Label(""); + this.passphrase = new TextBox(); + this.passphrase.setMask('*'); + + Panel buttonPanel = new Panel(); + buttonPanel.setLayoutManager(new GridLayout(2).setHorizontalSpacing(1)); + buttonPanel.addComponent(new Button(LocalizedString.OK.toString(), this::onOK).setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.CENTER, GridLayout.Alignment.CENTER, true, false))); + buttonPanel.addComponent(new Button(LocalizedString.Cancel.toString(), this::onCancel)); + + Panel mainPanel = new Panel(); + mainPanel.setLayoutManager(new GridLayout(1).setLeftMarginSize(1).setRightMarginSize(1)); + mainPanel.addComponent(new Label("Enter the BIP39 passphrase for keystore:\n" + keystore.getLabel())); + mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); + passphrase.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.FILL, GridLayout.Alignment.CENTER, true, false)).addTo(mainPanel); + mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); + mainPanel.addComponent(masterFingerprint); + mainPanel.addComponent(new EmptySpace(TerminalSize.ONE)); + buttonPanel.setLayoutData(GridLayout.createLayoutData(GridLayout.Alignment.END, GridLayout.Alignment.CENTER, false, false)).addTo(mainPanel); + setComponent(mainPanel); + + passphrase.setTextChangeListener((newText, changedByUserInteraction) -> { + setMasterFingerprintLabel(keystore, newText); + }); + setMasterFingerprintLabel(keystore, ""); + } + + private void onOK() { + result = passphrase.getText(); + close(); + } + + private void onCancel() { + close(); + } + + @Override + public String showDialog(WindowBasedTextGUI textGUI) { + result = null; + super.showDialog(textGUI); + return result; + } + + private void setMasterFingerprintLabel(Keystore keystore, String passphrase) { + masterFingerprint.setText("Master fingerprint: " + Utils.bytesToHex(getMasterFingerprint(keystore, passphrase))); + } + + private byte[] getMasterFingerprint(Keystore keystore, String passphrase) { + try { + Keystore copyKeystore = keystore.copy(); + copyKeystore.getSeed().setPassphrase(passphrase); + return copyKeystore.getExtendedMasterPrivateKey().getKey().getFingerprint(); + } catch(MnemonicException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/terminal/TerminalInteractionServices.java b/src/main/java/com/sparrowwallet/sparrow/terminal/TerminalInteractionServices.java index f8c35c43..1b143f3c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/TerminalInteractionServices.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/TerminalInteractionServices.java @@ -2,7 +2,6 @@ package com.sparrowwallet.sparrow.terminal; import com.googlecode.lanterna.gui2.dialogs.MessageDialogBuilder; import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton; -import com.googlecode.lanterna.gui2.dialogs.TextInputDialogBuilder; import com.sparrowwallet.drongo.wallet.Keystore; import com.sparrowwallet.sparrow.InteractionServices; import javafx.application.Platform; @@ -103,10 +102,8 @@ public class TerminalInteractionServices implements InteractionServices { } private Optional showPassphraseDialog(String walletName, Keystore keystore) { - TextInputDialogBuilder builder = new TextInputDialogBuilder().setTitle("Passphrase for " + walletName); - builder.setDescription("Enter the BIP39 passphrase for keystore:\n" + keystore.getLabel()); - builder.setPasswordInput(true); - String passphrase = builder.build().showDialog(SparrowTerminal.get().getGui()); + PassphraseDialog passphraseDialog = new PassphraseDialog(walletName, keystore); + String passphrase = passphraseDialog.showDialog(SparrowTerminal.get().getGui()); return passphrase == null ? Optional.empty() : Optional.of(passphrase); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/LoadWallet.java b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/LoadWallet.java index 52f92d68..6f6db413 100644 --- a/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/LoadWallet.java +++ b/src/main/java/com/sparrowwallet/sparrow/terminal/wallet/LoadWallet.java @@ -121,6 +121,7 @@ public class LoadWallet implements Runnable { } } catch(Exception e) { log.error("Wallet Error", e); + SparrowTerminal.get().getGuiThread().invokeLater(() -> SparrowTerminal.get().getGui().removeWindow(loadingDialog)); showErrorDialog("Wallet Error", e.getMessage()); } finally { walletAndKey.clear();