Skip to content

Commit 35515b8

Browse files
feat: moved mbe ping enclave to api-ts
Ticket: WP-4593
1 parent 7778f2f commit 35515b8

11 files changed

Lines changed: 805 additions & 117 deletions

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,19 @@
1414
"test:watch": "jest --watch",
1515
"test:coverage": "jest --coverage",
1616
"lint": "eslint --quiet .",
17-
"generate-test-ssl": "openssl req -x509 -newkey rsa:2048 -keyout test-ssl-key.pem -out test-ssl-cert.pem -days 365 -nodes -subj '/CN=localhost'"
17+
"generate-test-ssl": "openssl req -x509 -newkey rsa:2048 -keyout test-ssl-key.pem -out test-ssl-cert.pem -days 365 -nodes -subj '/CN=localhost'",
18+
"generate-openapi": "npx openapi-generator ./src/masterExpressApi.ts > src/masterExpressApi.openapi.json"
1819
},
1920
"dependencies": {
2021
"@bitgo/sdk-core": "^33.2.0",
2122
"bitgo": "^44.2.0",
2223
"body-parser": "^1.20.3",
2324
"connect-timeout": "^1.9.0",
2425
"debug": "^3.1.0",
26+
"@api-ts/io-ts-http": "^3.2.1",
27+
"@api-ts/express-wrapper": "^1.0.33",
28+
"@api-ts/response": "^2.1.0",
29+
"io-ts": "~2.1.3",
2530
"express": "4.17.3",
2631
"lodash": "^4.17.20",
2732
"morgan": "^1.9.1",
@@ -31,6 +36,7 @@
3136
"zod": "^3.25.48"
3237
},
3338
"devDependencies": {
39+
"@api-ts/openapi-generator": "^5.7.0",
3440
"@types/body-parser": "^1.17.0",
3541
"@types/connect-timeout": "^1.9.0",
3642
"@types/debug": "^4.1.12",

src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ function masterExpressEnvConfig(): Partial<MasterExpressConfig> {
209209
timeout: Number(readEnvVar('BITGO_TIMEOUT')),
210210
keepAliveTimeout: Number(readEnvVar('BITGO_KEEP_ALIVE_TIMEOUT')),
211211
headersTimeout: Number(readEnvVar('BITGO_HEADERS_TIMEOUT')),
212-
// BitGo API settings
212+
// BitGo MasterExpressApi settings
213213
env: readEnvVar('BITGO_ENV') as EnvironmentName,
214214
customRootUri: readEnvVar('BITGO_CUSTOM_ROOT_URI'),
215215
enableSSL: readEnvVar('BITGO_ENABLE_SSL') !== 'false', // Default to true unless explicitly set to false

src/errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class EnclavedError extends Error {
1717
}
1818

1919
/**
20-
* Error for API responses
20+
* Error for MasterExpressApi responses
2121
*/
2222
export class ApiResponseError extends EnclavedError {
2323
public result: any;

src/masterBitgoExpress/enclavedExpressClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export class EnclavedExpressClient {
7070
try {
7171
debugLogger('Creating independent keychain for coin: %s', this.coin);
7272
const { body: keychain } = await superagent
73-
.post(`${this.url}/api/${this.coin}/key/independent`)
73+
.post(`${this.url}/${this.coin}/key/independentkey`)
7474
.ca(this.sslCert)
7575
.agent(
7676
new https.Agent({
Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,60 @@
11
import {
2-
GenerateWalletOptions,
2+
AddKeychainOptions,
3+
Keychain,
4+
KeychainsTriplet,
35
promiseProps,
46
RequestTracer,
57
SupplementGenerateWalletOptions,
6-
Keychain,
7-
KeychainsTriplet,
8-
Wallet,
98
WalletWithKeychains,
10-
AddKeychainOptions,
9+
type Wallet,
1110
} from '@bitgo/sdk-core';
1211
import { createEnclavedExpressClient } from './enclavedExpressClient';
13-
import _ from 'lodash';
14-
import { BitGoRequest } from '../types/request';
12+
import { BitGo } from 'bitgo';
13+
14+
export type GenerateMultiSigOnPremWalletParams = {
15+
coin: string;
16+
label: string;
17+
enterprise?: string;
18+
};
1519

1620
/**
17-
* This route is used to generate a multisig wallet when enclaved express is enabled
21+
* Generate multisig wallet keys using enclaved express and create the wallet in BitGo
22+
* @param {BitGo} bitgo the sdk instance
23+
* @param {GenerateMultiSigOnPremWalletParams} params
1824
*/
19-
export async function handleGenerateWalletOnPrem(req: BitGoRequest) {
20-
const bitgo = req.bitgo;
21-
const baseCoin = bitgo.coin(req.params.coin);
22-
23-
const enclavedExpressClient = createEnclavedExpressClient(req.params.coin);
25+
export async function generateMultiSigOnPremWallet({
26+
bitgo,
27+
params,
28+
}: {
29+
bitgo: BitGo;
30+
params: GenerateMultiSigOnPremWalletParams;
31+
}): Promise<WalletWithKeychains> {
32+
const baseCoin = bitgo.coin(params.coin);
33+
34+
const enclavedExpressClient = createEnclavedExpressClient(params.coin);
2435
if (!enclavedExpressClient) {
2536
throw new Error(
2637
'Enclaved express client not configured - enclaved express features will be disabled',
2738
);
2839
}
2940

30-
const params = req.body as GenerateWalletOptions;
3141
const reqId = new RequestTracer();
3242

33-
// Assign the default multiSig type value based on the coin
34-
if (!params.multisigType) {
35-
params.multisigType = baseCoin.getDefaultMultisigType();
36-
}
37-
38-
if (typeof params.label !== 'string') {
39-
throw new Error('missing required string parameter label');
40-
}
41-
42-
const { label, enterprise } = params;
43-
4443
// Create wallet parameters with type assertion to allow 'onprem' subtype
4544
const walletParams = {
46-
label: label,
45+
label: params.label,
4746
m: 2,
4847
n: 3,
4948
keys: [],
5049
type: 'cold',
51-
subType: 'onprem',
50+
subType: 'onPrem',
5251
multisigType: 'onchain',
5352
} as unknown as SupplementGenerateWalletOptions; // TODO: Add onprem to the SDK subType and remove "unknown" type casting
5453

55-
if (!_.isUndefined(enterprise)) {
56-
if (!_.isString(enterprise)) {
57-
throw new Error('invalid enterprise argument, expecting string');
58-
}
59-
walletParams.enterprise = enterprise;
60-
}
61-
6254
const userKeychainPromise = async (): Promise<Keychain> => {
6355
const userKeychain = await enclavedExpressClient.createIndependentKeychain({
6456
source: 'user',
65-
coin: req.params.coin,
57+
coin: params.coin,
6658
type: 'independent',
6759
});
6860
const userKeychainParams: AddKeychainOptions = {
@@ -73,13 +65,13 @@ export async function handleGenerateWalletOnPrem(req: BitGoRequest) {
7365
};
7466

7567
const newUserKeychain = await baseCoin.keychains().add(userKeychainParams);
76-
return _.extend({}, newUserKeychain, userKeychain);
68+
return { ...newUserKeychain, ...userKeychain };
7769
};
7870

7971
const backupKeychainPromise = async (): Promise<Keychain> => {
8072
const backupKeychain = await enclavedExpressClient.createIndependentKeychain({
8173
source: 'backup',
82-
coin: req.params.coin,
74+
coin: params.coin,
8375
type: 'independent',
8476
});
8577
const backupKeychainParams: AddKeychainOptions = {
@@ -90,7 +82,7 @@ export async function handleGenerateWalletOnPrem(req: BitGoRequest) {
9082
};
9183

9284
const newBackupKeychain = await baseCoin.keychains().add(backupKeychainParams);
93-
return _.extend({}, newBackupKeychain, backupKeychain);
85+
return { ...newBackupKeychain, ...backupKeychain };
9486
};
9587

9688
const { userKeychain, backupKeychain, bitgoKeychain }: KeychainsTriplet = await promiseProps({
@@ -99,7 +91,8 @@ export async function handleGenerateWalletOnPrem(req: BitGoRequest) {
9991
bitgoKeychain: baseCoin.keychains().createBitGo({
10092
enterprise: params.enterprise,
10193
reqId,
102-
isDistributedCustody: params.isDistributedCustody,
94+
// not applicable for onPrem wallets
95+
isDistributedCustody: false,
10396
}),
10497
});
10598

@@ -114,15 +107,19 @@ export async function handleGenerateWalletOnPrem(req: BitGoRequest) {
114107
const finalWalletParams = await baseCoin.supplementGenerateWallet(walletParams, keychains);
115108

116109
bitgo.setRequestTracer(reqId);
117-
const newWallet = await bitgo.post(baseCoin.url('/wallet/add')).send(finalWalletParams).result();
118-
119-
const result: WalletWithKeychains = {
120-
wallet: new Wallet(bitgo, baseCoin, newWallet),
110+
const wallet = (await baseCoin.wallets().add({
111+
...finalWalletParams,
112+
enterprise: params.enterprise,
113+
reqId,
114+
// Not valid for onPrem wallets
115+
isDistributedCustody: false,
116+
})) as Wallet;
117+
118+
return {
119+
wallet: wallet,
121120
userKeychain: userKeychain,
122121
backupKeychain: backupKeychain,
123122
bitgoKeychain: bitgoKeychain,
124123
responseType: 'WalletWithKeychains',
125124
};
126-
127-
return { ...result, wallet: result.wallet.toJSON() };
128125
}

0 commit comments

Comments
 (0)