From a9ab4d6c788038b29ec46ac6ec82929e31cd21ef Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Thu, 17 Jun 2021 14:34:11 +0200 Subject: [PATCH] Handle importing a wallet from a crypto-account QR using the File > Import Wallet dialog --- .../control/FileWalletKeystoreImportPane.java | 64 ++++++++++++++----- .../sparrow/wallet/WalletForm.java | 4 +- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java index 61aea405..0aa9c9e8 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileWalletKeystoreImportPane.java @@ -1,6 +1,7 @@ package com.sparrowwallet.sparrow.control; import com.google.common.io.ByteStreams; +import com.google.common.io.Files; import com.google.gson.JsonParseException; import com.sparrowwallet.drongo.policy.Policy; import com.sparrowwallet.drongo.policy.PolicyType; @@ -27,6 +28,8 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.List; +import java.util.stream.Collectors; public class FileWalletKeystoreImportPane extends FileImportPane { private static final Logger log = LoggerFactory.getLogger(FileWalletKeystoreImportPane.class); @@ -42,35 +45,62 @@ public class FileWalletKeystoreImportPane extends FileImportPane { protected void importFile(String fileName, InputStream inputStream, String password) throws ImportException { this.fileName = fileName; - try { - fileBytes = ByteStreams.toByteArray(inputStream); - } catch(IOException e) { - throw new ImportException("Could not read file", e); + + List scriptTypes = ScriptType.getAddressableScriptTypes(PolicyType.SINGLE); + if(wallets != null && !wallets.isEmpty()) { + if(wallets.size() == 1 && scriptTypes.contains(wallets.get(0).getScriptType())) { + Wallet wallet = wallets.get(0); + wallet.setPolicyType(PolicyType.SINGLE); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, wallet.getScriptType(), wallet.getKeystores(), null)); + wallet.setName(importer.getName()); + EventManager.get().post(new WalletImportEvent(wallets.get(0))); + } else { + scriptTypes.retainAll(wallets.stream().map(Wallet::getScriptType).collect(Collectors.toList())); + if(scriptTypes.isEmpty()) { + throw new ImportException("No singlesig script types present in QR code"); + } + } + } else { + try { + fileBytes = ByteStreams.toByteArray(inputStream); + } catch(IOException e) { + throw new ImportException("Could not read file", e); + } } - setContent(getScriptTypeEntry()); + setContent(getScriptTypeEntry(scriptTypes)); setExpanded(true); importButton.setDisable(true); } private void importWallet(ScriptType scriptType) throws ImportException { - ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes); - Keystore keystore = importer.getKeystore(scriptType, bais, ""); + if(wallets != null && !wallets.isEmpty()) { + Wallet wallet = wallets.stream().filter(wallet1 -> wallet1.getScriptType() == scriptType).findFirst().orElseThrow(ImportException::new); + wallet.setName(importer.getName()); + wallet.setPolicyType(PolicyType.SINGLE); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, wallet.getScriptType(), wallet.getKeystores(), null)); + EventManager.get().post(new WalletImportEvent(wallet)); + } else { + ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes); + Keystore keystore = importer.getKeystore(scriptType, bais, ""); - Wallet wallet = new Wallet(); - wallet.setName(fileName); - wallet.setPolicyType(PolicyType.SINGLE); - wallet.setScriptType(scriptType); - wallet.getKeystores().add(keystore); - wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), null)); + Wallet wallet = new Wallet(); + wallet.setName(Files.getNameWithoutExtension(fileName)); + wallet.setPolicyType(PolicyType.SINGLE); + wallet.setScriptType(scriptType); + wallet.getKeystores().add(keystore); + wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), null)); - EventManager.get().post(new WalletImportEvent(wallet)); + EventManager.get().post(new WalletImportEvent(wallet)); + } } - private Node getScriptTypeEntry() { + private Node getScriptTypeEntry(List scriptTypes) { Label label = new Label("Script Type:"); - ComboBox scriptTypeComboBox = new ComboBox<>(FXCollections.observableArrayList(ScriptType.getAddressableScriptTypes(PolicyType.SINGLE))); - scriptTypeComboBox.setValue(ScriptType.P2WPKH); + ComboBox scriptTypeComboBox = new ComboBox<>(FXCollections.observableArrayList(scriptTypes)); + if(scriptTypes.contains(ScriptType.P2WPKH)) { + scriptTypeComboBox.setValue(ScriptType.P2WPKH); + } HelpLabel helpLabel = new HelpLabel(); helpLabel.setHelpText("P2WPKH is a Native Segwit type and is usually the best choice for new wallets.\nP2SH-P2WPKH is a Wrapped Segwit type and is a reasonable choice for the widest compatibility.\nP2PKH is a Legacy type and should be avoided for new wallets.\nFor existing wallets, be sure to choose the type that matches the wallet you are importing."); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java index a42f0aa5..f6c190fc 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletForm.java @@ -461,7 +461,9 @@ public class WalletForm { public void walletTabsClosed(WalletTabsClosedEvent event) { for(WalletTabData tabData : event.getClosedWalletTabData()) { if(tabData.getWalletForm() == this) { - storage.close(); + if(wallet.isMasterWallet()) { + storage.close(); + } if(wallet.isValid()) { AppServices.clearTransactionHistoryCache(wallet); }