Gas Price Oracle library for Ethereum dApps
This is a library with a collection of onchain and offchain gas price oracle URLs
Supported networks
Ethereum Mainnet
Current offchain list:
Current onchain list:
Binance Smart Chain
Current offchain list:
Gnosis Chain
Current offchain list:
Polygon (Matic) Network
Current offchain list:
Avalanche C Network
Current offchain list:
Installation
npm i gas-price-oracle
or
yarn add gas-price-oracle
Import
const { GasPriceOracle } = require('gas-price-oracle')
or
import { GasPriceOracle } from 'gas-price-oracle'
Usage
Configuration
type GasPrice = Record<'instant' | 'fast' | 'standard' | 'low', number>
type EstimatedGasPrice = {
maxFeePerGas: number
baseFee: number | undefined
maxPriorityFeePerGas: number
}
type FallbackGasPrices = {
gasPrices?: GasPrice
estimated?: EstimatedGasPrice
}
type GasOracleOptions = {
chainId?: number
timeout?: number
defaultRpc?: string
blocksCount?: number
percentile?: number
blockTime?: number // seconds
shouldCache?: boolean
fallbackGasPrices?: FallbackGasPrices
}
const options: GasOracleOptions = {
chainId: 1,
percentile: 5, // Which percentile of effective priority fees to include
blocksCount: 10, // How many blocks to consider for priority fee estimation
defaultRpc: 'https://api.mycryptoapi.com/eth',
blockTime: 10, // seconds
shouldCache: false,
timeout: 10000, // specifies the number of milliseconds before the request times out.
minPriority: 0, // specifies the min maxPriorityFeePerGas.
fallbackGasPrices: {
gasPrices: {
instant: 28,
fast: 22,
standard: 17,
low: 11,
},
estimated: {
maxFeePerGas: 20,
maxPriorityFeePerGas: 3,
},
},
}
The Oracle can cache rpc calls
For caching needs to provide to GasOracleOptions
shouldCache: true
blockTime: <Chain block time duration>
EIP-1559 (estimated) gasPrice only
const oracle = new GasPriceOracle({ chainId: 1 })
type EstimatedGasPrice = {
maxFeePerGas: number
baseFee: number | undefined
maxPriorityFeePerGas: number
}
fallbackGasPrices: EstimatedGasPrice = {
maxFeePerGas: 20,
maxPriorityFeePerGas: 3,
}
oracle.eip1559.estimateFees(fallbackGasPrices).then((gasPrices: EstimatedGasPrice) => {
console.log(gasPrices) // { baseFee: 14, maxFeePerGas: 17, maxPriorityFeePerGas: 3 }
})
Legacy gasPrice only
const oracle = new GasPriceOracle({ chainId: 1 })
type GasPrice = Record<'instant' | 'fast' | 'standard' | 'low', number>
fallbackGasPrices: GasPrice = {
instant: 28,
fast: 22,
standard: 17,
low: 11,
}
oracle.legacy.gasPrices(fallbackGasPrices).then((gasPrices: GasPrice) => {
console.log(gasPrices) // { instant: 21.5, fast: 19, standard: 17, low: 15 }
})
The oracle.legacy.gasPrices
method also accepts shouldGetMedian
argument (true
) by default. For more details see below.
Under the hood it's a combination of fetchMedianGasPriceOffChain
(fetchGasPricesOffChain
) and fetchGasPricesOnChain
methods.
Estimated gasPrices (EIP-1559) and Legacy gasPrice
const oracle = new GasPriceOracle(options)
type GasPriceWithEstimate = {
gasPrices: GasPrice
estimate: EstimatedGasPrice
}
type GasPricesWithEstimateInput = {
shouldGetMedian?: boolean
fallbackGasPrices?: FallbackGasPrices
}
// optional fallbackGasPrices
const fallbackGasPrices: FallbackGasPrices = {
gasPrices: {
instant: 28,
fast: 22,
standard: 17,
low: 11,
},
estimated: {
maxFeePerGas: 20,
maxPriorityFeePerGas: 3,
},
}
oracle.gasPricesWithEstimate({ fallbackGasPrices, shouldGetMedian: true }).then((gasPrices: GasPriceWithEstimate) => {
console.log(gasPrices) // {
// estimated: { baseFee: 14, maxFeePerGas: 17, maxPriorityFeePerGas: 3 },
// gasPrices: { instant: 21.5, fast: 19, standard: 17, low: 15 }
// }}
})
Estimated gasPrices (EIP-1559) or Legacy gasPrice
const oracle = new GasPriceOracle(options)
type GetGasPriceInput = {
isLegacy?: boolean
shouldGetMedian?: boolean
fallbackGasPrices?: GasPrice
}
// optional fallbackGasPrices
const fallbackGasPrices: FallbackGasPrices = {
gasPrices: {
instant: 28,
fast: 22,
standard: 17,
low: 11,
},
estimated: {
maxFeePerGas: 20,
maxPriorityFeePerGas: 3,
},
}
oracle.gasPrices({ fallbackGasPrices, shouldGetMedian: true }).then((gasPrices: GasPrice | EstimatedGasPrice) => {
console.log(gasPrices) // {
// baseFee: 14, maxFeePerGas: 17, maxPriorityFeePerGas: 3 ||
// instant: 21.5, fast: 19, standard: 17, low: 15
// }}
})
The gasPrices
method also accepts isLegacy
argument (false
) by default. If isLegacy: true
- legacy gasPrice
will be provided. If the estimate Gas
crashes, legacy gas Price
will be provided.
Get transaction gasPrice params
const oracle = new GasPriceOracle(options)
type GetTxGasParamsInput = {
bumpPercent?: number
legacySpeed?: GasPriceKey
isLegacy?: boolean
shouldGetMedian?: boolean
fallbackGasPrices?: FallbackGasPrices
}
type GetTxGasParamsRes =
| {
gasPrice: number
}
| {
maxFeePerGas: number
maxPriorityFeePerGas: number
}
const gasParams: GetTxGasParamsRes = await oracle.getTxGasParams({ legacySpeed: 'fast', bumpPercent: 30 })
console.log(gasParams) // { maxFeePerGas: 17, maxPriorityFeePerGas: 3 } || { gasPrice: 19 }
web3.eth.sendTransaction({
from: '0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8',
to: '0xac03bb73b6a9e108530aff4df5077c2b3d481e5a',
nonce: '0',
gasLimit: '21000',
value: '10000000000',
...gasParams,
})
bumpPercent
argument (0
by default) - response data will increase by bumpPercent
%.
legacySpeed
argument (fast
by default) - select the speed of legacy gasPrice.
Offchain oracles only
const oracle = new GasPriceOracle({ chainId: 1 })
// shouldGetMedian: boolean | undefined
oracle.legacy.fetchGasPricesOffChain((shouldGetMedian = true)).then((gasPrices: GasPrice) => {
console.log(gasPrices) // { instant: 50, fast: 21, standard: 10, low: 3 }
})
Offchain oracles only (get median price)
const oracle = new GasPriceOracle({ chainId: 1 })
oracle.legacy.fetchMedianGasPriceOffChain().then((gasPrices: GasPrice) => {
console.log(gasPrices) // { instant: 50, fast: 21, standard: 10, low: 3 }
})
This command provides the median gas price of all configured oracles.
Custom RPC URL for onchain oracles
const defaultRpc = 'https://mainnet.infura.io/v3/<API_KEY>'
const oracle = new GasPriceOracle({ defaultRpc, chainId: 1 })
oracle.legacy.fetchGasPricesOnChain().then((gasPrices: number) => {
console.log(gasPrices) // 21
})
To get gasPrices from a chain outside of the application's chain list (Binance, Gnosis, Polygon, Avalanche), you should enter the rpcUrl into initial GasPriceOracle options_
const defaultRpc = 'https://rpc.goerli.mudit.blog/' // goerli public rpcUrl
const oracle = new GasPriceOracle({ defaultRpc, chainId: 5 })
oracle.gasPrices()