Skip to main content

Try it Live

Run MaxPriorityFeePerGas examples in the interactive playground

MaxPriorityFeePerGas

EIP-1559 maximum priority fee per gas (tip) representing the maximum additional fee paid to miners/validators for transaction inclusion. Incentivizes faster processing and transaction ordering.

Overview

Branded bigint type representing priority fee (tip) in Wei. Goes directly to block producer. Higher tips increase inclusion probability and speed.

Quick Start

import * as MaxPriorityFeePerGas from './primitives/MaxPriorityFeePerGas/index.js';

// Set tip for miners
const tip = MaxPriorityFeePerGas.fromGwei(2n); // 2 Gwei tip
console.log(MaxPriorityFeePerGas.toWei(tip)); // 2000000000n

// From hex (RPC format)
const fee = MaxPriorityFeePerGas.from("0x77359400");
console.log(MaxPriorityFeePerGas.toGwei(fee)); // 2n

Type Definition

type MaxPriorityFeePerGasType = bigint & { readonly [brand]: "MaxPriorityFeePerGas" };
Branded bigint preventing confusion with other fee types. All values in Wei.

API

Construction

from(value)

Create from bigint, number, or hex string.
const fee1 = MaxPriorityFeePerGas.from(2000000000n);
const fee2 = MaxPriorityFeePerGas.from("0x77359400");
const fee3 = MaxPriorityFeePerGas.from(2000000000);

fromGwei(gwei)

Create from Gwei value.
const fee = MaxPriorityFeePerGas.fromGwei(2n); // 2000000000n Wei

fromWei(wei)

Create from Wei value (alias for from).
const fee = MaxPriorityFeePerGas.fromWei(2000000000n);

Conversion

toGwei(priorityFee)

Convert to Gwei.
const fee = MaxPriorityFeePerGas.from(2000000000n);
MaxPriorityFeePerGas.toGwei(fee); // 2n

toWei(priorityFee)

Convert to Wei (identity).
MaxPriorityFeePerGas.toWei(fee); // 2000000000n

toNumber(priorityFee)

Convert to number. Warning: precision loss on large values.
MaxPriorityFeePerGas.toNumber(fee); // 2000000000

toBigInt(priorityFee)

Convert to bigint (identity).
MaxPriorityFeePerGas.toBigInt(fee); // 2000000000n

Comparison

equals(priorityFee1, priorityFee2)

Check equality.
const fee1 = MaxPriorityFeePerGas.from(2000000000n);
const fee2 = MaxPriorityFeePerGas.from(2000000000n);
MaxPriorityFeePerGas.equals(fee1, fee2); // true

compare(priorityFee1, priorityFee2)

Compare values. Returns -1, 0, or 1.
const fee1 = MaxPriorityFeePerGas.from(2000000000n);
const fee2 = MaxPriorityFeePerGas.from(5000000000n);
MaxPriorityFeePerGas.compare(fee1, fee2); // -1

Priority Fee Mechanics

Fee Distribution

Priority fee goes to block producer:
const priorityFee = MaxPriorityFeePerGas.fromGwei(2n);
const gasUsed = 21000n;

// Miner receives
const minerRevenue = priorityFee * gasUsed; // 42000000000000n Wei (0.000042 ETH)

Effective Priority Fee

Capped by available budget:
const baseFee = BaseFeePerGas.fromGwei(25n);
const maxFee = MaxFeePerGas.fromGwei(30n);
const maxPriorityFee = MaxPriorityFeePerGas.fromGwei(10n);

// Available for tip: maxFee - baseFee = 5 Gwei
const availableForTip = maxFee - baseFee; // 5000000000n

// Effective priority fee = min(maxPriorityFee, availableForTip)
const effectiveTip = availableForTip < maxPriorityFee
  ? availableForTip
  : maxPriorityFee; // 5 Gwei (capped)

Priority Levels

Standard Levels (2024)

const priority = {
  // No rush, lowest cost
  low: MaxPriorityFeePerGas.fromGwei(1n),

  // Normal inclusion speed
  normal: MaxPriorityFeePerGas.fromGwei(2n),

  // Faster inclusion
  high: MaxPriorityFeePerGas.fromGwei(5n),

  // Next block priority
  urgent: MaxPriorityFeePerGas.fromGwei(10n),
};

Zero Tip

Valid but may delay inclusion:
const noTip = MaxPriorityFeePerGas.from(0n);
// Transaction still valid, but low priority

Real-world Examples

Transaction Priority

// Standard transfer - normal priority
const normalTx = {
  to: '0x...',
  value: parseEther('1.0'),
  maxPriorityFeePerGas: MaxPriorityFeePerGas.fromGwei(2n),
};

// Contract interaction - higher priority
const contractTx = {
  to: '0x...',
  data: '0x...',
  maxPriorityFeePerGas: MaxPriorityFeePerGas.fromGwei(5n),
};

// Time-sensitive trade - urgent
const tradeTx = {
  to: '0x...',
  data: '0x...',
  maxPriorityFeePerGas: MaxPriorityFeePerGas.fromGwei(10n),
};

Dynamic Priority

// Adjust priority based on mempool congestion
async function getRecommendedPriorityFee(
  urgency: 'low' | 'normal' | 'high'
): Promise<bigint> {
  // Query mempool or fee estimation service
  const mempoolStats = await fetchMempoolStats();

  const percentiles = {
    low: mempoolStats.p25,    // 25th percentile
    normal: mempoolStats.p50,  // 50th percentile
    high: mempoolStats.p75,    // 75th percentile
  };

  return MaxPriorityFeePerGas.fromGwei(
    BigInt(percentiles[urgency])
  );
}

MEV Protection

Higher tips can help with MEV:
// Sandwich attack protection
const mevProtectionTip = MaxPriorityFeePerGas.fromGwei(50n);

// Front-run prevention
const privateTx = {
  to: '0x...',
  data: '0x...',
  maxPriorityFeePerGas: mevProtectionTip,
  // Consider using Flashbots or private relay
};

Fee Estimation

Historical Analysis

async function estimatePriorityFee(
  provider,
  blocks = 20,
  percentile = 50
): Promise<bigint> {
  const fees: bigint[] = [];

  for (let i = 0; i < blocks; i++) {
    const block = await provider.getBlock(-i);

    // Collect priority fees from block transactions
    for (const tx of block.transactions) {
      if (tx.maxPriorityFeePerGas) {
        fees.push(MaxPriorityFeePerGas.from(tx.maxPriorityFeePerGas));
      }
    }
  }

  fees.sort((a, b) => Number(a - b));
  const index = Math.floor((fees.length * percentile) / 100);

  return fees[index];
}

Network-specific Defaults

// Mainnet typical
const mainnet = MaxPriorityFeePerGas.fromGwei(2n);

// L2s (cheaper)
const arbitrum = MaxPriorityFeePerGas.fromGwei(1n);
const optimism = MaxPriorityFeePerGas.fromGwei(1n);

// Polygon (very cheap)
const polygon = MaxPriorityFeePerGas.fromGwei(30n); // 30 Gwei common

Common Patterns

Retry with Higher Tip

// Initial submission
let priorityFee = MaxPriorityFeePerGas.fromGwei(2n);
const txHash = await sendTransaction({ maxPriorityFeePerGas: priorityFee });

// If stuck, increase tip
setTimeout(async () => {
  const receipt = await provider.getTransactionReceipt(txHash);
  if (!receipt) {
    // Increase by 20%
    const newPriority = MaxPriorityFeePerGas.fromGwei(
      (MaxPriorityFeePerGas.toGwei(priorityFee) * 120n) / 100n
    );

    // Replace transaction with same nonce
    await sendTransaction({
      nonce: originalNonce,
      maxPriorityFeePerGas: newPriority,
    });
  }
}, 30000); // Check after 30s

Tip Budget

// Calculate optimal tip within budget
function calculateTip(
  baseFee: bigint,
  maxFee: bigint,
  desiredTip: bigint
): bigint {
  const available = maxFee - baseFee;

  return MaxPriorityFeePerGas.from(
    available < desiredTip ? available : desiredTip
  );
}

const baseFee = BaseFeePerGas.fromGwei(25n);
const maxFee = MaxFeePerGas.fromGwei(35n);
const desiredTip = MaxPriorityFeePerGas.fromGwei(15n);

const actualTip = calculateTip(baseFee, maxFee, desiredTip);
// Returns 10 Gwei (capped by available budget)

Cost Calculation

const priorityFee = MaxPriorityFeePerGas.fromGwei(2n);
const gasUsed = 21000n; // Standard transfer

// Cost in Wei
const tipCost = priorityFee * gasUsed; // 42000000000000n

// Cost in ETH (using Denomination)
const ethCost = Number(tipCost) / 1e18; // 0.000042 ETH

Specification