Skip to content

Commit 6bbdc35

Browse files
authored
feat(express): migrate consolidateUnspents to typed routes
2 parents ba3c8dc + af8f7d4 commit 6bbdc35

File tree

4 files changed

+759
-6
lines changed

4 files changed

+759
-6
lines changed

modules/express/src/clientRoutes.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ function handleConstructApprovalTx(req: ExpressApiRouteRequest<'express.v1.pendi
271271
* @deprecated
272272
* @param req
273273
*/
274-
function handleConsolidateUnspents(req: express.Request) {
274+
function handleConsolidateUnspents(req: ExpressApiRouteRequest<'express.v1.wallet.consolidateunspents', 'put'>) {
275275
return req.bitgo
276276
.wallets()
277277
.get({ id: req.params.id })
@@ -1598,12 +1598,11 @@ export function setupAPIRoutes(app: express.Application, config: Config): void {
15981598
typedPromiseWrapper(handleConstructApprovalTx),
15991599
]);
16001600

1601-
app.put(
1602-
'/api/v1/wallet/:id/consolidateunspents',
1603-
parseBody,
1601+
router.put('express.v1.wallet.consolidateunspents', [
16041602
prepareBitGo(config),
1605-
promiseWrapper(handleConsolidateUnspents)
1606-
);
1603+
typedPromiseWrapper(handleConsolidateUnspents),
1604+
]);
1605+
16071606
app.put('/api/v1/wallet/:id/fanoutunspents', parseBody, prepareBitGo(config), promiseWrapper(handleFanOutUnspents));
16081607

16091608
// any other API call

modules/express/src/typedRoutes/api/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { PostVerifyCoinAddress } from './v2/verifyAddress';
2121
import { PostDeriveLocalKeyChain } from './v1/deriveLocalKeyChain';
2222
import { PostCreateLocalKeyChain } from './v1/createLocalKeyChain';
2323
import { PutConstructPendingApprovalTx } from './v1/constructPendingApprovalTx';
24+
import { PutConsolidateUnspents } from './v1/consolidateUnspents';
2425

2526
export const ExpressApi = apiSpec({
2627
'express.ping': {
@@ -80,6 +81,9 @@ export const ExpressApi = apiSpec({
8081
'express.v1.pendingapproval.constructTx': {
8182
put: PutConstructPendingApprovalTx,
8283
},
84+
'express.v1.wallet.consolidateunspents': {
85+
put: PutConsolidateUnspents,
86+
},
8387
});
8488

8589
export type ExpressApi = typeof ExpressApi;
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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 consolidating unspents in a wallet
7+
*/
8+
export const ConsolidateUnspentsRequestParams = {
9+
/** The ID of the wallet */
10+
id: t.string,
11+
};
12+
13+
/**
14+
* Request body for consolidating unspents in a wallet
15+
*/
16+
export const ConsolidateUnspentsRequestBody = {
17+
/** The wallet passphrase to decrypt the user key */
18+
walletPassphrase: optional(t.string),
19+
/** The extended private key (alternative to walletPassphrase) */
20+
xprv: optional(t.string),
21+
/** Whether to validate addresses (defaults to true) */
22+
validate: optional(t.boolean),
23+
/** Target number of unspents to maintain (defaults to 1) */
24+
target: optional(t.number),
25+
/** Minimum size of unspents to consolidate */
26+
minSize: optional(t.union([t.number, t.string])),
27+
/** Maximum size of unspents to consolidate */
28+
maxSize: optional(t.union([t.number, t.string])),
29+
/** Maximum number of inputs per consolidation transaction (defaults to 200, must be ≥ 2) */
30+
maxInputCountPerConsolidation: optional(t.number),
31+
/** Maximum number of consolidation iterations (defaults to -1) */
32+
maxIterationCount: optional(t.number),
33+
/** Minimum number of confirmations needed for an unspent to be included (defaults to 1) */
34+
minConfirms: optional(t.number),
35+
/** Custom fee rate in satoshis per kilobyte */
36+
feeRate: optional(t.number),
37+
};
38+
39+
/**
40+
* Response for consolidating unspents in a wallet
41+
*/
42+
export const ConsolidateUnspentsResponse = t.array(
43+
t.type({
44+
/** The status of the transaction ('accepted', 'pendingApproval', or 'otp') */
45+
status: t.string,
46+
/** The transaction hex */
47+
tx: t.string,
48+
/** The transaction hash/ID */
49+
hash: t.string,
50+
/** Whether the transaction is instant */
51+
instant: t.boolean,
52+
/** The instant ID (if applicable) */
53+
instantId: optional(t.string),
54+
/** The fee amount in satoshis */
55+
fee: t.number,
56+
/** The fee rate in satoshis per kilobyte */
57+
feeRate: t.number,
58+
/** Travel rule information */
59+
travelInfos: t.unknown,
60+
/** BitGo fee information (if applicable) */
61+
bitgoFee: optional(t.unknown),
62+
/** Travel rule result (if applicable) */
63+
travelResult: optional(t.unknown),
64+
})
65+
);
66+
67+
/**
68+
* Consolidate unspents in a wallet
69+
*
70+
* This endpoint consolidates unspents in a wallet by creating a transaction that spends from
71+
* multiple inputs to a single output. This is useful for reducing the number of UTXOs in a wallet,
72+
* which can improve performance and reduce transaction fees.
73+
*
74+
* @operationId express.v1.wallet.consolidateunspents
75+
*/
76+
export const PutConsolidateUnspents = httpRoute({
77+
path: '/api/v1/wallet/:id/consolidateunspents',
78+
method: 'PUT',
79+
request: httpRequest({
80+
params: ConsolidateUnspentsRequestParams,
81+
body: ConsolidateUnspentsRequestBody,
82+
}),
83+
response: {
84+
/** Successfully consolidated unspents */
85+
200: ConsolidateUnspentsResponse,
86+
/** Invalid request or consolidation fails */
87+
400: BitgoExpressError,
88+
},
89+
});

0 commit comments

Comments
 (0)