diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index e65eeff5..062140d2 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -7,6 +7,8 @@ import com.sparrowwallet.drongo.BitcoinUnit; import com.sparrowwallet.drongo.Network; import com.sparrowwallet.drongo.SecureString; import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.crypto.EncryptionType; import com.sparrowwallet.drongo.crypto.InvalidPasswordException; import com.sparrowwallet.drongo.crypto.Key; import com.sparrowwallet.drongo.policy.PolicyType; @@ -908,13 +910,13 @@ public class AppController implements Initializable { } private void addImportedWallet(Wallet wallet) { - File walletFile = Storage.getWalletFile(wallet.getName()); + File walletFile = Storage.getExistingWallet(wallet.getName()); - if(walletFile.exists()) { + if(walletFile != null) { Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setTitle("Existing wallet found"); alert.setHeaderText("Replace existing wallet?"); - alert.setContentText("Wallet file " + wallet.getName() + " already exists"); + alert.setContentText("Wallet file " + walletFile.getName() + " already exists.\n"); Optional result = alert.showAndWait(); if(result.isPresent() && result.get() == ButtonType.CANCEL) { return; @@ -931,11 +933,47 @@ public class AppController implements Initializable { } } } + + walletFile.delete(); } - Storage storage = new Storage(walletFile); - Tab tab = addWalletTab(storage, wallet); - tabs.getSelectionModel().select(tab); + Storage storage = new Storage(Storage.getWalletFile(wallet.getName())); + WalletPasswordDialog dlg = new WalletPasswordDialog(WalletPasswordDialog.PasswordRequirement.UPDATE_NEW); + Optional password = dlg.showAndWait(); + if(password.isPresent()) { + if(password.get().length() == 0) { + storage.setEncryptionPubKey(Storage.NO_PASSWORD_KEY); + Tab tab = addWalletTab(storage, wallet); + tabs.getSelectionModel().select(tab); + } else { + Storage.KeyDerivationService keyDerivationService = new Storage.KeyDerivationService(storage, password.get()); + keyDerivationService.setOnSucceeded(workerStateEvent -> { + EventManager.get().post(new StorageEvent(Storage.getWalletFile(wallet.getName()), TimedEvent.Action.END, "Done")); + ECKey encryptionFullKey = keyDerivationService.getValue(); + Key key = null; + + try { + ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey); + key = new Key(encryptionFullKey.getPrivKeyBytes(), storage.getKeyDeriver().getSalt(), EncryptionType.Deriver.ARGON2); + wallet.encrypt(key); + storage.setEncryptionPubKey(encryptionPubKey); + Tab tab = addWalletTab(storage, wallet); + tabs.getSelectionModel().select(tab); + } finally { + encryptionFullKey.clear(); + if(key != null) { + key.clear(); + } + } + }); + keyDerivationService.setOnFailed(workerStateEvent -> { + EventManager.get().post(new StorageEvent(Storage.getWalletFile(wallet.getName()), TimedEvent.Action.END, "Failed")); + showErrorDialog("Error encrypting wallet", keyDerivationService.getException().getMessage()); + }); + EventManager.get().post(new StorageEvent(Storage.getWalletFile(wallet.getName()), TimedEvent.Action.START, "Encrypting wallet...")); + keyDerivationService.start(); + } + } } public void exportWallet(ActionEvent event) { diff --git a/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java b/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java index 8a7ea8db..376dda14 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/FileImportPane.java @@ -158,6 +158,7 @@ public abstract class FileImportPane extends TitledDescriptionPane { HBox.setHgrow(passwordField, Priority.ALWAYS); Button importEncryptedButton = new Button("Import"); + importEncryptedButton.setDefaultButton(true); importEncryptedButton.setOnAction(event -> { showHideLink.setVisible(true); setExpanded(false); diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java index e91a76d6..ddc6c382 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Electrum.java @@ -191,7 +191,7 @@ public class Electrum implements KeystoreFileImport, WalletImport, WalletExport if(blockTransaction != null) { blockTransaction.setLabel(ew.labels.get(key)); } - } catch(IllegalArgumentException e) { + } catch(Exception e) { //not a tx, probably an address } } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java index d48010c0..3908b60c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java @@ -254,6 +254,19 @@ public class Storage { return (encrypted.exists() || unencrypted.exists()); } + public static File getExistingWallet(String walletName) { + File encrypted = new File(getWalletsDir(), walletName); + File unencrypted = new File(getWalletsDir(), walletName + ".json"); + + if(encrypted.exists()) { + return encrypted; + } else if(unencrypted.exists()) { + return unencrypted; + } + + return null; + } + public static File getWalletFile(String walletName) { //TODO: Check for existing file return new File(getWalletsDir(), walletName);