Skip to main content

Overview

FeeMarket implements Ethereum’s dynamic fee mechanisms: EIP-1559 for base fees and EIP-4844 for blob fees. Use it to calculate next block fees, validate transactions, project fee trends, and estimate costs.
import * as FeeMarket from '@voltaire/FeeMarket';

// Calculate next base fee
const nextBaseFee = FeeMarket.BaseFee(
  15_000_000n,    // parent gas used
  30_000_000n,    // parent gas limit
  1_000_000_000n  // parent base fee (1 gwei)
);

// Calculate blob base fee
const blobFee = FeeMarket.BlobBaseFee(393216n); // excess blob gas

Types

State

Complete fee market state for a block:
type FeeMarketType = {
  gasUsed: bigint;        // Gas used in block
  gasLimit: bigint;       // Gas limit of block
  baseFee: bigint;        // Base fee per gas (wei)
  excessBlobGas: bigint;  // Excess blob gas accumulated
  blobGasUsed: bigint;    // Blob gas used in block
};

TxFeeParams

Transaction fee parameters for EIP-1559:
type TxFeeParams = {
  maxFeePerGas: bigint;         // Maximum fee per gas (wei)
  maxPriorityFeePerGas: bigint; // Priority fee tip (wei)
  baseFee: bigint;              // Current block base fee (wei)
};

BlobTxFeeParams

Extended parameters for blob transactions (EIP-4844):
type BlobTxFeeParams = TxFeeParams & {
  maxFeePerBlobGas: bigint; // Maximum fee per blob gas (wei)
  blobBaseFee: bigint;      // Current blob base fee (wei)
  blobCount: bigint;        // Number of blobs in transaction
};

TxFee

Calculated transaction fee breakdown:
type TxFee = {
  effectiveGasPrice: bigint; // Effective gas price paid (wei/gas)
  priorityFee: bigint;       // Priority fee paid (wei/gas)
  baseFee: bigint;           // Base fee paid (wei/gas)
};

BlobTxFee

Extended fee breakdown for blob transactions:
type BlobTxFee = TxFee & {
  blobGasPrice: bigint;  // Blob gas price paid (wei/blob gas)
  totalBlobFee: bigint;  // Total blob fee (wei)
};

EIP-1559 Methods

BaseFee

Calculate next block’s base fee using the EIP-1559 formula.
const nextBaseFee = FeeMarket.BaseFee(
  parentGasUsed,   // bigint
  parentGasLimit,  // bigint
  parentBaseFee    // bigint
);
Formula:
  • gasTarget = gasLimit / 2
  • If gasUsed > gasTarget: base fee increases (up to 12.5%)
  • If gasUsed < gasTarget: base fee decreases (up to 12.5%)
  • If gasUsed == gasTarget: base fee unchanged
  • Minimum base fee: 7 wei
// Block at target (50% full): unchanged
const fee1 = FeeMarket.BaseFee(15_000_000n, 30_000_000n, 1_000_000_000n);
// fee1 === 1_000_000_000n

// Block full: increases ~12.5%
const fee2 = FeeMarket.BaseFee(30_000_000n, 30_000_000n, 1_000_000_000n);
// fee2 === 1_125_000_000n

// Empty block: decreases ~12.5%
const fee3 = FeeMarket.BaseFee(0n, 30_000_000n, 1_000_000_000n);
// fee3 === 1_000_000_000n (empty blocks maintain fee)

calculateTxFee

Calculate effective transaction fee breakdown.
const fee = FeeMarket.calculateTxFee({
  maxFeePerGas: 2_000_000_000n,
  maxPriorityFeePerGas: 1_000_000_000n,
  baseFee: 800_000_000n
});

// fee.effectiveGasPrice === 1_800_000_000n (baseFee + priority)
// fee.priorityFee === 1_000_000_000n
// fee.baseFee === 800_000_000n
Formula:
  • effectiveGasPrice = min(maxFeePerGas, baseFee + maxPriorityFeePerGas)
  • priorityFee = effectiveGasPrice - baseFee

canIncludeTx

Check if transaction meets minimum fee requirements.
const canInclude = FeeMarket.canIncludeTx({
  maxFeePerGas: 1_000_000_000n,
  maxPriorityFeePerGas: 100_000_000n,
  baseFee: 900_000_000n
});
// canInclude === true (maxFeePerGas >= baseFee)
For blob transactions, also checks maxFeePerBlobGas >= blobBaseFee.

validateTxFeeParams

Validate transaction fee parameters.
const errors = FeeMarket.validateTxFeeParams({
  maxFeePerGas: 2_000_000_000n,
  maxPriorityFeePerGas: 1_000_000_000n,
  baseFee: 800_000_000n
});
// errors === [] (empty array = valid)
Validates:
  • maxFeePerGas >= 0
  • maxPriorityFeePerGas >= 0
  • maxPriorityFeePerGas <= maxFeePerGas
  • baseFee >= 0
  • For blob txs: blobCount between 1 and 6

EIP-4844 Methods

BlobBaseFee

Calculate blob base fee using EIP-4844 exponential formula.
const blobFee = FeeMarket.BlobBaseFee(excessBlobGas);
Formula: Uses Taylor series approximation of MIN_BLOB_BASE_FEE * e^(excessBlobGas / UPDATE_FRACTION)
// No excess: minimum fee (1 wei)
const fee1 = FeeMarket.BlobBaseFee(0n);
// fee1 === 1n

// With excess: exponentially increasing
const fee2 = FeeMarket.BlobBaseFee(393216n);
// fee2 > 1n (increases with excess)

calculateExcessBlobGas

Calculate excess blob gas for next block.
const excess = FeeMarket.calculateExcessBlobGas(
  parentExcessBlobGas,  // bigint
  parentBlobGasUsed     // bigint
);
Formula: max(0, parentExcess + parentBlobGasUsed - TARGET_BLOB_GAS_PER_BLOCK)
// Below target: no excess
const excess1 = FeeMarket.calculateExcessBlobGas(0n, 131072n);
// excess1 === 0n (1 blob < 3 blob target)

// Above target: accumulates
const excess2 = FeeMarket.calculateExcessBlobGas(0n, 524288n);
// excess2 === 131072n (4 blobs - 3 blob target = 1 blob excess)

calculateBlobTxFee

Calculate complete blob transaction fee breakdown.
const fee = FeeMarket.calculateBlobTxFee({
  maxFeePerGas: 2_000_000_000n,
  maxPriorityFeePerGas: 1_000_000_000n,
  baseFee: 800_000_000n,
  maxFeePerBlobGas: 10_000_000n,
  blobBaseFee: 5_000_000n,
  blobCount: 3n
});

// Includes all TxFee fields plus:
// fee.blobGasPrice === 5_000_000n
// fee.totalBlobFee === 5_000_000n * 131072n * 3n

State Methods

nextState

Calculate next block’s complete fee market state.
const currentState = {
  gasUsed: 20_000_000n,
  gasLimit: 30_000_000n,
  baseFee: 1_000_000_000n,
  excessBlobGas: 0n,
  blobGasUsed: 262144n  // 2 blobs
};

const next = FeeMarket.nextState(currentState);
// next.gasUsed === 0n (reset)
// next.baseFee === calculated new base fee
// next.excessBlobGas === calculated new excess
// next.blobGasUsed === 0n (reset)

validateState

Validate block state parameters.
const errors = FeeMarket.validateState({
  gasUsed: 0n,
  gasLimit: 30_000_000n,
  baseFee: 1_000_000_000n,
  excessBlobGas: 0n,
  blobGasUsed: 0n
});
// errors === []
Validates:
  • gasUsed >= 0 and <= gasLimit
  • gasLimit > 0
  • baseFee >= MIN_BASE_FEE (7 wei)
  • excessBlobGas >= 0
  • blobGasUsed >= 0 and <= MAX_BLOB_GAS_PER_BLOCK

projectBaseFees

Project base fees over multiple blocks.
const fees = FeeMarket.projectBaseFees(
  initialState,     // FeeMarketType
  10,               // number of blocks
  25_000_000n,      // average gas used per block
  262144n           // average blob gas used (optional)
);
// fees === [baseFee1, baseFee2, ..., baseFee10]
Useful for fee trend analysis and gas price estimation.

Utility Functions

gweiToWei

Convert gwei to wei.
const wei = FeeMarket.gweiToWei(1.5);
// wei === 1_500_000_000n

weiToGwei

Convert wei to gwei for display.
const gwei = FeeMarket.weiToGwei(1_500_000_000n);
// gwei === "1.500000000"

Constants

EIP-1559 Constants

FeeMarket.Eip1559.MIN_BASE_FEE              // 7n (wei)
FeeMarket.Eip1559.BASE_FEE_CHANGE_DENOMINATOR // 8n (12.5% = 1/8)
FeeMarket.Eip1559.ELASTICITY_MULTIPLIER     // 2n (limit = target * 2)

EIP-4844 Constants

FeeMarket.Eip4844.MIN_BLOB_BASE_FEE          // 1n (wei)
FeeMarket.Eip4844.BLOB_BASE_FEE_UPDATE_FRACTION // 3338477n
FeeMarket.Eip4844.TARGET_BLOB_GAS_PER_BLOCK  // 393216n (3 blobs)
FeeMarket.Eip4844.BLOB_GAS_PER_BLOB          // 131072n (128 KiB)
FeeMarket.Eip4844.MAX_BLOBS_PER_BLOCK        // 6n
FeeMarket.Eip4844.MAX_BLOB_GAS_PER_BLOCK     // 786432n (6 * 131072)

Usage Examples

Estimate Transaction Cost

import * as FeeMarket from '@voltaire/FeeMarket';

async function estimateTransactionCost(
  gasEstimate: bigint,
  currentBaseFee: bigint,
  priorityFee: bigint = 1_000_000_000n
): { maxFee: bigint; estimatedCost: bigint } {
  // Add 20% buffer for base fee volatility
  const maxFeePerGas = currentBaseFee * 120n / 100n + priorityFee;

  const fee = FeeMarket.calculateTxFee({
    maxFeePerGas,
    maxPriorityFeePerGas: priorityFee,
    baseFee: currentBaseFee
  });

  return {
    maxFee: maxFeePerGas,
    estimatedCost: fee.effectiveGasPrice * gasEstimate
  };
}
import * as FeeMarket from '@voltaire/FeeMarket';

function analyzeFeeTrends(state: FeeMarket.FeeMarketType) {
  // Project fees for next 10 blocks at current usage
  const optimistic = FeeMarket.projectBaseFees(state, 10, state.gasLimit / 4n);
  const average = FeeMarket.projectBaseFees(state, 10, state.gasLimit / 2n);
  const congested = FeeMarket.projectBaseFees(state, 10, state.gasLimit * 3n / 4n);

  return {
    low: optimistic[9],
    medium: average[9],
    high: congested[9]
  };
}

Validate Before Submission

import * as FeeMarket from '@voltaire/FeeMarket';

function validateTransaction(
  params: FeeMarket.TxFeeParams | FeeMarket.BlobTxFeeParams
): { valid: boolean; errors: string[] } {
  const errors = FeeMarket.validateTxFeeParams(params);

  if (errors.length === 0 && !FeeMarket.canIncludeTx(params)) {
    errors.push('Transaction fee too low for current base fee');
  }

  return { valid: errors.length === 0, errors };
}
  • Gas - Gas limits and usage
  • Transaction - Transaction types
  • KZG - Blob commitment cryptography
  • EIP-1559 - Fee market specification
  • EIP-4844 - Blob transaction specification