eth_feeHistory - Bittensor RPC Method
Get historical gas fee data on Bittensor including base fees and priority fee percentiles. Essential for gas price prediction, fee estimation UIs, and network congestion monitoring.
Returns historical gas fee data on Bittensor, including base fees per gas and priority fee percentiles for a range of recent blocks. This data is essential for building accurate fee estimation algorithms for EIP-1559 transactions.
Why Bittensor? Build on the decentralized machine intelligence network built around subnets, TAO staking, and validator-miner coordination with Yuma Consensus, subnet-based specialization, dual Substrate and EVM surfaces, and onchain incentive coordination.
When to Use This Method
The eth_feeHistory method serves these key scenarios for AI/ML developers, subnet operators, and teams building decentralized machine learning applications:
- Calculate optimal EIP-1559 fee parameters - Derive
maxPriorityFeePerGasfrom reward percentiles andmaxFeePerGasfrom base fee trends for decentralized AI inference, subnet-specific AI models, TAO staking, and cross-subnet AI collaboration - Analyze fee market trends - Inspect historical base fees and gas utilization ratios to forecast fee direction and time transactions for lower costs
- Build intelligent gas pricing strategies - Create automated fee estimation that adapts to network congestion on Bittensor without manual intervention
- Predict future base fees - Use the trailing
baseFeePerGasvalue (indexblockCountin the array) to anticipate the next block's base fee using EIP-1559 elasticity math
Common Use Cases
1. Calculate Optimal EIP-1559 Fee Parameters
Derive maxPriorityFeePerGas from reward percentile data and set maxFeePerGas with a safety margin above the predicted next base fee. This approach gives you fee parameters tuned to real network conditions on Bittensor.
import { JsonRpcProvider, formatUnits } from 'ethers';
const provider = new JsonRpcProvider('https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY');
async function getEIP1559Fees(blockCount = 10) {
const feeHistory = await provider.send('eth_feeHistory', [
'0x' + blockCount.toString(16),
'latest',
[50, 90]
]);
const nextBaseFee = BigInt(feeHistory.baseFeePerGas[blockCount]);
const rewards50th = feeHistory.reward.map(r => BigInt(r[0]));
const rewards90th = feeHistory.reward.map(r => BigInt(r[1]));
const avg50th = rewards50th.reduce((s, r) => s + r, 0n) / BigInt(blockCount);
const avg90th = rewards90th.reduce((s, r) => s + r, 0n) / BigInt(blockCount);
return {
medium: {
maxPriorityFeePerGas: avg50th,
maxFeePerGas: nextBaseFee * 2n + avg50th
},
fast: {
maxPriorityFeePerGas: avg90th,
maxFeePerGas: nextBaseFee * 2n + avg90th
}
};
}
const fees = await getEIP1559Fees();
console.log('Medium priority fee:', formatUnits(fees.medium.maxPriorityFeePerGas, 'gwei'), 'Gwei');
console.log('Fast priority fee:', formatUnits(fees.fast.maxPriorityFeePerGas, 'gwei'), 'Gwei');2. Build Fee Estimation UI
Display recent base fee trends and provide low/medium/high fee estimates to end users. This pattern powers gas estimation widgets in wallets and dApp interfaces.
import { JsonRpcProvider, formatUnits } from 'ethers';
const provider = new JsonRpcProvider('https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY');
async function getFeeEstimateUI(blockRange = 20) {
const feeHistory = await provider.send('eth_feeHistory', [
'0x' + blockRange.toString(16),
'latest',
[10, 50, 90]
]);
const baseFees = feeHistory.baseFeePerGas.map(f => Number(BigInt(f)) / 1e9);
const rewardAvgs = [0, 1, 2].map(idx => {
const fees = feeHistory.reward.map(r => Number(BigInt(r[idx])) / 1e9);
return fees.reduce((s, f) => s + f, 0) / fees.length;
});
const nextBaseFee = baseFees[baseFees.length - 1];
return {
currentBaseFee: nextBaseFee,
baseFeeTrend: baseFees.slice(-5),
fees: {
low: { maxPriority: rewardAvgs[0], max: nextBaseFee + rewardAvgs[0] },
medium: { maxPriority: rewardAvgs[1], max: nextBaseFee * 2 + rewardAvgs[1] },
high: { maxPriority: rewardAvgs[2], max: nextBaseFee * 3 + rewardAvgs[2] }
}
};
}
const estimate = await getFeeEstimateUI();
console.log('Base fee:', estimate.currentBaseFee, 'Gwei');
console.log('Low:', estimate.fees.low);
console.log('Medium:', estimate.fees.medium);
console.log('High:', estimate.fees.high);3. Implement Adaptive Gas Pricing
Build a pricing engine that automatically adjusts fee parameters based on real-time network congestion. When gas utilization ratios spike above 80%, the system shifts to higher priority fees to maintain inclusion speed.
import { JsonRpcProvider } from 'ethers';
const provider = new JsonRpcProvider('https://api-bittensor-mainnet.n.dwellir.com/YOUR_API_KEY');
async function adaptiveFeeParams(window = 10) {
const feeHistory = await provider.send('eth_feeHistory', [
'0x' + window.toString(16),
'latest',
[25, 50, 75, 90]
]);
const recentUtilization = feeHistory.gasUsedRatio.slice(-3);
const avgUtilization = recentUtilization.reduce((s, r) => s + r, 0) / recentUtilization.length;
const baseFeePerGas = BigInt(feeHistory.baseFeePerGas[window]);
let priorityFeePercentile;
let baseFeeMultiplier;
if (avgUtilization > 0.8) {
priorityFeePercentile = 3;
baseFeeMultiplier = 3;
console.log('High congestion detected, using premium fees');
} else if (avgUtilization > 0.5) {
priorityFeePercentile = 2;
baseFeeMultiplier = 2;
console.log('Moderate congestion, using standard fees');
} else {
priorityFeePercentile = 1;
baseFeeMultiplier = 2;
console.log('Low congestion, using economy fees');
}
const maxPriorityFeePerGas = feeHistory.reward.reduce(
(sum, r) => sum + BigInt(r[priorityFeePercentile]), 0n
) / BigInt(window);
return {
maxPriorityFeePerGas,
maxFeePerGas: baseFeePerGas * BigInt(baseFeeMultiplier) + maxPriorityFeePerGas,
congestionLevel: avgUtilization > 0.8 ? 'high' : avgUtilization > 0.5 ? 'moderate' : 'low'
};
}
const params = await adaptiveFeeParams();
console.log('Adaptive fee params:', params);Best Practices
- Use 5-20 blocks of history for accurate fee estimation: fewer blocks miss recent trends, more blocks dilute signal with stale data
- Calculate
maxPriorityFeePerGasfrom reward percentiles: use the 50th percentile for normal confirmation and the 90th for fast inclusion - Multiply
baseFeePerGasby 2x as a safety margin formaxFeePerGas: this covers a 12.5% base fee increase per full block over 6 consecutive blocks - Cache fee history results with a short TTL of 12 seconds (roughly one block on Bittensor) to balance freshness with API call efficiency
- Fall back to
eth_gasPriceifeth_feeHistoryreturns a "method not found" error, indicating the node does not support EIP-1559
Code Examples
Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| -32602 | Invalid params | Ensure blockCount is 1-1024, rewardPercentiles is sorted ascending, and values are 0-100 |
| -32601 | Method not found | The node may not support EIP-1559: fall back to eth_gasPrice |
| -32603 | Internal error | Retry with exponential backoff |
| -32005 | Rate limit exceeded | Reduce blockCount or implement caching |
| -32000 | Block range unavailable | Requested blocks may be pruned: use a smaller range or more recent newestBlock |
async function safeFeeHistory(provider, blockCount = 10, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await provider.send('eth_feeHistory', [
'0x' + blockCount.toString(16),
'latest',
[25, 50, 75]
]);
} catch (error) {
if (error.code === -32602 && blockCount > 1) {
// Reduce block count and retry
blockCount = Math.max(1, Math.floor(blockCount / 2));
continue;
}
if (error.code === -32005) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
continue;
}
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}Related Methods
eth_gasPrice- Get the current legacy gas priceeth_maxPriorityFeePerGas- Get the suggested priority fee for EIP-1559 transactionseth_estimateGas- Estimate gas units required for a transactioneth_getBlockByNumber- Get block details includingbaseFeePerGas
eth_maxPriorityFeePerGas
Get the suggested priority fee (tip) per gas for EIP-1559 transactions on Bittensor. Essential for gas estimation, fee optimization, and time-sensitive transaction pricing.
eth_signTransaction
Sign a transaction without broadcasting it on Bittensor. Public shared RPC endpoints commonly return deprecation, unsupported-method, or account-management errors because they do not keep unlocked signers.