12 changed files with 215 additions and 59 deletions
@ -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; |
|||
} |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -1,11 +1,11 @@ |
|||
package com.sparrowwallet.sparrow.wallet; |
|||
|
|||
public enum FeeRateSelection { |
|||
public enum FeeRatesSelection { |
|||
BLOCK_TARGET("Block Target"), MEMPOOL_SIZE("Mempool Size"); |
|||
|
|||
private final String name; |
|||
|
|||
private FeeRateSelection(String name) { |
|||
private FeeRatesSelection(String name) { |
|||
this.name = name; |
|||
} |
|||
|
Loading…
Reference in new issue