import { PsbtInput, Psbt as PsbtBase } from 'bip174'; import { ByteString, Sig, SigHashType, ChangeInfo } from '../smart-contract/types/index.js'; import { InputIndex, SupportedNetwork, ExtUtxo, B2GUTXO, UTXO } from '../globalTypes.js'; import { ToSignInput, SignOptions, Signer } from '../signer.js'; import { Script } from '../smart-contract/types/script.js'; import { InputContext } from '../smart-contract/types/context.js'; import { IExtPsbt, ContractCall } from './types.js'; import { Psbt, PsbtOptsOptional, PsbtOutputExtended, TransactionInput } from './psbt.js'; import { Transaction, Network } from '@opcat-labs/opcat'; import { SmartContract } from '../smart-contract/smartContract.js'; import { OpcatState } from '../smart-contract/types/primitives.js'; import { BacktraceInfo, SpentDataHashes } from '../smart-contract/types/structs.js'; import { UtxoProvider } from '../providers/utxoProvider.js'; import { ChainProvider } from '../providers/chainProvider.js'; import { OpcatUtxo } from './utxoConverter.js'; type Finalizer = (self: ExtPsbt, inputIndex: number, // Which input is it? input: PsbtInput) => Script; /** * Extended PSBT input interface that combines standard PsbtInput and TransactionInput * with additional OP_CAT-specific fields. * * @property opcatUtxo - The OP_CAT-specific UTXO data associated with this input * @property finalizer - Optional finalizer for this input * @property sigRequests - Array of signature requests for this input */ export interface PsbtInputExtended extends PsbtInput, TransactionInput { opcatUtxo: OpcatUtxo; finalizer?: Finalizer; sigRequests?: { inputIndex: InputIndex; options: Omit; }[]; } /** * Extended PSBT options interface that inherits from PsbtOptsOptional, excluding 'network'. * * @remarks * The `network` property is optional and used by `spendUTXO()` and `change()` methods. * It is recommended to set the `network` when working with opcat Signet to avoid address conversion issues, * as opcat Signet uses a different address format. */ export interface ExtPsbtOpts extends Omit { /** * network config, used by spendUTXO() and change() * * if you are create a psbt on opcat-signet, you should set `network` to avoid address convertion issues, because opcat-signet has a different address format. * * make sure you have set the network if you are working on opcat-signet */ network?: Network | SupportedNetwork; } /** * Extends the standard Psbt class with additional functionality for OP_CAT transactions. * Provides methods for: * - Managing contract inputs/outputs * - Handling UTXO spending * - Calculating transaction fees and sizes * - Finalizing and sealing transactions * - Backtrace information for contract inputs * - Change output management * * Supports serialization to/from hex, base64 and buffer formats. * Includes network-aware operations and signature handling. */ export declare class ExtPsbt extends Psbt implements IExtPsbt { constructor(opts?: ExtPsbtOpts, data?: PsbtBase); /** * Signs the PSBT with the provided signer and finalizes all inputs. * @param signer - The signer instance used to sign the PSBT. * @returns A promise that resolves when signing and finalization are complete. */ signAndFinalize(signer: Signer): Promise; /** * Gets the sequence number for the specified input index. * @param inputIndex - The index of the input in the transaction. * @returns The sequence number of the input. */ getSequence(inputIndex: InputIndex): number; /** * Gets the lock time (nLockTime) value from the unsigned transaction. * @returns The lock time value as a number. */ getlockTime(): number; /** * Creates an ExtPsbt instance from a base64-encoded string. * @param data - The base64-encoded PSBT data * @param opts - Optional configuration options for the ExtPsbt * @returns A new ExtPsbt instance */ static fromBase64(data: string, opts?: ExtPsbtOpts): ExtPsbt; /** * Creates an ExtPsbt instance from a hex string. * @param data - Hex string representation of the PSBT data * @param opts - Optional configuration options for the ExtPsbt * @returns A new ExtPsbt instance */ static fromHex(data: string, opts?: ExtPsbtOpts): ExtPsbt; /** * Creates an ExtPsbt instance from a buffer containing PSBT data. * @param buffer - The buffer containing the PSBT data. * @param opts - Optional parameters including network configuration. * @returns A new ExtPsbt instance initialized with the PSBT data. */ static fromBuffer(buffer: Uint8Array, opts?: ExtPsbtOpts): ExtPsbt; private _ctxProvider; private _sigHashTypes; /** * Sets the sighash type for a specific input index. * Throws an error if attempting to set a different sighash type for the same input index. * @param inputIndex - The index of the input to set the sighash type for. * @param sigHashType - The sighash type to set. * @throws {Error} If the sighash type differs from the previously set type for the same input index. */ setSighashType(inputIndex: number, sigHashType: SigHashType): void; /** * Gets the signature hash type for the specified input index. * @param inputIndex - The index of the input to get the signature hash type for. * @returns The signature hash type for the specified input index. */ getSigHashType(inputIndex: number): SigHashType; /** * Gets the input context for the specified input index. * @param inputIndex - The index of the input to retrieve context for * @returns The InputContext object associated with the specified input index */ getInputCtx(inputIndex: InputIndex): InputContext; /** * Calculates and returns the concatenated SHA-256 hashes of all input OP_CAT UTXO data. * Each input's data is hashed individually and the results are concatenated. * @returns {SpentDataHashes} The combined hashes of all input data as a ByteString. */ getSpentDataHashes(): SpentDataHashes; /** * Computes the hash of all spent data hashes in the PSBT. * Concatenates all non-empty spent data hashes and returns their double SHA-256 hash. * @returns {ByteString} The hash256 of all spent data hashes concatenated together. */ get hashSpentDatas(): ByteString; private _sigRequests; private _finalizers; private _inputContracts; private _B2GUtxos; private _B2GInfos; private _outputContracts; private _inputUnlockScripts; private _changeOutputIndex; private _changeToAddr; private _changeFeeRate; /** * Adds an extended PSBT input with optional finalizer and signature requests. * - Calls parent class's `addInput` method * - Validates PSBT isn't sealed * - If input has a finalizer, caches the unlock script and sets the finalizer callback * - Processes any signature requests for the input * @param inputData - Extended PSBT input data containing optional finalizer and sigRequests * @returns PSBT instance for chaining */ addInput(inputData: PsbtInputExtended): this; /** * Add input(s) for current psbt to spend the utxos. * @param utxos the utxos to spend * @returns this */ spendUTXO(utxos: ExtUtxo[] | ExtUtxo): this; /** * Adds an extended output to the PSBT. * @param outputData - The extended output data to add * @returns The PSBT instance for chaining * @throws Error if the PSBT is already sealed */ addOutput(outputData: PsbtOutputExtended): this; /** * Sets the version number of the PSBT. * @param version - The version number to set. * @returns The PSBT instance for chaining. * @throws Error if the PSBT is sealed. */ setVersion(version: number): this; /** * Sets the locktime for the PSBT (Partially Signed Opcat Transaction). * @param locktime - The locktime value to set (in blocks or timestamp) * @returns The PSBT instance for chaining * @throws Error if the PSBT is already sealed */ setLocktime(locktime: number): this; /** * Sets the sequence number for the specified input. * @param inputIndex - The index of the input to modify * @param sequence - The sequence number to set * @returns The PSBT instance for method chaining * @throws If the PSBT is sealed (immutable) */ setInputSequence(inputIndex: number, sequence: number): this; /** * Adds a contract input to the PSBT (Partially Signed Bitcoin Transaction). * * @param contract - The smart contract instance to add as input. * @param contractCall - The contract call containing the method and arguments. * @returns The PSBT instance for method chaining. * @throws Error if the contract does not have a bound UTXO. */ addContractInput>(contract: Contract, contractCall: ContractCall): this; /** * Removes an input from the PSBT at the specified index. * This updates the unsigned transaction, input data, and clears related contract, * UTXO, finalizer, and signature request mappings for the removed input. * @param inputIndex - The index of the input to remove * @returns The PSBT instance for method chaining */ removeInput(inputIndex: number): this; /** * Removes the last input from the PSBT. * @throws {Error} If there are no inputs to remove. * @returns {this} The modified PSBT instance for chaining. */ removeLastInput(): this; /** * Updates a contract input with the provided contract call and sets up a finalizer. * Equivalent to setting the unlock of contract input. * @param inputIndex - The index of the input to update. * @param contractCall - The contract call to be executed during finalization. * @returns The current instance for method chaining. * @throws {Error} If no contract is found for the specified input index. */ private updateContractInput; /** * Adds a contract output to the PSBT (Partially Signed Opcat Transaction). * * @param contract - The smart contract instance to add as output * @param satoshis - The amount in satoshis to lock in this output * @returns The PSBT instance for method chaining * @template Contract - Type parameter extending `SmartContract` */ addContractOutput>(contract: Contract, satoshis: number): this; /** * Gets the total input amount in satoshis as a bigint. * @returns The sum of all input values in the PSBT. */ get inputAmount(): bigint; /** * Gets the total output amount of the PSBT transaction by summing up all output values. * @returns The sum of all output values as a bigint. */ get outputAmount(): bigint; /** * Adds or updates a change output to the PSBT. * @param toAddr - The address to receive the change. * @param feeRate - The fee rate to use for the change output. * @param data - Optional data to include in the output (hex string or Uint8Array). * @returns The PSBT instance for chaining. */ change(toAddr: string, feeRate: number, data?: Uint8Array | string): this; private finalizeChangeOutput; /** * Gets the change output information from the PSBT transaction. * @returns {ChangeInfo} An object containing the pubkeyhash, satoshis value, and data hash of the change output. * If no change output exists, returns an empty ChangeInfo with default values (zero pubkeyhash/data hash and 0 satoshis). * @throws {Error} If the change output index is set but the output is not found at that index. * @throws {Error} If the change output script is not a valid P2PKH script. */ getChangeInfo(): ChangeInfo; /** * Gets the unsigned transaction from the PSBT's internal cache. * @returns The raw unsigned transaction object. */ get unsignedTx(): Transaction; /** * Gets the network associated with this PSBT instance. * @private * @returns {Network} The network object (defaults to livenet if not specified in options). * @remarks This is intentionally kept private to avoid confusion between network strings passed to constructor and the Network object returned here. */ private get network(); /** * Estimates the total size of the PSBT by summing the unsigned transaction size * and the size of unfinalized call arguments. * @returns The estimated size in bytes. */ estimateSize(): number; /** * Estimates the transaction fee by multiplying the estimated size (in vbytes) by the given fee rate. * @param feeRate - Fee rate in satoshis per virtual byte (sat/vbyte). * @returns The estimated fee amount in satoshis. */ estimateFee(feeRate: number): number; private _setInputFinalizer; private _finalizing; private _isSealed; /** * Indicates whether the PSBT is currently in the process of being finalized. * @returns {boolean} True if the PSBT is being finalized, false otherwise. */ get isFinalizing(): boolean; /** * Indicates whether the PSBT (Partially Signed Bitcoin Transaction) is sealed. * A sealed PSBT cannot be modified further. */ get isSealed(): boolean; /** * Finalizes all inputs in the PSBT by applying their respective finalizers. * For each input, if a finalizer is present, it generates the unlocking script * and creates a finalization function. After finalizing all inputs, it binds * the contract UTXOs. Throws an error if any input fails to finalize. * * @returns The current PSBT instance for chaining. */ finalizeAllInputs(): this; private _bindcontractsUtxo; /** * Checks if all inputs in the PSBT are finalized. * @returns {boolean} True if all inputs are finalized, false otherwise. */ get isFinalized(): boolean; private _cacheInputUnlockScript; private _hasInputUnlockScript; private _getInputUnlockScript; /** * Checks if the input at the specified index is a contract input. * @param inputIndex - The index of the input to check. * @returns True if the input is a contract input, false otherwise. */ isContractInput(inputIndex: InputIndex): boolean; private _unfinalizedCallArgsSize; private isModifiable; private _throwIfNonModifiable; private _throwIfModifiable; private _addSigRequest; /** * Generates PSBT signing options based on signature requests. * * @param autoFinalized - Whether to automatically finalize the PSBT after signing (default: false) * @returns SignOptions object containing signing inputs, or undefined if no signatures are required */ psbtOptions(autoFinalized?: boolean): SignOptions | undefined; /** * Retrieves a signature for a specific input in the PSBT. * * @param inputIndex - The index of the input to sign. * @param options - Signing options including address or public key. * @returns The signature as a `Sig` object. If no signature is found, returns a default zero-filled signature. * @throws May throw if the input index is invalid or if there are issues with public key conversion. */ getSig(inputIndex: InputIndex, options: Omit): Sig; /** * Gets the smart contract associated with a specific input index. * * @param inputIndex - The index of the input to retrieve the contract for * @returns The smart contract for the specified input, or undefined if not found */ getInputContract(inputIndex: number): SmartContract | undefined; /** * Retrieves the B2G UTXO (Unspent Transaction Output) for a specific input index. * @param inputIndex - The index of the input to retrieve the UTXO for. * @returns The B2G UTXO if found, otherwise undefined. */ getB2GInputUtxo(inputIndex: number): B2GUTXO | undefined; /** * Gets the change UTXO (Unspent Transaction Output) if it exists. * @returns The change UTXO if found, otherwise null. * @throws {Error} If the change output index is defined but no output is found at that index. */ getChangeUTXO(): UTXO | null; /** * Retrieves the UTXO (Unspent Transaction Output) at the specified output index. * * @param outputIndex - The index of the output to retrieve * @returns An ExtUtxo object containing the UTXO details * @throws Error if the output at the specified index is not found */ getUtxo(outputIndex: number): ExtUtxo; /** * Retrieves backtrace information for a PSBT input by fetching and analyzing previous transactions. * * @param provider - Provider interface for fetching UTXO and chain data * @param inputIndex - Index of the input to trace back from * @param prevPrevTxFinder - Async function to locate the transaction before the previous transaction * @returns Promise resolving to backtrace information including: * - Previous transaction input details * - Input index in current transaction * - Preimage of the transaction before previous transaction */ getBacktraceInfo(provider: UtxoProvider & ChainProvider, inputIndex: InputIndex, prevPrevTxFinder: (prevTx: Transaction, provider: UtxoProvider & ChainProvider, inputIndex: InputIndex) => Promise): Promise; /** * Calculates backtrace information for contract inputs in the PSBT. * * Iterates through all inputs and collects backtrace info for contract inputs. * Uses the provided provider to fetch previous transaction data when needed. * * @param provider - Provider interface for fetching UTXO and chain data * @param prevPrevTxFinder - Optional function to find previous transactions * @returns Promise that resolves when all backtrace info is calculated */ calculateBacktraceInfo(provider: UtxoProvider & ChainProvider, prevPrevTxFinder?: (prevTx: Transaction, provider: UtxoProvider & ChainProvider, inputIndex: InputIndex) => Promise): Promise; /** * Checks if a given UTXO is a B2G (Back to Genesis) UTXO. * A B2G UTXO is identified by the presence of a 'txHashPreimage' property in the object. * * @param utxo - The UTXO object to check * @returns boolean indicating if the UTXO is a B2G UTXO */ isB2GUtxo(utxo: object): boolean; /** * Generates the transaction hash preimage for the PSBT. * @returns The transaction hash preimage as a hexadecimal string. * @throws {Error} If the PSBT is not sealed (must call `seal()` first). */ txHashPreimage(): string; /** * Finalizes the PSBT by calculating and caching input unlocking scripts, * finalizing the change output if specified, and marking the transaction as sealed. * Also calculates input contexts after sealing. * @returns The sealed PSBT instance for method chaining. */ seal(): this; /** * Converts the PSBT to a Uint8Array buffer. * @throws {Error} If the PSBT is not sealed (must call seal() first). * @returns {Uint8Array} The serialized PSBT buffer. */ toBuffer(): Uint8Array; /** * Converts the PSBT to a hexadecimal string representation. * @throws {Error} If the PSBT is not sealed (must call seal() first). * @returns {string} The hexadecimal string representation of the PSBT. */ toHex(): string; /** * Converts the PSBT to Base64 string representation. * @throws {Error} If the PSBT is not sealed (must call seal() first) * @returns {string} Base64 encoded PSBT data */ toBase64(): string; } export {}; //# sourceMappingURL=extPsbt.d.ts.map