@@ -3,8 +3,13 @@ import { MethodNotImplementedError } from 'bitgo';
33import { EnclavedApiSpecRouteRequest } from '../../../enclavedBitgoExpress/routers/enclavedApiSpec' ;
44import logger from '../../../logger' ;
55import { isEthLikeCoin } from '../../../shared/coinUtils' ;
6+ import {
7+ addEthLikeRecoveryExtras ,
8+ getDefaultMusigEthGasParams ,
9+ getReplayProtectionOptions ,
10+ } from '../../../shared/recoveryUtils' ;
11+ import { SignedEthLikeRecoveryTx } from '../../../types/transaction' ;
612import { retrieveKmsPrvKey } from '../utils' ;
7- import { HalfSignedEthLikeRecoveryTx } from '../../../types/transaction' ;
813
914export async function recoveryMultisigTransaction (
1015 req : EnclavedApiSpecRouteRequest < 'v1.multisig.recovery' , 'post' > ,
@@ -29,28 +34,79 @@ export async function recoveryMultisigTransaction(
2934 if ( coin . isEVM ( ) ) {
3035 // Every recovery method on every coin family varies one from another so we need to ensure with a guard.
3136 if ( isEthLikeCoin ( coin ) ) {
37+ const walletKeys = unsignedSweepPrebuildTx . xpubxWithDerivationPath ;
38+ const pubs = [ walletKeys ?. user ?. xpub , walletKeys ?. backup ?. xpub , walletKeys ?. bitgo ?. xpub ] ;
39+ const { gasPrice, gasLimit, maxFeePerGas, maxPriorityFeePerGas } =
40+ getDefaultMusigEthGasParams ( ) ;
41+
3242 try {
33- const halfSignedTx = await coin . signTransaction ( {
43+ const halfSignedTxBase = await coin . signTransaction ( {
3444 isLastSignature : false ,
3545 prv : userPrv ,
36- txPrebuild : { ...unsignedSweepPrebuildTx } as unknown as SignFinalOptions ,
46+ pubs,
47+ keyList : walletKeys ,
48+ recipients : unsignedSweepPrebuildTx . recipients ?? [ ] ,
49+ expireTime : unsignedSweepPrebuildTx . expireTime ,
50+ signingKeyNonce : unsignedSweepPrebuildTx . signingKeyNonce ,
51+ gasPrice,
52+ gasLimit,
53+ eip1559 : {
54+ maxFeePerGas,
55+ maxPriorityFeePerGas,
56+ } ,
57+ replayProtectionOptions : getReplayProtectionOptions (
58+ unsignedSweepPrebuildTx . replayProtectionOptions ,
59+ ) ,
60+ txPrebuild : {
61+ ...unsignedSweepPrebuildTx ,
62+ gasPrice,
63+ gasLimit,
64+ eip1559 : {
65+ maxFeePerGas,
66+ maxPriorityFeePerGas,
67+ } ,
68+ replayProtectionOptions : getReplayProtectionOptions (
69+ unsignedSweepPrebuildTx . replayProtectionOptions ,
70+ ) ,
71+ } ,
3772 walletContractAddress,
3873 } ) ;
3974
40- const { halfSigned } = halfSignedTx as HalfSignedEthLikeRecoveryTx ;
75+ const halfSignedTx = addEthLikeRecoveryExtras ( {
76+ signedTx : halfSignedTxBase as SignedEthLikeRecoveryTx ,
77+ transaction : unsignedSweepPrebuildTx ,
78+ isLastSignature : false ,
79+ replayProtectionOptions : unsignedSweepPrebuildTx . replayProtectionOptions ,
80+ } ) ;
81+
82+ const { halfSigned } = halfSignedTx ;
4183 const fullSignedTx = await coin . signTransaction ( {
4284 isLastSignature : true ,
4385 prv : backupPrv ,
86+ pubs,
87+ keyList : walletKeys ,
88+ recipients : halfSignedTx . recipients ?? [ ] ,
89+ expireTime : halfSigned ?. expireTime ,
90+ signingKeyNonce : halfSigned ?. backupKeyNonce ,
91+ gasPrice,
92+ gasLimit,
4493 txPrebuild : {
4594 ...halfSignedTx ,
46- txHex : halfSigned . signatures ,
95+ txHex : halfSigned ?. txHex ,
4796 halfSigned,
48- recipients : halfSigned . recipients ?? [ ] ,
97+ recipients : halfSigned ?. recipients ?? [ ] ,
98+ gasPrice,
99+ gasLimit,
100+ eip1559 : {
101+ maxFeePerGas,
102+ maxPriorityFeePerGas,
103+ } ,
104+ replayProtectionOptions : getReplayProtectionOptions (
105+ halfSignedTx ?. replayProtectionOptions ,
106+ ) ,
49107 } as unknown as SignFinalOptions ,
50108 walletContractAddress,
51- signingKeyNonce : halfSigned . signingKeyNonce ?? 0 ,
52- backupKeyNonce : halfSigned . backupKeyNonce ?? 0 ,
53- recipients : halfSigned . recipients ?? [ ] ,
109+ backupKeyNonce : halfSigned ?. backupKeyNonce ?? 0 ,
54110 } ) ;
55111
56112 return fullSignedTx ;
0 commit comments