mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
fetch fee rates from configurable external sources
This commit is contained in:
parent
02c8415a7b
commit
ee7b741a69
12 changed files with 215 additions and 59 deletions
|
@ -1495,6 +1495,15 @@ public class AppController implements Initializable {
|
||||||
selectedToggle.ifPresent(toggle -> bitcoinUnit.selectToggle(toggle));
|
selectedToggle.ifPresent(toggle -> bitcoinUnit.selectToggle(toggle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void feeRateSourceChanged(FeeRatesSourceChangedEvent event) {
|
||||||
|
ElectrumServer.FeeRatesService feeRatesService = new ElectrumServer.FeeRatesService();
|
||||||
|
feeRatesService.setOnSucceeded(workerStateEvent -> {
|
||||||
|
EventManager.get().post(feeRatesService.getValue());
|
||||||
|
});
|
||||||
|
feeRatesService.start();
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void fiatCurrencySelected(FiatCurrencySelectedEvent event) {
|
public void fiatCurrencySelected(FiatCurrencySelectedEvent event) {
|
||||||
ratesService.cancel();
|
ratesService.cancel();
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package com.sparrowwallet.sparrow.event;
|
|
||||||
|
|
||||||
import com.sparrowwallet.sparrow.wallet.FeeRateSelection;
|
|
||||||
|
|
||||||
public class FeeRateSelectionChangedEvent {
|
|
||||||
private final FeeRateSelection feeRateSelection;
|
|
||||||
|
|
||||||
public FeeRateSelectionChangedEvent(FeeRateSelection feeRateSelection) {
|
|
||||||
this.feeRateSelection = feeRateSelection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FeeRateSelection getFeeRateSelection() {
|
|
||||||
return feeRateSelection;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.wallet.FeeRatesSelection;
|
||||||
|
|
||||||
|
public class FeeRatesSelectionChangedEvent {
|
||||||
|
private final FeeRatesSelection feeRatesSelection;
|
||||||
|
|
||||||
|
public FeeRatesSelectionChangedEvent(FeeRatesSelection feeRatesSelection) {
|
||||||
|
this.feeRatesSelection = feeRatesSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeeRatesSelection getFeeRateSelection() {
|
||||||
|
return feeRatesSelection;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.net.FeeRatesSource;
|
||||||
|
|
||||||
|
public class FeeRatesSourceChangedEvent {
|
||||||
|
private final FeeRatesSource feeRatesSource;
|
||||||
|
|
||||||
|
public FeeRatesSourceChangedEvent(FeeRatesSource feeRatesSource) {
|
||||||
|
this.feeRatesSource = feeRatesSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeeRatesSource getFeeRateSource() {
|
||||||
|
return feeRatesSource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,8 @@ import com.sparrowwallet.drongo.BitcoinUnit;
|
||||||
import com.sparrowwallet.sparrow.Mode;
|
import com.sparrowwallet.sparrow.Mode;
|
||||||
import com.sparrowwallet.sparrow.Theme;
|
import com.sparrowwallet.sparrow.Theme;
|
||||||
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
||||||
import com.sparrowwallet.sparrow.wallet.FeeRateSelection;
|
import com.sparrowwallet.sparrow.net.FeeRatesSource;
|
||||||
|
import com.sparrowwallet.sparrow.wallet.FeeRatesSelection;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -21,7 +22,8 @@ public class Config {
|
||||||
|
|
||||||
private Mode mode;
|
private Mode mode;
|
||||||
private BitcoinUnit bitcoinUnit;
|
private BitcoinUnit bitcoinUnit;
|
||||||
private FeeRateSelection feeRateSelection;
|
private FeeRatesSource feeRatesSource;
|
||||||
|
private FeeRatesSelection feeRatesSelection;
|
||||||
private Currency fiatCurrency;
|
private Currency fiatCurrency;
|
||||||
private ExchangeSource exchangeSource;
|
private ExchangeSource exchangeSource;
|
||||||
private boolean groupByAddress = true;
|
private boolean groupByAddress = true;
|
||||||
|
@ -101,12 +103,21 @@ public class Config {
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeeRateSelection getFeeRateSelection() {
|
public FeeRatesSource getFeeRatesSource() {
|
||||||
return feeRateSelection;
|
return feeRatesSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFeeRateSelection(FeeRateSelection feeRateSelection) {
|
public void setFeeRatesSource(FeeRatesSource feeRatesSource) {
|
||||||
this.feeRateSelection = feeRateSelection;
|
this.feeRatesSource = feeRatesSource;
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeeRatesSelection getFeeRatesSelection() {
|
||||||
|
return feeRatesSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeRatesSelection(FeeRatesSelection feeRatesSelection) {
|
||||||
|
this.feeRatesSelection = feeRatesSelection;
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -604,6 +604,11 @@ public class ElectrumServer {
|
||||||
targetBlocksFeeRatesSats.put(target, minFeeRateSatsKb / 1000d);
|
targetBlocksFeeRatesSats.put(target, minFeeRateSatsKb / 1000d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FeeRatesSource feeRatesSource = Config.get().getFeeRatesSource();
|
||||||
|
if(feeRatesSource != null) {
|
||||||
|
targetBlocksFeeRatesSats.putAll(feeRatesSource.getBlockTargetFeeRates(targetBlocksFeeRatesSats));
|
||||||
|
}
|
||||||
|
|
||||||
return targetBlocksFeeRatesSats;
|
return targetBlocksFeeRatesSats;
|
||||||
} catch(ElectrumServerRpcException e) {
|
} catch(ElectrumServerRpcException e) {
|
||||||
throw new ServerException(e.getMessage(), e);
|
throw new ServerException(e.getMessage(), e);
|
||||||
|
@ -718,7 +723,7 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ConnectionService extends ScheduledService<FeeRatesUpdatedEvent> implements Thread.UncaughtExceptionHandler {
|
public static class ConnectionService extends ScheduledService<FeeRatesUpdatedEvent> implements Thread.UncaughtExceptionHandler {
|
||||||
private static final int FEE_RATES_PERIOD = 1 * 60 * 1000;
|
private static final int FEE_RATES_PERIOD = 30 * 1000;
|
||||||
|
|
||||||
private final boolean subscribe;
|
private final boolean subscribe;
|
||||||
private boolean firstCall = true;
|
private boolean firstCall = true;
|
||||||
|
@ -1014,4 +1019,18 @@ public class ElectrumServer {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class FeeRatesService extends Service<FeeRatesUpdatedEvent> {
|
||||||
|
@Override
|
||||||
|
protected Task<FeeRatesUpdatedEvent> createTask() {
|
||||||
|
return new Task<>() {
|
||||||
|
protected FeeRatesUpdatedEvent call() throws ServerException {
|
||||||
|
ElectrumServer electrumServer = new ElectrumServer();
|
||||||
|
Map<Integer, Double> blockTargetFeeRates = electrumServer.getFeeEstimates(SendController.TARGET_BLOCKS_RANGE);
|
||||||
|
Set<MempoolRateSize> mempoolRateSizes = electrumServer.getMempoolRateSizes();
|
||||||
|
return new FeeRatesUpdatedEvent(blockTargetFeeRates, mempoolRateSizes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
102
src/main/java/com/sparrowwallet/sparrow/net/FeeRatesSource.java
Normal file
102
src/main/java/com/sparrowwallet/sparrow/net/FeeRatesSource.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package com.sparrowwallet.sparrow.net;
|
||||||
|
|
||||||
|
import com.google.common.net.HostAndPort;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum FeeRatesSource {
|
||||||
|
ELECTRUM_SERVER("Electrum Server") {
|
||||||
|
@Override
|
||||||
|
public Map<Integer, Double> getBlockTargetFeeRates(Map<Integer, Double> defaultblockTargetFeeRates) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MEMPOOL_SPACE("mempool.space") {
|
||||||
|
@Override
|
||||||
|
public Map<Integer, Double> getBlockTargetFeeRates(Map<Integer, Double> defaultblockTargetFeeRates) {
|
||||||
|
String url = "https://mempool.space/api/v1/fees/recommended";
|
||||||
|
return getThreeTierFeeRates(defaultblockTargetFeeRates, url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
BITCOINFEES_EARN_COM("bitcoinfees.earn.com") {
|
||||||
|
@Override
|
||||||
|
public Map<Integer, Double> getBlockTargetFeeRates(Map<Integer, Double> defaultblockTargetFeeRates) {
|
||||||
|
String url = "https://bitcoinfees.earn.com/api/v1/fees/recommended";
|
||||||
|
return getThreeTierFeeRates(defaultblockTargetFeeRates, url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(FeeRatesSource.class);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
FeeRatesSource(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Map<Integer, Double> getBlockTargetFeeRates(Map<Integer, Double> defaultblockTargetFeeRates);
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, Double> getThreeTierFeeRates(Map<Integer, Double> defaultblockTargetFeeRates, String url) {
|
||||||
|
Proxy proxy = getProxy();
|
||||||
|
|
||||||
|
Map<Integer, Double> blockTargetFeeRates = new LinkedHashMap<>();
|
||||||
|
try(InputStream is = (proxy == null ? new URL(url).openStream() : new URL(url).openConnection(proxy).getInputStream()); Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ThreeTierRates threeTierRates = gson.fromJson(reader, ThreeTierRates.class);
|
||||||
|
for(Integer blockTarget : defaultblockTargetFeeRates.keySet()) {
|
||||||
|
if(blockTarget < 3) {
|
||||||
|
blockTargetFeeRates.put(blockTarget, threeTierRates.fastestFee);
|
||||||
|
} else if(blockTarget < 6) {
|
||||||
|
blockTargetFeeRates.put(blockTarget, threeTierRates.halfHourFee);
|
||||||
|
} else if(blockTarget <= 10 || defaultblockTargetFeeRates.get(blockTarget) > threeTierRates.hourFee) {
|
||||||
|
blockTargetFeeRates.put(blockTarget, threeTierRates.hourFee);
|
||||||
|
} else {
|
||||||
|
blockTargetFeeRates.put(blockTarget, defaultblockTargetFeeRates.get(blockTarget));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Error retrieving recommended fee rates from " + url, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockTargetFeeRates;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Proxy getProxy() {
|
||||||
|
Config config = Config.get();
|
||||||
|
if(config.isUseProxy()) {
|
||||||
|
HostAndPort proxy = HostAndPort.fromString(config.getProxyServer());
|
||||||
|
InetSocketAddress proxyAddress = new InetSocketAddress(proxy.getHost(), proxy.getPortOrDefault(ProxyTcpOverTlsTransport.DEFAULT_PROXY_PORT));
|
||||||
|
return new Proxy(Proxy.Type.SOCKS, proxyAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ThreeTierRates {
|
||||||
|
Double fastestFee;
|
||||||
|
Double halfHourFee;
|
||||||
|
Double hourFee;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,13 +3,10 @@ package com.sparrowwallet.sparrow.preferences;
|
||||||
import com.sparrowwallet.drongo.BitcoinUnit;
|
import com.sparrowwallet.drongo.BitcoinUnit;
|
||||||
import com.sparrowwallet.sparrow.EventManager;
|
import com.sparrowwallet.sparrow.EventManager;
|
||||||
import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch;
|
import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch;
|
||||||
import com.sparrowwallet.sparrow.event.BitcoinUnitChangedEvent;
|
import com.sparrowwallet.sparrow.event.*;
|
||||||
import com.sparrowwallet.sparrow.event.FeeRateSelectionChangedEvent;
|
|
||||||
import com.sparrowwallet.sparrow.event.FiatCurrencySelectedEvent;
|
|
||||||
import com.sparrowwallet.sparrow.event.VersionCheckStatusEvent;
|
|
||||||
import com.sparrowwallet.sparrow.io.Config;
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
import com.sparrowwallet.sparrow.net.ExchangeSource;
|
||||||
import com.sparrowwallet.sparrow.wallet.FeeRateSelection;
|
import com.sparrowwallet.sparrow.net.FeeRatesSource;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
@ -27,7 +24,7 @@ public class GeneralPreferencesController extends PreferencesDetailController {
|
||||||
private ComboBox<BitcoinUnit> bitcoinUnit;
|
private ComboBox<BitcoinUnit> bitcoinUnit;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ComboBox<FeeRateSelection> feeRateSelection;
|
private ComboBox<FeeRatesSource> feeRatesSource;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ComboBox<Currency> fiatCurrency;
|
private ComboBox<Currency> fiatCurrency;
|
||||||
|
@ -68,16 +65,16 @@ public class GeneralPreferencesController extends PreferencesDetailController {
|
||||||
EventManager.get().post(new BitcoinUnitChangedEvent(newValue));
|
EventManager.get().post(new BitcoinUnitChangedEvent(newValue));
|
||||||
});
|
});
|
||||||
|
|
||||||
if(config.getFeeRateSelection() != null) {
|
if(config.getFeeRatesSource() != null) {
|
||||||
feeRateSelection.setValue(config.getFeeRateSelection());
|
feeRatesSource.setValue(config.getFeeRatesSource());
|
||||||
} else {
|
} else {
|
||||||
feeRateSelection.getSelectionModel().select(0);
|
feeRatesSource.getSelectionModel().select(1);
|
||||||
config.setFeeRateSelection(FeeRateSelection.BLOCK_TARGET);
|
config.setFeeRatesSource(feeRatesSource.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
feeRateSelection.valueProperty().addListener((observable, oldValue, newValue) -> {
|
feeRatesSource.valueProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
config.setFeeRateSelection(newValue);
|
config.setFeeRatesSource(newValue);
|
||||||
EventManager.get().post(new FeeRateSelectionChangedEvent(newValue));
|
EventManager.get().post(new FeeRatesSourceChangedEvent(newValue));
|
||||||
});
|
});
|
||||||
|
|
||||||
if(config.getExchangeSource() != null) {
|
if(config.getExchangeSource() != null) {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package com.sparrowwallet.sparrow.wallet;
|
package com.sparrowwallet.sparrow.wallet;
|
||||||
|
|
||||||
public enum FeeRateSelection {
|
public enum FeeRatesSelection {
|
||||||
BLOCK_TARGET("Block Target"), MEMPOOL_SIZE("Mempool Size");
|
BLOCK_TARGET("Block Target"), MEMPOOL_SIZE("Mempool Size");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private FeeRateSelection(String name) {
|
private FeeRatesSelection(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,13 +269,14 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
mempoolSizeFeeRatesChart.update(mempoolHistogram);
|
mempoolSizeFeeRatesChart.update(mempoolHistogram);
|
||||||
}
|
}
|
||||||
|
|
||||||
FeeRateSelection feeRateSelection = Config.get().getFeeRateSelection();
|
FeeRatesSelection feeRatesSelection = Config.get().getFeeRatesSelection();
|
||||||
updateFeeRateSelection(feeRateSelection);
|
feeRatesSelection = (feeRatesSelection == null ? FeeRatesSelection.BLOCK_TARGET : feeRatesSelection);
|
||||||
feeSelectionToggleGroup.selectToggle(feeRateSelection == FeeRateSelection.BLOCK_TARGET ? targetBlocksToggle : mempoolSizeToggle);
|
updateFeeRateSelection(feeRatesSelection);
|
||||||
|
feeSelectionToggleGroup.selectToggle(feeRatesSelection == FeeRatesSelection.BLOCK_TARGET ? targetBlocksToggle : mempoolSizeToggle);
|
||||||
feeSelectionToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
|
feeSelectionToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
FeeRateSelection newFeeRateSelection = (FeeRateSelection)newValue.getUserData();
|
FeeRatesSelection newFeeRatesSelection = (FeeRatesSelection)newValue.getUserData();
|
||||||
Config.get().setFeeRateSelection(newFeeRateSelection);
|
Config.get().setFeeRatesSelection(newFeeRatesSelection);
|
||||||
EventManager.get().post(new FeeRateSelectionChangedEvent(newFeeRateSelection));
|
EventManager.get().post(new FeeRatesSelectionChangedEvent(newFeeRatesSelection));
|
||||||
});
|
});
|
||||||
|
|
||||||
fee.setTextFormatter(new CoinTextFormatter());
|
fee.setTextFormatter(new CoinTextFormatter());
|
||||||
|
@ -472,8 +473,8 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFeeRateSelection(FeeRateSelection feeRateSelection) {
|
private void updateFeeRateSelection(FeeRatesSelection feeRatesSelection) {
|
||||||
boolean blockTargetSelection = (feeRateSelection == FeeRateSelection.BLOCK_TARGET);
|
boolean blockTargetSelection = (feeRatesSelection == FeeRatesSelection.BLOCK_TARGET);
|
||||||
targetBlocksField.setVisible(blockTargetSelection);
|
targetBlocksField.setVisible(blockTargetSelection);
|
||||||
blockTargetFeeRatesChart.setVisible(blockTargetSelection);
|
blockTargetFeeRatesChart.setVisible(blockTargetSelection);
|
||||||
setDefaultFeeRate();
|
setDefaultFeeRate();
|
||||||
|
@ -481,14 +482,15 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDefaultFeeRate() {
|
private void setDefaultFeeRate() {
|
||||||
|
int defaultTarget = TARGET_BLOCKS_RANGE.get((TARGET_BLOCKS_RANGE.size() / 2) - 1);
|
||||||
|
int index = TARGET_BLOCKS_RANGE.indexOf(defaultTarget);
|
||||||
|
Double defaultRate = getTargetBlocksFeeRates().get(defaultTarget);
|
||||||
if(targetBlocksField.isVisible()) {
|
if(targetBlocksField.isVisible()) {
|
||||||
int defaultTarget = TARGET_BLOCKS_RANGE.get((TARGET_BLOCKS_RANGE.size() / 2) - 1);
|
|
||||||
int index = TARGET_BLOCKS_RANGE.indexOf(defaultTarget);
|
|
||||||
targetBlocks.setValue(index);
|
targetBlocks.setValue(index);
|
||||||
blockTargetFeeRatesChart.select(defaultTarget);
|
blockTargetFeeRatesChart.select(defaultTarget);
|
||||||
setFeeRate(getTargetBlocksFeeRates().get(getTargetBlocks()));
|
setFeeRate(defaultRate);
|
||||||
} else {
|
} else {
|
||||||
feeRange.setValue(5.0);
|
feeRange.setValue(Math.log(defaultRate) / Math.log(2));
|
||||||
setFeeRate(getFeeRangeRate());
|
setFeeRate(getFeeRangeRate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,7 +773,7 @@ public class SendController extends WalletFormController implements Initializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void feeRateSelectionChanged(FeeRateSelectionChangedEvent event) {
|
public void feeRateSelectionChanged(FeeRatesSelectionChangedEvent event) {
|
||||||
updateFeeRateSelection(event.getFeeRateSelection());
|
updateFeeRateSelection(event.getFeeRateSelection());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<?import com.sparrowwallet.sparrow.net.ExchangeSource?>
|
<?import com.sparrowwallet.sparrow.net.ExchangeSource?>
|
||||||
<?import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch?>
|
<?import com.sparrowwallet.sparrow.control.UnlabeledToggleSwitch?>
|
||||||
<?import com.sparrowwallet.sparrow.control.HelpLabel?>
|
<?import com.sparrowwallet.sparrow.control.HelpLabel?>
|
||||||
<?import com.sparrowwallet.sparrow.wallet.FeeRateSelection?>
|
<?import com.sparrowwallet.sparrow.net.FeeRatesSource?>
|
||||||
|
|
||||||
<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.GeneralPreferencesController">
|
<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.GeneralPreferencesController">
|
||||||
<padding>
|
<padding>
|
||||||
|
@ -42,16 +42,17 @@
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<HelpLabel helpText="Display unit for bitcoin amounts.\nAuto displays amounts over 1 BTC in BTC, and amounts under that in satoshis."/>
|
<HelpLabel helpText="Display unit for bitcoin amounts.\nAuto displays amounts over 1 BTC in BTC, and amounts under that in satoshis."/>
|
||||||
</Field>
|
</Field>
|
||||||
<Field text="Fee rate selection:">
|
<Field text="Fee rates source:">
|
||||||
<ComboBox fx:id="feeRateSelection">
|
<ComboBox fx:id="feeRatesSource">
|
||||||
<items>
|
<items>
|
||||||
<FXCollections fx:factory="observableArrayList">
|
<FXCollections fx:factory="observableArrayList">
|
||||||
<FeeRateSelection fx:constant="BLOCK_TARGET" />
|
<FeeRatesSource fx:constant="ELECTRUM_SERVER" />
|
||||||
<FeeRateSelection fx:constant="MEMPOOL_SIZE" />
|
<FeeRatesSource fx:constant="MEMPOOL_SPACE" />
|
||||||
|
<FeeRatesSource fx:constant="BITCOINFEES_EARN_COM" />
|
||||||
</FXCollections>
|
</FXCollections>
|
||||||
</items>
|
</items>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<HelpLabel helpText="Fee rate selection can be done either by estimating the number of blocks until a transaction is mined, or examining the current size of the mempool."/>
|
<HelpLabel helpText="Recommended fee rates can be sourced from your connected Electrum server, or an external source."/>
|
||||||
</Field>
|
</Field>
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
<Fieldset inputGrow="SOMETIMES" text="Fiat" styleClass="wideLabelFieldSet">
|
<Fieldset inputGrow="SOMETIMES" text="Fiat" styleClass="wideLabelFieldSet">
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<?import org.controlsfx.glyphfont.Glyph?>
|
<?import org.controlsfx.glyphfont.Glyph?>
|
||||||
<?import com.sparrowwallet.sparrow.control.MempoolSizeFeeRatesChart?>
|
<?import com.sparrowwallet.sparrow.control.MempoolSizeFeeRatesChart?>
|
||||||
<?import org.controlsfx.control.SegmentedButton?>
|
<?import org.controlsfx.control.SegmentedButton?>
|
||||||
<?import com.sparrowwallet.sparrow.wallet.FeeRateSelection?>
|
<?import com.sparrowwallet.sparrow.wallet.FeeRatesSelection?>
|
||||||
|
|
||||||
<BorderPane stylesheets="@send.css, @wallet.css, @../script.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.SendController">
|
<BorderPane stylesheets="@send.css, @wallet.css, @../script.css, @../general.css" styleClass="wallet-pane" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.wallet.SendController">
|
||||||
<center>
|
<center>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
<Tooltip text="Determine fee via estimated number of blocks"/>
|
<Tooltip text="Determine fee via estimated number of blocks"/>
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<userData>
|
<userData>
|
||||||
<FeeRateSelection fx:constant="BLOCK_TARGET"/>
|
<FeeRatesSelection fx:constant="BLOCK_TARGET"/>
|
||||||
</userData>
|
</userData>
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
<ToggleButton fx:id="mempoolSizeToggle" text="Mempool Size" toggleGroup="$feeSelectionToggleGroup">
|
<ToggleButton fx:id="mempoolSizeToggle" text="Mempool Size" toggleGroup="$feeSelectionToggleGroup">
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<Tooltip text="Determine fee via current mempool size"/>
|
<Tooltip text="Determine fee via current mempool size"/>
|
||||||
</tooltip>
|
</tooltip>
|
||||||
<userData>
|
<userData>
|
||||||
<FeeRateSelection fx:constant="MEMPOOL_SIZE"/>
|
<FeeRatesSelection fx:constant="MEMPOOL_SIZE"/>
|
||||||
</userData>
|
</userData>
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</buttons>
|
</buttons>
|
||||||
|
|
Loading…
Reference in a new issue