UNPKG

opnet

Version:

The perfect library for building Bitcoin-based applications.

321 lines (233 loc) 7.77 kB
# UTXO Manager API Reference Complete API reference for UTXO management. ## UTXOsManager Class Manages UTXO tracking and retrieval for transaction building. ### Constructor ```typescript new UTXOsManager(provider: IProviderForUTXO) ``` --- ## Methods ### getUTXOs Get UTXOs for an address with optional filters. ```typescript async getUTXOs(params: RequestUTXOsParams): Promise<UTXOs> ``` #### RequestUTXOsParams ```typescript interface RequestUTXOsParams { readonly address: string; // Bitcoin address readonly optimize?: boolean; // Optimize UTXO selection readonly mergePendingUTXOs?: boolean; // Include unconfirmed UTXOs readonly filterSpentUTXOs?: boolean; // Exclude known spent UTXOs readonly olderThan?: bigint; // Only UTXOs older than this block readonly isCSV?: boolean; // CSV (timelock) UTXOs } ``` ### getUTXOsForAmount Get UTXOs that cover a specific amount. ```typescript async getUTXOsForAmount( params: RequestUTXOsParamsWithAmount ): Promise<UTXOs> ``` #### RequestUTXOsParamsWithAmount ```typescript interface RequestUTXOsParamsWithAmount extends RequestUTXOsParams { readonly amount: bigint; // Amount to cover readonly throwErrors?: boolean; // Throw if insufficient readonly csvAddress?: string; // CSV address as fallback readonly maxUTXOs?: number; // Max UTXOs to select (default: 5000) readonly throwIfUTXOsLimitReached?: boolean; // Throw if limit reached } ``` > **Note:** `getUTXOsForAmount` prioritizes normal UTXOs first and only falls back to CSV UTXOs if normal ones cannot cover the requested amount. UTXOs are sorted by value descending (largest first) for greedy selection. ### spentUTXO Mark UTXOs as spent and register new UTXOs (for tracking). ```typescript spentUTXO(address: string, spent: UTXOs, newUTXOs: UTXOs): void ``` | Parameter | Type | Description | |-----------|------|-------------| | `address` | `string` | The address whose UTXOs to update | | `spent` | `UTXOs` | UTXOs that were spent | | `newUTXOs` | `UTXOs` | New UTXOs created (e.g., change outputs) | ### getPendingUTXOs Get pending (unconfirmed) UTXOs for an address. ```typescript getPendingUTXOs(address: string): UTXOs ``` | Parameter | Type | Description | |-----------|------|-------------| | `address` | `string` | The address to get pending UTXOs for | ### getMultipleUTXOs Get UTXOs for multiple addresses in a single call. ```typescript async getMultipleUTXOs( params: RequestMultipleUTXOsParams ): Promise<Record<string, UTXOs>> ``` #### RequestMultipleUTXOsParams ```typescript interface RequestMultipleUTXOsParams { readonly requests: RequestUTXOsParams[]; readonly mergePendingUTXOs?: boolean; readonly filterSpentUTXOs?: boolean; } ``` ### clean Clear the spent UTXO tracking cache. Optionally pass an address to clear only that address. ```typescript clean(address?: string): void ``` --- ## UTXO Class ```typescript class UTXO { readonly transactionId: string; // Transaction ID readonly outputIndex: number; // Output index readonly value: bigint; // Value in satoshis readonly scriptPubKey: ScriptPubKey; // Locking script readonly nonWitnessUtxo?: Uint8Array | string; // Full previous transaction witnessScript?: Uint8Array | string; // Witness script redeemScript?: Uint8Array | string; // Redeem script isCSV?: boolean; // CheckSequenceVerify timelock } ``` --- ## UTXOs Type ```typescript type UTXOs = UTXO[]; ``` --- ## Usage Examples ### Basic UTXO Retrieval ```typescript import { UTXOsManager, JSONRpcProvider } from 'opnet'; const provider = new JSONRpcProvider({ url, network }); const utxoManager = new UTXOsManager(provider); // Get all UTXOs const utxos = await utxoManager.getUTXOs({ address: 'bc1p...', }); console.log('Found', utxos.length, 'UTXOs'); for (const utxo of utxos) { console.log(`${utxo.transactionId}:${utxo.outputIndex} = ${utxo.value} sats`); } ``` ### Get UTXOs for Amount ```typescript // Get UTXOs covering at least 1 BTC const utxos = await utxoManager.getUTXOsForAmount({ address: 'bc1p...', amount: 100000000n, // 1 BTC throwErrors: true, }); const totalValue = utxos.reduce((sum, u) => sum + u.value, 0n); console.log('Total value:', totalValue, 'sats'); ``` ### With Optimization ```typescript // Optimize UTXO selection (consolidate small UTXOs) const utxos = await utxoManager.getUTXOs({ address: 'bc1p...', optimize: true, }); ``` ### Without Pending UTXOs ```typescript // Only get confirmed UTXOs (exclude pending) const confirmedUtxos = await utxoManager.getUTXOs({ address: 'bc1p...', mergePendingUTXOs: false, }); ``` ### Track Spent UTXOs ```typescript // After using UTXOs in a transaction, mark them spent and register new ones utxoManager.spentUTXO('bc1p...', usedUtxos, newChangeUtxos); // Later queries won't return spent UTXOs const availableUtxos = await utxoManager.getUTXOs({ address: 'bc1p...', }); // Clear spent tracking when needed utxoManager.clean(); ``` --- ## Integration with Contracts ### Use with Transaction Parameters ```typescript // Get UTXOs for transaction const utxos = await utxoManager.getUTXOsForAmount({ address: wallet.p2tr, amount: estimatedCost, throwErrors: true, }); // Simulate first const simulation = await contract.transfer(recipient, amount, new Uint8Array(0)); if (simulation.revert) { throw new Error(`Transfer would fail: ${simulation.revert}`); } // Send with specific UTXOs const result = await simulation.sendTransaction({ signer: wallet.keypair, mldsaSigner: wallet.mldsaKeypair, refundTo: wallet.p2tr, feeRate: 10, network: network, maximumAllowedSatToSpend: 10000n, utxos: utxos, // Provide specific UTXOs }); // Mark as spent and register new UTXOs utxoManager.spentUTXO(wallet.p2tr, utxos, result.newUTXOs); ``` --- ## UTXO Service Pattern ```typescript class UTXOService { private manager: UTXOsManager; constructor(provider: AbstractRpcProvider) { this.manager = provider.utxoManager; } async getAvailable(address: string): Promise<UTXOs> { return this.manager.getUTXOs({ address, mergePendingUTXOs: false, }); } async getForAmount( address: string, amount: bigint ): Promise<UTXOs> { return this.manager.getUTXOsForAmount({ address, amount, optimize: true, }); } async getTotalBalance(address: string): Promise<bigint> { const utxos = await this.getAvailable(address); return utxos.reduce((sum, u) => sum + u.value, 0n); } markSpent(address: string, spent: UTXOs, newUTXOs: UTXOs): void { this.manager.spentUTXO(address, spent, newUTXOs); } clearCache(): void { this.manager.clean(); } } ``` --- ## Best Practices 1. **Track Spent UTXOs**: Use `spentUTXO` to prevent double-spending attempts 2. **Use Optimization**: Enable `optimize` for better UTXO selection 3. **Clear Cache Periodically**: Call `clean()` when UTXOs are confirmed 4. **Handle Errors**: Use `throwErrors: true` for critical operations 5. **Exclude Pending**: Use `mergePendingUTXOs: false` for confirmed-only queries --- ## Next Steps - [Provider API](./provider-api.md) - Provider methods - [Contract API](./contract-api.md) - Contract interactions - [Epoch API](./epoch-api.md) - Epoch operations --- [ Previous: Contract API](./contract-api.md) | [Next: Epoch API ](./epoch-api.md)