mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-05 05:46:44 +00:00
add public electrum server type
This commit is contained in:
parent
48a63c25d2
commit
454e4b4c4b
9 changed files with 221 additions and 11 deletions
|
@ -542,7 +542,18 @@ public class AppController implements Initializable {
|
|||
}
|
||||
|
||||
private void setServerToggleTooltip(Integer currentBlockHeight) {
|
||||
serverToggle.setTooltip(new Tooltip(AppServices.isConnected() ? "Connected to " + Config.get().getServerAddress() + (currentBlockHeight != null ? " at height " + currentBlockHeight : "") : "Disconnected"));
|
||||
Tooltip tooltip = new Tooltip(getServerToggleTooltipText(currentBlockHeight));
|
||||
tooltip.setShowDuration(Duration.seconds(15));
|
||||
serverToggle.setTooltip(tooltip);
|
||||
}
|
||||
|
||||
private String getServerToggleTooltipText(Integer currentBlockHeight) {
|
||||
if(AppServices.isConnected()) {
|
||||
return "Connected to " + Config.get().getServerAddress() + (currentBlockHeight != null ? " at height " + currentBlockHeight : "") +
|
||||
(Config.get().getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER ? "\nWarning! You are connected to a public server and sharing your transaction data with it.\nFor better privacy, consider using your own Bitcoin Core node or private Electrum server." : "");
|
||||
}
|
||||
|
||||
return "Disconnected";
|
||||
}
|
||||
|
||||
public void newWallet(ActionEvent event) {
|
||||
|
@ -1069,6 +1080,12 @@ public class AppController implements Initializable {
|
|||
}
|
||||
|
||||
public void setServerType(ServerType serverType) {
|
||||
if(serverType == ServerType.PUBLIC_ELECTRUM_SERVER && !serverToggle.getStyleClass().contains("public-server")) {
|
||||
serverToggle.getStyleClass().add("public-server");
|
||||
} else {
|
||||
serverToggle.getStyleClass().remove("public-server");
|
||||
}
|
||||
|
||||
if(serverType == ServerType.BITCOIN_CORE && !serverToggle.getStyleClass().contains("core-server")) {
|
||||
serverToggle.getStyleClass().add("core-server");
|
||||
} else {
|
||||
|
|
|
@ -38,6 +38,7 @@ public class Config {
|
|||
private File hwi;
|
||||
private boolean hdCapture;
|
||||
private ServerType serverType;
|
||||
private String publicElectrumServer;
|
||||
private String coreServer;
|
||||
private CoreAuthType coreAuthType;
|
||||
private File coreDataDir;
|
||||
|
@ -275,7 +276,7 @@ public class Config {
|
|||
}
|
||||
|
||||
public String getServerAddress() {
|
||||
return getServerType() == ServerType.BITCOIN_CORE ? getCoreServer() : getElectrumServer();
|
||||
return getServerType() == ServerType.BITCOIN_CORE ? getCoreServer() : (getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER ? getPublicElectrumServer() : getElectrumServer());
|
||||
}
|
||||
|
||||
public boolean requiresTor() {
|
||||
|
@ -291,6 +292,15 @@ public class Config {
|
|||
return protocol.isOnionAddress(protocol.getServerHostAndPort(getServerAddress()));
|
||||
}
|
||||
|
||||
public String getPublicElectrumServer() {
|
||||
return publicElectrumServer;
|
||||
}
|
||||
|
||||
public void setPublicElectrumServer(String publicElectrumServer) {
|
||||
this.publicElectrumServer = publicElectrumServer;
|
||||
flush();
|
||||
}
|
||||
|
||||
public String getCoreServer() {
|
||||
return coreServer;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,10 @@ public class ElectrumServer {
|
|||
File electrumServerCert = null;
|
||||
String proxyServer = null;
|
||||
|
||||
if(Config.get().getServerType() == ServerType.BITCOIN_CORE) {
|
||||
if(Config.get().getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER) {
|
||||
electrumServer = Config.get().getPublicElectrumServer();
|
||||
proxyServer = Config.get().getProxyServer();
|
||||
} else if(Config.get().getServerType() == ServerType.BITCOIN_CORE) {
|
||||
if(bwtElectrumServer == null) {
|
||||
throw new ServerConfigException("Could not connect to Bitcoin Core RPC");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package com.sparrowwallet.sparrow.net;
|
||||
|
||||
public enum PublicElectrumServer {
|
||||
BLOCKSTREAM_INFO("blockstream.info", "ssl://blockstream.info:700"),
|
||||
ELECTRUM_BLOCKSTREAM_INFO("electrum.blockstream.info", "ssl://electrum.blockstream.info:50002"),
|
||||
LUKECHILDS_CO("bitcoin.lukechilds.co", "ssl://bitcoin.lukechilds.co:50002");
|
||||
|
||||
PublicElectrumServer(String name, String url) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final String url;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public static PublicElectrumServer fromUrl(String url) {
|
||||
for(PublicElectrumServer server : values()) {
|
||||
if(server.url.equals(url)) {
|
||||
return server;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.sparrowwallet.sparrow.net;
|
||||
|
||||
public enum ServerType {
|
||||
BITCOIN_CORE("Bitcoin Core"), ELECTRUM_SERVER("Electrum Server");
|
||||
BITCOIN_CORE("Bitcoin Core"), ELECTRUM_SERVER("Private Electrum"), PUBLIC_ELECTRUM_SERVER("Public Electrum");
|
||||
|
||||
private final String name;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ public class PreferencesDialog extends Dialog<Boolean> {
|
|||
dialogPane.getButtonTypes().addAll(newWalletButtonType);
|
||||
}
|
||||
|
||||
dialogPane.setPrefWidth(650);
|
||||
dialogPane.setPrefWidth(710);
|
||||
dialogPane.setPrefHeight(600);
|
||||
|
||||
preferencesController.reconnectOnClosingProperty().set(AppServices.isConnecting() || AppServices.isConnected());
|
||||
|
|
|
@ -23,6 +23,7 @@ import javafx.stage.Stage;
|
|||
import javafx.util.Duration;
|
||||
import net.freehaven.tor.control.TorControlError;
|
||||
import org.berndpruenster.netlayer.tor.Tor;
|
||||
import org.controlsfx.control.SegmentedButton;
|
||||
import org.controlsfx.glyphfont.Glyph;
|
||||
import org.controlsfx.validation.ValidationResult;
|
||||
import org.controlsfx.validation.ValidationSupport;
|
||||
|
@ -41,6 +42,7 @@ import java.security.cert.CertificateFactory;
|
|||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class ServerPreferencesController extends PreferencesDetailController {
|
||||
private static final Logger log = LoggerFactory.getLogger(ServerPreferencesController.class);
|
||||
|
@ -48,6 +50,27 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
@FXML
|
||||
private ToggleGroup serverTypeToggleGroup;
|
||||
|
||||
@FXML
|
||||
private SegmentedButton serverTypeSegmentedButton;
|
||||
|
||||
@FXML
|
||||
private ToggleButton publicElectrumToggle;
|
||||
|
||||
@FXML
|
||||
private Form publicElectrumForm;
|
||||
|
||||
@FXML
|
||||
private ComboBox<PublicElectrumServer> publicElectrumServer;
|
||||
|
||||
@FXML
|
||||
private UnlabeledToggleSwitch publicUseProxy;
|
||||
|
||||
@FXML
|
||||
private TextField publicProxyHost;
|
||||
|
||||
@FXML
|
||||
private TextField publicProxyPort;
|
||||
|
||||
@FXML
|
||||
private Form coreForm;
|
||||
|
||||
|
@ -135,13 +158,15 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
|
||||
Platform.runLater(this::setupValidation);
|
||||
|
||||
publicElectrumForm.managedProperty().bind(publicElectrumForm.visibleProperty());
|
||||
coreForm.managedProperty().bind(coreForm.visibleProperty());
|
||||
electrumForm.managedProperty().bind(electrumForm.visibleProperty());
|
||||
coreForm.visibleProperty().bind(electrumForm.visibleProperty().not());
|
||||
serverTypeToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if(serverTypeToggleGroup.getSelectedToggle() != null) {
|
||||
ServerType existingType = config.getServerType();
|
||||
ServerType serverType = (ServerType)newValue.getUserData();
|
||||
publicElectrumForm.setVisible(serverType == ServerType.PUBLIC_ELECTRUM_SERVER);
|
||||
coreForm.setVisible(serverType == ServerType.BITCOIN_CORE);
|
||||
electrumForm.setVisible(serverType == ServerType.ELECTRUM_SERVER);
|
||||
config.setServerType(serverType);
|
||||
testConnection.setGraphic(getGlyph(FontAwesome5.Glyph.QUESTION_CIRCLE, ""));
|
||||
|
@ -153,12 +178,26 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
oldValue.setSelected(true);
|
||||
}
|
||||
});
|
||||
ServerType serverType = config.getServerType() != null ? config.getServerType() : (config.getCoreServer() == null && config.getElectrumServer() != null ? ServerType.ELECTRUM_SERVER : ServerType.BITCOIN_CORE);
|
||||
ServerType serverType = config.getServerType() != null ?
|
||||
(config.getServerType() == ServerType.PUBLIC_ELECTRUM_SERVER && Network.get() != Network.MAINNET ? ServerType.BITCOIN_CORE : config.getServerType()) :
|
||||
(config.getCoreServer() == null && config.getElectrumServer() != null ? ServerType.ELECTRUM_SERVER :
|
||||
(config.getCoreServer() != null || Network.get() != Network.MAINNET ? ServerType.BITCOIN_CORE : ServerType.PUBLIC_ELECTRUM_SERVER));
|
||||
if(Network.get() != Network.MAINNET) {
|
||||
serverTypeSegmentedButton.getButtons().remove(publicElectrumToggle);
|
||||
serverTypeToggleGroup.getToggles().remove(publicElectrumToggle);
|
||||
}
|
||||
serverTypeToggleGroup.selectToggle(serverTypeToggleGroup.getToggles().stream().filter(toggle -> toggle.getUserData() == serverType).findFirst().orElse(null));
|
||||
|
||||
publicElectrumServer.getSelectionModel().selectedItemProperty().addListener(getPublicElectrumServerListener(config));
|
||||
|
||||
publicUseProxy.selectedProperty().bindBidirectional(useProxy.selectedProperty());
|
||||
publicProxyHost.textProperty().bindBidirectional(proxyHost.textProperty());
|
||||
publicProxyPort.textProperty().bindBidirectional(proxyPort.textProperty());
|
||||
|
||||
corePort.setTextFormatter(new TextFieldValidator(TextFieldValidator.ValidationModus.MAX_INTEGERS, 5).getFormatter());
|
||||
electrumPort.setTextFormatter(new TextFieldValidator(TextFieldValidator.ValidationModus.MAX_INTEGERS, 5).getFormatter());
|
||||
proxyPort.setTextFormatter(new TextFieldValidator(TextFieldValidator.ValidationModus.MAX_INTEGERS, 5).getFormatter());
|
||||
publicProxyPort.setTextFormatter(new TextFieldValidator(TextFieldValidator.ValidationModus.MAX_INTEGERS, 5).getFormatter());
|
||||
|
||||
coreHost.textProperty().addListener(getBitcoinCoreListener(config));
|
||||
corePort.textProperty().addListener(getBitcoinCoreListener(config));
|
||||
|
@ -245,6 +284,8 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
proxyHost.setText(proxyHost.getText().trim());
|
||||
proxyHost.setDisable(!newValue);
|
||||
proxyPort.setDisable(!newValue);
|
||||
publicProxyHost.setDisable(!newValue);
|
||||
publicProxyPort.setDisable(!newValue);
|
||||
});
|
||||
|
||||
boolean isConnected = AppServices.isConnecting() || AppServices.isConnected();
|
||||
|
@ -277,6 +318,13 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
testConnection.setVisible(true);
|
||||
});
|
||||
|
||||
PublicElectrumServer configPublicElectrumServer = PublicElectrumServer.fromUrl(config.getPublicElectrumServer());
|
||||
if(configPublicElectrumServer == null) {
|
||||
publicElectrumServer.setValue(PublicElectrumServer.values()[new Random().nextInt(PublicElectrumServer.values().length)]);
|
||||
} else {
|
||||
publicElectrumServer.setValue(configPublicElectrumServer);
|
||||
}
|
||||
|
||||
String coreServer = config.getCoreServer();
|
||||
if(coreServer != null) {
|
||||
Protocol protocol = Protocol.getProtocol(coreServer);
|
||||
|
@ -340,6 +388,8 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
useProxy.setSelected(config.isUseProxy());
|
||||
proxyHost.setDisable(!config.isUseProxy());
|
||||
proxyPort.setDisable(!config.isUseProxy());
|
||||
publicProxyHost.setDisable(!config.isUseProxy());
|
||||
publicProxyPort.setDisable(!config.isUseProxy());
|
||||
|
||||
String proxyServer = config.getProxyServer();
|
||||
if(proxyServer != null) {
|
||||
|
@ -407,6 +457,11 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
private void setFieldsEditable(boolean editable) {
|
||||
serverTypeToggleGroup.getToggles().forEach(toggle -> ((ToggleButton)toggle).setDisable(!editable));
|
||||
|
||||
publicElectrumServer.setDisable(!editable);
|
||||
publicUseProxy.setDisable(!editable);
|
||||
publicProxyHost.setDisable(!editable);
|
||||
publicProxyPort.setDisable(!editable);
|
||||
|
||||
coreHost.setDisable(!editable);
|
||||
corePort.setDisable(!editable);
|
||||
coreAuthToggleGroup.getToggles().forEach(toggle -> ((ToggleButton)toggle).setDisable(!editable));
|
||||
|
@ -455,6 +510,15 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
}
|
||||
|
||||
private void setupValidation() {
|
||||
validationSupport.registerValidator(publicProxyHost, Validator.combine(
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Proxy host required", publicUseProxy.isSelected() && newValue.isEmpty()),
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Invalid host name", getHost(newValue) == null)
|
||||
));
|
||||
|
||||
validationSupport.registerValidator(publicProxyPort, Validator.combine(
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Invalid proxy port", !newValue.isEmpty() && !isValidPort(Integer.parseInt(newValue)))
|
||||
));
|
||||
|
||||
validationSupport.registerValidator(coreHost, Validator.combine(
|
||||
(Control c, String newValue) -> ValidationResult.fromErrorIf( c, "Invalid Core host", getHost(newValue) == null)
|
||||
));
|
||||
|
@ -499,6 +563,13 @@ public class ServerPreferencesController extends PreferencesDetailController {
|
|||
validationSupport.setValidationDecorator(new StyleClassValidationDecoration());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ChangeListener<PublicElectrumServer> getPublicElectrumServerListener(Config config) {
|
||||
return (observable, oldValue, newValue) -> {
|
||||
config.setPublicElectrumServer(newValue.getUrl());
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ChangeListener<String> getBitcoinCoreListener(Config config) {
|
||||
return (observable, oldValue, newValue) -> {
|
||||
|
|
|
@ -32,3 +32,20 @@
|
|||
.scroll-pane {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.public-warning {
|
||||
-fx-text-fill: rgb(238, 210, 2);
|
||||
}
|
||||
|
||||
.public-electrum {
|
||||
-fx-text-fill: linear-gradient(to bottom, derive(rgb(238, 210, 2), 30%), rgb(238, 210, 2));
|
||||
}
|
||||
|
||||
.bitcoin-core {
|
||||
-fx-text-fill: linear-gradient(to bottom, derive(#50a14f, 30%), #50a14f);
|
||||
}
|
||||
|
||||
.private-electrum {
|
||||
-fx-text-fill: linear-gradient(to bottom, derive(#0b99c9, 30%), #0b99c9);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<?import com.sparrowwallet.sparrow.net.ServerType?>
|
||||
<?import com.sparrowwallet.sparrow.net.CoreAuthType?>
|
||||
<?import com.sparrowwallet.sparrow.control.HelpLabel?>
|
||||
<?import javafx.collections.FXCollections?>
|
||||
<?import com.sparrowwallet.sparrow.net.PublicElectrumServer?>
|
||||
<?import com.sparrowwallet.sparrow.control.CopyableLabel?>
|
||||
<GridPane hgap="10.0" vgap="10.0" stylesheets="@preferences.css, @../general.css" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.preferences.ServerPreferencesController">
|
||||
<padding>
|
||||
<Insets left="25.0" right="25.0" top="25.0" />
|
||||
|
@ -30,17 +33,31 @@
|
|||
<Form GridPane.columnIndex="0" GridPane.rowIndex="0">
|
||||
<Fieldset inputGrow="SOMETIMES" text="Server">
|
||||
<Field text="Type:">
|
||||
<SegmentedButton>
|
||||
<SegmentedButton fx:id="serverTypeSegmentedButton">
|
||||
<toggleGroup>
|
||||
<ToggleGroup fx:id="serverTypeToggleGroup" />
|
||||
</toggleGroup>
|
||||
<buttons>
|
||||
<ToggleButton fx:id="publicElectrumToggle" text="Public Electrum" toggleGroup="$serverTypeToggleGroup">
|
||||
<graphic>
|
||||
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="TOGGLE_ON" styleClass="public-electrum" />
|
||||
</graphic>
|
||||
<userData>
|
||||
<ServerType fx:constant="PUBLIC_ELECTRUM_SERVER"/>
|
||||
</userData>
|
||||
</ToggleButton>
|
||||
<ToggleButton text="Bitcoin Core" toggleGroup="$serverTypeToggleGroup">
|
||||
<graphic>
|
||||
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="TOGGLE_ON" styleClass="bitcoin-core" />
|
||||
</graphic>
|
||||
<userData>
|
||||
<ServerType fx:constant="BITCOIN_CORE"/>
|
||||
</userData>
|
||||
</ToggleButton>
|
||||
<ToggleButton text="Electrum Server" toggleGroup="$serverTypeToggleGroup">
|
||||
<ToggleButton text="Private Electrum" toggleGroup="$serverTypeToggleGroup">
|
||||
<graphic>
|
||||
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="TOGGLE_ON" styleClass="private-electrum" />
|
||||
</graphic>
|
||||
<userData>
|
||||
<ServerType fx:constant="ELECTRUM_SERVER"/>
|
||||
</userData>
|
||||
|
@ -51,6 +68,43 @@
|
|||
</Fieldset>
|
||||
</Form>
|
||||
|
||||
<Form fx:id="publicElectrumForm" GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||
<Fieldset inputGrow="SOMETIMES" text="Public Electrum Server">
|
||||
<Field text="URL:">
|
||||
<ComboBox fx:id="publicElectrumServer">
|
||||
<items>
|
||||
<FXCollections fx:factory="observableArrayList">
|
||||
<PublicElectrumServer fx:constant="BLOCKSTREAM_INFO" />
|
||||
<PublicElectrumServer fx:constant="ELECTRUM_BLOCKSTREAM_INFO" />
|
||||
<PublicElectrumServer fx:constant="LUKECHILDS_CO" />
|
||||
</FXCollections>
|
||||
</items>
|
||||
</ComboBox>
|
||||
</Field>
|
||||
<Field text="">
|
||||
<Label alignment="CENTER">
|
||||
<graphic>
|
||||
<Glyph fontFamily="Font Awesome 5 Free Solid" fontSize="12" icon="EXCLAMATION_TRIANGLE" styleClass="public-warning" />
|
||||
</graphic>
|
||||
<padding>
|
||||
<Insets right="5" />
|
||||
</padding>
|
||||
</Label>
|
||||
<CopyableLabel text="Warning!" />
|
||||
</Field>
|
||||
<Field text="">
|
||||
<CopyableLabel text="Using a public server means it can see your transactions."/>
|
||||
</Field>
|
||||
<Field text="Use Proxy:">
|
||||
<UnlabeledToggleSwitch fx:id="publicUseProxy"/>
|
||||
</Field>
|
||||
<Field text="Proxy URL:">
|
||||
<TextField fx:id="publicProxyHost" />
|
||||
<TextField fx:id="publicProxyPort" prefWidth="80" />
|
||||
</Field>
|
||||
</Fieldset>
|
||||
</Form>
|
||||
|
||||
<Form fx:id="coreForm" GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||
<Fieldset inputGrow="SOMETIMES" text="Bitcoin Core RPC">
|
||||
<Field text="URL:">
|
||||
|
@ -98,7 +152,7 @@
|
|||
</Form>
|
||||
|
||||
<Form fx:id="electrumForm" GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||
<Fieldset inputGrow="SOMETIMES" text="Electrum Server">
|
||||
<Fieldset inputGrow="SOMETIMES" text="Private Electrum Server">
|
||||
<Field text="URL:">
|
||||
<TextField fx:id="electrumHost" promptText="e.g. 127.0.0.1"/>
|
||||
<TextField fx:id="electrumPort" promptText="e.g. 50002" prefWidth="80" />
|
||||
|
|
Loading…
Reference in a new issue