Skip to content

Commit 05b3b85

Browse files
committed
feat(express): migrate fanoutunspents to typed routes
Ticket: WP-5413
1 parent c66ec15 commit 05b3b85

File tree

4 files changed

+477
-2
lines changed

4 files changed

+477
-2
lines changed

modules/express/src/clientRoutes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ function handleConsolidateUnspents(req: ExpressApiRouteRequest<'express.v1.walle
284284
* @deprecated
285285
* @param req
286286
*/
287-
function handleFanOutUnspents(req: express.Request) {
287+
function handleFanOutUnspents(req: ExpressApiRouteRequest<'express.v1.wallet.fanoutunspents', 'put'>) {
288288
return req.bitgo
289289
.wallets()
290290
.get({ id: req.params.id })
@@ -1603,7 +1603,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void {
16031603
typedPromiseWrapper(handleConsolidateUnspents),
16041604
]);
16051605

1606-
app.put('/api/v1/wallet/:id/fanoutunspents', parseBody, prepareBitGo(config), promiseWrapper(handleFanOutUnspents));
1606+
router.put('express.v1.wallet.fanoutunspents', [prepareBitGo(config), typedPromiseWrapper(handleFanOutUnspents)]);
16071607

16081608
// any other API call
16091609
app.use('/api/v[1]/*', parseBody, prepareBitGo(config), promiseWrapper(handleREST));

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { PostDeriveLocalKeyChain } from './v1/deriveLocalKeyChain';
2222
import { PostCreateLocalKeyChain } from './v1/createLocalKeyChain';
2323
import { PutConstructPendingApprovalTx } from './v1/constructPendingApprovalTx';
2424
import { PutConsolidateUnspents } from './v1/consolidateUnspents';
25+
import { PutFanoutUnspents } from './v1/fanoutUnspents';
2526

2627
export const ExpressApi = apiSpec({
2728
'express.ping': {
@@ -84,6 +85,9 @@ export const ExpressApi = apiSpec({
8485
'express.v1.wallet.consolidateunspents': {
8586
put: PutConsolidateUnspents,
8687
},
88+
'express.v1.wallet.fanoutunspents': {
89+
put: PutFanoutUnspents,
90+
},
8791
});
8892

8993
export type ExpressApi = typeof ExpressApi;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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
7+
*/
8+
export const FanoutUnspentsRequestParams = {
9+
/** The ID of the wallet */
10+
id: t.string,
11+
};
12+
13+
/**
14+
* Request body for fanning out unspents in a wallet
15+
*/
16+
export const FanoutUnspentsRequestBody = {
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 create (must be at least 2 and less than 300) */
24+
target: t.number,
25+
/** Minimum number of confirmations needed for an unspent to be included (defaults to 1) */
26+
minConfirms: optional(t.number),
27+
};
28+
29+
/**
30+
* Response for fanning out unspents in a wallet
31+
*/
32+
export const FanoutUnspentsResponse = t.type({
33+
/** The status of the transaction ('accepted', 'pendingApproval', or 'otp') */
34+
status: t.string,
35+
/** The transaction hex */
36+
tx: t.string,
37+
/** The transaction hash/ID */
38+
hash: t.string,
39+
/** Whether the transaction is instant */
40+
instant: t.boolean,
41+
/** The instant ID (if applicable) */
42+
instantId: optional(t.string),
43+
/** The fee amount in satoshis */
44+
fee: t.number,
45+
/** The fee rate in satoshis per kilobyte */
46+
feeRate: t.number,
47+
/** Travel rule information */
48+
travelInfos: t.unknown,
49+
/** BitGo fee information (if applicable) */
50+
bitgoFee: optional(t.unknown),
51+
/** Travel rule result (if applicable) */
52+
travelResult: optional(t.unknown),
53+
});
54+
55+
/**
56+
* Fan out unspents in a wallet
57+
*
58+
* This endpoint fans out unspents in a wallet by creating a transaction that spends from
59+
* multiple inputs to multiple outputs. This is useful for increasing the number of UTXOs
60+
* in a wallet, which can improve transaction parallelization.
61+
*
62+
* @operationId express.v1.wallet.fanoutunspents
63+
*/
64+
export const PutFanoutUnspents = httpRoute({
65+
path: '/api/v1/wallet/:id/fanoutunspents',
66+
method: 'PUT',
67+
request: httpRequest({
68+
params: FanoutUnspentsRequestParams,
69+
body: FanoutUnspentsRequestBody,
70+
}),
71+
response: {
72+
/** Successfully fanned out unspents */
73+
200: FanoutUnspentsResponse,
74+
/** Invalid request or fan out fails */
75+
400: BitgoExpressError,
76+
},
77+
});

0 commit comments

Comments
 (0)