@btc-vision/transaction
Version:
OPNet transaction library allows you to create and sign transactions for the OPNet network.
360 lines • 14.2 kB
TypeScript
import { Logger } from '@btc-vision/logger';
import type { Script, XOnlyPublicKey } from '@btc-vision/bitcoin';
import { type Network, type P2MRPayment, type P2TRPayment, type ParallelSigningResult, Psbt, type PsbtInput, type PsbtInputExtended, type Signer, type SigningPoolLike, Transaction, type WorkerPoolConfig } from '@btc-vision/bitcoin';
import { type UniversalSigner } from '@btc-vision/ecpair';
import type { UTXO } from '../../utxo/interfaces/IUTXO.js';
import type { TapLeafScript } from '../interfaces/Tap.js';
import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
import type { QuantumBIP32Interface } from '@btc-vision/bip32';
import { type RotationSigner, type SignerMap } from '../../signer/AddressRotation.js';
import type { 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