hw improvements including arbitrary derivation

This commit is contained in:
Craig Raw 2020-05-08 16:08:15 +02:00
parent a409c28b20
commit ef5399008f
4 changed files with 95 additions and 4 deletions

View file

@ -25,6 +25,10 @@ import org.controlsfx.control.textfield.CustomPasswordField;
import org.controlsfx.control.textfield.CustomTextField; import org.controlsfx.control.textfield.CustomTextField;
import org.controlsfx.control.textfield.TextFields; import org.controlsfx.control.textfield.TextFields;
import org.controlsfx.glyphfont.Glyph; import org.controlsfx.glyphfont.Glyph;
import org.controlsfx.validation.ValidationResult;
import org.controlsfx.validation.ValidationSupport;
import org.controlsfx.validation.Validator;
import org.controlsfx.validation.decoration.StyleClassValidationDecoration;
import java.util.List; import java.util.List;
@ -35,6 +39,7 @@ public class DevicePane extends TitledPane {
private Label mainLabel; private Label mainLabel;
private Label statusLabel; private Label statusLabel;
private Hyperlink showHideLink;
private CustomPasswordField pinField; private CustomPasswordField pinField;
private CustomTextField passphraseField; private CustomTextField passphraseField;
private Button unlockButton; private Button unlockButton;
@ -101,11 +106,34 @@ public class DevicePane extends TitledPane {
mainLabel.getStyleClass().add("main-label"); mainLabel.getStyleClass().add("main-label");
labelsBox.getChildren().add(mainLabel); labelsBox.getChildren().add(mainLabel);
HBox statusBox = new HBox();
statusBox.setSpacing(7);
this.statusLabel = new Label(); this.statusLabel = new Label();
statusLabel.textProperty().bind(status);
labelsBox.getChildren().add(statusLabel);
statusLabel.getStyleClass().add("status-label"); statusLabel.getStyleClass().add("status-label");
statusLabel.textProperty().bind(status);
statusBox.getChildren().add(statusLabel);
showHideLink = new Hyperlink("Show details...");
showHideLink.managedProperty().bind(showHideLink.visibleProperty());
showHideLink.setVisible(false);
showHideLink.setOnAction(event -> {
if(this.isExpanded()) {
setExpanded(false);
} else {
setExpanded(true);
}
});
this.expandedProperty().addListener((observable, oldValue, newValue) -> {
if(newValue) {
showHideLink.setText(showHideLink.getText().replace("Show", "Hide"));
} else {
showHideLink.setText(showHideLink.getText().replace("Hide", "Show"));
}
});
statusBox.getChildren().add(showHideLink);
labelsBox.getChildren().add(statusBox);
listItem.getChildren().add(labelsBox); listItem.getChildren().add(labelsBox);
HBox.setHgrow(labelsBox, Priority.ALWAYS); HBox.setHgrow(labelsBox, Priority.ALWAYS);
@ -388,8 +416,47 @@ public class DevicePane extends TitledPane {
private void showOperationButton() { private void showOperationButton() {
if(deviceAccordion.getDeviceOperation().equals(DeviceAccordion.DeviceOperation.IMPORT)) { if(deviceAccordion.getDeviceOperation().equals(DeviceAccordion.DeviceOperation.IMPORT)) {
importButton.setVisible(true); importButton.setVisible(true);
showHideLink.setText("Show derivation...");
showHideLink.setVisible(true);
setContent(getDerivationEntry(wallet.getScriptType().getDefaultDerivation()));
} else { } else {
//TODO: Support further device operations such as signing //TODO: Support further device operations such as signing
} }
} }
private Node getDerivationEntry(List<ChildNumber> derivation) {
TextField derivationField = new TextField();
derivationField.setPromptText("Derivation path");
derivationField.setText(KeyDerivation.writePath(derivation));
HBox.setHgrow(derivationField, Priority.ALWAYS);
ValidationSupport validationSupport = new ValidationSupport();
validationSupport.registerValidator(derivationField, Validator.combine(
Validator.createEmptyValidator("Derivation is required"),
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Invalid derivation", !KeyDerivation.isValid(newValue))
));
validationSupport.setValidationDecorator(new StyleClassValidationDecoration());
Button importDerivationButton = new Button("Import");
importDerivationButton.setOnAction(event -> {
showHideLink.setVisible(true);
setExpanded(false);
List<ChildNumber> importDerivation = KeyDerivation.parsePath(derivationField.getText());
importXpub(importDerivation);
});
derivationField.textProperty().addListener((observable, oldValue, newValue) -> {
importDerivationButton.setDisable(newValue.isEmpty() || !KeyDerivation.isValid(newValue));
});
HBox contentBox = new HBox();
contentBox.setAlignment(Pos.TOP_RIGHT);
contentBox.setSpacing(20);
contentBox.getChildren().add(derivationField);
contentBox.getChildren().add(importDerivationButton);
contentBox.setPadding(new Insets(10, 30, 10, 30));
contentBox.setPrefHeight(60);
return contentBox;
}
} }

View file

@ -28,7 +28,11 @@ public class HwUsbScanController extends KeystoreImportDetailController {
Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(null); Hwi.EnumerateService enumerateService = new Hwi.EnumerateService(null);
enumerateService.setOnSucceeded(workerStateEvent -> { enumerateService.setOnSucceeded(workerStateEvent -> {
List<Device> devices = enumerateService.getValue(); List<Device> devices = enumerateService.getValue();
getMasterController().showUsbDevices(devices); if(devices.isEmpty()) {
getMasterController().showUsbNone();
} else {
getMasterController().showUsbDevices(devices);
}
}); });
enumerateService.setOnFailed(workerStateEvent -> { enumerateService.setOnFailed(workerStateEvent -> {
getMasterController().showUsbError(enumerateService.getException().getMessage()); getMasterController().showUsbError(enumerateService.getException().getMessage());

View file

@ -57,6 +57,12 @@ public class KeystoreImportController implements Initializable {
controller.initializeView(devices); controller.initializeView(devices);
} }
void showUsbNone() {
FXMLLoader loader = setImportPane("hw_usb-none");
HwUsbScanController controller = loader.getController();
controller.initializeView("No hardware wallets found");
}
void showUsbError(String message) { void showUsbError(String message) {
FXMLLoader loader = setImportPane("hw_usb-error"); FXMLLoader loader = setImportPane("hw_usb-error");
HwUsbScanController controller = loader.getController(); HwUsbScanController controller = loader.getController();

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.glyphfont.Glyph?>
<VBox alignment="CENTER" spacing="30" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sparrowwallet.sparrow.keystoreimport.HwUsbScanController">
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="50" icon="EXCLAMATION_CIRCLE" />
<Label fx:id="message" />
<Button fx:id="scan" text="Scan Again..." wrapText="true" prefWidth="120" prefHeight="60" onAction="#scan"/>
</VBox>