@@ -14,7 +14,7 @@ import {
1414import logger from '../../../logger' ;
1515import { MasterApiSpecRouteRequest } from '../routers/masterApiSpec' ;
1616import { handleEddsaSigning } from './eddsa' ;
17- import { handleEcdsaMPCv2Signing } from './ecdsaMPCv2' ;
17+ import { handleEcdsaMPCv2Signing , createEcdsaMPCv2CustomSigners } from './ecdsaMPCv2' ;
1818import { EnclavedExpressClient } from '../clients/enclavedExpressClient' ;
1919
2020/**
@@ -30,6 +30,43 @@ interface Recipient {
3030 tokenData ?: any ;
3131}
3232
33+ /**
34+ * Creates TSS send parameters for ECDSA MPCv2 signing with custom functions
35+ */
36+ function createEcdsaMPCv2SendParams (
37+ req : MasterApiSpecRouteRequest < 'v1.wallet.sendMany' , 'post' > ,
38+ wallet : Wallet ,
39+ enclavedExpressClient : EnclavedExpressClient ,
40+ signingKeychain : Keychain ,
41+ ) : SendManyOptions {
42+ const coin = req . bitgo . coin ( req . params . coin ) ;
43+ const mpcAlgorithm = coin . getMPCAlgorithm ( ) ;
44+
45+ if ( mpcAlgorithm === 'ecdsa' ) {
46+ // For ECDSA MPCv2, we need to create custom signing functions
47+ const source = signingKeychain . source as 'user' | 'backup' ;
48+ const commonKeychain = signingKeychain . commonKeychain ;
49+
50+ if ( ! commonKeychain ) {
51+ throw new Error ( 'Common keychain is required for ECDSA MPCv2 signing' ) ;
52+ }
53+
54+ // Use the shared custom signing functions
55+ const { customMPCv2Round1Generator, customMPCv2Round2Generator, customMPCv2Round3Generator } =
56+ createEcdsaMPCv2CustomSigners ( enclavedExpressClient , source , commonKeychain ) ;
57+
58+ return {
59+ ...( req . decoded as SendManyOptions ) ,
60+ customMPCv2SigningRound1GenerationFunction : customMPCv2Round1Generator ,
61+ customMPCv2SigningRound2GenerationFunction : customMPCv2Round2Generator ,
62+ customMPCv2SigningRound3GenerationFunction : customMPCv2Round3Generator ,
63+ } ;
64+ } else {
65+ // For non-ECDSA algorithms, return the original parameters
66+ return req . decoded as SendManyOptions ;
67+ }
68+ }
69+
3370export async function handleSendMany ( req : MasterApiSpecRouteRequest < 'v1.wallet.sendMany' , 'post' > ) {
3471 const enclavedExpressClient = req . enclavedExpressClient ;
3572 const reqId = new RequestTracer ( ) ;
@@ -45,9 +82,9 @@ export async function handleSendMany(req: MasterApiSpecRouteRequest<'v1.wallet.s
4582 throw new Error ( `Wallet ${ walletId } not found` ) ;
4683 }
4784
48- // if (wallet.type() !== 'cold' || wallet.subType() !== 'onPrem') {
49- // throw new Error('Wallet is not an on-prem wallet');
50- // }
85+ if ( wallet . type ( ) !== 'cold' || wallet . subType ( ) !== 'onPrem' ) {
86+ throw new Error ( 'Wallet is not an on-prem wallet' ) ;
87+ }
5188
5289 const keyIdIndex = params . source === 'user' ? KeyIndices . USER : KeyIndices . BACKUP ;
5390 logger . info ( `Key ID index: ${ keyIdIndex } ` ) ;
@@ -64,13 +101,25 @@ export async function handleSendMany(req: MasterApiSpecRouteRequest<'v1.wallet.s
64101 if ( params . pubkey && signingKeychain . pub !== params . pubkey ) {
65102 throw new Error ( `Pub provided does not match the keychain on wallet for ${ params . source } ` ) ;
66103 }
67- if ( params . commonKeychain && signingKeychain . commonKeychain !== params . commonKeychain ) {
68- throw new Error (
69- `Common keychain provided does not match the keychain on wallet for ${ params . source } ` ,
70- ) ;
71- }
104+ // if (params.commonKeychain && signingKeychain.commonKeychain !== params.commonKeychain) {
105+ // throw new Error(
106+ // `Common keychain provided does not match the keychain on wallet for ${params.source}`,
107+ // );
108+ // }
72109
73110 try {
111+ // Create TSS send parameters with custom signing functions if needed
112+
113+ if ( wallet . baseCoin . getMPCAlgorithm ( ) === 'ecdsa' ) {
114+ const ecdsaMPCv2SendParams = createEcdsaMPCv2SendParams (
115+ req ,
116+ wallet ,
117+ enclavedExpressClient ,
118+ signingKeychain ,
119+ ) ;
120+ return wallet . sendMany ( ecdsaMPCv2SendParams ) ;
121+ }
122+
74123 const prebuildParams : PrebuildTransactionOptions = {
75124 ...params ,
76125 // Convert memo string to Memo object if present
0 commit comments