Files
skills/docs/money/finance/cryptocurrency/src/gas/gas-estimator.md
2026-05-29 08:20:56 +01:00

5.4 KiB

gas-estimator

(no submodules)

Purpose

Provides EIP-1559 gas-estimation primitives for Ethereum-style chains. Every helper accepts and returns bigint values so callers never lose precision at the JavaScript number boundary — gas costs in wei routinely exceed Number.MAX_SAFE_INTEGER (2^53 - 1) so passing them as number is a bug waiting to happen. The module covers the four canonical operations: estimating a full GasEstimate from a single set of parameters, computing the EIP-1559 ceiling (2 * baseFee + priority), computing the effective gas price (min(maxFee, baseFee + priority)), and formatting wei values as human-readable gwei or ETH decimal strings.

This module is consumed by wallet UIs, transaction-builder libraries, and analytics dashboards. The bigint-everywhere contract is the headline guarantee.

Features

  • estimateGas(params) — full EIP-1559 estimator returning GasEstimate (gasLimit, gasPrice, maxFeePerGas, maxPriorityFeePerGas, totalCost). Honours an optional legacyGasPrice override for non-EIP-1559 transactions.
  • calculateMaxFeePerGas(baseFee, priorityFee) — EIP-1559 ceiling formula.
  • calculateEffectiveGasPrice(baseFee, maxFee, priorityFee) — min(maxFee, baseFee + priorityFee).
  • formatGwei(weiValue) — sign-preserving decimal gwei string with trailing-zero trim.
  • estimateTxCostEth(gasLimit, gasPriceWei) — decimal ETH string (18-decimal contraction with trim).
  • 100% bigint arithmetic — no Number conversion anywhere on the hot path.
  • Universal — no node:* / bun:* / fs / crypto imports.

Usage: Basic

import { estimateGas, formatGwei } from "@suaveplan/cryptocurrency";

const estimate = estimateGas({
    gasLimit: 21000n,
    baseFeePerGas: 30000000000n, // 30 gwei
    maxPriorityFeePerGas: 2000000000n, // 2 gwei
});

console.log(formatGwei(estimate.gasPrice)); // "32"
console.log(estimate.totalCost); // 672000000000000n wei = 0.000672 ETH

Usage: Advanced

import {
    calculateEffectiveGasPrice,
    calculateMaxFeePerGas,
    estimateGas,
    estimateTxCostEth,
} from "@suaveplan/cryptocurrency";

interface BlockHeader {
    baseFeePerGas: bigint;
}

interface UserPreferences {
    priorityFee: bigint;
    gasLimit: bigint;
}

function quoteUserTransaction(header: BlockHeader, prefs: UserPreferences) {
    // Cap our max-fee at 2x base + priority so we don't get gouged on
    // sudden base-fee spikes
    const maxFee = calculateMaxFeePerGas(header.baseFeePerGas, prefs.priorityFee);

    const effective = calculateEffectiveGasPrice(
        header.baseFeePerGas,
        maxFee,
        prefs.priorityFee
    );

    const estimate = estimateGas({
        gasLimit: prefs.gasLimit,
        baseFeePerGas: header.baseFeePerGas,
        maxPriorityFeePerGas: prefs.priorityFee,
    });

    return {
        ...estimate,
        capMaxFee: maxFee,
        effectivePrice: effective,
        humanCost: `${estimateTxCostEth(prefs.gasLimit, effective)} ETH`,
    };
}

const quote = quoteUserTransaction(
    { baseFeePerGas: 50000000000n },
    { priorityFee: 2000000000n, gasLimit: 21000n }
);
// { ..., humanCost: "0.000021 * effectivePrice / 10^18 ETH" }

API Reference

Export Signature Returns
estimateGas (params: GasEstimateParams) => GasEstimate full estimate
calculateMaxFeePerGas (baseFee: bigint, priorityFee: bigint) => bigint 2 * base + priority
calculateEffectiveGasPrice (baseFee: bigint, maxFee: bigint, priorityFee: bigint) => bigint min(maxFee, baseFee + priorityFee)
formatGwei (weiValue: bigint) => string decimal gwei, signed, trimmed
estimateTxCostEth (gasLimit: bigint, gasPriceWei: bigint) => string decimal ETH, trimmed

GasEstimate shape

interface GasEstimate {
    gasLimit: bigint;
    gasPrice: bigint;            // legacy override or maxFeePerGas
    maxFeePerGas: bigint;        // baseFee + priorityFee
    maxPriorityFeePerGas: bigint;
    totalCost: bigint;           // gasLimit * gasPrice
}

Implementation Notes

  • estimateGas's maxFeePerGas is computed as baseFee + priorityFee rather than the EIP-1559 ceiling (2 * base + priority) — the ceiling is computed separately via calculateMaxFeePerGas because some workflows want the conservative target (base + priority) while others want the worst-case ceiling. Callers wanting the ceiling can pass it via legacyGasPrice to override gasPrice.
  • formatGwei divides by GWEI = 10^9n and uses padStart(9, "0") to render the fractional part. Trailing zeros are trimmed with /0+$/ so 1100000000n becomes "1.1", not "1.100000000".
  • estimateTxCostEth divides by 10^18n and uses padStart(18, "0") for the fractional ETH part. The same trailing-zero trim applies.
  • Negative wei values in formatGwei are supported — the absolute value drives the math and the sign is reapplied at the end.
  • estimateTxCostEth does not currently support negative inputs (gas refunds are out of scope for this primitive); the upstream library's behaviour is preserved bit-for-bit.
  • EIP-4844 blob-gas helpers are not included — calculateBlobGasPrice and friends land in add-cryptocurrency-blob-gas as called out in the enterprise audit (enterprise/cryptocurrency.md §3).
  • All arithmetic is bigint-pure; formatGwei and estimateTxCostEth are the only places where strings are produced, and even those use BigInt.prototype.toString exclusively.