# 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 ```ts 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 ```ts 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 ```ts 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.