mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
use json persistence for sparrow wallet export, add sparrow wallet import to wallets dir
This commit is contained in:
parent
8914acff68
commit
9ebabecfbe
5 changed files with 66 additions and 19 deletions
|
@ -858,10 +858,6 @@ public class AppServices {
|
||||||
deviceEnumerateService = createDeviceEnumerateService();
|
deviceEnumerateService = createDeviceEnumerateService();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(deviceEnumerateService.isRunning()) {
|
|
||||||
deviceEnumerateService.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(deviceEnumerateService.getState() == Worker.State.CANCELLED) {
|
if(deviceEnumerateService.getState() == Worker.State.CANCELLED) {
|
||||||
deviceEnumerateService.reset();
|
deviceEnumerateService.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,7 @@ import com.sparrowwallet.sparrow.event.StorageEvent;
|
||||||
import com.sparrowwallet.sparrow.event.TimedEvent;
|
import com.sparrowwallet.sparrow.event.TimedEvent;
|
||||||
import com.sparrowwallet.sparrow.event.WalletExportEvent;
|
import com.sparrowwallet.sparrow.event.WalletExportEvent;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
import com.sparrowwallet.sparrow.io.CoboVaultMultisig;
|
import com.sparrowwallet.sparrow.io.*;
|
||||||
import com.sparrowwallet.sparrow.io.PassportMultisig;
|
|
||||||
import com.sparrowwallet.sparrow.io.Storage;
|
|
||||||
import com.sparrowwallet.sparrow.io.WalletExport;
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Control;
|
import javafx.scene.control.Control;
|
||||||
|
@ -83,8 +80,8 @@ public class FileWalletExportPane extends TitledDescriptionPane {
|
||||||
FileChooser fileChooser = new FileChooser();
|
FileChooser fileChooser = new FileChooser();
|
||||||
fileChooser.setTitle("Export " + exporter.getWalletModel().toDisplayString() + " File");
|
fileChooser.setTitle("Export " + exporter.getWalletModel().toDisplayString() + " File");
|
||||||
String extension = exporter.getExportFileExtension(wallet);
|
String extension = exporter.getExportFileExtension(wallet);
|
||||||
fileChooser.setInitialFileName(wallet.getName() + "-" +
|
fileChooser.setInitialFileName(wallet.getName() +
|
||||||
exporter.getWalletModel().toDisplayString().toLowerCase().replace(" ", "") +
|
(exporter instanceof Sparrow ? "" : "-" + exporter.getWalletModel().toDisplayString().toLowerCase().replace(" ", "")) +
|
||||||
(extension == null || extension.isEmpty() ? "" : "." + extension));
|
(extension == null || extension.isEmpty() ? "" : "." + extension));
|
||||||
|
|
||||||
AppServices.moveToActiveWindowScreen(window, 800, 450);
|
AppServices.moveToActiveWindowScreen(window, 800, 450);
|
||||||
|
@ -137,7 +134,7 @@ public class FileWalletExportPane extends TitledDescriptionPane {
|
||||||
QRDisplayDialog qrDisplayDialog;
|
QRDisplayDialog qrDisplayDialog;
|
||||||
if(exporter instanceof CoboVaultMultisig) {
|
if(exporter instanceof CoboVaultMultisig) {
|
||||||
qrDisplayDialog = new QRDisplayDialog(RegistryType.BYTES.toString(), outputStream.toByteArray(), true);
|
qrDisplayDialog = new QRDisplayDialog(RegistryType.BYTES.toString(), outputStream.toByteArray(), true);
|
||||||
} else if(exporter instanceof PassportMultisig) {
|
} else if(exporter instanceof PassportMultisig || exporter instanceof KeystoneMultisig) {
|
||||||
qrDisplayDialog = new QRDisplayDialog(RegistryType.BYTES.toString(), outputStream.toByteArray(), false);
|
qrDisplayDialog = new QRDisplayDialog(RegistryType.BYTES.toString(), outputStream.toByteArray(), false);
|
||||||
} else {
|
} else {
|
||||||
qrDisplayDialog = new QRDisplayDialog(outputStream.toString(StandardCharsets.UTF_8));
|
qrDisplayDialog = new QRDisplayDialog(outputStream.toString(StandardCharsets.UTF_8));
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class WalletImportDialog extends Dialog<Wallet> {
|
||||||
importAccordion.getPanes().add(importPane);
|
importAccordion.getPanes().add(importPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WalletImport> walletImporters = List.of(new ColdcardMultisig(), new CoboVaultMultisig(), new Electrum(), new KeystoneMultisig(), new SpecterDesktop(), new BlueWalletMultisig());
|
List<WalletImport> walletImporters = List.of(new ColdcardMultisig(), new CoboVaultMultisig(), new Electrum(), new KeystoneMultisig(), new SpecterDesktop(), new BlueWalletMultisig(), new Sparrow());
|
||||||
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);
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
package com.sparrowwallet.sparrow.io;
|
package com.sparrowwallet.sparrow.io;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletModel;
|
import com.sparrowwallet.drongo.wallet.WalletModel;
|
||||||
import com.sparrowwallet.sparrow.AppServices;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
public class Sparrow implements WalletExport {
|
public class Sparrow implements WalletImport, WalletExport {
|
||||||
private static final Logger log = LoggerFactory.getLogger(Sparrow.class);
|
private static final Logger log = LoggerFactory.getLogger(Sparrow.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,8 +30,14 @@ public class Sparrow implements WalletExport {
|
||||||
public void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException {
|
public void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException {
|
||||||
try {
|
try {
|
||||||
Storage storage = AppServices.get().getOpenWallets().get(wallet);
|
Storage storage = AppServices.get().getOpenWallets().get(wallet);
|
||||||
storage.copyWallet(outputStream);
|
File tempFile = File.createTempFile(wallet.getName(), null);
|
||||||
|
Storage tempStorage = new Storage(PersistenceType.JSON, tempFile);
|
||||||
|
tempStorage.setKeyDeriver(storage.getKeyDeriver());
|
||||||
|
tempStorage.setEncryptionPubKey(storage.getEncryptionPubKey());
|
||||||
|
tempStorage.saveWallet(wallet);
|
||||||
|
Files.copy(tempStorage.getWalletFile(), outputStream);
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
|
tempStorage.getWalletFile().delete();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
log.error("Error exporting Sparrow wallet file", e);
|
log.error("Error exporting Sparrow wallet file", e);
|
||||||
throw new ExportException("Error exporting Sparrow wallet file", e);
|
throw new ExportException("Error exporting Sparrow wallet file", e);
|
||||||
|
@ -36,13 +46,19 @@ public class Sparrow implements WalletExport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWalletExportDescription() {
|
public String getWalletExportDescription() {
|
||||||
return "Exports a copy of your Sparrow wallet file, which can be loaded in another Sparrow instance running on any supported platform.";
|
return "Exports your Sparrow wallet file, which can be imported into another Sparrow instance running on any supported platform.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getExportFileExtension(Wallet wallet) {
|
public String getExportFileExtension(Wallet wallet) {
|
||||||
|
try {
|
||||||
Storage storage = AppServices.get().getOpenWallets().get(wallet);
|
Storage storage = AppServices.get().getOpenWallets().get(wallet);
|
||||||
return storage.getWalletFileExtension();
|
return storage.isEncrypted() ? "" : PersistenceType.JSON.getExtension();
|
||||||
|
} catch(IOException e) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -54,4 +70,41 @@ public class Sparrow implements WalletExport {
|
||||||
public boolean walletExportRequiresDecryption() {
|
public boolean walletExportRequiresDecryption() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEncrypted(File file) {
|
||||||
|
return Storage.isEncrypted(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWalletImportDescription() {
|
||||||
|
return "Imports an exported Sparrow wallet file into Sparrow's wallets folder.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Wallet importWallet(InputStream inputStream, String password) throws ImportException {
|
||||||
|
File tempFile = null;
|
||||||
|
try {
|
||||||
|
tempFile = File.createTempFile("sparrow", null);
|
||||||
|
java.nio.file.Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
Storage storage = new Storage(PersistenceType.JSON, tempFile);
|
||||||
|
if(!isEncrypted(tempFile)) {
|
||||||
|
return storage.loadUnencryptedWallet().getWallet();
|
||||||
|
} else {
|
||||||
|
return storage.loadEncryptedWallet(password).getWallet();
|
||||||
|
}
|
||||||
|
} catch(IOException | StorageException e) {
|
||||||
|
log.error("Error importing Sparrow wallet", e);
|
||||||
|
throw new ImportException("Error importing Sparrow wallet", e);
|
||||||
|
} finally {
|
||||||
|
if(tempFile != null) {
|
||||||
|
tempFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWalletImportScannable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ public class Storage {
|
||||||
public static final String WALLETS_BACKUP_DIR = "backup";
|
public static final String WALLETS_BACKUP_DIR = "backup";
|
||||||
public static final String CERTS_DIR = "certs";
|
public static final String CERTS_DIR = "certs";
|
||||||
public static final String TEMP_BACKUP_PREFIX = "tmp";
|
public static final String TEMP_BACKUP_PREFIX = "tmp";
|
||||||
|
public static final List<String> RESERVED_WALLET_NAMES = List.of("temp");
|
||||||
|
|
||||||
private Persistence persistence;
|
private Persistence persistence;
|
||||||
private File walletFile;
|
private File walletFile;
|
||||||
|
@ -284,7 +285,7 @@ public class Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return RESERVED_WALLET_NAMES.contains(walletName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getExistingWallet(String walletName) {
|
public static File getExistingWallet(String walletName) {
|
||||||
|
|
Loading…
Reference in a new issue