mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-04 21:36:45 +00:00
hw improvements including arbitrary derivation
This commit is contained in:
parent
a409c28b20
commit
ef5399008f
4 changed files with 95 additions and 4 deletions
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
if(devices.isEmpty()) {
|
||||||
|
getMasterController().showUsbNone();
|
||||||
|
} else {
|
||||||
getMasterController().showUsbDevices(devices);
|
getMasterController().showUsbDevices(devices);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
enumerateService.setOnFailed(workerStateEvent -> {
|
enumerateService.setOnFailed(workerStateEvent -> {
|
||||||
getMasterController().showUsbError(enumerateService.getException().getMessage());
|
getMasterController().showUsbError(enumerateService.getException().getMessage());
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in a new issue