|  | 
|  | 1 | +import * as t from 'io-ts'; | 
|  | 2 | +import { httpRoute, httpRequest, optional } from '@api-ts/io-ts-http'; | 
|  | 3 | +import { BitgoExpressError } from '../../schemas/error'; | 
|  | 4 | + | 
|  | 5 | +/** | 
|  | 6 | + * Request parameters for fanning out unspents in a wallet (v2) | 
|  | 7 | + */ | 
|  | 8 | +export const FanoutUnspentsRequestParams = { | 
|  | 9 | +  /** The coin identifier (e.g., 'btc', 'tbtc') */ | 
|  | 10 | +  coin: t.string, | 
|  | 11 | +  /** The ID of the wallet */ | 
|  | 12 | +  id: t.string, | 
|  | 13 | +} as const; | 
|  | 14 | + | 
|  | 15 | +/** | 
|  | 16 | + * Request body for fanning out unspents in a wallet (v2) | 
|  | 17 | + * | 
|  | 18 | + * This endpoint supports the full set of parameters available in the BitGo SDK | 
|  | 19 | + * for advanced UTXO management. The fanout operation takes existing unspents and | 
|  | 20 | + * creates a larger number of equally-sized outputs for improved transaction parallelization. | 
|  | 21 | + */ | 
|  | 22 | +export const FanoutUnspentsRequestBody = { | 
|  | 23 | +  /** The wallet passphrase to decrypt the user key */ | 
|  | 24 | +  walletPassphrase: optional(t.string), | 
|  | 25 | +  /** The extended private key (alternative to walletPassphrase) */ | 
|  | 26 | +  xprv: optional(t.string), | 
|  | 27 | +  /** The number of new unspents to create */ | 
|  | 28 | +  numUnspentsToMake: optional(t.number), | 
|  | 29 | +  /** Minimum value of unspents to use (in base units) */ | 
|  | 30 | +  minValue: optional(t.union([t.number, t.string])), | 
|  | 31 | +  /** Maximum value of unspents to use (in base units) */ | 
|  | 32 | +  maxValue: optional(t.union([t.number, t.string])), | 
|  | 33 | +  /** Minimum block height of unspents to use */ | 
|  | 34 | +  minHeight: optional(t.number), | 
|  | 35 | +  /** Minimum number of confirmations needed for an unspent to be included (defaults to 1) */ | 
|  | 36 | +  minConfirms: optional(t.number), | 
|  | 37 | +  /** If true, minConfirms also applies to change outputs */ | 
|  | 38 | +  enforceMinConfirmsForChange: optional(t.boolean), | 
|  | 39 | +  /** Maximum number of inputs to use in the transaction */ | 
|  | 40 | +  maxNumInputsToUse: optional(t.number), | 
|  | 41 | +  /** Array of specific unspent IDs to use */ | 
|  | 42 | +  unspents: optional(t.array(t.string)), | 
|  | 43 | +  /** The desired fee rate for the transaction in satoshis/kB */ | 
|  | 44 | +  feeRate: optional(t.number), | 
|  | 45 | +  /** The maximum limit for a fee rate in satoshis/kB */ | 
|  | 46 | +  maxFeeRate: optional(t.number), | 
|  | 47 | +  /** The maximum proportion of value you're willing to lose to fees (as a decimal, e.g., 0.1 for 10%) */ | 
|  | 48 | +  maxFeePercentage: optional(t.number), | 
|  | 49 | +  /** Estimate fees to aim for first confirmation within this number of blocks */ | 
|  | 50 | +  feeTxConfirmTarget: optional(t.number), | 
|  | 51 | +  /** Comment to attach to the transaction */ | 
|  | 52 | +  comment: optional(t.string), | 
|  | 53 | +  /** One-time password for 2FA */ | 
|  | 54 | +  otp: optional(t.string), | 
|  | 55 | +  /** Target address for the fanout outputs */ | 
|  | 56 | +  targetAddress: optional(t.string), | 
|  | 57 | +} as const; | 
|  | 58 | + | 
|  | 59 | +/** | 
|  | 60 | + * Response for fanning out unspents in a wallet (v2) | 
|  | 61 | + * | 
|  | 62 | + * Returns transaction details after the fanout operation is built, signed, and sent. | 
|  | 63 | + */ | 
|  | 64 | +export const FanoutUnspentsResponse = t.type({ | 
|  | 65 | +  /** The status of the transaction ('accepted', 'signed', 'pendingApproval', or 'otp') */ | 
|  | 66 | +  status: t.string, | 
|  | 67 | +  /** The transaction hex/serialized transaction */ | 
|  | 68 | +  tx: t.string, | 
|  | 69 | +  /** The transaction hash/ID */ | 
|  | 70 | +  hash: optional(t.string), | 
|  | 71 | +  /** Alternative field for transaction ID (some responses use this instead of hash) */ | 
|  | 72 | +  txid: optional(t.string), | 
|  | 73 | +  /** The fee amount in base units (satoshis for BTC) */ | 
|  | 74 | +  fee: optional(t.number), | 
|  | 75 | +  /** The fee rate in base units per kilobyte (satoshis/kB for BTC) */ | 
|  | 76 | +  feeRate: optional(t.number), | 
|  | 77 | +  /** Whether the transaction is instant */ | 
|  | 78 | +  instant: optional(t.boolean), | 
|  | 79 | +  /** The instant transaction ID (if applicable) */ | 
|  | 80 | +  instantId: optional(t.string), | 
|  | 81 | +  /** Travel rule information */ | 
|  | 82 | +  travelInfos: optional(t.unknown), | 
|  | 83 | +  /** BitGo fee information (if applicable) */ | 
|  | 84 | +  bitgoFee: optional(t.unknown), | 
|  | 85 | +  /** Travel rule result (if applicable) */ | 
|  | 86 | +  travelResult: optional(t.unknown), | 
|  | 87 | +}); | 
|  | 88 | + | 
|  | 89 | +/** | 
|  | 90 | + * Fan out unspents in a wallet (v2) | 
|  | 91 | + * | 
|  | 92 | + * This endpoint fans out unspents in a wallet by creating a transaction that spends from | 
|  | 93 | + * one or more inputs to create multiple equal-sized outputs. This is useful for increasing | 
|  | 94 | + * the number of UTXOs in a wallet, which can improve transaction parallelization and allow | 
|  | 95 | + * for concurrent spending operations. | 
|  | 96 | + * | 
|  | 97 | + * The v2 API differs from v1 by: | 
|  | 98 | + * - Requiring a coin parameter in the path | 
|  | 99 | + * - Supporting the full set of SDK parameters for advanced UTXO management | 
|  | 100 | + * - Using numUnspentsToMake instead of target (though both refer to output count) | 
|  | 101 | + * - Supporting additional parameters like maxNumInputsToUse, unspents array, fee controls | 
|  | 102 | + * | 
|  | 103 | + * @operationId express.v2.wallet.fanoutunspents | 
|  | 104 | + * @tag express | 
|  | 105 | + */ | 
|  | 106 | +export const PostFanoutUnspents = httpRoute({ | 
|  | 107 | +  path: '/api/v2/{coin}/wallet/{id}/fanoutunspents', | 
|  | 108 | +  method: 'POST', | 
|  | 109 | +  request: httpRequest({ | 
|  | 110 | +    params: FanoutUnspentsRequestParams, | 
|  | 111 | +    body: FanoutUnspentsRequestBody, | 
|  | 112 | +  }), | 
|  | 113 | +  response: { | 
|  | 114 | +    /** Successfully fanned out unspents */ | 
|  | 115 | +    200: FanoutUnspentsResponse, | 
|  | 116 | +    /** Invalid request or fan out operation fails */ | 
|  | 117 | +    400: BitgoExpressError, | 
|  | 118 | +  }, | 
|  | 119 | +}); | 
0 commit comments