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