Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
Overview
FeeOracle provides real-time gas price estimation for Ethereum transactions. It fetches current network fee data, estimates EIP-1559 fees with configurable priority levels, and supports watching for fee updates.
import { FeeOracle } from '@voltaire/FeeOracle'
const oracle = FeeOracle({ provider })
// Get current fee data
const feeData = await oracle.getFeeData()
console.log(`Gas price: ${feeData.gasPrice}`)
console.log(`Base fee: ${feeData.baseFeePerGas}`)
// Estimate EIP-1559 fees with priority
const fees = await oracle.estimateEip1559Fees({ priority: 'high' })
const tx = {
maxFeePerGas: fees.maxFeePerGas,
maxPriorityFeePerGas: fees.maxPriorityFeePerGas,
}
// Watch for fee updates
const unsubscribe = oracle.watchFees(
(data) => console.log(`New base fee: ${data.baseFeePerGas}`),
{ pollingInterval: 12000 }
)
API
Factory
function FeeOracle(options: FeeOracleOptions): FeeOracleInstance
Creates a FeeOracle instance bound to a provider.
Options:
| Option | Type | Default | Description |
|---|
provider | EIP-1193 Provider | required | JSON-RPC provider with request method |
priorityFeePercentile | number | 50 | Percentile for priority fee calculation from fee history |
historyBlocks | number | 4 | Number of blocks to analyze for priority fee estimation |
getFeeData
Fetch current network fee data.
const feeData = await oracle.getFeeData()
console.log(`Gas price: ${feeData.gasPrice}`) // Legacy gas price
console.log(`Base fee: ${feeData.baseFeePerGas}`) // EIP-1559 base fee
console.log(`Max fee: ${feeData.maxFeePerGas}`) // Suggested max fee
console.log(`Priority fee: ${feeData.maxPriorityFeePerGas}`) // Suggested priority fee
console.log(`Blob fee: ${feeData.blobBaseFee}`) // EIP-4844 blob fee
console.log(`Block: ${feeData.blockNumber}`) // Block this data is from
Returns: Promise<FeeDataType>
estimateEip1559Fees
Estimate fees for an EIP-1559 transaction with configurable priority.
// Default (medium priority)
const fees = await oracle.estimateEip1559Fees()
// High priority for urgent transactions
const urgentFees = await oracle.estimateEip1559Fees({ priority: 'high' })
// Low priority for non-urgent transactions
const cheapFees = await oracle.estimateEip1559Fees({ priority: 'low' })
// Custom base fee buffer (50% instead of default 25%)
const bufferedFees = await oracle.estimateEip1559Fees({
priority: 'medium',
baseFeeMultiplier: 1.5
})
Options:
| Option | Type | Default | Description |
|---|
priority | 'low' | 'medium' | 'high' | 'medium' | Transaction priority level |
baseFeeMultiplier | number | 1.25 | Buffer multiplier for base fee increases |
Priority multipliers:
low: 0.8x priority fee
medium: 1.0x priority fee
high: 1.5x priority fee
Returns: Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }>
watchFees
Subscribe to fee updates with polling.
// Basic usage
const unsubscribe = oracle.watchFees((feeData) => {
console.log(`Base fee: ${feeData.baseFeePerGas}`)
})
// With custom polling interval (every 6 seconds)
const unsubscribe = oracle.watchFees(
(feeData) => updateUI(feeData),
{ pollingInterval: 6000 }
)
// With AbortSignal for cleanup
const controller = new AbortController()
oracle.watchFees(
(feeData) => process(feeData),
{ signal: controller.signal }
)
// Later: stop watching
controller.abort()
// or: unsubscribe()
Options:
| Option | Type | Default | Description |
|---|
pollingInterval | number | 12000 | Poll interval in milliseconds |
signal | AbortSignal | - | Signal for cancellation |
Returns: () => void - Unsubscribe function
Types
FeeDataType
type FeeDataType = {
/** Current gas price (legacy transactions) */
readonly gasPrice: bigint
/** Current base fee per gas (EIP-1559, null if not supported) */
readonly baseFeePerGas: bigint | null
/** Suggested max fee per gas (EIP-1559) */
readonly maxFeePerGas: bigint | null
/** Suggested max priority fee per gas (EIP-1559) */
readonly maxPriorityFeePerGas: bigint | null
/** Current blob base fee (EIP-4844, null if not supported) */
readonly blobBaseFee: bigint | null
/** Block number this data was fetched from */
readonly blockNumber: bigint
}
FeeEstimateOptions
interface FeeEstimateOptions {
/** Priority level for fee estimation */
priority?: 'low' | 'medium' | 'high'
/** Multiplier for base fee buffer (default: 1.25) */
baseFeeMultiplier?: number
}
FeeOracleOptions
interface FeeOracleOptions {
/** EIP-1193 provider */
provider: {
request(args: { method: string; params?: unknown[] }): Promise<unknown>
}
/** Default priority fee percentile (default: 50) */
priorityFeePercentile?: number
/** History blocks to analyze for priority fee (default: 4) */
historyBlocks?: number
}
Examples
Transaction with Dynamic Fees
import { FeeOracle } from '@voltaire/FeeOracle'
const oracle = FeeOracle({ provider })
const fees = await oracle.estimateEip1559Fees({ priority: 'high' })
const tx = {
to: '0x...',
value: 1000000000000000000n, // 1 ETH
maxFeePerGas: fees.maxFeePerGas,
maxPriorityFeePerGas: fees.maxPriorityFeePerGas,
}
const hash = await wallet.sendTransaction(tx)
Fee Display UI
import { FeeOracle } from '@voltaire/FeeOracle'
const oracle = FeeOracle({ provider })
// Update UI every block (~12s on mainnet)
oracle.watchFees((feeData) => {
const gweiBaseFee = Number(feeData.baseFeePerGas) / 1e9
document.getElementById('baseFee').textContent = `${gweiBaseFee.toFixed(2)} gwei`
if (feeData.maxPriorityFeePerGas) {
const gweiPriority = Number(feeData.maxPriorityFeePerGas) / 1e9
document.getElementById('priorityFee').textContent = `${gweiPriority.toFixed(2)} gwei`
}
}, { pollingInterval: 12000 })
Legacy Chain Support
FeeOracle handles chains without EIP-1559 support gracefully:
const oracle = FeeOracle({ provider })
const fees = await oracle.estimateEip1559Fees({ priority: 'medium' })
// On non-EIP-1559 chains, both values equal the adjusted gas price
console.log(fees.maxFeePerGas === fees.maxPriorityFeePerGas) // true
Custom Fee History Analysis
// Analyze more blocks for smoother estimates
const oracle = FeeOracle({
provider,
historyBlocks: 10, // Look at last 10 blocks
priorityFeePercentile: 75 // Target 75th percentile
})
const feeData = await oracle.getFeeData()
How It Works
FeeOracle uses three JSON-RPC methods:
- eth_gasPrice - Gets the legacy gas price
- eth_getBlockByNumber - Fetches the latest block for base fee and blob fee
- eth_feeHistory - Analyzes recent blocks for priority fee estimation
The maxFeePerGas is calculated as baseFee * 2 + priorityFee, providing a buffer for base fee increases across blocks.
See Also