mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-02 12:26:45 +00:00
select alternative network, support testnet on hwi, other fixes
This commit is contained in:
parent
c68cda5b2f
commit
ff7a35e68b
12 changed files with 133 additions and 15 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
|||
Subproject commit 747bfa915f1ecf743b5e8876b9a4c54062e57c94
|
||||
Subproject commit b877e94cd09adb3fbc17ecba95897ae5c428ffe9
|
7
sparrow.bat
Normal file
7
sparrow.bat
Normal file
|
@ -0,0 +1,7 @@
|
|||
set ARGS=%*
|
||||
|
||||
if "%ARGS%" != "" (
|
||||
gradlew.bat run --args="%ARGS%"
|
||||
) else (
|
||||
gradlew.bat run
|
||||
)
|
11
sparrow.sh
Executable file
11
sparrow.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
args="$*"
|
||||
args="${args%"${args##*[![:space:]]}"}"
|
||||
|
||||
if [ -n "$args" ]
|
||||
then
|
||||
./gradlew run --args="$args"
|
||||
else
|
||||
./gradlew run
|
||||
fi
|
|
@ -4,6 +4,7 @@ import com.google.common.base.Charsets;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.common.io.ByteSource;
|
||||
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.InvalidPasswordException;
|
||||
|
@ -770,6 +771,7 @@ public class AppController implements Initializable {
|
|||
FileType fileType = IOUtils.getFileType(file);
|
||||
if(FileType.JSON.equals(fileType)) {
|
||||
Wallet wallet = storage.loadWallet();
|
||||
checkWalletNetwork(wallet);
|
||||
restorePublicKeysFromSeed(wallet, null);
|
||||
Tab tab = addWalletTab(storage, wallet);
|
||||
tabs.getSelectionModel().select(tab);
|
||||
|
@ -786,10 +788,11 @@ public class AppController implements Initializable {
|
|||
EventManager.get().post(new StorageEvent(storage.getWalletFile(), TimedEvent.Action.END, "Done"));
|
||||
Storage.WalletAndKey walletAndKey = loadWalletService.getValue();
|
||||
try {
|
||||
checkWalletNetwork(walletAndKey.wallet);
|
||||
restorePublicKeysFromSeed(walletAndKey.wallet, walletAndKey.key);
|
||||
Tab tab = addWalletTab(storage, walletAndKey.wallet);
|
||||
tabs.getSelectionModel().select(tab);
|
||||
} catch(MnemonicException e) {
|
||||
} catch(Exception e) {
|
||||
showErrorDialog("Error Opening Wallet", e.getMessage());
|
||||
} finally {
|
||||
walletAndKey.key.clear();
|
||||
|
@ -816,6 +819,12 @@ public class AppController implements Initializable {
|
|||
}
|
||||
}
|
||||
|
||||
private void checkWalletNetwork(Wallet wallet) {
|
||||
if(wallet.getNetwork() != null && wallet.getNetwork() != Network.get()) {
|
||||
throw new IllegalStateException("Provided " + wallet.getNetwork() + " wallet is invalid on a " + Network.get() + " network. Use a " + wallet.getNetwork() + " configuration to load this wallet.");
|
||||
}
|
||||
}
|
||||
|
||||
private void restorePublicKeysFromSeed(Wallet wallet, Key key) throws MnemonicException {
|
||||
if(wallet.containsSeeds()) {
|
||||
//Derive xpub and master fingerprint from seed, potentially with passphrase
|
||||
|
@ -1382,7 +1391,7 @@ public class AppController implements Initializable {
|
|||
|
||||
@Subscribe
|
||||
public void openWallets(OpenWalletsEvent event) {
|
||||
List<File> walletFiles = event.getWalletsMap().values().stream().map(storage -> storage.getWalletFile()).collect(Collectors.toList());
|
||||
List<File> walletFiles = event.getWalletsMap().values().stream().map(Storage::getWalletFile).collect(Collectors.toList());
|
||||
Config.get().setRecentWalletFiles(walletFiles);
|
||||
|
||||
boolean usbWallet = false;
|
||||
|
|
15
src/main/java/com/sparrowwallet/sparrow/Args.java
Normal file
15
src/main/java/com/sparrowwallet/sparrow/Args.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package com.sparrowwallet.sparrow;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
|
||||
public class Args {
|
||||
@Parameter(names = { "--dir", "-d" }, description = "Path to Sparrow home folder")
|
||||
public String dir;
|
||||
|
||||
@Parameter(names = { "--network", "-n" }, description = "Network to use (mainnet, testnet or regtest)")
|
||||
public Network network;
|
||||
|
||||
@Parameter(names = { "--help", "-h" }, description = "Show usage", help = true)
|
||||
public boolean help;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.sparrowwallet.sparrow;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
import com.sparrowwallet.sparrow.control.WelcomeDialog;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5Brands;
|
||||
|
@ -17,18 +19,20 @@ import javafx.scene.image.Image;
|
|||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Stage;
|
||||
import org.controlsfx.glyphfont.GlyphFontRegistry;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MainApp extends Application {
|
||||
private static final Logger log = LoggerFactory.getLogger(MainApp.class);
|
||||
|
||||
public static final String APP_NAME = "Sparrow";
|
||||
public static final String APP_VERSION = "0.9.4";
|
||||
public static final String APP_HOME_PROPERTY = "sparrow.home";
|
||||
public static final String NETWORK_ENV_PROPERTY = "SPARROW_NETWORK";
|
||||
|
||||
private Stage mainStage;
|
||||
|
||||
|
@ -107,7 +111,37 @@ public class MainApp extends Application {
|
|||
mainStage.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
com.sun.javafx.application.LauncherImpl.launchApplication(MainApp.class, MainAppPreloader.class, args);
|
||||
public static void main(String[] argv) {
|
||||
Args args = new Args();
|
||||
JCommander jCommander = JCommander.newBuilder().addObject(args).programName(APP_NAME.toLowerCase()).acceptUnknownOptions(true).build();
|
||||
jCommander.parse(argv);
|
||||
if(args.help) {
|
||||
jCommander.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
if(args.dir != null) {
|
||||
log.info("Using configured Sparrow home folder of " + args.dir);
|
||||
System.setProperty(APP_HOME_PROPERTY, args.dir);
|
||||
}
|
||||
|
||||
if(args.network != null) {
|
||||
Network.set(args.network);
|
||||
} else {
|
||||
String envNetwork = System.getenv(NETWORK_ENV_PROPERTY);
|
||||
if(envNetwork != null) {
|
||||
try {
|
||||
Network.set(Network.valueOf(envNetwork.toUpperCase()));
|
||||
} catch(Exception e) {
|
||||
log.warn("Invalid " + NETWORK_ENV_PROPERTY + " property: " + envNetwork);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Network.get() != Network.MAINNET) {
|
||||
log.info("Using " + Network.get() + " configuration");
|
||||
}
|
||||
|
||||
com.sun.javafx.application.LauncherImpl.launchApplication(MainApp.class, MainAppPreloader.class, argv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,12 @@ public class Config {
|
|||
}
|
||||
|
||||
private static File getConfigFile() {
|
||||
return new File(Storage.getSparrowDir(), CONFIG_FILENAME);
|
||||
File sparrowDir = Storage.getSparrowDir();
|
||||
if(!sparrowDir.exists()) {
|
||||
sparrowDir.mkdirs();
|
||||
}
|
||||
|
||||
return new File(sparrowDir, CONFIG_FILENAME);
|
||||
}
|
||||
|
||||
private static Config load() {
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.io;
|
|||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.gson.*;
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||
import com.sparrowwallet.drongo.psbt.PSBTParseException;
|
||||
|
@ -322,17 +323,27 @@ public class Hwi {
|
|||
}
|
||||
|
||||
private List<String> getDeviceCommand(Device device, Command command) throws IOException {
|
||||
return List.of(getHwiExecutable(command).getAbsolutePath(), "--device-path", device.getPath(), "--device-type", device.getType(), command.toString());
|
||||
List<String> elements = new ArrayList<>(List.of(getHwiExecutable(command).getAbsolutePath(), "--device-path", device.getPath(), "--device-type", device.getType(), command.toString()));
|
||||
if(Network.get() != Network.MAINNET) {
|
||||
elements.add(elements.size() - 1, "--testnet");
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
private List<String> getDeviceCommand(Device device, Command command, String... commandData) throws IOException {
|
||||
List<String> elements = new ArrayList<>(List.of(getHwiExecutable(command).getAbsolutePath(), "--device-path", device.getPath(), "--device-type", device.getType(), command.toString()));
|
||||
if(Network.get() != Network.MAINNET) {
|
||||
elements.add(elements.size() - 1, "--testnet");
|
||||
}
|
||||
elements.addAll(Arrays.stream(commandData).filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
return elements;
|
||||
}
|
||||
|
||||
private List<String> getDeviceCommand(Device device, String passphrase, Command command, String... commandData) throws IOException {
|
||||
List<String> elements = new ArrayList<>(List.of(getHwiExecutable(command).getAbsolutePath(), "--device-path", device.getPath(), "--device-type", device.getType(), "--password", passphrase, command.toString()));
|
||||
if(Network.get() != Network.MAINNET) {
|
||||
elements.add(elements.size() - 1, "--testnet");
|
||||
}
|
||||
elements.addAll(Arrays.stream(commandData).filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
return elements;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.sparrowwallet.sparrow.io;
|
|||
import com.google.common.io.Files;
|
||||
import com.google.gson.*;
|
||||
import com.sparrowwallet.drongo.ExtendedKey;
|
||||
import com.sparrowwallet.drongo.Network;
|
||||
import com.sparrowwallet.drongo.SecureString;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.crypto.*;
|
||||
|
@ -12,6 +13,7 @@ import com.sparrowwallet.drongo.wallet.Keystore;
|
|||
import com.sparrowwallet.drongo.wallet.MnemonicException;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||
import com.sparrowwallet.sparrow.MainApp;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import org.controlsfx.tools.Platform;
|
||||
|
@ -272,6 +274,18 @@ public class Storage {
|
|||
}
|
||||
|
||||
static File getSparrowDir() {
|
||||
if(Network.get() != Network.MAINNET) {
|
||||
return new File(getSparrowHome(), Network.get().getName());
|
||||
}
|
||||
|
||||
return getSparrowHome();
|
||||
}
|
||||
|
||||
static File getSparrowHome() {
|
||||
if(System.getProperty(MainApp.APP_HOME_PROPERTY) != null) {
|
||||
return new File(System.getProperty(MainApp.APP_HOME_PROPERTY));
|
||||
}
|
||||
|
||||
if(Platform.getCurrent() == Platform.WINDOWS) {
|
||||
return new File(getHomeDir(), WINDOWS_SPARROW_DIR);
|
||||
}
|
||||
|
|
|
@ -97,6 +97,8 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
|
||||
private final ObjectProperty<WalletTransaction> walletTransactionProperty = new SimpleObjectProperty<>(null);
|
||||
|
||||
private final ObjectProperty<WalletTransaction> createdWalletTransactionProperty = new SimpleObjectProperty<>(null);
|
||||
|
||||
private final BooleanProperty insufficientInputsProperty = new SimpleBooleanProperty(false);
|
||||
|
||||
private final ChangeListener<String> amountListener = new ChangeListener<>() {
|
||||
|
@ -570,6 +572,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
utxoSelectorProperty.setValue(null);
|
||||
utxoFilterProperty.setValue(null);
|
||||
walletTransactionProperty.setValue(null);
|
||||
createdWalletTransactionProperty.set(null);
|
||||
|
||||
validationSupport.setErrorDecorationEnabled(false);
|
||||
}
|
||||
|
@ -583,6 +586,7 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
}
|
||||
|
||||
public void createTransaction(ActionEvent event) {
|
||||
createdWalletTransactionProperty.set(walletTransactionProperty.get());
|
||||
PSBT psbt = walletTransactionProperty.get().createPSBT();
|
||||
EventManager.get().post(new ViewPSBTEvent(label.getText(), psbt));
|
||||
}
|
||||
|
@ -596,8 +600,8 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
|
||||
@Subscribe
|
||||
public void walletHistoryChanged(WalletHistoryChangedEvent event) {
|
||||
if(event.getWallet().equals(walletForm.getWallet())) {
|
||||
if(walletTransactionProperty.get() != null && walletTransactionProperty.get().getSelectedUtxos() != null && allSelectedUtxosSpent(event.getHistoryChangedNodes())) {
|
||||
if(event.getWallet().equals(walletForm.getWallet()) && createdWalletTransactionProperty.get() != null) {
|
||||
if(createdWalletTransactionProperty.get().getSelectedUtxos() != null && allSelectedUtxosSpent(event.getHistoryChangedNodes())) {
|
||||
clear(null);
|
||||
} else {
|
||||
updateTransaction();
|
||||
|
@ -606,9 +610,9 @@ public class SendController extends WalletFormController implements Initializabl
|
|||
}
|
||||
|
||||
private boolean allSelectedUtxosSpent(List<WalletNode> historyChangedNodes) {
|
||||
Set<BlockTransactionHashIndex> unspentUtxos = new HashSet<>(walletTransactionProperty.get().getSelectedUtxos().keySet());
|
||||
Set<BlockTransactionHashIndex> unspentUtxos = new HashSet<>(createdWalletTransactionProperty.get().getSelectedUtxos().keySet());
|
||||
|
||||
for(Map.Entry<BlockTransactionHashIndex, WalletNode> selectedUtxoEntry : walletTransactionProperty.get().getSelectedUtxos().entrySet()) {
|
||||
for(Map.Entry<BlockTransactionHashIndex, WalletNode> selectedUtxoEntry : createdWalletTransactionProperty.get().getSelectedUtxos().entrySet()) {
|
||||
BlockTransactionHashIndex utxo = selectedUtxoEntry.getKey();
|
||||
WalletNode utxoWalletNode = selectedUtxoEntry.getValue();
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.sparrowwallet.sparrow.control.CopyableLabel;
|
|||
import com.sparrowwallet.sparrow.control.DescriptorArea;
|
||||
import com.sparrowwallet.sparrow.control.TextAreaDialog;
|
||||
import com.sparrowwallet.sparrow.control.WalletPasswordDialog;
|
||||
import com.sparrowwallet.sparrow.event.RequestOpenWalletsEvent;
|
||||
import com.sparrowwallet.sparrow.event.SettingsChangedEvent;
|
||||
import com.sparrowwallet.sparrow.event.StorageEvent;
|
||||
import com.sparrowwallet.sparrow.event.TimedEvent;
|
||||
|
@ -347,6 +348,9 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
try {
|
||||
walletForm.getStorage().setEncryptionPubKey(Storage.NO_PASSWORD_KEY);
|
||||
walletForm.saveAndRefresh();
|
||||
if(requirement == WalletPasswordDialog.PasswordRequirement.UPDATE_NEW) {
|
||||
EventManager.get().post(new RequestOpenWalletsEvent());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error saving wallet", e);
|
||||
AppController.showErrorDialog("Error saving wallet", e.getMessage());
|
||||
|
@ -381,6 +385,9 @@ public class SettingsController extends WalletFormController implements Initiali
|
|||
|
||||
walletForm.getStorage().setEncryptionPubKey(encryptionPubKey);
|
||||
walletForm.saveAndRefresh();
|
||||
if(requirement == WalletPasswordDialog.PasswordRequirement.UPDATE_NEW) {
|
||||
EventManager.get().post(new RequestOpenWalletsEvent());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error saving wallet", e);
|
||||
AppController.showErrorDialog("Error saving wallet", e.getMessage());
|
||||
|
|
|
@ -22,5 +22,6 @@ open module com.sparrowwallet.sparrow {
|
|||
requires webcam.capture;
|
||||
requires netlayer.jpms;
|
||||
requires centerdevice.nsmenufx;
|
||||
requires jcommander;
|
||||
requires slf4j.api;
|
||||
}
|
Loading…
Reference in a new issue