initial specter wallet import and export functionality

This commit is contained in:
Craig Raw 2020-09-07 17:23:12 +02:00
parent 7d7c5e5064
commit 0adf94bf62
7 changed files with 100 additions and 6 deletions

2
drongo

@ -1 +1 @@
Subproject commit 10ebfe463d504f39be2aacec41d48c2cf5ba4c56 Subproject commit 70fdecf919ea9dcae46cc35df23e0a20ba90683f

View file

@ -8,6 +8,7 @@ import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.event.WalletExportEvent; import com.sparrowwallet.sparrow.event.WalletExportEvent;
import com.sparrowwallet.sparrow.io.ColdcardMultisig; import com.sparrowwallet.sparrow.io.ColdcardMultisig;
import com.sparrowwallet.sparrow.io.Electrum; import com.sparrowwallet.sparrow.io.Electrum;
import com.sparrowwallet.sparrow.io.Specter;
import com.sparrowwallet.sparrow.io.WalletExport; import com.sparrowwallet.sparrow.io.WalletExport;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
@ -43,9 +44,9 @@ public class WalletExportDialog extends Dialog<Wallet> {
List<WalletExport> exporters; List<WalletExport> exporters;
if(wallet.getPolicyType() == PolicyType.SINGLE) { if(wallet.getPolicyType() == PolicyType.SINGLE) {
exporters = List.of(new Electrum()); exporters = List.of(new Electrum(), new Specter());
} else if(wallet.getPolicyType() == PolicyType.MULTI) { } else if(wallet.getPolicyType() == PolicyType.MULTI) {
exporters = List.of(new ColdcardMultisig(), new Electrum()); exporters = List.of(new ColdcardMultisig(), new Electrum(), new Specter());
} else { } else {
throw new UnsupportedOperationException("Cannot export wallet with policy type " + wallet.getPolicyType()); throw new UnsupportedOperationException("Cannot export wallet with policy type " + wallet.getPolicyType());
} }

View file

@ -31,7 +31,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
stackPane.getChildren().add(anchorPane); stackPane.getChildren().add(anchorPane);
ScrollPane scrollPane = new ScrollPane(); ScrollPane scrollPane = new ScrollPane();
scrollPane.setPrefHeight(320); scrollPane.setPrefHeight(400);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
anchorPane.getChildren().add(scrollPane); anchorPane.getChildren().add(scrollPane);
scrollPane.setFitToWidth(true); scrollPane.setFitToWidth(true);
@ -45,7 +45,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
importAccordion.getPanes().add(importPane); importAccordion.getPanes().add(importPane);
} }
List<WalletImport> walletImporters = List.of(new ColdcardMultisig(), new Electrum()); List<WalletImport> walletImporters = List.of(new ColdcardMultisig(), new Electrum(), new Specter());
for(WalletImport importer : walletImporters) { for(WalletImport importer : walletImporters) {
FileWalletImportPane importPane = new FileWalletImportPane(importer); FileWalletImportPane importPane = new FileWalletImportPane(importer);
importAccordion.getPanes().add(importPane); importAccordion.getPanes().add(importPane);
@ -55,7 +55,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE); final ButtonType cancelButtonType = new javafx.scene.control.ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);
dialogPane.getButtonTypes().addAll(cancelButtonType); dialogPane.getButtonTypes().addAll(cancelButtonType);
dialogPane.setPrefWidth(500); dialogPane.setPrefWidth(500);
dialogPane.setPrefHeight(400); dialogPane.setPrefHeight(480);
setResultConverter(dialogButton -> dialogButton != cancelButtonType ? wallet : null); setResultConverter(dialogButton -> dialogButton != cancelButtonType ? wallet : null);
} }

View file

@ -0,0 +1,93 @@
package com.sparrowwallet.sparrow.io;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.sparrowwallet.drongo.OutputDescriptor;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.drongo.wallet.WalletModel;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class Specter implements WalletImport, WalletExport {
@Override
public void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException {
try {
SpecterWallet specterWallet = new SpecterWallet();
specterWallet.label = wallet.getName();
specterWallet.blockheight = wallet.getStoredBlockHeight();
specterWallet.descriptor = OutputDescriptor.getOutputDescriptor(wallet).toString();
Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
String json = gson.toJson(specterWallet);
outputStream.write(json.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
} catch(Exception e) {
throw new ExportException(e);
}
}
@Override
public String getWalletExportDescription() {
return "Export a Specter wallet that can be read by Specter Desktop using Add new wallet > Import from wallet software";
}
@Override
public String getExportFileExtension() {
return "json";
}
@Override
public String getWalletImportDescription() {
return "Import a Specter wallet created by using the Wallets > Settings > Export to Wallet Software in Specter Desktop";
}
@Override
public Wallet importWallet(InputStream inputStream, String password) throws ImportException {
try {
Gson gson = new Gson();
SpecterWallet specterWallet = gson.fromJson(new InputStreamReader(inputStream), SpecterWallet.class);
if(specterWallet.descriptor != null) {
OutputDescriptor outputDescriptor = OutputDescriptor.getOutputDescriptor(specterWallet.descriptor);
Wallet wallet = outputDescriptor.toWallet();
wallet.setName(specterWallet.label);
if(!wallet.isValid()) {
throw new ImportException("Specter wallet file did not contain a valid wallet");
}
return wallet;
}
} catch(Exception e) {
throw new ImportException(e);
}
throw new ImportException("Could not import Specter wallet");
}
@Override
public boolean isEncrypted(File file) {
return false;
}
@Override
public String getName() {
return "Specter";
}
@Override
public WalletModel getWalletModel() {
return WalletModel.SPECTER;
}
public static class SpecterWallet {
public String label;
public Integer blockheight;
public String descriptor;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB