@@ -553,20 +553,25 @@ export class Sol extends BaseCoin {
553553 return response . body . result . value . blockhash ;
554554 }
555555
556- /** TODO Update to getFeeForMessage and make necssary changes in fee calculation, GetFees is deprecated */
557- protected async getFees ( ) : Promise < number > {
556+ protected async getFeeForMessage ( message : string ) : Promise < number > {
558557 const response = await this . getDataFromNode ( {
559558 payload : {
560559 id : '1' ,
561560 jsonrpc : '2.0' ,
562- method : 'getFees' ,
561+ method : 'getFeeForMessage' ,
562+ params : [
563+ message ,
564+ {
565+ commitment : 'finalized' ,
566+ } ,
567+ ] ,
563568 } ,
564569 } ) ;
565570 if ( response . status !== 200 ) {
566571 throw new Error ( 'Account not found' ) ;
567572 }
568573
569- return response . body . result . value . feeCalculator . lamportsPerSignature ;
574+ return response . body . result . value ;
570575 }
571576
572577 protected async getRentExemptAmount ( ) : Promise < number > {
@@ -758,19 +763,13 @@ export class Sol extends BaseCoin {
758763 // Build the transaction
759764 const MPC = await EDDSAMethods . getInitializedMpcInstance ( ) ;
760765 let balance = 0 ;
761- const feePerSignature = await this . getFees ( ) ;
762- const baseFee = params . durableNonce ? feePerSignature * 2 : feePerSignature ;
763- let totalFee = new BigNumber ( baseFee ) ;
764766
765767 const index = params . index || 0 ;
766768 const currPath = params . seed ? getDerivationPath ( params . seed ) + `/${ index } ` : `m/${ index } ` ;
767769 const accountId = MPC . deriveUnhardened ( bitgoKey , currPath ) . slice ( 0 , 64 ) ;
768770 const bs58EncodedPublicKey = new SolKeyPair ( { pub : accountId } ) . getAddress ( ) ;
769771
770772 balance = await this . getAccountBalance ( bs58EncodedPublicKey ) ;
771- if ( totalFee . gt ( balance ) ) {
772- throw Error ( 'Did not find address with funds to recover' ) ;
773- }
774773
775774 const factory = this . getBuilder ( ) ;
776775 const walletCoin = this . getChain ( ) ;
@@ -779,6 +778,8 @@ export class Sol extends BaseCoin {
779778 let blockhash = await this . getBlockhash ( ) ;
780779 let rentExemptAmount ;
781780 let authority = '' ;
781+ let totalFee = new BigNumber ( 0 ) ;
782+ let totalFeeForTokenRecovery = new BigNumber ( 0 ) ;
782783
783784 if ( params . durableNonce ) {
784785 const durableNonceInfo = await this . getAccountInfo ( params . durableNonce . publicKey ) ;
@@ -815,7 +816,6 @@ export class Sol extends BaseCoin {
815816 . getTokenTransferBuilder ( )
816817 . nonce ( blockhash )
817818 . sender ( bs58EncodedPublicKey )
818- . fee ( { amount : feePerSignature } )
819819 . associatedTokenAccountRent ( rentExemptAmount . toString ( ) )
820820 . feePayer ( bs58EncodedPublicKey ) ;
821821
@@ -849,16 +849,9 @@ export class Sol extends BaseCoin {
849849 tokenName : tokenName ,
850850 } ) ;
851851 // add rent exempt amount to total fee for each token account that has to be created
852- totalFee = totalFee . plus ( rentExemptAmount ) ;
852+ totalFeeForTokenRecovery = totalFeeForTokenRecovery . plus ( rentExemptAmount ) ;
853853 }
854854 }
855-
856- // there are recoverable token accounts, need to check if there is sufficient native solana to recover tokens
857- if ( new BigNumber ( balance ) . lt ( totalFee ) ) {
858- throw Error (
859- 'Not enough funds to pay for recover tokens fees, have: ' + balance + ' need: ' + totalFee . toString ( )
860- ) ;
861- }
862855 } else {
863856 throw Error ( 'Not enough token funds to recover' ) ;
864857 }
@@ -867,14 +860,11 @@ export class Sol extends BaseCoin {
867860 throw Error ( 'Did not find token account to recover tokens, please check token account' ) ;
868861 }
869862 } else {
870- const netAmount = new BigNumber ( balance ) . minus ( totalFee ) ;
871-
872863 txBuilder = factory
873864 . getTransferBuilder ( )
874865 . nonce ( blockhash )
875866 . sender ( bs58EncodedPublicKey )
876- . send ( { address : params . recoveryDestination , amount : netAmount . toString ( ) } )
877- . fee ( { amount : feePerSignature } )
867+ . send ( { address : params . recoveryDestination , amount : balance . toString ( ) } )
878868 . feePayer ( bs58EncodedPublicKey ) ;
879869 }
880870
@@ -885,6 +875,17 @@ export class Sol extends BaseCoin {
885875 } ) ;
886876 }
887877
878+ // build the transaction without fee
879+ const unsignedTransactionWithoutFee = ( await txBuilder . build ( ) ) as Transaction ;
880+ const serializedMessage = unsignedTransactionWithoutFee . solTransaction . serializeMessage ( ) . toString ( 'base64' ) ;
881+
882+ const feePerSignature = await this . getFeeForMessage ( serializedMessage ) ;
883+ const baseFee = params . durableNonce ? feePerSignature * 2 : feePerSignature ;
884+ totalFee = totalFee . plus ( new BigNumber ( baseFee ) ) ;
885+ totalFeeForTokenRecovery = totalFeeForTokenRecovery . plus ( new BigNumber ( baseFee ) ) ;
886+ if ( totalFee . gt ( balance ) ) {
887+ throw Error ( 'Did not find address with funds to recover' ) ;
888+ }
888889 if ( ! isUnsignedSweep ) {
889890 // Sign the txn
890891 if ( ! params . userKey ) {
@@ -899,6 +900,26 @@ export class Sol extends BaseCoin {
899900 throw new Error ( 'missing wallet passphrase' ) ;
900901 }
901902
903+ if ( params . tokenContractAddress ) {
904+ totalFeeForTokenRecovery = totalFeeForTokenRecovery . plus ( new BigNumber ( baseFee ) ) ;
905+ // Check if there is sufficient native solana to recover tokens
906+ if ( new BigNumber ( balance ) . lt ( totalFeeForTokenRecovery ) ) {
907+ throw Error (
908+ 'Not enough funds to pay for recover tokens fees, have: ' +
909+ balance +
910+ ' need: ' +
911+ totalFeeForTokenRecovery . toString ( )
912+ ) ;
913+ }
914+ txBuilder . fee ( { amount : feePerSignature } ) ;
915+ } else {
916+ totalFee = new BigNumber ( baseFee ) ;
917+ const netAmount = new BigNumber ( balance ) . minus ( totalFee ) ;
918+ txBuilder
919+ . send ( { address : params . recoveryDestination , amount : netAmount . toString ( ) } )
920+ . fee ( { amount : feePerSignature } ) ;
921+ }
922+ // build the transaction with fee
902923 const unsignedTransaction = ( await txBuilder . build ( ) ) as Transaction ;
903924
904925 const userKey = params . userKey . replace ( / \s / g, '' ) ;
@@ -966,7 +987,7 @@ export class Sol extends BaseCoin {
966987 }
967988 const spendAmount = completedTransaction . inputs . length === 1 ? completedTransaction . inputs [ 0 ] . value : 0 ;
968989 const parsedTx = { inputs : inputs , outputs : outputs , spendAmount : spendAmount , type : '' } ;
969- const feeInfo = { fee : totalFee . toNumber ( ) , feeString : totalFee . toString ( ) } ;
990+ const feeInfo = { fee : totalFeeForTokenRecovery . toNumber ( ) , feeString : totalFee . toString ( ) } ;
970991 const coinSpecific = { commonKeychain : bitgoKey } ;
971992 if ( isUnsignedSweep ) {
972993 const transaction : MPCTx = {
@@ -1021,19 +1042,13 @@ export class Sol extends BaseCoin {
10211042 // Build the transaction
10221043 const MPC = await EDDSAMethods . getInitializedMpcInstance ( ) ;
10231044 let balance = 0 ;
1024- const feePerSignature = await this . getFees ( ) ;
1025- const baseFee = params . durableNonce ? feePerSignature * 2 : feePerSignature ;
1026- const totalFee = new BigNumber ( baseFee ) ;
10271045
10281046 const index = params . index || 0 ;
10291047 const currPath = params . seed ? getDerivationPath ( params . seed ) + `/${ index } ` : `m/${ index } ` ;
10301048 const accountId = MPC . deriveUnhardened ( bitgoKey , currPath ) . slice ( 0 , 64 ) ;
10311049 const bs58EncodedPublicKey = new SolKeyPair ( { pub : accountId } ) . getAddress ( ) ;
10321050
1033- balance = await this . getAccountBalance ( bs58EncodedPublicKey ) ;
1034- if ( totalFee . gt ( balance ) ) {
1035- throw Error ( 'Did not find address with funds to recover' ) ;
1036- }
1051+ const accountBalance = await this . getAccountBalance ( bs58EncodedPublicKey ) ;
10371052
10381053 balance = await this . getAccountBalance ( params . closeAtaAddress ) ;
10391054 if ( balance <= 0 ) {
@@ -1069,9 +1084,17 @@ export class Sol extends BaseCoin {
10691084 . getTokenTransferBuilder ( )
10701085 . nonce ( blockhash )
10711086 . sender ( bs58EncodedPublicKey )
1072- . fee ( { amount : feePerSignature } )
10731087 . associatedTokenAccountRent ( rentExemptAmount . toString ( ) )
10741088 . feePayer ( bs58EncodedPublicKey ) ;
1089+ const unsignedTransaction = ( await txBuilder . build ( ) ) as Transaction ;
1090+ const serializedMessage = unsignedTransaction . solTransaction . serializeMessage ( ) . toString ( 'base64' ) ;
1091+ const feePerSignature = await this . getFeeForMessage ( serializedMessage ) ;
1092+ const baseFee = params . durableNonce ? feePerSignature * 2 : feePerSignature ;
1093+ const totalFee = new BigNumber ( baseFee ) ;
1094+ if ( totalFee . gt ( accountBalance ) ) {
1095+ throw Error ( 'Did not find address with funds to recover' ) ;
1096+ }
1097+ txBuilder . fee ( { amount : feePerSignature } ) ;
10751098
10761099 const network = this . getNetwork ( ) ;
10771100 const token = getSolTokenFromAddress ( tokenInfo . info . mint , network ) ;
@@ -1238,6 +1261,7 @@ export class Sol extends BaseCoin {
12381261 const durableNoncePubKeysLength = params . durableNonces . publicKeys . length ;
12391262 const consolidationTransactions : any [ ] = [ ] ;
12401263 let lastScanIndex = startIdx ;
1264+
12411265 for ( let i = startIdx ; i < endIdx ; i ++ ) {
12421266 const recoverParams = {
12431267 userKey : params . userKey ,
0 commit comments