UNPKG

@btc-vision/transaction

Version:

OPNet transaction library allows you to create and sign transactions for the OPNet network.

359 lines 14.2 kB
import { Logger } from '@btc-vision/logger'; import { Script, XOnlyPublicKey, Network, P2MRPayment, P2TRPayment, ParallelSigningResult, Psbt, PsbtInput, PsbtInputExtended, Signer, SigningPoolLike, Transaction, WorkerPoolConfig } from '../../../node_modules/@btc-vision/bitcoin/browser/index.js'; import { UniversalSigner } from '@btc-vision/ecpair'; import { UTXO } from '../../utxo/interfaces/IUTXO.js'; import { TapLeafScript } from '../interfaces/Tap.js'; import { UnisatSigner } from '../browser/extensions/UnisatSigner.js'; import { QuantumBIP32Interface } from '../../../node_modules/@btc-vision/bip32/src/cjs/index.cjs'; import { RotationSigner, SignerMap } from '../../signer/AddressRotation.js'; import { ITweakedTransactionData, SupportedTransactionVersion } from '../interfaces/ITweakedTransactionData.js'; /** * The transaction sequence */ export declare enum TransactionSequence { REPLACE_BY_FEE = 4294967293, FINAL = 4294967295 } export declare enum CSVModes { BLOCKS = 0, TIMESTAMPS = 1 } /** * Union type for P2TR and P2MR payment objects. */ export type TapPayment = P2TRPayment | P2MRPayment; /** * @description PSBT Transaction processor. * */ export declare abstract class TweakedTransaction extends Logger implements Disposable { readonly logColor: string; finalized: boolean; /** * @description Was the transaction signed? */ protected signer: Signer | UniversalSigner | UnisatSigner; /** * @description Tweaked signer */ protected tweakedSigner?: UniversalSigner; /** * @description The network of the transaction */ protected network: Network; /** * @description Was the transaction signed? */ protected signed: boolean; /** * @description The transaction * @protected */ protected abstract readonly transaction: Psbt; /** * @description The sighash types of the transaction * @protected */ protected sighashTypes: number[] | undefined; /** * @description The script data of the transaction */ protected scriptData: TapPayment | null; /** * @description The tap data of the transaction */ protected tapData: TapPayment | null; /** * @description The inputs of the transaction */ protected readonly inputs: PsbtInputExtended[]; /** * @description The sequence of the transaction * @protected */ protected sequence: number; /** * The tap leaf script * @protected */ protected tapLeafScript: TapLeafScript | null; /** * Add a non-witness utxo to the transaction * @protected */ protected nonWitnessUtxo?: Uint8Array; /** * Is the transaction being generated inside a browser? * @protected */ protected readonly isBrowser: boolean; /** * Track which inputs contain CSV scripts * @protected */ protected csvInputIndices: Set<number>; protected anchorInputIndices: Set<number>; protected regenerated: boolean; protected ignoreSignatureErrors: boolean; protected noSignatures: boolean; protected unlockScript: Uint8Array[] | undefined; protected txVersion: SupportedTransactionVersion; protected readonly _mldsaSigner: QuantumBIP32Interface | null; protected readonly _hashedPublicKey: Uint8Array | null; /** * Whether address rotation mode is enabled. * When true, each UTXO can be signed by a different signer. */ protected readonly addressRotationEnabled: boolean; /** * Map of addresses to their respective signers for address rotation mode. */ protected readonly signerMap: SignerMap; /** * Map of input indices to their signers (resolved from UTXOs or signerMap). * Populated during input addition. */ protected readonly inputSignerMap: Map<number, RotationSigner>; /** * Cache of tweaked signers per input for address rotation mode. */ protected readonly tweakedSignerCache: Map<number, UniversalSigner | undefined>; /** * Parallel signing configuration using worker threads. * When set, key-path taproot inputs are signed in parallel via workers. */ protected parallelSigningConfig?: SigningPoolLike | WorkerPoolConfig; /** * Whether to use P2MR (Pay-to-Merkle-Root, BIP 360) instead of P2TR. */ protected readonly useP2MR: boolean; protected constructor(data: ITweakedTransactionData); /** * Get the MLDSA signer * @protected */ protected get mldsaSigner(): QuantumBIP32Interface; /** * Get the hashed public key * @protected */ protected get hashedPublicKey(): Uint8Array; /** * Whether parallel signing can be used for this transaction. * Requires parallelSigningConfig and excludes browser, address rotation, and no-signature modes. */ protected get canUseParallelSigning(): boolean; /** * Read witnesses * @protected */ static readScriptWitnessToWitnessStack(buffer: Uint8Array): Uint8Array[]; /** * Pre-estimate the transaction fees for a Taproot transaction * @param {bigint} feeRate - The fee rate in satoshis per virtual byte * @param {bigint} numInputs - The number of inputs * @param {bigint} numOutputs - The number of outputs * @param {bigint} numWitnessElements - The number of witness elements (e.g., number of control blocks and witnesses) * @param {bigint} witnessElementSize - The average size of each witness element in bytes * @param {bigint} emptyWitness - The amount of empty witnesses * @param {bigint} [taprootControlWitnessSize=139n] - The size of the control block witness in bytes * @param {bigint} [taprootScriptSize=32n] - The size of the taproot script in bytes * @returns {bigint} - The estimated transaction fees */ static preEstimateTaprootTransactionFees(feeRate: bigint, // satoshis per virtual byte numInputs: bigint, numOutputs: bigint, numWitnessElements: bigint, witnessElementSize: bigint, emptyWitness: bigint, taprootControlWitnessSize?: bigint, taprootScriptSize?: bigint): bigint; protected static signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | UniversalSigner, sighashTypes: number[]): void; /** * Calculate the sign hash number * @description Calculates the sign hash * @protected * @returns {number} */ protected static calculateSignHash(sighashTypes: number[]): number; [Symbol.dispose](): void; /** * Check if address rotation mode is enabled. */ isAddressRotationEnabled(): boolean; ignoreSignatureError(): void; /** * @description Returns the script address * @returns {string} */ getScriptAddress(): string; /** * @description Returns the transaction * @returns {Transaction} */ getTransaction(): Transaction; /** * @description Returns the tap address * @returns {string} * @throws {Error} - If tap data is not set */ getTapAddress(): string; /** * @description Disables replace by fee on the transaction */ disableRBF(): void; /** * Get the tweaked hash * @private * * @returns {Uint8Array | undefined} The tweaked hash */ getTweakerHash(): Uint8Array | undefined; /** * Pre-estimate the transaction fees * @param {bigint} feeRate - The fee rate * @param {bigint} numInputs - The number of inputs * @param {bigint} numOutputs - The number of outputs * @param {bigint} numSignatures - The number of signatures * @param {bigint} numPubkeys - The number of public keys * @returns {bigint} - The estimated transaction fees */ preEstimateTransactionFees(feeRate: bigint, // satoshis per byte numInputs: bigint, numOutputs: bigint, numSignatures: bigint, numPubkeys: bigint): bigint; /** * Get the signer for a specific input index. * Returns the input-specific signer if in rotation mode, otherwise the default signer. * @param inputIndex - The index of the input */ protected getSignerForInput(inputIndex: number): RotationSigner; /** * Register a signer for a specific input index. * Called during UTXO processing to map each input to its signer. * @param inputIndex - The index of the input * @param utxo - The UTXO being added */ protected registerInputSigner(inputIndex: number, utxo: UTXO): void; /** * Get the x-only public key for a specific input's signer. * Used for taproot inputs in address rotation mode. * @param inputIndex - The index of the input */ protected internalPubKeyToXOnlyForInput(inputIndex: number): XOnlyPublicKey; /** * Get the tweaked signer for a specific input. * Caches the result for efficiency. * @param inputIndex - The index of the input * @param useTweakedHash - Whether to use the tweaked hash */ protected getTweakedSignerForInput(inputIndex: number, useTweakedHash?: boolean): UniversalSigner | undefined; protected generateTapData(): TapPayment; /** * Generates the script address. * @protected * @returns {TapPayment} */ protected generateScriptAddress(): TapPayment; /** * Returns the signer key. * @protected * @returns {Signer | UniversalSigner} */ protected getSignerKey(): Signer | UniversalSigner; /** * Signs an input of the transaction. * @param {Psbt} transaction - The transaction to sign * @param {PsbtInput} input - The input to sign * @param {number} i - The index of the input * @param {Signer} signer - The signer to use * @param {boolean} [reverse=false] - Should the input be signed in reverse * @param {boolean} [errored=false] - Was there an error * @protected */ protected signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | UniversalSigner, reverse?: boolean, errored?: boolean): Promise<void>; protected splitArray<T>(arr: T[], chunkSize: number): T[][]; /** * Signs all the inputs of the transaction. * @param {Psbt} transaction - The transaction to sign * @protected * @returns {Promise<void>} */ protected signInputs(transaction: Psbt): Promise<void>; protected signInputsNonWalletBased(transaction: Psbt): Promise<void>; /** * Signs all inputs sequentially in batches of 20. * This is the original signing logic, used as fallback when parallel signing is unavailable. */ protected signInputsSequential(transaction: Psbt): Promise<void>; /** * Signs inputs that were not handled by parallel signing. * After parallel key-path signing, script-path taproot inputs, non-taproot inputs, * and any inputs that failed parallel signing need sequential signing. */ protected signRemainingInputsSequential(transaction: Psbt, signedIndices: Set<number>): Promise<void>; /** * Converts the public key to x-only. * @protected * @returns {Uint8Array} */ protected internalPubKeyToXOnly(): XOnlyPublicKey; /** * Internal init. * @protected */ protected internalInit(): void; /** * Tweak the signer for the interaction * @protected */ protected tweakSigner(): void; /** * Get the tweaked signer * @private * @returns {UniversalSigner} The tweaked signer */ protected getTweakedSigner(useTweakedHash?: boolean, signer?: Signer | UniversalSigner): UniversalSigner | undefined; /** * Signs key-path taproot inputs in parallel using worker threads. * @param transaction - The PSBT to sign * @param excludeIndices - Input indices to skip (e.g., script-path inputs already signed) * @returns The parallel signing result */ protected signKeyPathInputsParallel(transaction: Psbt, excludeIndices?: Set<number>): Promise<ParallelSigningResult>; protected generateP2SHRedeemScript(customWitnessScript: Uint8Array): Uint8Array | undefined; protected generateP2SHRedeemScriptLegacy(inputAddr: string): { redeemScript: Uint8Array; outputScript: Uint8Array; } | undefined; protected generateP2SHP2PKHRedeemScript(inputAddr: string, inputIndex?: number): { redeemScript: Uint8Array; outputScript: Uint8Array; } | undefined; /** * Generate the PSBT input extended, supporting various script types * @param {UTXO} utxo The UTXO * @param {number} i The index of the input * @param {UTXO} _extra Extra UTXO * @protected * @returns {PsbtInputExtended} The PSBT input extended */ protected generatePsbtInputExtended(utxo: UTXO, i: number, _extra?: boolean): PsbtInputExtended; protected processP2WSHInput(utxo: UTXO, input: PsbtInputExtended, i: number): void; protected secondsToCSVTimeUnits(seconds: number): number; protected createTimeBasedCSV(seconds: number): number; protected isCSVEnabled(sequence: number): boolean; protected extractCSVValue(sequence: number): number; protected customFinalizerP2SH: (inputIndex: number, input: PsbtInput, scriptA: Script, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean, _canRunChecks?: boolean) => { finalScriptSig: Script | undefined; finalScriptWitness: Uint8Array | undefined; }; /** * Finalize secondary P2WDA inputs with empty data */ protected finalizeSecondaryP2WDA(inputIndex: number, input: PsbtInput): { finalScriptWitness: Uint8Array | undefined; finalScriptSig: Script | undefined; }; protected signInputsWalletBased(transaction: Psbt): Promise<void>; protected isCSVScript(decompiled: (number | Uint8Array)[]): boolean; protected setCSVSequence(csvBlocks: number, currentSequence: number): number; protected getCSVType(csvValue: number): CSVModes; private extractCSVBlocks; private attemptSignTaproot; private isTaprootScriptSpend; private signTaprootInput; private signNonTaprootInput; } //# sourceMappingURL=TweakedTransaction.d.ts.map