mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
finalising wallet settings
This commit is contained in:
parent
84888b4a43
commit
bc5690346c
17 changed files with 101 additions and 22 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit b951f79cfded507112cc7f213567c6a43c00e7e8
|
Subproject commit 766a986abb72ea84317a405b93055abc3d1eaf22
|
BIN
src/.DS_Store
vendored
Normal file
BIN
src/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -259,7 +259,11 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
public Tab addWalletTab(File walletFile, ECKey encryptionPubKey, Wallet wallet) {
|
public Tab addWalletTab(File walletFile, ECKey encryptionPubKey, Wallet wallet) {
|
||||||
try {
|
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);
|
TabData tabData = new TabData(TabData.TabType.WALLET);
|
||||||
tab.setUserData(tabData);
|
tab.setUserData(tabData);
|
||||||
tab.setContextMenu(getTabContextMenu(tab));
|
tab.setContextMenu(getTabContextMenu(tab));
|
||||||
|
|
|
@ -40,8 +40,8 @@ public class MainApp extends Application {
|
||||||
wallet.setPolicyType(PolicyType.SINGLE);
|
wallet.setPolicyType(PolicyType.SINGLE);
|
||||||
wallet.setScriptType(ScriptType.P2WPKH);
|
wallet.setScriptType(ScriptType.P2WPKH);
|
||||||
|
|
||||||
KeystoreImportDialog dlg = new KeystoreImportDialog(wallet);
|
// KeystoreImportDialog dlg = new KeystoreImportDialog(wallet);
|
||||||
dlg.showAndWait();
|
// dlg.showAndWait();
|
||||||
|
|
||||||
stage.show();
|
stage.show();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,16 @@ public class Storage {
|
||||||
throw new IOException("Could not create folder " + parent);
|
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);
|
Writer writer = new FileWriter(file);
|
||||||
gson.toJson(wallet, writer);
|
gson.toJson(wallet, writer);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
@ -73,6 +83,16 @@ public class Storage {
|
||||||
throw new IOException("Could not create folder " + parent);
|
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);
|
OutputStreamWriter writer = new OutputStreamWriter(new DeflaterOutputStream(new ECIESOutputStream(new FileOutputStream(file), encryptionKey, getEncryptionMagic())), StandardCharsets.UTF_8);
|
||||||
gson.toJson(wallet, writer);
|
gson.toJson(wallet, writer);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
|
@ -63,6 +63,9 @@ public class KeystoreController extends WalletFormController implements Initiali
|
||||||
Platform.runLater(this::setupValidation);
|
Platform.runLater(this::setupValidation);
|
||||||
|
|
||||||
selectSourcePane.managedProperty().bind(selectSourcePane.visibleProperty());
|
selectSourcePane.managedProperty().bind(selectSourcePane.visibleProperty());
|
||||||
|
if(keystore.isValid()) {
|
||||||
|
selectSourcePane.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
updateType();
|
updateType();
|
||||||
|
|
||||||
|
|
|
@ -88,14 +88,14 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
scriptType.getSelectionModel().select(policyType.getDefaultScriptType());
|
scriptType.getSelectionModel().select(policyType.getDefaultScriptType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(oldValue != null) {
|
||||||
|
clearKeystoreTabs();
|
||||||
|
}
|
||||||
|
|
||||||
multisigFieldset.setVisible(policyType.equals(PolicyType.MULTI));
|
multisigFieldset.setVisible(policyType.equals(PolicyType.MULTI));
|
||||||
if(policyType.equals(PolicyType.MULTI)) {
|
if(policyType.equals(PolicyType.MULTI)) {
|
||||||
totalKeystores.unbind();
|
|
||||||
totalKeystores.set(0);
|
|
||||||
totalKeystores.bind(multisigControl.highValueProperty());
|
totalKeystores.bind(multisigControl.highValueProperty());
|
||||||
} else {
|
} else {
|
||||||
totalKeystores.unbind();
|
|
||||||
totalKeystores.set(0);
|
|
||||||
totalKeystores.set(1);
|
totalKeystores.set(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -159,9 +159,9 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
|
|
||||||
apply.setOnAction(event -> {
|
apply.setOnAction(event -> {
|
||||||
try {
|
try {
|
||||||
Optional<ECKey> optionalPubKey = askForWalletPassword(walletForm.getEncryptionPubKey());
|
Optional<ECKey> optionalPubKey = requestEncryption(walletForm.getEncryptionPubKey());
|
||||||
if(optionalPubKey.isPresent()) {
|
if(optionalPubKey.isPresent()) {
|
||||||
walletForm.setEncryptionPubKey(ECKey.fromPublicOnly(optionalPubKey.get()));
|
walletForm.setEncryptionPubKey(optionalPubKey.get());
|
||||||
walletForm.save();
|
walletForm.save();
|
||||||
revert.setDisable(true);
|
revert.setDisable(true);
|
||||||
apply.setDisable(true);
|
apply.setDisable(true);
|
||||||
|
@ -175,6 +175,11 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
setFieldsFromWallet(walletForm.getWallet());
|
setFieldsFromWallet(walletForm.getWallet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearKeystoreTabs() {
|
||||||
|
totalKeystores.unbind();
|
||||||
|
totalKeystores.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
private void setFieldsFromWallet(Wallet wallet) {
|
private void setFieldsFromWallet(Wallet wallet) {
|
||||||
if(wallet.getPolicyType() == null) {
|
if(wallet.getPolicyType() == null) {
|
||||||
wallet.setPolicyType(PolicyType.SINGLE);
|
wallet.setPolicyType(PolicyType.SINGLE);
|
||||||
|
@ -261,7 +266,7 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
Platform.runLater(() -> apply.setDisable(!tabsValidate()));
|
Platform.runLater(() -> apply.setDisable(!tabsValidate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ECKey> askForWalletPassword(ECKey existingPubKey) {
|
private Optional<ECKey> requestEncryption(ECKey existingPubKey) {
|
||||||
WalletPasswordDialog.PasswordRequirement requirement;
|
WalletPasswordDialog.PasswordRequirement requirement;
|
||||||
if(existingPubKey == null) {
|
if(existingPubKey == null) {
|
||||||
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_NEW;
|
requirement = WalletPasswordDialog.PasswordRequirement.UPDATE_NEW;
|
||||||
|
@ -280,16 +285,14 @@ public class SettingsController extends WalletFormController implements Initiali
|
||||||
|
|
||||||
ECKey encryptionFullKey = ECIESKeyCrypter.deriveECKey(password.get());
|
ECKey encryptionFullKey = ECIESKeyCrypter.deriveECKey(password.get());
|
||||||
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
|
ECKey encryptionPubKey = ECKey.fromPublicOnly(encryptionFullKey);
|
||||||
if(existingPubKey != null) {
|
|
||||||
if(WalletForm.NO_PASSWORD_KEY.equals(existingPubKey) || existingPubKey.equals(encryptionPubKey)) {
|
if(existingPubKey != null && !WalletForm.NO_PASSWORD_KEY.equals(existingPubKey) && !existingPubKey.equals(encryptionPubKey)) {
|
||||||
return Optional.of(encryptionPubKey);
|
AppController.showErrorDialog("Incorrect Password", "The password was incorrect.");
|
||||||
} else {
|
return Optional.empty();
|
||||||
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();
|
return Optional.empty();
|
||||||
|
|
|
@ -2,10 +2,13 @@ package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.AppController;
|
import com.sparrowwallet.sparrow.AppController;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Toggle;
|
||||||
|
import javafx.scene.control.ToggleButton;
|
||||||
import javafx.scene.control.ToggleGroup;
|
import javafx.scene.control.ToggleGroup;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
@ -61,5 +64,25 @@ public class WalletController extends WalletFormController implements Initializa
|
||||||
throw new IllegalStateException("Can't find pane", e);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
-fx-background-color: #1e88cf;
|
-fx-background-color: #1e88cf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-item:disabled {
|
||||||
|
-fx-background-color: #a0a1a7;
|
||||||
|
-fx-opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
#walletPane {
|
#walletPane {
|
||||||
-fx-background-color: -fx-background;
|
-fx-background-color: -fx-background;
|
||||||
}
|
}
|
BIN
src/test/.DS_Store
vendored
Normal file
BIN
src/test/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -1,14 +1,15 @@
|
||||||
package com.sparrowwallet.sparrow.io;
|
package com.sparrowwallet.sparrow.io;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter;
|
import com.sparrowwallet.drongo.crypto.ECIESKeyCrypter;
|
||||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
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 com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class StorageTest extends IoTest {
|
public class StorageTest extends IoTest {
|
||||||
@Test
|
@Test
|
||||||
|
@ -18,6 +19,25 @@ public class StorageTest extends IoTest {
|
||||||
Assert.assertTrue(wallet.isValid());
|
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
|
@Test
|
||||||
public void saveWallet() throws IOException {
|
public void saveWallet() throws IOException {
|
||||||
ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass");
|
ECKey decryptionKey = ECIESKeyCrypter.deriveECKey("pass");
|
||||||
|
|
BIN
src/test/resources/.DS_Store
vendored
Normal file
BIN
src/test/resources/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/test/resources/com/.DS_Store
vendored
Normal file
BIN
src/test/resources/com/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/test/resources/com/sparrowwallet/.DS_Store
vendored
Normal file
BIN
src/test/resources/com/sparrowwallet/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
src/test/resources/com/sparrowwallet/sparrow/.DS_Store
vendored
Normal file
BIN
src/test/resources/com/sparrowwallet/sparrow/.DS_Store
vendored
Normal file
Binary file not shown.
|
@ -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=
|
Loading…
Reference in a new issue