19 changed files with 340 additions and 45 deletions
@ -1 +1 @@ |
|||||
Subproject commit ed056bc49fb919799f70a6d7ee2dd65a38c25b5d |
Subproject commit d740895bd68f0ded97e382e5944feb26fa759875 |
@ -0,0 +1,153 @@ |
|||||
|
package com.sparrowwallet.sparrow.control; |
||||
|
|
||||
|
import com.sparrowwallet.drongo.wallet.Keystore; |
||||
|
import com.sparrowwallet.drongo.wallet.Wallet; |
||||
|
import com.sparrowwallet.sparrow.EventManager; |
||||
|
import com.sparrowwallet.sparrow.event.KeystoreImportEvent; |
||||
|
import com.sparrowwallet.sparrow.external.KeystoreFileImport; |
||||
|
import javafx.application.Platform; |
||||
|
import javafx.geometry.Insets; |
||||
|
import javafx.geometry.Pos; |
||||
|
import javafx.scene.Node; |
||||
|
import javafx.scene.control.Button; |
||||
|
import javafx.scene.control.Label; |
||||
|
import javafx.scene.control.TitledPane; |
||||
|
import javafx.scene.image.Image; |
||||
|
import javafx.scene.image.ImageView; |
||||
|
import javafx.scene.layout.HBox; |
||||
|
import javafx.scene.layout.Priority; |
||||
|
import javafx.scene.layout.VBox; |
||||
|
import javafx.stage.FileChooser; |
||||
|
import javafx.stage.Stage; |
||||
|
import org.controlsfx.control.HyperlinkLabel; |
||||
|
|
||||
|
import java.io.*; |
||||
|
|
||||
|
public class KeystoreFileImportPane extends TitledPane { |
||||
|
private final KeystoreImportAccordion importAccordion; |
||||
|
private final Wallet wallet; |
||||
|
private final KeystoreFileImport importer; |
||||
|
|
||||
|
private Label mainLabel; |
||||
|
private HyperlinkLabel descriptionLabel; |
||||
|
|
||||
|
public KeystoreFileImportPane(KeystoreImportAccordion importAccordion, Wallet wallet, KeystoreFileImport importer) { |
||||
|
this.importAccordion = importAccordion; |
||||
|
this.wallet = wallet; |
||||
|
this.importer = importer; |
||||
|
|
||||
|
setPadding(Insets.EMPTY); |
||||
|
|
||||
|
setGraphic(getTitle()); |
||||
|
getStyleClass().add("importpane"); |
||||
|
setContent(getContentBox(importer.getKeystoreImportDescription())); |
||||
|
|
||||
|
Platform.runLater(() -> { |
||||
|
Node arrow = this.lookup(".arrow"); |
||||
|
if(arrow != null) { |
||||
|
arrow.setVisible(false); |
||||
|
arrow.setManaged(false); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private Node getTitle() { |
||||
|
HBox listItem = new HBox(); |
||||
|
listItem.setPadding(new Insets(10, 20, 10, 10)); |
||||
|
listItem.setSpacing(10); |
||||
|
|
||||
|
HBox imageBox = new HBox(); |
||||
|
imageBox.setMinWidth(50); |
||||
|
imageBox.setMinHeight(50); |
||||
|
listItem.getChildren().add(imageBox); |
||||
|
|
||||
|
Image image = new Image("image/" + importer.getWalletModel().getType() + ".png", 50, 50, true, true); |
||||
|
if (!image.isError()) { |
||||
|
ImageView imageView = new ImageView(); |
||||
|
imageView.setImage(image); |
||||
|
imageBox.getChildren().add(imageView); |
||||
|
} |
||||
|
|
||||
|
VBox labelsBox = new VBox(); |
||||
|
labelsBox.setSpacing(5); |
||||
|
labelsBox.setAlignment(Pos.CENTER_LEFT); |
||||
|
this.mainLabel = new Label(); |
||||
|
mainLabel.setText(importer.getName()); |
||||
|
mainLabel.getStyleClass().add("main-label"); |
||||
|
labelsBox.getChildren().add(mainLabel); |
||||
|
|
||||
|
this.descriptionLabel = new HyperlinkLabel(); |
||||
|
|
||||
|
labelsBox.getChildren().add(descriptionLabel); |
||||
|
descriptionLabel.getStyleClass().add("description-label"); |
||||
|
descriptionLabel.setText("Keystore file import [View Details...]"); |
||||
|
descriptionLabel.setOnAction(event -> { |
||||
|
setExpanded(true); |
||||
|
}); |
||||
|
listItem.getChildren().add(labelsBox); |
||||
|
HBox.setHgrow(labelsBox, Priority.ALWAYS); |
||||
|
|
||||
|
HBox buttonBox = new HBox(); |
||||
|
buttonBox.setAlignment(Pos.CENTER_RIGHT); |
||||
|
|
||||
|
Button importButton = new Button("Import File..."); |
||||
|
importButton.setAlignment(Pos.CENTER_RIGHT); |
||||
|
importButton.setOnAction(event -> { |
||||
|
importFile(); |
||||
|
}); |
||||
|
|
||||
|
buttonBox.getChildren().add(importButton); |
||||
|
listItem.getChildren().add(buttonBox); |
||||
|
|
||||
|
this.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> { |
||||
|
listItem.setPrefWidth(newValue.getWidth()); |
||||
|
}); |
||||
|
|
||||
|
return listItem; |
||||
|
} |
||||
|
|
||||
|
private void importFile() { |
||||
|
Stage window = new Stage(); |
||||
|
|
||||
|
FileChooser fileChooser = new FileChooser(); |
||||
|
fileChooser.setTitle("Open " + importer.getWalletModel().toDisplayString() + " keystore"); |
||||
|
fileChooser.getExtensionFilters().addAll( |
||||
|
new FileChooser.ExtensionFilter("All Files", "*.*"), |
||||
|
new FileChooser.ExtensionFilter("JSON", "*.json") |
||||
|
); |
||||
|
|
||||
|
File file = fileChooser.showOpenDialog(window); |
||||
|
if(file != null) { |
||||
|
importFile(file); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void importFile(File file) { |
||||
|
if(file.exists()) { |
||||
|
try { |
||||
|
InputStream inputStream = new BufferedInputStream(new FileInputStream(file)); |
||||
|
Keystore keystore = importer.getKeystore(wallet.getScriptType(), inputStream); |
||||
|
EventManager.get().post(new KeystoreImportEvent(keystore)); |
||||
|
} catch (Exception e) { |
||||
|
setExpanded(false); |
||||
|
descriptionLabel.getStyleClass().remove("description-label"); |
||||
|
descriptionLabel.getStyleClass().add("description-error"); |
||||
|
descriptionLabel.setText("Error Importing [View Details...]"); |
||||
|
setContent(getContentBox(e.getMessage())); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private Node getContentBox(String message) { |
||||
|
Label details = new Label(message); |
||||
|
details.setWrapText(true); |
||||
|
|
||||
|
HBox contentBox = new HBox(); |
||||
|
contentBox.setAlignment(Pos.TOP_RIGHT); |
||||
|
contentBox.getChildren().add(details); |
||||
|
contentBox.setPadding(new Insets(10, 30, 10, 30)); |
||||
|
contentBox.setPrefHeight(60); |
||||
|
|
||||
|
return contentBox; |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
package com.sparrowwallet.sparrow.control; |
||||
|
|
||||
|
import com.sparrowwallet.drongo.wallet.Wallet; |
||||
|
import com.sparrowwallet.sparrow.external.KeystoreFileImport; |
||||
|
import com.sparrowwallet.sparrow.external.KeystoreImport; |
||||
|
import com.sparrowwallet.sparrow.external.KeystoreMnemonicImport; |
||||
|
import javafx.collections.ObservableList; |
||||
|
import javafx.scene.control.Accordion; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
public class KeystoreImportAccordion extends Accordion { |
||||
|
private List<KeystoreImport> importers; |
||||
|
|
||||
|
public void setKeystoreImporters(Wallet wallet, ObservableList<KeystoreImport> importers) { |
||||
|
this.importers = importers; |
||||
|
|
||||
|
for(KeystoreImport importer : importers) { |
||||
|
KeystoreFileImportPane importPane = null; |
||||
|
|
||||
|
if(importer instanceof KeystoreFileImport) { |
||||
|
importPane = new KeystoreFileImportPane(this, wallet, (KeystoreFileImport)importer); |
||||
|
} else if(importer instanceof KeystoreMnemonicImport) { |
||||
|
//TODO:
|
||||
|
} else { |
||||
|
throw new IllegalArgumentException("Could not create ImportPane for importer of type " + importer.getClass()); |
||||
|
} |
||||
|
|
||||
|
this.getPanes().add(importPane); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
package com.sparrowwallet.sparrow.external; |
||||
|
|
||||
|
import com.sparrowwallet.drongo.protocol.ScriptType; |
||||
|
import com.sparrowwallet.drongo.wallet.Keystore; |
||||
|
|
||||
|
import java.io.InputStream; |
||||
|
|
||||
|
public interface KeystoreFileImport extends KeystoreImport { |
||||
|
Keystore getKeystore(ScriptType scriptType, InputStream inputStream) throws ImportException; |
||||
|
} |
@ -1,13 +1,10 @@ |
|||||
package com.sparrowwallet.sparrow.external; |
package com.sparrowwallet.sparrow.external; |
||||
|
|
||||
import com.sparrowwallet.drongo.policy.PolicyType; |
import com.sparrowwallet.drongo.policy.PolicyType; |
||||
import com.sparrowwallet.drongo.protocol.ScriptType; |
import com.sparrowwallet.drongo.wallet.WalletModel; |
||||
import com.sparrowwallet.drongo.wallet.Keystore; |
|
||||
|
|
||||
import java.io.InputStream; |
|
||||
|
|
||||
public interface KeystoreImport extends Import { |
public interface KeystoreImport extends Import { |
||||
PolicyType getPolicyType(); |
PolicyType getKeystorePolicyType(); |
||||
Keystore getKeystore(ScriptType scriptType, InputStream inputStream) throws ImportException; |
WalletModel getWalletModel(); |
||||
String getKeystoreImportDescription(); |
String getKeystoreImportDescription(); |
||||
} |
} |
||||
|
@ -0,0 +1,8 @@ |
|||||
|
package com.sparrowwallet.sparrow.external; |
||||
|
|
||||
|
import com.sparrowwallet.drongo.protocol.ScriptType; |
||||
|
import com.sparrowwallet.drongo.wallet.Keystore; |
||||
|
|
||||
|
public interface KeystoreMnemonicImport extends KeystoreImport { |
||||
|
Keystore getKeystore(ScriptType scriptType, String[] mnemonicWords, String passphrase) throws ImportException; |
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
package com.sparrowwallet.sparrow.keystoreimport; |
||||
|
|
||||
|
import com.sparrowwallet.drongo.policy.PolicyType; |
||||
|
import com.sparrowwallet.sparrow.control.KeystoreImportAccordion; |
||||
|
import com.sparrowwallet.sparrow.external.ColdcardMultisig; |
||||
|
import com.sparrowwallet.sparrow.external.ColdcardSinglesig; |
||||
|
import com.sparrowwallet.sparrow.external.KeystoreImport; |
||||
|
import javafx.collections.FXCollections; |
||||
|
import javafx.fxml.FXML; |
||||
|
|
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
|
||||
|
public class UsbAirgappedController extends KeystoreImportDetailController { |
||||
|
@FXML |
||||
|
private KeystoreImportAccordion importAccordion; |
||||
|
|
||||
|
public void initializeView() { |
||||
|
List<KeystoreImport> importers = Collections.emptyList(); |
||||
|
if(getMasterController().getWallet().getPolicyType().equals(PolicyType.SINGLE)) { |
||||
|
importers = List.of(new ColdcardSinglesig()); |
||||
|
} else if(getMasterController().getWallet().getPolicyType().equals(PolicyType.MULTI)) { |
||||
|
importers = List.of(new ColdcardMultisig()); |
||||
|
} |
||||
|
|
||||
|
importAccordion.setKeystoreImporters(getMasterController().getWallet(), FXCollections.observableList(importers)); |
||||
|
} |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
<?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.UsbAirgappedController"> |
||||
|
<ScrollPane AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0" fitToWidth="true"> |
||||
|
<KeystoreImportAccordion fx:id="importAccordion" /> |
||||
|
</ScrollPane> |
||||
|
</AnchorPane> |
Loading…
Reference in new issue