feat: add fetch gas price from rpc

This commit is contained in:
Danil Kovtonyuk 2021-10-04 17:50:53 +10:00 committed by Alexey Pertsev
parent 5036c65643
commit b13a4252ab
3 changed files with 74 additions and 2 deletions

@ -1,6 +1,6 @@
{ {
"name": "gas-price-oracle", "name": "gas-price-oracle",
"version": "0.3.5", "version": "0.4.0",
"description": "Gas Price Oracle library for Ethereum dApps.", "description": "Gas Price Oracle library for Ethereum dApps.",
"main": "lib/index.js", "main": "lib/index.js",
"homepage": "https://github.com/peppersec/gas-price-oracle", "homepage": "https://github.com/peppersec/gas-price-oracle",

@ -185,6 +185,34 @@ export class GasPriceOracle {
throw new Error('All oracles are down. Probably a network error.'); throw new Error('All oracles are down. Probably a network error.');
} }
async fetchGasPriceFromRpc(): Promise<number> {
const rpcUrl = this.configuration.defaultRpc;
const body = {
jsonrpc: '2.0',
id: 1337,
method: 'eth_gasPrice',
params: [],
};
try {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const response = await axios.post(rpcUrl!, body, { timeout: this.configuration.timeout });
if (response.status === 200) {
const { result } = response.data;
let fastGasPrice = new BigNumber(result);
if (fastGasPrice.isZero()) {
throw new Error(`Default RPC provides corrupted values`);
}
fastGasPrice = fastGasPrice.div(1e9);
return fastGasPrice.toNumber();
}
throw new Error(`Fetch gasPrice from default RPC failed..`);
} catch (e) {
console.error(e.message);
throw new Error('Default RPC is down. Probably a network error.');
}
}
async gasPrices(fallbackGasPrices?: GasPrice, median = true): Promise<GasPrice> { async gasPrices(fallbackGasPrices?: GasPrice, median = true): Promise<GasPrice> {
this.lastGasPrice = this.lastGasPrice || fallbackGasPrices || this.configuration.defaultFallbackGasPrices; this.lastGasPrice = this.lastGasPrice || fallbackGasPrices || this.configuration.defaultFallbackGasPrices;
try { try {
@ -206,7 +234,20 @@ export class GasPriceOracle {
}; };
return this.lastGasPrice; return this.lastGasPrice;
} catch (e) { } catch (e) {
console.log('Failed to fetch gas prices from onchain oracles. Last known gas will be returned'); console.log('Failed to fetch gas prices from onchain oracles. Trying from default RPC...');
}
try {
const fastGas = await this.fetchGasPriceFromRpc();
this.lastGasPrice = {
instant: fastGas * 1.3,
fast: fastGas,
standard: fastGas * 0.85,
low: fastGas * 0.5,
};
return this.lastGasPrice;
} catch (e) {
console.log('Failed to fetch gas prices from default RPC. Last known gas will be returned');
} }
return this.lastGasPrice; return this.lastGasPrice;
} }

@ -119,6 +119,37 @@ describe('fetchGasPricesOnChain', function () {
}); });
}); });
describe('fetchGasPriceFromRpc', function () {
it('should work', async function () {
const gas: number = await oracle.fetchGasPriceFromRpc();
gas.should.be.a('number');
gas.should.be.above(1);
gas.should.not.be.equal(0);
});
it('should work with custom rpc', async function () {
const rpc = 'https://ethereum-rpc.trustwalletapp.com';
const oracle = new GasPriceOracle({ defaultRpc: rpc });
oracle.configuration.defaultRpc.should.be.equal(rpc);
const gas: number = await oracle.fetchGasPriceFromRpc();
gas.should.be.a('number');
gas.should.be.above(1);
gas.should.not.be.equal(0);
});
it('should throw if default rpc is down', async function () {
mockery.enable({ useCleanCache: true, warnOnUnregistered: false });
const { GasPriceOracle } = require('../src/index');
oracle = new GasPriceOracle();
await oracle
.fetchGasPriceFromRpc()
.should.be.rejectedWith('Default RPC is down. Probably a network error.');
mockery.disable();
});
});
describe('gasPrice', function () { describe('gasPrice', function () {
it('should work', async function () { it('should work', async function () {
const gas: GasPrice = await oracle.gasPrices(); const gas: GasPrice = await oracle.gasPrices();