Improve gas calc (#3356)
* update to use Infura gas provider if available. * Ensure up to date gas information has been received before sending transactions.pull/3357/head
parent
80e6ae788f
commit
9677256493
@ -0,0 +1,126 @@ |
||||
package com.alphawallet.app.service; |
||||
|
||||
import static com.alphawallet.app.util.BalanceUtils.gweiToWei; |
||||
|
||||
import android.text.TextUtils; |
||||
|
||||
import com.alphawallet.app.entity.EIP1559FeeOracleResult; |
||||
import com.alphawallet.app.repository.EthereumNetworkRepository; |
||||
import com.alphawallet.app.repository.HttpServiceHelper; |
||||
import com.alphawallet.app.repository.KeyProviderFactory; |
||||
|
||||
import org.json.JSONException; |
||||
import org.json.JSONObject; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.math.BigInteger; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import io.reactivex.Single; |
||||
import okhttp3.OkHttpClient; |
||||
import okhttp3.Request; |
||||
import okhttp3.Response; |
||||
import timber.log.Timber; |
||||
|
||||
public class InfuraGasAPI |
||||
{ |
||||
public static Single<Map<Integer, EIP1559FeeOracleResult>> get1559GasEstimates(final long chainId, final OkHttpClient httpClient) |
||||
{ |
||||
return Single.fromCallable(() -> { |
||||
Map<Integer, EIP1559FeeOracleResult> gasMap = new HashMap<>(); |
||||
|
||||
//ensure we have correct Infura details
|
||||
String gasOracleAPI = EthereumNetworkRepository.getGasOracle(chainId); |
||||
String infuraKey = KeyProviderFactory.get().getInfuraKey(); |
||||
String infuraSecret = KeyProviderFactory.get().getInfuraSecret(); |
||||
|
||||
if (TextUtils.isEmpty(gasOracleAPI) || TextUtils.isEmpty(infuraKey) || TextUtils.isEmpty(infuraSecret)) |
||||
{ |
||||
//require Infura key with API and secret to operate the gas API
|
||||
return gasMap; |
||||
} |
||||
|
||||
final Request.Builder rqBuilder = new Request.Builder() |
||||
.url(gasOracleAPI) |
||||
.get(); |
||||
|
||||
HttpServiceHelper.addInfuraGasCredentials(rqBuilder, KeyProviderFactory.get().getInfuraSecret()); |
||||
|
||||
try (Response response = httpClient.newCall(rqBuilder.build()).execute()) |
||||
{ |
||||
if (response.code() / 200 == 1) |
||||
{ |
||||
String result = response.body() |
||||
.string(); |
||||
gasMap = readGasMap(result); |
||||
} |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
Timber.w(e); |
||||
} |
||||
|
||||
return gasMap; |
||||
}); |
||||
} |
||||
|
||||
private static Map<Integer, EIP1559FeeOracleResult> readGasMap(String apiReturn) |
||||
{ |
||||
Map<Integer, EIP1559FeeOracleResult> gasMap = new HashMap<>(); |
||||
try |
||||
{ |
||||
BigDecimal rBaseFee = BigDecimal.ZERO; |
||||
JSONObject result = new JSONObject(apiReturn); |
||||
if (result.has("estimatedBaseFee")) |
||||
{ |
||||
rBaseFee = new BigDecimal(result.getString("estimatedBaseFee")); |
||||
} |
||||
|
||||
EIP1559FeeOracleResult low = readFeeResult(result, "low", rBaseFee); |
||||
EIP1559FeeOracleResult medium = readFeeResult(result, "medium", rBaseFee); |
||||
EIP1559FeeOracleResult high = readFeeResult(result, "high", rBaseFee); |
||||
|
||||
if (low == null || medium == null || high == null) |
||||
{ |
||||
return gasMap; |
||||
} |
||||
|
||||
BigInteger rapidPriorityFee = (new BigDecimal(high.priorityFee)).multiply(BigDecimal.valueOf(1.2)).toBigInteger(); |
||||
EIP1559FeeOracleResult rapid = new EIP1559FeeOracleResult(high.maxFeePerGas, rapidPriorityFee, gweiToWei(rBaseFee)); |
||||
|
||||
gasMap.put(0, rapid); |
||||
gasMap.put(1, high); |
||||
gasMap.put(2, medium); |
||||
gasMap.put(3, low); |
||||
} |
||||
catch (JSONException e) |
||||
{ |
||||
//
|
||||
} |
||||
|
||||
return gasMap; |
||||
} |
||||
|
||||
private static EIP1559FeeOracleResult readFeeResult(JSONObject result, String speed, BigDecimal rBaseFee) |
||||
{ |
||||
EIP1559FeeOracleResult oracleResult = null; |
||||
|
||||
try |
||||
{ |
||||
if (result.has(speed)) |
||||
{ |
||||
JSONObject thisSpeed = result.getJSONObject(speed); |
||||
BigDecimal maxFeePerGas = new BigDecimal(thisSpeed.getString("suggestedMaxFeePerGas")); |
||||
BigDecimal priorityFee = new BigDecimal(thisSpeed.getString("suggestedMaxPriorityFeePerGas")); |
||||
oracleResult = new EIP1559FeeOracleResult(gweiToWei(maxFeePerGas), gweiToWei(priorityFee), gweiToWei(rBaseFee)); |
||||
} |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
Timber.e("Infura GasOracle read failing; please adjust your Infura API settings."); |
||||
} |
||||
|
||||
return oracleResult; |
||||
} |
||||
} |
Loading…
Reference in new issue