Docs
Supported ChainsZetachainJSON-RPC APITransaction Methods

eth_feeHistory - Zetachain RPC Method

Get historical gas fee data on Zetachain 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 Zetachain, 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 Zetachain? Build on the universal omnichain blockchain enabling cross-chain smart contracts across 50+ chains including Bitcoin with native Bitcoin support, 50+ chain interoperability via UNISON, no bridging required, and partnerships with Curve and SushiSwap.

When to Use This Method

eth_feeHistory is essential for cross-chain dApp developers, Bitcoin DeFi builders, and teams requiring native multi-chain interoperability:

  • Gas Price Prediction — Analyze recent base fee trends to predict future gas costs and set appropriate maxFeePerGas values
  • Fee Estimation UIs — Build gas fee dashboards that show low/medium/high price tiers based on historical percentiles
  • Network Congestion Monitoring — Track gasUsedRatio across blocks to detect congestion patterns on omnichain DeFi, native Bitcoin smart contracts, cross-chain asset management, and unified liquidity aggregation
  • Transaction Cost Analysis — Calculate average transaction costs over time for budgeting and cost optimization

Request Parameters

Request
blockCountQUANTITY

Number of blocks in the requested range (1 to 1024)

newestBlockQUANTITY|TAG

Highest block number or tag (latest, pending) for the range

rewardPercentilesArray<Float>

Ascending list of percentile values (0-100) to sample effective priority fees at each block

Response Body

Response
oldestBlockQUANTITY

Block number of the oldest block in the range

baseFeePerGasArray<QUANTITY>

Array of base fees per gas for each block (length = blockCount + 1, includes the next block's predicted base fee)

gasUsedRatioArray<Float>

Array of gas used ratios (0.0 to 1.0) for each block — values above 0.5 indicate blocks over 50% full

rewardArray<Array<QUANTITY>>

Array of effective priority fee arrays per block, one entry per requested percentile

Error Responses

Errors
Error Response-32602

Code Examples

Bash
curl -X POST https://api-zetachain-mainnet.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_feeHistory",
    "params": ["0x5", "latest", [25, 50, 75]],
    "id": 1
  }'

Common Use Cases

1. Gas Fee Estimator with Confidence Tiers

Build a fee estimator that provides low/medium/high options on Zetachain:

JavaScript
import { JsonRpcProvider, formatUnits } from 'ethers';

const provider = new JsonRpcProvider('https://api-zetachain-mainnet.n.dwellir.com/YOUR_API_KEY');

async function estimateGasFees(blockRange = 20) {
  const feeHistory = await provider.send('eth_feeHistory', [
    '0x' + blockRange.toString(16),
    'latest',
    [10, 50, 90]
  ]);

  // Get the predicted next base fee (last element in baseFeePerGas)
  const nextBaseFee = BigInt(feeHistory.baseFeePerGas[feeHistory.baseFeePerGas.length - 1]);

  // Calculate average priority fees at each percentile
  const avgRewards = [0, 1, 2].map(idx => {
    const fees = feeHistory.reward.map(r => BigInt(r[idx]));
    return fees.reduce((sum, f) => sum + f, 0n) / BigInt(fees.length);
  });

  return {
    low: {
      maxPriorityFeePerGas: avgRewards[0],
      maxFeePerGas: nextBaseFee + avgRewards[0],
      label: 'Low — may take several blocks'
    },
    medium: {
      maxPriorityFeePerGas: avgRewards[1],
      maxFeePerGas: nextBaseFee * 2n + avgRewards[1],
      label: 'Medium — next few blocks'
    },
    high: {
      maxPriorityFeePerGas: avgRewards[2],
      maxFeePerGas: nextBaseFee * 3n + avgRewards[2],
      label: 'High — next block target'
    }
  };
}

const fees = await estimateGasFees();
for (const [tier, data] of Object.entries(fees)) {
  console.log(`${data.label}`);
  console.log(`  Priority: ${formatUnits(data.maxPriorityFeePerGas, 'gwei')} Gwei`);
  console.log(`  Max Fee:  ${formatUnits(data.maxFeePerGas, 'gwei')} Gwei`);
}

2. Network Congestion Monitor

Track Zetachain network congestion using gas utilization ratios:

JavaScript
async function getCongestionLevel(provider, blockRange = 50) {
  const feeHistory = await provider.send('eth_feeHistory', [
    '0x' + blockRange.toString(16),
    'latest',
    []
  ]);

  const ratios = feeHistory.gasUsedRatio;
  const avgRatio = ratios.reduce((sum, r) => sum + r, 0) / ratios.length;
  const recentRatio = ratios.slice(-5).reduce((sum, r) => sum + r, 0) / 5;

  // Detect base fee trend
  const baseFees = feeHistory.baseFeePerGas.map(f => Number(BigInt(f)));
  const firstHalf = baseFees.slice(0, Math.floor(baseFees.length / 2));
  const secondHalf = baseFees.slice(Math.floor(baseFees.length / 2));
  const avgFirst = firstHalf.reduce((a, b) => a + b, 0) / firstHalf.length;
  const avgSecond = secondHalf.reduce((a, b) => a + b, 0) / secondHalf.length;
  const trend = avgSecond > avgFirst * 1.1 ? 'rising' : avgSecond < avgFirst * 0.9 ? 'falling' : 'stable';

  let level;
  if (recentRatio > 0.8) level = 'high';
  else if (recentRatio > 0.5) level = 'moderate';
  else level = 'low';

  return {
    congestion: level,
    averageUtilization: (avgRatio * 100).toFixed(1) + '%',
    recentUtilization: (recentRatio * 100).toFixed(1) + '%',
    baseFeeTrend: trend
  };
}

const congestion = await getCongestionLevel(provider);
console.log('Network congestion:', congestion);

3. Base Fee Prediction

Predict the next block's base fee from recent history:

JavaScript
async function predictBaseFee(provider) {
  const feeHistory = await provider.send('eth_feeHistory', ['0x1', 'latest', []]);

  const currentBaseFee = BigInt(feeHistory.baseFeePerGas[0]);
  const gasUsedRatio = feeHistory.gasUsedRatio[0];

  // EIP-1559 base fee adjustment formula
  // If gas used > 50% target, base fee increases (up to 12.5%)
  // If gas used < 50% target, base fee decreases (up to 12.5%)
  const targetRatio = 0.5;
  const maxChange = 0.125; // 12.5%

  let changeRatio;
  if (gasUsedRatio > targetRatio) {
    changeRatio = Math.min((gasUsedRatio - targetRatio) / targetRatio, 1) * maxChange;
  } else {
    changeRatio = -Math.min((targetRatio - gasUsedRatio) / targetRatio, 1) * maxChange;
  }

  const predictedBaseFee = currentBaseFee + BigInt(Math.floor(Number(currentBaseFee) * changeRatio));

  console.log(`Current base fee: ${Number(currentBaseFee) / 1e9} Gwei`);
  console.log(`Gas used ratio: ${(gasUsedRatio * 100).toFixed(1)}%`);
  console.log(`Predicted next base fee: ${Number(predictedBaseFee) / 1e9} Gwei`);

  return predictedBaseFee;
}

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32602Invalid paramsEnsure blockCount is 1-1024, rewardPercentiles is sorted ascending, and values are 0-100
-32601Method not foundThe node may not support EIP-1559 — fall back to eth_gasPrice
-32603Internal errorRetry with exponential backoff
-32005Rate limit exceededReduce blockCount or implement caching
-32000Block range unavailableRequested blocks may be pruned — use a smaller range or more recent newestBlock
JavaScript
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));
    }
  }
}