Skip to content

Commit 8978e78

Browse files
committed
refactor: signAndSend sdk functions and ECDSA MPCv2 utils
Ticket: WAL-1489
1 parent 304ca86 commit 8978e78

4 files changed

Lines changed: 525 additions & 622 deletions

File tree

src/__tests__/api/master/ecdsa.test.ts

Lines changed: 24 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@ import {
66
IRequestTracer,
77
openpgpUtils,
88
RequestTracer,
9-
SignatureShareRecord,
10-
SignatureShareType,
11-
TransactionState,
129
TxRequest,
1310
Wallet,
1411
} from '@bitgo-beta/sdk-core';
1512
import { BitGoAPI } from '@bitgo-beta/sdk-api';
1613
import { AdvancedWalletManagerClient } from '../../../masterBitgoExpress/clients/advancedWalletManagerClient';
1714
import { signAndSendEcdsaMPCv2FromTxRequest } from '../../../masterBitgoExpress/handlers/ecdsa';
18-
import { BitGoAPITestHarness } from './testUtils';
15+
import {
16+
BitGoAPITestHarness,
17+
buildEcdsaMpcv2TxRequest,
18+
nockEcdsaMpcv2SigningFlow,
19+
} from './testUtils';
1920

2021
describe('Ecdsa Signing Handler', () => {
2122
let bitgo: BitGoAPI;
@@ -65,22 +66,8 @@ describe('Ecdsa Signing Handler', () => {
6566
});
6667

6768
it('should successfully sign an ECDSA MPCv2 transaction', async () => {
68-
const txRequest: TxRequest = {
69-
txRequestId: 'test-tx-request-id',
70-
apiVersion: 'full',
71-
enterpriseId: 'test-enterprise-id',
72-
transactions: [],
73-
state: 'pendingUserSignature',
74-
walletId: 'test-wallet-id',
75-
walletType: 'hot',
76-
version: 2,
77-
date: new Date().toISOString(),
78-
userId: 'test-user-id',
79-
intent: {},
80-
policiesChecked: true,
81-
unsignedTxs: [],
82-
latest: true,
83-
};
69+
const txRequestData = buildEcdsaMpcv2TxRequest('pendingUserSignature');
70+
const txRequest = txRequestData as TxRequest;
8471
const userPubKey = 'test-user-pub-key';
8572

8673
const bitgoGpgKey = await openpgpUtils.generateGPGKeyPair('secp256k1');
@@ -98,145 +85,15 @@ describe('Ecdsa Signing Handler', () => {
9885
},
9986
});
10087

101-
// Mock sendSignatureShareV2 calls for each round
102-
const round1SignatureShare: SignatureShareRecord = {
103-
from: SignatureShareType.USER,
104-
to: SignatureShareType.BITGO,
105-
share: JSON.stringify({
106-
type: 'round1Input',
107-
data: {
108-
msg1: {
109-
from: 1,
110-
message: 'round1-message',
111-
},
112-
},
113-
}),
114-
};
115-
116-
const round1TxRequest: TxRequest = {
117-
...txRequest,
118-
transactions: [
119-
{
120-
unsignedTx: {
121-
derivationPath: 'm/0',
122-
signableHex: 'testMessage',
123-
serializedTxHex: 'testMessage',
124-
},
125-
signatureShares: [round1SignatureShare],
126-
state: 'pendingSignature' as TransactionState,
127-
},
128-
],
129-
};
130-
131-
const sendSignatureShareV2Round1Nock = nock(bitgoApiUrl)
132-
.post(`/api/v2/wallet/${walletId}/txrequests/test-tx-request-id/transactions/0/sign`)
133-
.matchHeader('any', () => true)
134-
.reply(200, {
135-
...round1TxRequest,
136-
});
137-
138-
const round2SignatureShare: SignatureShareRecord = {
139-
from: SignatureShareType.USER,
140-
to: SignatureShareType.BITGO,
141-
share: JSON.stringify({
142-
type: 'round2Input',
143-
data: {
144-
msg2: {
145-
from: 1,
146-
to: 3,
147-
encryptedMessage: 'round2-encrypted-message',
148-
signature: 'round2-signature',
149-
},
150-
msg3: {
151-
from: 1,
152-
to: 3,
153-
encryptedMessage: 'round3-encrypted-message',
154-
signature: 'round3-signature',
155-
},
156-
},
157-
}),
158-
};
159-
160-
const round2TxRequest: TxRequest = {
161-
...round1TxRequest,
162-
transactions: [
163-
{
164-
...round1TxRequest.transactions![0],
165-
signatureShares: [round1SignatureShare, round2SignatureShare],
166-
},
167-
],
168-
};
169-
170-
const sendSignatureShareV2Round2Nock = nock(bitgoApiUrl)
171-
.post(`/api/v2/wallet/${walletId}/txrequests/test-tx-request-id/transactions/0/sign`)
172-
.matchHeader('any', () => true)
173-
.reply(200, {
174-
...round2TxRequest,
175-
});
176-
177-
const round3SignatureShare: SignatureShareRecord = {
178-
from: SignatureShareType.USER,
179-
to: SignatureShareType.BITGO,
180-
share: JSON.stringify({
181-
type: 'round3Input',
182-
data: {
183-
msg4: {
184-
from: 1,
185-
message: 'round4-message',
186-
signature: 'round4-signature',
187-
signatureR: 'round4-signature-r',
188-
},
189-
},
190-
}),
191-
};
192-
193-
const sendSignatureShareV2Round3Nock = nock(bitgoApiUrl)
194-
.post(`/api/v2/wallet/${walletId}/txrequests/test-tx-request-id/transactions/0/sign`)
195-
.matchHeader('any', () => true)
196-
.reply(200, {
197-
...round2TxRequest,
198-
transactions: [
199-
{
200-
...round2TxRequest.transactions![0],
201-
signatureShares: [round1SignatureShare, round2SignatureShare, round3SignatureShare],
202-
},
203-
],
204-
});
205-
206-
// Mock sendTxRequest call
207-
const sendTxRequestNock = nock(bitgoApiUrl)
208-
.post(`/api/v2/wallet/${walletId}/txrequests/test-tx-request-id/transactions/0/send`)
209-
.matchHeader('any', () => true)
210-
.reply(200, {
211-
...txRequest,
212-
state: 'signed',
213-
});
214-
215-
// Mock MPCv2 Round 1 signing
216-
const signMpcV2Round1NockAwm = nock(advancedWalletManagerUrl)
217-
.post(`/api/${coin}/mpc/sign/mpcv2round1`)
218-
.reply(200, {
219-
signatureShareRound1: round1SignatureShare,
220-
userGpgPubKey: bitgoGpgKey.publicKey,
221-
encryptedRound1Session: 'encrypted-round1-session',
222-
encryptedUserGpgPrvKey: 'encrypted-user-gpg-prv-key',
223-
encryptedDataKey: 'test-encrypted-data-key',
224-
});
225-
226-
// Mock MPCv2 Round 2 signing
227-
const signMpcV2Round2NockAwm = nock(advancedWalletManagerUrl)
228-
.post(`/api/${coin}/mpc/sign/mpcv2round2`)
229-
.reply(200, {
230-
signatureShareRound2: round2SignatureShare,
231-
encryptedRound2Session: 'encrypted-round2-session',
232-
});
233-
234-
// Mock MPCv2 Round 3 signing
235-
const signMpcV2Round3NockAwm = nock(advancedWalletManagerUrl)
236-
.post(`/api/${coin}/mpc/sign/mpcv2round3`)
237-
.reply(200, {
238-
signatureShareRound3: round3SignatureShare,
239-
});
88+
const sendResponse = { ...txRequestData, state: 'signed' };
89+
const nocks = nockEcdsaMpcv2SigningFlow({
90+
coin,
91+
bitgoApiUrl,
92+
advancedWalletManagerUrl,
93+
sendResponse,
94+
walletId,
95+
userGpgPubKey: bitgoGpgKey.publicKey,
96+
});
24097

24198
const result = await signAndSendEcdsaMPCv2FromTxRequest(
24299
bitgo,
@@ -248,17 +105,14 @@ describe('Ecdsa Signing Handler', () => {
248105
reqId,
249106
);
250107

251-
result.should.eql({
252-
...txRequest,
253-
state: 'signed',
254-
});
108+
result.should.eql(sendResponse);
255109

256-
sendSignatureShareV2Round1Nock.done();
257-
sendSignatureShareV2Round2Nock.done();
258-
sendSignatureShareV2Round3Nock.done();
259-
sendTxRequestNock.done();
260-
signMpcV2Round1NockAwm.done();
261-
signMpcV2Round2NockAwm.done();
262-
signMpcV2Round3NockAwm.done();
110+
nocks.round1SignNock.done();
111+
nocks.round2SignNock.done();
112+
nocks.round3SignNock.done();
113+
nocks.sendTxNock.done();
114+
nocks.awmRound1Nock.done();
115+
nocks.awmRound2Nock.done();
116+
nocks.awmRound3Nock.done();
263117
});
264118
});

0 commit comments

Comments
 (0)