mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-23 20:36:44 +00:00
integrate keystore importer
This commit is contained in:
parent
9af17bcac8
commit
6872e069a9
5 changed files with 75 additions and 8 deletions
|
@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.io;
|
|||
|
||||
import com.google.gson.*;
|
||||
import com.sparrowwallet.drongo.ExtendedKey;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
|
||||
|
@ -22,7 +23,9 @@ public class Storage {
|
|||
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeySerializer());
|
||||
gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeyDeserializer());
|
||||
gson = gsonBuilder.setPrettyPrinting().create();
|
||||
gsonBuilder.registerTypeAdapter(byte[].class, new ByteArraySerializer());
|
||||
gsonBuilder.registerTypeAdapter(byte[].class, new ByteArrayDeserializer());
|
||||
gson = gsonBuilder.setPrettyPrinting().disableHtmlEscaping().create();
|
||||
}
|
||||
|
||||
public static Storage getStorage() {
|
||||
|
@ -76,7 +79,7 @@ public class Storage {
|
|||
}
|
||||
|
||||
private static byte[] getEncryptionMagic() {
|
||||
return "BIE1".getBytes(StandardCharsets.UTF_8);
|
||||
return "SPRW1".getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public File getWalletFile(String walletName) {
|
||||
|
@ -84,7 +87,12 @@ public class Storage {
|
|||
}
|
||||
|
||||
public File getWalletsDir() {
|
||||
return new File(getSparrowDir(), WALLETS_DIR);
|
||||
File walletsDir = new File(getSparrowDir(), WALLETS_DIR);
|
||||
if(!walletsDir.exists()) {
|
||||
walletsDir.mkdirs();
|
||||
}
|
||||
|
||||
return walletsDir;
|
||||
}
|
||||
|
||||
private File getSparrowDir() {
|
||||
|
@ -108,4 +116,18 @@ public class Storage {
|
|||
return ExtendedKey.fromDescriptor(json.getAsJsonPrimitive().getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ByteArraySerializer implements JsonSerializer<byte[]> {
|
||||
@Override
|
||||
public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(Utils.bytesToHex(src));
|
||||
}
|
||||
}
|
||||
|
||||
private static class ByteArrayDeserializer implements JsonDeserializer<byte[]> {
|
||||
@Override
|
||||
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
return Utils.hexToBytes(json.getAsJsonPrimitive().getAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class KeystoreImportDialog extends Dialog<Keystore> {
|
|||
@Subscribe
|
||||
public void keystoreImported(KeystoreImportEvent event) {
|
||||
this.keystore = event.getKeystore();
|
||||
System.out.println(keystore.getLabel() + " " + keystore.getKeyDerivation().getMasterFingerprint());
|
||||
setResult(keystore);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.sparrowwallet.drongo.ExtendedKey;
|
|||
import com.sparrowwallet.drongo.KeyDerivation;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.KeystoreSource;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.keystoreimport.KeystoreImportDialog;
|
||||
import com.sparrowwallet.sparrow.event.SettingsChangedEvent;
|
||||
|
@ -12,6 +13,7 @@ import javafx.event.ActionEvent;
|
|||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Control;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import org.controlsfx.validation.ValidationResult;
|
||||
|
@ -27,6 +29,9 @@ import java.util.stream.Collectors;
|
|||
public class KeystoreController extends WalletFormController implements Initializable {
|
||||
private Keystore keystore;
|
||||
|
||||
@FXML
|
||||
private Label type;
|
||||
|
||||
@FXML
|
||||
private TextField label;
|
||||
|
||||
|
@ -55,6 +60,8 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
public void initializeView() {
|
||||
Platform.runLater(this::setupValidation);
|
||||
|
||||
updateType();
|
||||
|
||||
label.setText(keystore.getLabel());
|
||||
|
||||
if(keystore.getExtendedPublicKey() != null) {
|
||||
|
@ -102,7 +109,7 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
validationSupport.registerValidator(label, Validator.combine(
|
||||
Validator.createEmptyValidator("Label is required"),
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Label is not unique", walletForm.getWallet().getKeystores().stream().filter(k -> k != keystore).map(Keystore::getLabel).collect(Collectors.toList()).contains(newValue)),
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Label is too long", newValue.length() > 16)
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Label is too long", newValue.replace(" ", "").length() > 16)
|
||||
));
|
||||
|
||||
validationSupport.registerValidator(xpub, Validator.combine(
|
||||
|
@ -123,11 +130,43 @@ public class KeystoreController extends WalletFormController implements Initiali
|
|||
validationSupport.setValidationDecorator(new StyleClassValidationDecoration());
|
||||
}
|
||||
|
||||
private void updateType() {
|
||||
type.setText(getTypeLabel(keystore));
|
||||
|
||||
boolean editable = (keystore.getSource() == KeystoreSource.SW_WATCH);
|
||||
label.setEditable(editable);
|
||||
fingerprint.setEditable(editable);
|
||||
derivation.setEditable(editable);
|
||||
xpub.setEditable(editable);
|
||||
}
|
||||
|
||||
private String getTypeLabel(Keystore keystore) {
|
||||
switch (keystore.getSource()) {
|
||||
case HW_USB:
|
||||
return "Connected Hardware Wallet (" + keystore.getWalletModel().toDisplayString() + ")";
|
||||
case HW_AIRGAPPED:
|
||||
return "Airgapped Hardware Wallet (" + keystore.getWalletModel().toDisplayString() + ")";
|
||||
case SW_SEED:
|
||||
return "Software Wallet";
|
||||
case SW_WATCH:
|
||||
default:
|
||||
return "Software Wallet (Watch Only)";
|
||||
}
|
||||
}
|
||||
|
||||
public void importKeystore(ActionEvent event) {
|
||||
KeystoreImportDialog dlg = new KeystoreImportDialog(getWalletForm().getWallet());
|
||||
Optional<Keystore> result = dlg.showAndWait();
|
||||
if(result.isPresent()) {
|
||||
Keystore keystore = result.get();
|
||||
Keystore importedKeystore = result.get();
|
||||
keystore.setSource(importedKeystore.getSource());
|
||||
keystore.setWalletModel(importedKeystore.getWalletModel());
|
||||
keystore.setLabel(importedKeystore.getLabel());
|
||||
keystore.setKeyDerivation(importedKeystore.getKeyDerivation());
|
||||
keystore.setExtendedPublicKey(importedKeystore.getExtendedPublicKey());
|
||||
keystore.setSeed(importedKeystore.getSeed());
|
||||
|
||||
updateType();
|
||||
label.setText(keystore.getLabel());
|
||||
fingerprint.setText(keystore.getKeyDerivation().getMasterFingerprint());
|
||||
derivation.setText(keystore.getKeyDerivation().getDerivationPath());
|
||||
|
|
|
@ -89,9 +89,12 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
|
||||
multisigFieldset.setVisible(policyType.equals(PolicyType.MULTI));
|
||||
if(policyType.equals(PolicyType.MULTI)) {
|
||||
totalKeystores.unbind();
|
||||
totalKeystores.set(0);
|
||||
totalKeystores.bind(multisigControl.highValueProperty());
|
||||
} else {
|
||||
totalKeystores.unbind();
|
||||
totalKeystores.set(0);
|
||||
totalKeystores.set(1);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
</padding>
|
||||
<Form GridPane.columnIndex="0" GridPane.rowIndex="0">
|
||||
<Fieldset inputGrow="SOMETIMES" text="">
|
||||
<Field text="Label:">
|
||||
<TextField fx:id="label" maxWidth="160"/>
|
||||
<Field text="Type:">
|
||||
<Label fx:id="type"/>
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Button text="Import..." onAction="#importKeystore"/>
|
||||
</Field>
|
||||
<Field text="Label:">
|
||||
<TextField fx:id="label" maxWidth="160"/>
|
||||
</Field>
|
||||
<Field text="Master fingerprint:">
|
||||
<TextField fx:id="fingerprint" maxWidth="80"/>
|
||||
</Field>
|
||||
|
|
Loading…
Reference in a new issue