Skip to content

Commit fd693d9

Browse files
committed
feat(express): migrate keychainlocal to typed routes
TICKET: WP-5414
1 parent c1ee597 commit fd693d9

File tree

4 files changed

+62
-6
lines changed

4 files changed

+62
-6
lines changed

modules/express/src/clientRoutes.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,12 +1617,7 @@ export function setupAPIRoutes(app: express.Application, config: Config): void {
16171617
// API v2
16181618

16191619
// create keychain
1620-
app.post(
1621-
'/api/v2/:coin/keychain/local',
1622-
parseBody,
1623-
prepareBitGo(config),
1624-
promiseWrapper(handleV2CreateLocalKeyChain)
1625-
);
1620+
router.post('express.keychain.local', [prepareBitGo(config), typedPromiseWrapper(handleV2CreateLocalKeyChain)]);
16261621

16271622
// generate wallet
16281623
app.post('/api/v2/:coin/wallet/generate', parseBody, prepareBitGo(config), promiseWrapper(handleV2GenerateWallet));

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { PostAcceptShare } from './v1/acceptShare';
1212
import { PostSimpleCreate } from './v1/simpleCreate';
1313
import { PutPendingApproval } from './v1/pendingApproval';
1414
import { PostSignTransaction } from './v1/signTransaction';
15+
import { PostKeychainLocal } from './v2/keychainLocal';
1516

1617
export const ExpressApi = apiSpec({
1718
'express.ping': {
@@ -44,6 +45,9 @@ export const ExpressApi = apiSpec({
4445
'express.v1.wallet.signTransaction': {
4546
post: PostSignTransaction,
4647
},
48+
'express.keychain.local': {
49+
post: PostKeychainLocal,
50+
},
4751
});
4852

4953
export type ExpressApi = typeof ExpressApi;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as t from 'io-ts';
2+
import { httpRoute, httpRequest } from '@api-ts/io-ts-http';
3+
import { BitgoExpressError } from '../../schemas/error';
4+
5+
/**
6+
* @property {string} coin - Coin identifier (e.g. btc, tbtc, eth)
7+
*/
8+
export const KeychainLocalRequestParams = {
9+
coin: t.string,
10+
};
11+
12+
/**
13+
* Local client-side function to create a new keychain.
14+
* Creating your keychains is a critical step for safely securing your Bitcoin. When generating new keychains, this API uses a random number generator that adheres to industry standards. If you provide your own seed, you must take extreme caution when creating it.
15+
* Returns an object containing the xprv and xpub for the new chain. The created keychain is not known to the BitGo service. To use it with the BitGo service, use the ‘Store Keychain’ API call.
16+
*
17+
* For security reasons, it is highly recommended that you encrypt and destroy the original xprv immediately to prevent theft.
18+
*
19+
* @operationId express.keychain.local
20+
*/
21+
export const PostKeychainLocal = httpRoute({
22+
path: '/api/v2/{coin}/keychain/local',
23+
method: 'POST',
24+
request: httpRequest({
25+
params: KeychainLocalRequestParams,
26+
}),
27+
response: {
28+
200: t.type({
29+
prv: t.string,
30+
pub: t.string,
31+
}),
32+
400: BitgoExpressError,
33+
},
34+
});

modules/express/test/unit/typedRoutes/decode.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { EncryptRequestBody } from '../../../src/typedRoutes/api/common/encrypt'
55
import { LoginRequest } from '../../../src/typedRoutes/api/common/login';
66
import { VerifyAddressBody } from '../../../src/typedRoutes/api/common/verifyAddress';
77
import { SimpleCreateRequestBody } from '../../../src/typedRoutes/api/v1/simpleCreate';
8+
import { KeychainLocalRequestParams } from '../../../src/typedRoutes/api/v2/keychainLocal';
89

910
export function assertDecode<T>(codec: t.Type<T, unknown>, input: unknown): T {
1011
const result = codec.decode(input);
@@ -100,4 +101,26 @@ describe('io-ts decode tests', function () {
100101
passphrase: 'pass',
101102
});
102103
});
104+
it('express.keychain.local', function () {
105+
// coin parameter is required
106+
assert.throws(() => assertDecode(t.type(KeychainLocalRequestParams), {}));
107+
// coin must be a string
108+
assert.throws(() =>
109+
assertDecode(t.type(KeychainLocalRequestParams), {
110+
coin: 123,
111+
})
112+
);
113+
// valid with coin parameter
114+
assertDecode(t.type(KeychainLocalRequestParams), {
115+
coin: 'btc',
116+
});
117+
// valid with different coin
118+
assertDecode(t.type(KeychainLocalRequestParams), {
119+
coin: 'eth',
120+
});
121+
// valid with testnet coin
122+
assertDecode(t.type(KeychainLocalRequestParams), {
123+
coin: 'tbtc',
124+
});
125+
});
103126
});

0 commit comments

Comments
 (0)