@@ -14,23 +14,23 @@ export const ConsolidateUnspentsRequestParams = {
1414 * Request body for consolidating unspents in a wallet
1515 */
1616export const ConsolidateUnspentsRequestBody = {
17- /** The wallet passphrase to decrypt the user key */
17+ /** Wallet passphrase to decrypt the user key for signing (required unless xprv is provided) */
1818 walletPassphrase : optional ( t . string ) ,
19- /** The extended private key ( alternative to walletPassphrase) */
19+ /** Extended private key as alternative to walletPassphrase (provide only one ) */
2020 xprv : optional ( t . string ) ,
21- /** Whether to validate addresses (defaults to true) */
21+ /** Whether to validate addresses before creating transactions (defaults to true) */
2222 validate : optional ( t . boolean ) ,
23- /** Target number of unspents to maintain (defaults to 1) */
23+ /** Target number of unspents to maintain in the wallet (defaults to 1, must be positive integer ) */
2424 target : optional ( t . number ) ,
25- /** Minimum size of unspents to consolidate */
25+ /** Minimum size of unspents to consolidate in satoshis (defaults to 0 or auto-calculated from feeRate) */
2626 minSize : optional ( t . union ( [ t . number , t . string ] ) ) ,
27- /** Maximum size of unspents to consolidate */
27+ /** Maximum size of unspents to consolidate in satoshis */
2828 maxSize : optional ( t . union ( [ t . number , t . string ] ) ) ,
29- /** Maximum number of inputs per consolidation transaction (defaults to 200, must be ≥ 2 ) */
29+ /** Maximum inputs per consolidation transaction (defaults to 200, must be 2-200 ) */
3030 maxInputCountPerConsolidation : optional ( t . number ) ,
31- /** Maximum number of consolidation iterations (defaults to -1) */
31+ /** Maximum consolidation iterations (defaults to -1 for unlimited, or positive integer ) */
3232 maxIterationCount : optional ( t . number ) ,
33- /** Minimum number of confirmations needed for an unspent to be included (defaults to 1) */
33+ /** Minimum confirmations needed for an unspent to be included (defaults to 1) */
3434 minConfirms : optional ( t . number ) ,
3535 /** Custom fee rate in satoshis per kilobyte */
3636 feeRate : optional ( t . number ) ,
@@ -48,9 +48,9 @@ export const ConsolidateUnspentsRequestBody = {
4848 enforceMinConfirmsForChange : optional ( t . boolean ) ,
4949 /** Target number of unspents for the wallet */
5050 targetWalletUnspents : optional ( t . number ) ,
51- /** Minimum value of unspents to include ( in satoshis) - accepts number or string */
51+ /** Minimum value of unspents to include in satoshis */
5252 minValue : optional ( t . union ( [ t . number , t . string ] ) ) ,
53- /** Maximum value of unspents to include ( in satoshis) - accepts number or string */
53+ /** Maximum value of unspents to include in satoshis */
5454 maxValue : optional ( t . union ( [ t . number , t . string ] ) ) ,
5555 /** Comment to attach to the transaction */
5656 comment : optional ( t . string ) ,
@@ -59,44 +59,68 @@ export const ConsolidateUnspentsRequestBody = {
5959/**
6060 * Response for consolidating unspents in a wallet
6161 *
62- * Returns an array of transaction objects when consolidation occurs,
63- * or an empty object {} when no consolidation is needed (target already reached).
64- * The empty object is how Express serializes an undefined return from the V1 SDK.
62+ * Two possible response types:
63+ * 1. Array of transaction objects - when consolidation occurs (one per iteration)
64+ * 2. Empty object {} - when target is already reached (no consolidation needed)
6565 */
6666export const ConsolidateUnspentsResponse = t . union ( [
6767 t . array (
6868 t . type ( {
69- /** The status of the transaction ( 'accepted', 'pendingApproval', or 'otp') */
69+ /** Transaction status: 'accepted' (broadcasted) , 'pendingApproval' (needs approval) , or 'otp' (needs 2FA ) */
7070 status : t . union ( [ t . literal ( 'accepted' ) , t . literal ( 'pendingApproval' ) , t . literal ( 'otp' ) ] ) ,
71- /** The transaction hex */
71+ /** Signed transaction in hex format */
7272 tx : t . string ,
73- /** The transaction hash/ID */
73+ /** Transaction hash/ID */
7474 hash : t . string ,
75- /** Whether the transaction is instant */
75+ /** Whether this is an instant transaction (BitGo Instant) */
7676 instant : t . boolean ,
77- /** The instant ID (if applicable ) */
77+ /** Instant transaction ID (only present for instant transactions ) */
7878 instantId : optional ( t . string ) ,
79- /** The fee amount in satoshis */
79+ /** Total fee paid in satoshis */
8080 fee : t . number ,
81- /** The fee rate in satoshis per kilobyte */
81+ /** Fee rate in satoshis per kilobyte */
8282 feeRate : t . number ,
83- /** Travel rule information */
83+ /** Travel rule compliance information */
8484 travelInfos : t . unknown ,
85- /** BitGo fee information (if applicable) */
85+ /** BitGo service fee information (if applicable) */
8686 bitgoFee : optional ( t . unknown ) ,
87- /** Travel rule result (if applicable) */
87+ /** Travel rule submission result (if applicable) */
8888 travelResult : optional ( t . unknown ) ,
8989 } )
9090 ) ,
91- t . type ( { } ) , // Empty object when SDK returns undefined
91+ t . type ( { } ) , // Empty object when target already reached (no consolidation needed)
9292] ) ;
9393
9494/**
9595 * Consolidate unspents in a wallet
9696 *
97- * This endpoint consolidates unspents in a wallet by creating a transaction that spends from
98- * multiple inputs to a single output. This is useful for reducing the number of UTXOs in a wallet,
99- * which can improve performance and reduce transaction fees.
97+ * Consolidates unspent transaction outputs (UTXOs) by creating transactions that combine
98+ * multiple small inputs into fewer larger outputs. This reduces the UTXO count to improve
99+ * wallet performance and lower future transaction fees.
100+ *
101+ * ## How It Works
102+ * The consolidation process is iterative:
103+ * 1. Fetches unspents matching the filter criteria (minSize, maxSize, minConfirms)
104+ * 2. If unspents ≤ target: consolidation complete (returns empty object)
105+ * 3. Creates a new wallet address to receive consolidated funds
106+ * 4. Builds a transaction with up to maxInputCountPerConsolidation inputs
107+ * 5. Sends all inputs to the new address (minus fees)
108+ * 6. Repeats until target is reached or maxIterationCount is hit
109+ *
110+ * ## Parameters
111+ * - **target**: Desired final unspent count (default: 1)
112+ * - **maxInputCountPerConsolidation**: Max inputs per transaction (default: 200)
113+ * - **maxIterationCount**: Max iterations (default: -1 for unlimited)
114+ * - **minSize**: Auto-calculated from feeRate to avoid consolidating unspents smaller than their fee cost
115+ *
116+ * ## Response
117+ * - **Array of transactions**: When consolidation occurs, returns one transaction per iteration
118+ * - **Empty object {}**: When target is already reached (no consolidation needed)
119+ *
120+ * ## Performance Notes
121+ * - Large consolidations may take time due to multiple iterations
122+ * - Each iteration waits 1 second before the next to allow transaction confirmation
123+ * - Use maxIterationCount to limit execution time for very large wallets
100124 *
101125 * @operationId express.v1.wallet.consolidateunspents
102126 * @tag express
0 commit comments