import { Hex } from 'ox' // Tempo gas prices (`maxFeePerGas`, `effectiveGasPrice`, block base fee) are // denominated in attodollars (10^-18 USD) per gas, while fee-token balances // use 6 decimals (microdollars, 10^-6 USD). The charged fee is // `ceil(gas × gasPrice / 10^12)`, mirroring `calc_gas_balance_spending` in // tempoxyz/tempo. /** Attodollar exponent gas prices use (10^-18 USD per gas), fixed by the fee spec. */ const attoDecimals = 18 /** Fee-token decimals: TIP-20 fixes 6 (1 token unit = 1 microdollar). */ export const tokenDecimals = 6 /** Scaling between attodollar gas math and fee-token units, derived from the exponents. */ export const scalingFactor = 10n ** BigInt(attoDecimals - tokenDecimals) /** * Fee in fee-token base units for a gas amount priced in attodollars per gas * (ceiling division). Works for actual fees (`gasUsed × effectiveGasPrice`) * and signed caps (`gas × maxFeePerGas`) alike. * * @param gas - Gas amount. * @param gasPrice - Price in attodollars per gas. * @returns The fee in fee-token base units. */ export function fromGas(gas: bigint, gasPrice: bigint): bigint { return (gas * gasPrice + scalingFactor - 1n) / scalingFactor } /** * Signed fee cap of a candidate transaction in fee-token base units: * `gas × maxFeePerGas` (attodollars) scaled through {@link fromGas}. Undefined * when either field is missing or unparseable, so callers can fail closed. * * @param request - Transaction-shaped fee fields. * @returns The cap in base units, or undefined. */ export function maxOf(request: { gas?: unknown; maxFeePerGas?: unknown }): bigint | undefined { const gas = toBigInt(request.gas) const maxFeePerGas = toBigInt(request.maxFeePerGas) if (gas === undefined || maxFeePerGas === undefined) return undefined return fromGas(gas, maxFeePerGas) } /** Fee fields arrive as bigints (raw envelopes) or hex quantities (fills). */ function toBigInt(value: unknown): bigint | undefined { if (typeof value === 'bigint') return value if (typeof value === 'string' && Hex.validate(value)) return Hex.toBigInt(value) return undefined }