diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..81229e8d Binary files /dev/null and b/.DS_Store differ diff --git a/drongo b/drongo index b951f79c..766a986a 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit b951f79cfded507112cc7f213567c6a43c00e7e8 +Subproject commit 766a986abb72ea84317a405b93055abc3d1eaf22 diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 00000000..c3ac046f Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java index 397b0187..90615d17 100644 --- a/src/main/java/com/sparrowwallet/sparrow/AppController.java +++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java @@ -259,7 +259,11 @@ public class AppController implements Initializable { public Tab addWalletTab(File walletFile, ECKey encryptionPubKey, Wallet wallet) { try { - Tab tab = new Tab(walletFile.getName()); + String name = walletFile.getName(); + if(name.endsWith(".json")) { + name = name.substring(0, name.lastIndexOf('.')); + } + Tab tab = new Tab(name); TabData tabData = new TabData(TabData.TabType.WALLET); tab.setUserData(tabData); tab.setContextMenu(getTabContextMenu(tab)); diff --git a/src/main/java/com/sparrowwallet/sparrow/MainApp.java b/src/main/java/com/sparrowwallet/sparrow/MainApp.java index 3a5c43d4..25be1815 100644 --- a/src/main/java/com/sparrowwallet/sparrow/MainApp.java +++ b/src/main/java/com/sparrowwallet/sparrow/MainApp.java @@ -40,8 +40,8 @@ public class MainApp extends Application { wallet.setPolicyType(PolicyType.SINGLE); wallet.setScriptType(ScriptType.P2WPKH); - KeystoreImportDialog dlg = new KeystoreImportDialog(wallet); - dlg.showAndWait(); +// KeystoreImportDialog dlg = new KeystoreImportDialog(wallet); +// dlg.showAndWait(); stage.show(); } diff --git a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java index 9b348c40..3437763a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/io/Storage.java +++ b/src/main/java/com/sparrowwallet/sparrow/io/Storage.java @@ -62,6 +62,16 @@ public class Storage { throw new IOException("Could not create folder " + parent); } + if(!file.getName().endsWith(".json")) { + File jsonFile = new File(parent, file.getName() + ".json"); + if(file.exists()) { + if(!file.renameTo(jsonFile)) { + throw new IOException("Could not rename " + file.getName() + " to " + jsonFile.getName()); + } + } + file = jsonFile; + } + Writer writer = new FileWriter(file); gson.toJson(wallet, writer); writer.close(); @@ -73,6 +83,16 @@ public class Storage { throw new IOException("Could not create folder " + parent); } + if(file.getName().endsWith(".json")) { + File noJsonFile = new File(parent, file.getName().substring(0, file.getName().lastIndexOf('.'))); + if(file.exists()) { + if(!file.renameTo(noJsonFile)) { + throw new IOException("Could not rename " + file.getName() + " to " + noJsonFile.getName()); + } + } + file = noJsonFile; + } + OutputStreamWriter writer = new OutputStreamWriter(new DeflaterOutputStream(new ECIESOutputStream(new FileOutputStream(file), encryptionKey, getEncryptionMagic())), StandardCharsets.UTF_8); gson.toJson(wallet, writer); writer.close(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java index d63b8899..03346972 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/KeystoreController.java @@ -63,6 +63,9 @@ public class KeystoreController extends WalletFormController implements Initiali Platform.runLater(this::setupValidation); selectSourcePane.managedProperty().bind(selectSourcePane.visibleProperty()); + if(keystore.isValid()) { + selectSourcePane.setVisible(false); + } updateType(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java index 0d61166b..69d7e7fa 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java @@ -88,14 +88,14 @@ public class SettingsController extends WalletFormController implements Initiali scriptType.getSelectionModel().select(policyType.getDefaultScriptType()); } + if(oldValue != null) { + clearKeystoreTabs(); + } + 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); } }); @@ -159,9 +159,9 @@ public class SettingsController extends WalletFormController implements Initiali apply.setOnAction(event -> { try { - Optional optionalPubKey = askForWalletPassword(walletForm.getEncryptionPubKey()); + Optional optionalPubKey = requestEncryption(walletForm.getEncryptionPubKey()); if(optionalPubKey.isPresent()) { - walletForm.setEncryptionPubKey(ECKey.fromPublicOnly(optionalPubKey.get())); + walletForm.setEncryptionPubKey(optionalPubKey.get()); walletForm.save(); revert.setDisable(true); apply.setDisable(true); @@ -175,6 +175,11 @@ public class SettingsController extends WalletFormController implements Initiali setFieldsFromWallet(walletForm.getWallet()); } + private void clearKeystoreTabs() { + totalKeystores.unbind(); + totalKeystores.set(0); + } + private void setFieldsFromWallet(Wallet wallet) { if(wallet.getPolicyType() == null) { wallet.setPolicyType(PolicyType.SINGLE); @@ -261,7 +266,7 @@ public class SettingsController extends WalletFormController implements Initiali Platform.runLater(() -> apply.setDisable(!tabsValidate())); } - private Optional askForWalletPassword(ECKey existingPubKey) { + private Optional requestEncryption(ECKey existingPubKey) { WalletPasswordDialog.PasswordRequirement requirement; if(existingPubKey == null) { requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_NEW; @@ -280,16 +285,14 @@ public class SettingsController extends WalletFormController implements Initiali ECKey encryptionFullKey = ECIESKeyCrypter.deriveECKey(password.get()); ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey); - if(existingPubKey != null) { - if(WalletForm.NO_PASSWORD_KEY.equals(existingPubKey) || existingPubKey.equals(encryptionPubKey)) { - return Optional.of(encryptionPubKey); - } else { - AppController.showErrorDialog("Incorrect Password", "The password was incorrect."); - return Optional.empty(); - } + + if(existingPubKey != null && !WalletForm.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) { + AppController.showErrorDialog("Incorrect Password", "The password was incorrect."); + return Optional.empty(); } - return Optional.of(encryptionFullKey); + walletForm.getWallet().encrypt(password.get()); + return Optional.of(encryptionPubKey); } return Optional.empty(); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletController.java index 976a786f..432f571b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/WalletController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/WalletController.java @@ -2,10 +2,13 @@ package com.sparrowwallet.sparrow.wallet; import com.sparrowwallet.sparrow.AppController; import com.sparrowwallet.sparrow.EventManager; +import javafx.application.Platform; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.scene.Node; +import javafx.scene.control.Toggle; +import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.BorderPane; import javafx.scene.layout.StackPane; @@ -61,5 +64,25 @@ public class WalletController extends WalletFormController implements Initializa throw new IllegalStateException("Can't find pane", e); } }); + + if(!walletForm.getWallet().isValid()) { + for(Toggle toggle : walletMenu.getToggles()) { + if(toggle.getUserData().equals(Function.SETTINGS)) { + toggle.setSelected(true); + } else { + ((ToggleButton)toggle).setDisable(true); + } + } + } + } + + public void selectFunction(Function function) { + Platform.runLater(() -> { + for(Toggle toggle : walletMenu.getToggles()) { + if(toggle.getUserData().equals(function)) { + toggle.setSelected(true); + } + } + }); } } diff --git a/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css b/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css index 8ac6f650..ae854ac9 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css +++ b/src/main/resources/com/sparrowwallet/sparrow/wallet/wallet.css @@ -20,6 +20,11 @@ -fx-background-color: #1e88cf; } +.list-item:disabled { + -fx-background-color: #a0a1a7; + -fx-opacity: 1; +} + #walletPane { -fx-background-color: -fx-background; } \ No newline at end of file diff --git a/src/test/.DS_Store b/src/test/.DS_Store new file mode 100644 index 00000000..c10b9bb9 Binary files /dev/null and b/src/test/.DS_Store differ diff --git a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java index 8ee7a2d6..e041a45d 100644 --- a/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java +++ b/src/test/java/com/sparrowwallet/sparrow/io/StorageTest.java @@ -1,14 +1,15 @@ package com.sparrowwallet.sparrow.io; +import com.sparrowwallet.drongo.Utils; import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter; import com.sparrowwallet.drongo.crypto.ECKey; +import com.sparrowwallet.drongo.policy.PolicyType; +import com.sparrowwallet.drongo.protocol.ScriptType; import com.sparrowwallet.drongo.wallet.Wallet; import org.junit.Assert; import org.junit.Test; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; +import java.io.*; public class StorageTest extends IoTest { @Test @@ -18,6 +19,25 @@ public class StorageTest extends IoTest { Assert.assertTrue(wallet.isValid()); } + @Test + public void loadSeedWallet() throws IOException { + ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass"); + + Wallet wallet = Storage.getStorage().loadWallet(getFile("sparrow-single-seed-wallet"), decryptionKey); + Assert.assertTrue(wallet.isValid()); + + Assert.assertEquals("testa1", wallet.getName()); + Assert.assertEquals(PolicyType.SINGLE, wallet.getPolicyType()); + Assert.assertEquals(ScriptType.P2WPKH, wallet.getScriptType()); + Assert.assertEquals(1, wallet.getDefaultPolicy().getNumSignaturesRequired()); + Assert.assertEquals("pkh(60bcd3a7)", wallet.getDefaultPolicy().getMiniscript().getScript()); + Assert.assertEquals("60bcd3a7", wallet.getKeystores().get(0).getKeyDerivation().getMasterFingerprint()); + Assert.assertEquals("m/84'/0'/0'", wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath()); + Assert.assertEquals("xpub6BrhGFTWPd3DQaGP7p5zTQkE5nqVbaRs23HNae8jAoNJYS2NGa9Sgpeqv1dS5ygwD4sQfwqLCk5qXRK45FTgnqHRcrPnts3Qgh78BZrnoMn", wallet.getKeystores().get(0).getExtendedPublicKey().toString()); + Assert.assertEquals("b0e161bff5f589e74b20d9cd260702a6a1e6e1ab3ba4ce764f388dd8f360a1ccdb21099a2f22757ca72f9bde3a34b97a31fb513fb8931c821b0d25798e450b6a57dc106973849ca586b50b2db2840adc", Utils.bytesToHex(wallet.getKeystores().get(0).getSeed().getEncryptedSeedData().getEncryptedBytes())); + Assert.assertNull(wallet.getKeystores().get(0).getSeed().getSeedBytes()); + } + @Test public void saveWallet() throws IOException { ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass"); diff --git a/src/test/resources/.DS_Store b/src/test/resources/.DS_Store new file mode 100644 index 00000000..3ff3e4ce Binary files /dev/null and b/src/test/resources/.DS_Store differ diff --git a/src/test/resources/com/.DS_Store b/src/test/resources/com/.DS_Store new file mode 100644 index 00000000..60b9d678 Binary files /dev/null and b/src/test/resources/com/.DS_Store differ diff --git a/src/test/resources/com/sparrowwallet/.DS_Store b/src/test/resources/com/sparrowwallet/.DS_Store new file mode 100644 index 00000000..b151fb14 Binary files /dev/null and b/src/test/resources/com/sparrowwallet/.DS_Store differ diff --git a/src/test/resources/com/sparrowwallet/sparrow/.DS_Store b/src/test/resources/com/sparrowwallet/sparrow/.DS_Store new file mode 100644 index 00000000..dffb47f0 Binary files /dev/null and b/src/test/resources/com/sparrowwallet/sparrow/.DS_Store differ diff --git a/src/test/resources/com/sparrowwallet/sparrow/io/sparrow-single-seed-wallet b/src/test/resources/com/sparrowwallet/sparrow/io/sparrow-single-seed-wallet new file mode 100644 index 00000000..44225ae5 --- /dev/null +++ b/src/test/resources/com/sparrowwallet/sparrow/io/sparrow-single-seed-wallet @@ -0,0 +1 @@ +QklFMQOXQWixo1F4kqJjn/7UeGDmbpNdMGPUP+vzRWdUE2vOcHfejUklKAzq1cTpK0mMEOOHCZ+yg0LxF29KMFQpoSpRTl6GRjnmpGIu3HPuu7bjbL6GvZQXFkvmK+9zsrllxZl6sYMjP4zoHJH6JgL4qGFpnM9n/mtOGYAuOw7zj4fm10teHLLgJLpkZ4ze0n/t8QhbyPPkeEoNmw/gt1PrwNDneKtALCNNdGopEq0QWD15OCEY7fSIfu0K1VO9oMZpOHs78p335Ka7bRRjuq+RWvZLz/X5hb9zVlFIu+KLW/preykMbfg4UiPcVHfc9wSLsmqZe9btYa3yxsem9xRW7J4gXMr7uqMTw/dlrK6XNg0wBXH6cuBed3M6Nu72Hz0OU+M64HEUnsGRYLgz3XcsZAU7+jeUQp6D8sVjH7GsPFIdZl0wzhWNHsgQGLoGXnWyvatsPsklW9BQ5U1d0PxeLxWppwj42Y7YA0+O3BrN7lUmD6xATNt9/xwVotPIllXT84r/OpzFbULzSBZ0uwwV+4tdCOa7FHPUed5gXZCPk6lhPHkz2N6Ehm3WGOQBQsoTfObefYUjHhB+a6Rpggm7QgkLhBEtgy7sPCV39fnRYM52uOwDUhNB8K/h/RadkMX51eXtbx23+LU+jM8zpi4T6yLM1Rq8H9YZ+rJXUIZPOHwX2ytnXkwHcYanThhxvQa55v3vbC5X/JFVSA+yik1CejXctjv9I++5mCCJtGpk/USAWzIb3nhKURPi/a3sg7y/n47s79AxvzvLndlY96UIaI1QVaNoaoJtt1+cBLzrXGlc4hChIqloZN4GJ4F1KabDuyXwagGvsd14zTH6ELAprmJkrd0l9JNTEBrJJbRqFEZj7CwrREyUkxGaiskca+ZyHm4LuwKo/6m5dKgiqyeMUB6WdZFXDERSp9ldf8n+o6OSxolEq4wWxM2uGdbHZTBsORq0JyIS4CQcfiC4UQoXJnQpGAfKWNsc1jS/x0BlV/9n2rhGxC0LRQZ2YbtLwfwd138= \ No newline at end of file