Skip to content

Commit 7268b9b

Browse files
committed
feat(ebe): added integrated test for ebe api
1 parent b2761cf commit 7268b9b

File tree

3 files changed

+247
-4
lines changed

3 files changed

+247
-4
lines changed

src/__tests__/masterBitgoExpress/generateWallet.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ describe('POST /api/:coin/wallet/generate', () => {
4141
nock.cleanAll();
4242
});
4343

44-
after(() => {
45-
nock.restore();
46-
});
47-
4844
it('should generate a wallet by calling the enclaved express service', async () => {
4945
const userKeychainNock = nock(enclavedExpressUrl)
5046
.post(`/api/${coin}/key/independent`)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import 'should';
2+
3+
import * as request from 'supertest';
4+
import nock from 'nock';
5+
import { app as enclavedApp } from '../enclavedApp';
6+
import { AppMode, EnclavedConfig, TlsMode } from '../types';
7+
import express from 'express';
8+
9+
import * as sinon from 'sinon';
10+
import * as configModule from '../config';
11+
12+
describe('postIndependentKey', () => {
13+
let cfg: EnclavedConfig;
14+
let app: express.Application;
15+
let agent: request.SuperAgentTest;
16+
17+
// test cofig
18+
const kmsUrl = 'http://kms.invalid';
19+
const coin = 'hteth';
20+
const accessToken = 'test-token';
21+
22+
// sinon stubs
23+
let configStub: sinon.SinonStub;
24+
25+
before(() => {
26+
// nock config
27+
nock.disableNetConnect();
28+
nock.enableNetConnect('127.0.0.1');
29+
30+
// app config
31+
cfg = {
32+
appMode: AppMode.ENCLAVED,
33+
port: 0, // Let OS assign a free port
34+
bind: 'localhost',
35+
timeout: 60000,
36+
logFile: '',
37+
kmsUrl: kmsUrl,
38+
tlsMode: TlsMode.DISABLED,
39+
mtlsRequestCert: false,
40+
allowSelfSigned: true,
41+
};
42+
43+
configStub = sinon.stub(configModule, 'config').returns(cfg);
44+
45+
// app setup
46+
app = enclavedApp(cfg);
47+
agent = request.agent(app);
48+
49+
// activate nock
50+
if (!nock.isActive()) {
51+
nock.activate();
52+
}
53+
});
54+
55+
afterEach(() => {
56+
nock.cleanAll();
57+
});
58+
59+
after(() => {
60+
configStub.restore();
61+
});
62+
63+
// test cases
64+
it('should post an independent key successfully', async () => {
65+
const mockKmsResponse = {
66+
coin: coin,
67+
pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
68+
source: 'user',
69+
type: 'independent',
70+
};
71+
72+
const kmsNock = nock(kmsUrl).post(`/key`).reply(200, mockKmsResponse);
73+
74+
console.log(cfg.kmsUrl);
75+
76+
console.warn(nock.activeMocks());
77+
console.warn(nock.isActive());
78+
79+
const response = await agent
80+
.post(`/api/${coin}/key/independent`)
81+
.set('Authorization', `Bearer ${accessToken}`)
82+
.send({ source: 'user' });
83+
84+
response.status.should.equal(200);
85+
response.body.should.have.property('pub', mockKmsResponse.pub);
86+
response.body.should.have.property('coin', mockKmsResponse.coin);
87+
response.body.should.have.property('source', mockKmsResponse.source);
88+
89+
kmsNock.done();
90+
});
91+
});
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import 'should';
2+
3+
import * as request from 'supertest';
4+
import nock from 'nock';
5+
import { app as enclavedApp } from '../enclavedApp';
6+
import { AppMode, EnclavedConfig, TlsMode } from '../types';
7+
import express from 'express';
8+
9+
import * as sinon from 'sinon';
10+
import * as configModule from '../config';
11+
12+
describe('signMultisigTransaction', () => {
13+
let cfg: EnclavedConfig;
14+
let app: express.Application;
15+
let agent: request.SuperAgentTest;
16+
17+
// test cofig
18+
const kmsUrl = 'http://kms.invalid';
19+
const coin = 'hteth';
20+
const accessToken = 'test-token';
21+
22+
// sinon stubs
23+
let configStub: sinon.SinonStub;
24+
25+
before(() => {
26+
// nock config
27+
nock.disableNetConnect();
28+
nock.enableNetConnect('127.0.0.1');
29+
30+
// app config
31+
cfg = {
32+
appMode: AppMode.ENCLAVED,
33+
port: 0, // Let OS assign a free port
34+
bind: 'localhost',
35+
timeout: 60000,
36+
logFile: '',
37+
kmsUrl: kmsUrl,
38+
tlsMode: TlsMode.DISABLED,
39+
mtlsRequestCert: false,
40+
allowSelfSigned: true,
41+
};
42+
43+
configStub = sinon.stub(configModule, 'config').returns(cfg);
44+
45+
// app setup
46+
app = enclavedApp(cfg);
47+
agent = request.agent(app);
48+
49+
// activate nock
50+
if (!nock.isActive()) {
51+
nock.activate();
52+
}
53+
});
54+
55+
afterEach(() => {
56+
nock.cleanAll();
57+
});
58+
59+
after(() => {
60+
configStub.restore();
61+
});
62+
63+
// test cases
64+
it('should half-sign a multisig transaction successfully', async () => {
65+
const input = {
66+
source: 'user',
67+
pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
68+
txPrebuild: {
69+
feeInfo: {
70+
date: '2025-06-11T16:35:04.622Z',
71+
gasPrice: '11610471836',
72+
baseFee: '11478770445',
73+
gasUsedRatio: '0.9999833170418686',
74+
safeLowMinerTip: '521229555',
75+
normalMinerTip: '521229555',
76+
standardMinerTip: '521229555',
77+
fastestMinerTip: '521229555',
78+
ludicrousMinerTip: '550407891',
79+
},
80+
eip1559: { maxPriorityFeePerGas: '599413988', maxFeePerGas: '23556954878' },
81+
recipients: [
82+
{
83+
amount: '10000',
84+
address: '0xe9cbfdf9e02f4ee37ec81683a4be934b4eecc295',
85+
},
86+
],
87+
nextContractSequenceId: 5,
88+
gasLimit: 200000,
89+
isBatch: false,
90+
coin: 'hteth',
91+
walletId: '68489ecff6fb16304670b327db8eb31a',
92+
walletContractAddress: '0xe9cbfdf9e02f4ee37ec81683a4be934b4eecc295',
93+
reqId: {}, // modified
94+
wallet: {
95+
// modified
96+
bitgo: {},
97+
baseCoin: {},
98+
_wallet: {},
99+
},
100+
buildParams: {},
101+
},
102+
};
103+
104+
const mockKmsResponse = {
105+
prv: 'xprv9s21ZrQH143K3gACTjj6hGGGTME8nrhuYiuGVsiVqyxQjZJ1Tr2PZJKAABHLm2gMSwqRmXBXT8VcXppDy43xjwvt9xdgkDSyRPsBUekEaPq',
106+
pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
107+
source: 'user',
108+
type: 'independent',
109+
};
110+
111+
const kmsNock = nock(kmsUrl)
112+
.get(`/key/${input.pub}`)
113+
.query({ source: 'user' })
114+
.reply(200, mockKmsResponse);
115+
116+
const response = await agent
117+
.post(`/api/${coin}/multisig/sign`)
118+
.set('Authorization', `Bearer ${accessToken}`)
119+
.query({ source: input.source })
120+
.send(input);
121+
122+
response.status.should.equal(200);
123+
response.body.should.have.property('halfSigned');
124+
125+
kmsNock.done();
126+
});
127+
128+
// it('should half-sign a multisig transaction successfully', async () => {
129+
// const input = {
130+
// source: 'user',
131+
// };
132+
133+
// const mockKmsResponse = {
134+
// coin: coin,
135+
// pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
136+
// source: 'user',
137+
// type: 'independent',
138+
// };
139+
140+
// const kmsNock = nock(kmsUrl)
141+
// .get(`/key/${}`)
142+
// .matchHeader('any', () => true)
143+
// .reply(200, mockKmsResponse)
144+
// .persist();
145+
146+
// const response = await agent
147+
// .post(`/api/${coin}/key/independent`)
148+
// .set('Authorization', `Bearer ${accessToken}`)
149+
// .query({ source: input.source })
150+
// .send(input);
151+
152+
// response.status.should.equal(200);
153+
154+
// kmsNock.done();
155+
// });
156+
});

0 commit comments

Comments
 (0)