Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/__tests__/masterBitgoExpress/generateWallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ describe('POST /api/:coin/wallet/generate', () => {
nock.cleanAll();
});

after(() => {
nock.restore();
});

it('should generate a wallet by calling the enclaved express service', async () => {
const userKeychainNock = nock(enclavedExpressUrl)
.post(`/api/${coin}/key/independent`)
Expand Down
86 changes: 86 additions & 0 deletions src/__tests__/postIndependentKey.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'should';

import * as request from 'supertest';
import nock from 'nock';
import { app as enclavedApp } from '../enclavedApp';
import { AppMode, EnclavedConfig, TlsMode } from '../types';
import express from 'express';

import * as sinon from 'sinon';
import * as configModule from '../initConfig';

describe('postIndependentKey', () => {
let cfg: EnclavedConfig;
let app: express.Application;
let agent: request.SuperAgentTest;

// test cofig
const kmsUrl = 'http://kms.invalid';
const coin = 'hteth';
const accessToken = 'test-token';

// sinon stubs
let configStub: sinon.SinonStub;

before(() => {
// nock config
nock.disableNetConnect();
nock.enableNetConnect('127.0.0.1');

// app config
cfg = {
appMode: AppMode.ENCLAVED,
port: 0, // Let OS assign a free port
bind: 'localhost',
timeout: 60000,
logFile: '',
kmsUrl: kmsUrl,
tlsMode: TlsMode.DISABLED,
mtlsRequestCert: false,
allowSelfSigned: true,
};

configStub = sinon.stub(configModule, 'initConfig').returns(cfg);

// app setup
app = enclavedApp(cfg);
agent = request.agent(app);
});

afterEach(() => {
nock.cleanAll();
});

after(() => {
configStub.restore();
});

// test cases
it('should post an independent key successfully', async () => {
const mockKmsResponse = {
coin: coin,
pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
source: 'user',
type: 'independent',
};

const kmsNock = nock(kmsUrl).post(`/key`).reply(200, mockKmsResponse);

console.log(cfg.kmsUrl);

console.warn(nock.activeMocks());
console.warn(nock.isActive());

const response = await agent
.post(`/api/${coin}/key/independent`)
.set('Authorization', `Bearer ${accessToken}`)
.send({ source: 'user' });

response.status.should.equal(200);
response.body.should.have.property('pub', mockKmsResponse.pub);
response.body.should.have.property('coin', mockKmsResponse.coin);
response.body.should.have.property('source', mockKmsResponse.source);

kmsNock.done();
});
});
122 changes: 122 additions & 0 deletions src/__tests__/signMultisigTransaction.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'should';

import * as request from 'supertest';
import nock from 'nock';
import { app as enclavedApp } from '../enclavedApp';
import { AppMode, EnclavedConfig, TlsMode } from '../types';
import express from 'express';

import * as sinon from 'sinon';
import * as configModule from '../initConfig';

describe('signMultisigTransaction', () => {
let cfg: EnclavedConfig;
let app: express.Application;
let agent: request.SuperAgentTest;

// test cofig
const kmsUrl = 'http://kms.invalid';
const coin = 'hteth';
const accessToken = 'test-token';

// sinon stubs
let configStub: sinon.SinonStub;

before(() => {
// nock config
nock.disableNetConnect();
nock.enableNetConnect('127.0.0.1');

// app config
cfg = {
appMode: AppMode.ENCLAVED,
port: 0, // Let OS assign a free port
bind: 'localhost',
timeout: 60000,
logFile: '',
kmsUrl: kmsUrl,
tlsMode: TlsMode.DISABLED,
mtlsRequestCert: false,
allowSelfSigned: true,
};

configStub = sinon.stub(configModule, 'initConfig').returns(cfg);

// app setup
app = enclavedApp(cfg);
agent = request.agent(app);
});

afterEach(() => {
nock.cleanAll();
});

after(() => {
configStub.restore();
});

// test cases
it('should half-sign a multisig transaction successfully', async () => {
const input = {
source: 'user',
pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
txPrebuild: {
feeInfo: {
date: '2025-06-11T16:35:04.622Z',
gasPrice: '11610471836',
baseFee: '11478770445',
gasUsedRatio: '0.9999833170418686',
safeLowMinerTip: '521229555',
normalMinerTip: '521229555',
standardMinerTip: '521229555',
fastestMinerTip: '521229555',
ludicrousMinerTip: '550407891',
},
eip1559: { maxPriorityFeePerGas: '599413988', maxFeePerGas: '23556954878' },
recipients: [
{
amount: '10000',
address: '0xe9cbfdf9e02f4ee37ec81683a4be934b4eecc295',
},
],
nextContractSequenceId: 5,
gasLimit: 200000,
isBatch: false,
coin: 'hteth',
walletId: '68489ecff6fb16304670b327db8eb31a',
walletContractAddress: '0xe9cbfdf9e02f4ee37ec81683a4be934b4eecc295',
reqId: {}, // modified
wallet: {
// modified
bitgo: {},
baseCoin: {},
_wallet: {},
},
buildParams: {},
},
};

const mockKmsResponse = {
prv: 'xprv9s21ZrQH143K3gACTjj6hGGGTME8nrhuYiuGVsiVqyxQjZJ1Tr2PZJKAABHLm2gMSwqRmXBXT8VcXppDy43xjwvt9xdgkDSyRPsBUekEaPq',
pub: 'xpub661MyMwAqRbcGAEfZmG74QD11P4dCKRkuwpsJG87QKVPcMdA1PLe76de1Ted54rZ2gyqLYhmdhBCFMrt7AoVwPZwXa3Na9aUnvndvXbvmwu',
source: 'user',
type: 'independent',
};

const kmsNock = nock(kmsUrl)
.get(`/key/${input.pub}`)
.query({ source: 'user' })
.reply(200, mockKmsResponse);

const response = await agent
.post(`/api/${coin}/multisig/sign`)
.set('Authorization', `Bearer ${accessToken}`)
.query({ source: input.source })
.send(input);

response.status.should.equal(200);
response.body.should.have.property('halfSigned');

kmsNock.done();
});
});