mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-04 21:36:45 +00:00
software wallet import and airgapped fixes
This commit is contained in:
parent
ae03da257a
commit
7a554df619
16 changed files with 83 additions and 22 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit cbffaf3e416e0d94a01a9c00c99d9f2d61018d1e
|
Subproject commit 019a3cf34f60da053ca7b5540e2bb7bcee6fbd50
|
|
@ -57,11 +57,17 @@ public class DevicePane extends TitledPane {
|
||||||
getStyleClass().add("devicepane");
|
getStyleClass().add("devicepane");
|
||||||
setDefaultStatus();
|
setDefaultStatus();
|
||||||
|
|
||||||
|
removeArrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeArrow() {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Node arrow = this.lookup(".arrow");
|
Node arrow = this.lookup(".arrow");
|
||||||
if (arrow != null) {
|
if (arrow != null) {
|
||||||
arrow.setVisible(false);
|
arrow.setVisible(false);
|
||||||
arrow.setManaged(false);
|
arrow.setManaged(false);
|
||||||
|
} else {
|
||||||
|
removeArrow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.sparrowwallet.sparrow.control;
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
@ -42,11 +43,17 @@ public class KeystoreFileImportPane extends TitledPane {
|
||||||
getStyleClass().add("importpane");
|
getStyleClass().add("importpane");
|
||||||
setContent(getContentBox(importer.getKeystoreImportDescription()));
|
setContent(getContentBox(importer.getKeystoreImportDescription()));
|
||||||
|
|
||||||
|
removeArrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeArrow() {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Node arrow = this.lookup(".arrow");
|
Node arrow = this.lookup(".arrow");
|
||||||
if (arrow != null) {
|
if (arrow != null) {
|
||||||
arrow.setVisible(false);
|
arrow.setVisible(false);
|
||||||
arrow.setManaged(false);
|
arrow.setManaged(false);
|
||||||
|
} else {
|
||||||
|
removeArrow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -133,7 +140,14 @@ public class KeystoreFileImportPane extends TitledPane {
|
||||||
descriptionLabel.getStyleClass().remove("description-label");
|
descriptionLabel.getStyleClass().remove("description-label");
|
||||||
descriptionLabel.getStyleClass().add("description-error");
|
descriptionLabel.getStyleClass().add("description-error");
|
||||||
descriptionLabel.setText("Error Importing [View Details...]");
|
descriptionLabel.setText("Error Importing [View Details...]");
|
||||||
setContent(getContentBox(e.getMessage()));
|
String errorMessage = e.getMessage();
|
||||||
|
if(e.getCause() != null) {
|
||||||
|
errorMessage = e.getCause().getMessage();
|
||||||
|
}
|
||||||
|
if(e instanceof JsonParseException || e.getCause() instanceof JsonParseException) {
|
||||||
|
errorMessage = "File was not in JSON format";
|
||||||
|
}
|
||||||
|
setContent(getContentBox(errorMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,10 +157,14 @@ public class KeystoreFileImportPane extends TitledPane {
|
||||||
details.setWrapText(true);
|
details.setWrapText(true);
|
||||||
|
|
||||||
HBox contentBox = new HBox();
|
HBox contentBox = new HBox();
|
||||||
contentBox.setAlignment(Pos.TOP_RIGHT);
|
contentBox.setAlignment(Pos.TOP_LEFT);
|
||||||
contentBox.getChildren().add(details);
|
contentBox.getChildren().add(details);
|
||||||
contentBox.setPadding(new Insets(10, 30, 10, 30));
|
contentBox.setPadding(new Insets(10, 30, 10, 30));
|
||||||
contentBox.setPrefHeight(60);
|
|
||||||
|
double width = TextUtils.computeTextWidth(details.getFont(), message, 0.0D);
|
||||||
|
double numLines = Math.max(1, width / 400);
|
||||||
|
double height = Math.max(60, numLines * 40);
|
||||||
|
contentBox.setPrefHeight(height);
|
||||||
|
|
||||||
return contentBox;
|
return contentBox;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class KeystoreImportAccordion extends Accordion {
|
||||||
if(importer instanceof KeystoreFileImport) {
|
if(importer instanceof KeystoreFileImport) {
|
||||||
importPane = new KeystoreFileImportPane(this, wallet, (KeystoreFileImport)importer);
|
importPane = new KeystoreFileImportPane(this, wallet, (KeystoreFileImport)importer);
|
||||||
} else if(importer instanceof KeystoreMnemonicImport) {
|
} else if(importer instanceof KeystoreMnemonicImport) {
|
||||||
//TODO:
|
//TODO: Import from the new Bip39KeystoreImport
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Could not create ImportPane for importer of type " + importer.getClass());
|
throw new IllegalArgumentException("Could not create ImportPane for importer of type " + importer.getClass());
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class Electrum implements KeystoreFileImport, SinglesigWalletImport, Mult
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKeystoreImportDescription() {
|
public String getKeystoreImportDescription() {
|
||||||
return "Import from an Electrum wallet";
|
return "Import a single keystore from an Electrum wallet (use File > Import > Electrum to import a multisig wallet)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,12 +45,12 @@ public class Electrum implements KeystoreFileImport, SinglesigWalletImport, Mult
|
||||||
Wallet wallet = importWallet(inputStream);
|
Wallet wallet = importWallet(inputStream);
|
||||||
|
|
||||||
if(!wallet.getPolicyType().equals(PolicyType.SINGLE) || wallet.getKeystores().size() != 1) {
|
if(!wallet.getPolicyType().equals(PolicyType.SINGLE) || wallet.getKeystores().size() != 1) {
|
||||||
throw new ImportException("Multisig wallet detected - import it through the File > Import menu");
|
throw new ImportException("Multisig wallet detected - import it using File > Import > Electrum");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!wallet.getScriptType().equals(scriptType)) {
|
if(!wallet.getScriptType().equals(scriptType)) {
|
||||||
//TODO: Derive appropriate ScriptType keystore
|
//TODO: Derive appropriate ScriptType keystore from xprv if present
|
||||||
throw new ImportException("Wallet has an incompatible script type of " + wallet.getScriptType());
|
throw new ImportException("Wallet has an incompatible script type of " + wallet.getScriptType() + ", and the correct script type cannot be derived without the master private key");
|
||||||
}
|
}
|
||||||
|
|
||||||
return wallet.getKeystores().get(0);
|
return wallet.getKeystores().get(0);
|
||||||
|
@ -88,7 +88,7 @@ public class Electrum implements KeystoreFileImport, SinglesigWalletImport, Mult
|
||||||
keystore.setSource(KeystoreSource.HW_USB);
|
keystore.setSource(KeystoreSource.HW_USB);
|
||||||
keystore.setWalletModel(WalletModel.fromType(ek.hw_type));
|
keystore.setWalletModel(WalletModel.fromType(ek.hw_type));
|
||||||
if(keystore.getWalletModel() == null) {
|
if(keystore.getWalletModel() == null) {
|
||||||
throw new ImportException("Unknown hardware wallet type " + ek.hw_type);
|
throw new ImportException("Wallet has keystore of unknown hardware wallet type \"" + ek.hw_type + "\"");
|
||||||
}
|
}
|
||||||
} else if("bip32".equals(ek.type)) {
|
} else if("bip32".equals(ek.type)) {
|
||||||
if(ek.xprv != null) {
|
if(ek.xprv != null) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import javafx.fxml.FXML;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UsbAirgappedController extends KeystoreImportDetailController {
|
public class HwAirgappedController extends KeystoreImportDetailController {
|
||||||
@FXML
|
@FXML
|
||||||
private KeystoreImportAccordion importAccordion;
|
private KeystoreImportAccordion importAccordion;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import javafx.fxml.FXML;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UsbDevicesController extends KeystoreImportDetailController {
|
public class HwUsbDevicesController extends KeystoreImportDetailController {
|
||||||
@FXML
|
@FXML
|
||||||
private DeviceAccordion deviceAccordion;
|
private DeviceAccordion deviceAccordion;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import javafx.scene.control.Label;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class UsbScanController extends KeystoreImportDetailController {
|
public class HwUsbScanController extends KeystoreImportDetailController {
|
||||||
@FXML
|
@FXML
|
||||||
private Label message;
|
private Label message;
|
||||||
|
|
|
@ -39,19 +39,23 @@ public class KeystoreImportController implements Initializable {
|
||||||
importMenu.selectedToggleProperty().addListener((observable, oldValue, selectedToggle) -> {
|
importMenu.selectedToggleProperty().addListener((observable, oldValue, selectedToggle) -> {
|
||||||
KeystoreSource importType = (KeystoreSource) selectedToggle.getUserData();
|
KeystoreSource importType = (KeystoreSource) selectedToggle.getUserData();
|
||||||
System.out.println(importType);
|
System.out.println(importType);
|
||||||
setImportPane(importType.toString().toLowerCase());
|
String fxmlName = importType.toString().toLowerCase();
|
||||||
|
if(importType == KeystoreSource.SW_SEED || importType == KeystoreSource.SW_WATCH) {
|
||||||
|
fxmlName = "sw";
|
||||||
|
}
|
||||||
|
setImportPane(fxmlName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void showUsbDevices(List<Device> devices) {
|
void showUsbDevices(List<Device> devices) {
|
||||||
FXMLLoader loader = setImportPane("hw_usb-devices");
|
FXMLLoader loader = setImportPane("hw_usb-devices");
|
||||||
UsbDevicesController controller = loader.getController();
|
HwUsbDevicesController controller = loader.getController();
|
||||||
controller.initializeView(devices);
|
controller.initializeView(devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showUsbError(String message) {
|
void showUsbError(String message) {
|
||||||
FXMLLoader loader = setImportPane("hw_usb-error");
|
FXMLLoader loader = setImportPane("hw_usb-error");
|
||||||
UsbScanController controller = loader.getController();
|
HwUsbScanController controller = loader.getController();
|
||||||
controller.initializeView(message);
|
controller.initializeView(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.sparrowwallet.sparrow.keystoreimport;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.control.KeystoreImportAccordion;
|
||||||
|
import com.sparrowwallet.sparrow.external.Electrum;
|
||||||
|
import com.sparrowwallet.sparrow.external.KeystoreImport;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SwController extends KeystoreImportDetailController {
|
||||||
|
@FXML
|
||||||
|
private KeystoreImportAccordion importAccordion;
|
||||||
|
|
||||||
|
public void initializeView() {
|
||||||
|
List<KeystoreImport> importers = List.of(new Electrum());
|
||||||
|
importAccordion.setKeystoreImporters(getMasterController().getWallet(), FXCollections.observableList(importers));
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<?import com.sparrowwallet.sparrow.control.KeystoreImportAccordion?>
|
<?import com.sparrowwallet.sparrow.control.KeystoreImportAccordion?>
|
||||||
|
|
||||||
<AnchorPane stylesheets="@keystoreimport.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sparrowwallet.sparrow.keystoreimport.UsbAirgappedController">
|
<AnchorPane stylesheets="@keystoreimport.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sparrowwallet.sparrow.keystoreimport.HwAirgappedController">
|
||||||
<ScrollPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" fitToWidth="true">
|
<ScrollPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" fitToWidth="true">
|
||||||
<KeystoreImportAccordion fx:id="importAccordion" />
|
<KeystoreImportAccordion fx:id="importAccordion" />
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import com.sparrowwallet.sparrow.control.DeviceAccordion?>
|
<?import com.sparrowwallet.sparrow.control.DeviceAccordion?>
|
||||||
|
|
||||||
<AnchorPane stylesheets="@keystoreimport.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sparrowwallet.sparrow.keystoreimport.UsbDevicesController">
|
<AnchorPane stylesheets="@keystoreimport.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sparrowwallet.sparrow.keystoreimport.HwUsbDevicesController">
|
||||||
<ScrollPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" fitToWidth="true">
|
<ScrollPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" fitToWidth="true">
|
||||||
<DeviceAccordion fx:id="deviceAccordion" />
|
<DeviceAccordion fx:id="deviceAccordion" />
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import org.controlsfx.glyphfont.Glyph?>
|
<?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.UsbScanController">
|
<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" />
|
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="50" icon="EXCLAMATION_CIRCLE" />
|
||||||
<Label text="There was error connecting to the wallet:" />
|
<Label text="There was error connecting to the wallet:" />
|
||||||
<Label fx:id="message" />
|
<Label fx:id="message" />
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<?import javafx.scene.image.ImageView?>
|
<?import javafx.scene.image.ImageView?>
|
||||||
<?import org.controlsfx.glyphfont.Glyph?>
|
<?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.UsbScanController">
|
<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 Brands Regular" fontSize="50" icon="USB" />
|
<Glyph fontFamily="Font Awesome 5 Brands Regular" fontSize="50" icon="USB" />
|
||||||
<Label fx:id="message" text="Connect Hardware Wallet" />
|
<Label fx:id="message" text="Connect Hardware Wallet" />
|
||||||
<Button fx:id="scan" text="Scan..." wrapText="true" prefWidth="120" prefHeight="60" onAction="#scan"/>
|
<Button fx:id="scan" text="Scan..." wrapText="true" prefWidth="120" prefHeight="60" onAction="#scan"/>
|
||||||
|
|
|
@ -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 com.sparrowwallet.sparrow.control.KeystoreImportAccordion?>
|
||||||
|
|
||||||
|
<AnchorPane stylesheets="@keystoreimport.css" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="com.sparrowwallet.sparrow.keystoreimport.SwController">
|
||||||
|
<ScrollPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" fitToWidth="true">
|
||||||
|
<KeystoreImportAccordion fx:id="importAccordion" />
|
||||||
|
</ScrollPane>
|
||||||
|
</AnchorPane>
|
BIN
src/main/resources/image/electrum.png
Normal file
BIN
src/main/resources/image/electrum.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in a new issue