UNPKG

@ordinalsbot/bitcoin-fee-estimator

Version:

A library for calculating Bitcoin transaction fees

76 lines (64 loc) 2.06 kB
import { ScriptType } from "../types"; import { encodingLength } from "varuint-bitcoin"; import { estimateInputSize, getOutputSize } from "../common"; export function getTxOverhead( inputScripts: ScriptType[], outputCount: number, ): number { const inputCount = inputScripts.length; const hasWitnessInputs = inputScripts.some((type) => [ ScriptType.P2WPKH, ScriptType.P2WSH, ScriptType.P2TR, ScriptType.P2SH_P2WPKH, ScriptType.P2SH_P2WSH, ].includes(type), ); const baseSize = 4 + // nVersion encodingLength(inputCount) + // input count (varint) encodingLength(outputCount) + // output count (varint) 4; // nLockTime const segwitMarkerAndFlag = hasWitnessInputs ? 0.5 : 0; return baseSize + segwitMarkerAndFlag; } export function estimateTxVBytesSimple( inputScript: ScriptType[] = [ScriptType.P2TR], outputScript: ScriptType[] = [ScriptType.P2TR], opReturnData: Buffer | string | null = null, ): number { const overhead = getTxOverhead(inputScript, outputScript.length); let totalInput = 0; for (const script of inputScript) { totalInput += estimateInputSize(script); } const outputSize = outputScript.reduce( (total, scriptType) => total + getOutputSize(scriptType), 0, ); let opReturnSize = 0; if (opReturnData !== null) { const dataBuffer = typeof opReturnData === "string" ? Buffer.from(opReturnData, "utf8") : opReturnData; opReturnSize = 8 + 1 + encodingLength(dataBuffer.length) + dataBuffer.length; // (8)value + 1(OP_RETURN) + (N)length Bytes + (M)Data } const vBytes = Math.ceil(overhead + totalInput + outputSize + opReturnSize); return vBytes; } export function estimateTxFee( inputScript: ScriptType[] = [ScriptType.P2TR], outputScript: ScriptType[] = [ScriptType.P2TR], feeRate: number, opReturnData: Buffer | string | null = null, ): number { const vBytes = estimateTxVBytesSimple( inputScript, outputScript, opReturnData, ); return Math.ceil(vBytes * feeRate); }