Skip to content

Commit 498714e

Browse files
authored
feat(express): migrate recover token to typed routes
2 parents 86167cf + 4eac889 commit 498714e

File tree

4 files changed

+671
-7
lines changed

4 files changed

+671
-7
lines changed

modules/express/src/clientRoutes.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ async function handleV2SignTx(req: express.Request) {
739739
* handle wallet recover token
740740
* @param req
741741
*/
742-
async function handleV2RecoverToken(req: express.Request) {
742+
async function handleV2RecoverToken(req: ExpressApiRouteRequest<'express.v2.wallet.recovertoken', 'post'>) {
743743
const bitgo = req.bitgo;
744744
const coin = bitgo.coin(req.params.coin);
745745

@@ -1640,12 +1640,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void {
16401640
prepareBitGo(config),
16411641
promiseWrapper(handleV2SignTSSWalletTx)
16421642
);
1643-
app.post(
1644-
'/api/v2/:coin/wallet/:id/recovertoken',
1645-
parseBody,
1646-
prepareBitGo(config),
1647-
promiseWrapper(handleV2RecoverToken)
1648-
);
1643+
router.post('express.v2.wallet.recovertoken', [prepareBitGo(config), typedPromiseWrapper(handleV2RecoverToken)]);
16491644

16501645
// send transaction
16511646
app.post('/api/v2/:coin/wallet/:id/sendcoins', parseBody, prepareBitGo(config), promiseWrapper(handleV2SendOne));

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { PutConsolidateUnspents } from './v1/consolidateUnspents';
2525
import { PostCreateAddress } from './v2/createAddress';
2626
import { PutFanoutUnspents } from './v1/fanoutUnspents';
2727
import { PostOfcSignPayload } from './v2/ofcSignPayload';
28+
import { PostWalletRecoverToken } from './v2/walletRecoverToken';
2829

2930
export const ExpressApi = apiSpec({
3031
'express.ping': {
@@ -96,6 +97,9 @@ export const ExpressApi = apiSpec({
9697
'express.ofc.signPayload': {
9798
post: PostOfcSignPayload,
9899
},
100+
'express.v2.wallet.recovertoken': {
101+
post: PostWalletRecoverToken,
102+
},
99103
});
100104

101105
export type ExpressApi = typeof ExpressApi;
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
* Path parameters for recovering tokens from a wallet
7+
*/
8+
export const RecoverTokenParams = {
9+
/** Coin ticker / chain identifier */
10+
coin: t.string,
11+
/** The ID of the wallet */
12+
id: t.string,
13+
} as const;
14+
15+
/**
16+
* Request body for recovering tokens from a wallet
17+
*/
18+
export const RecoverTokenBody = {
19+
/** The contract address of the unsupported token to recover */
20+
tokenContractAddress: optional(t.string),
21+
/** The destination address where recovered tokens should be sent */
22+
recipient: optional(t.string),
23+
/** Whether to automatically broadcast the half-signed transaction to BitGo for cosigning and broadcasting */
24+
broadcast: optional(t.boolean),
25+
/** The wallet passphrase used to decrypt the user key */
26+
walletPassphrase: optional(t.string),
27+
/** The extended private key (alternative to walletPassphrase) */
28+
prv: optional(t.string),
29+
} as const;
30+
31+
/**
32+
* Response for recovering tokens from a wallet
33+
*/
34+
export const RecoverTokenResponse = t.type({
35+
halfSigned: t.type({
36+
/** Recipient information for the recovery transaction */
37+
recipient: t.unknown,
38+
/** Expiration time for the transaction */
39+
expireTime: t.number,
40+
/** Contract sequence ID */
41+
contractSequenceId: t.number,
42+
/** Operation hash for the transaction */
43+
operationHash: t.string,
44+
/** Signature for the half-signed transaction */
45+
signature: t.string,
46+
/** Gas limit for the transaction */
47+
gasLimit: t.number,
48+
/** Gas price for the transaction */
49+
gasPrice: t.number,
50+
/** The token contract address being recovered */
51+
tokenContractAddress: t.string,
52+
/** The wallet ID */
53+
walletId: t.string,
54+
}),
55+
});
56+
57+
/**
58+
* Recover unsupported tokens from a BitGo multisig wallet
59+
*
60+
* This endpoint builds a half-signed transaction to recover unsupported tokens from an ETH wallet.
61+
* The transaction can be manually submitted to BitGo for cosigning, or automatically broadcast
62+
* by setting the 'broadcast' parameter to true.
63+
*
64+
* Note: This endpoint is only supported for ETH family wallets.
65+
*
66+
* @operationId express.v2.wallet.recovertoken
67+
*/
68+
export const PostWalletRecoverToken = httpRoute({
69+
path: '/api/v2/:coin/wallet/:id/recovertoken',
70+
method: 'POST',
71+
request: httpRequest({
72+
params: RecoverTokenParams,
73+
body: RecoverTokenBody,
74+
}),
75+
response: {
76+
/** Successfully created token recovery transaction */
77+
200: RecoverTokenResponse,
78+
/** Invalid request or token recovery fails */
79+
400: BitgoExpressError,
80+
},
81+
});

0 commit comments

Comments
 (0)