@@ -160,7 +160,7 @@ impl<'a> MessageBuilder<'a> {
160160 let transfer_ix = SystemInstructionBuilder :: transfer ( from, to, transfer. value )
161161 . with_references ( references) ;
162162
163- let mut builder = InstructionBuilder :: default ( ) ;
163+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
164164 builder
165165 . maybe_advance_nonce ( self . nonce_account ( ) ?, from)
166166 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -197,7 +197,7 @@ impl<'a> MessageBuilder<'a> {
197197 space : DEFAULT_SPACE ,
198198 } ) ;
199199
200- let mut builder = InstructionBuilder :: default ( ) ;
200+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
201201 builder
202202 . maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
203203 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -217,7 +217,7 @@ impl<'a> MessageBuilder<'a> {
217217
218218 let deactivate_ix = StakeInstructionBuilder :: deactivate ( stake_account, sender) ;
219219
220- let mut builder = InstructionBuilder :: default ( ) ;
220+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
221221 builder
222222 . maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
223223 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -241,7 +241,7 @@ impl<'a> MessageBuilder<'a> {
241241 . collect :: < SigningResult < Vec < _ > > > ( )
242242 . context ( "Invalid stake account(s)" ) ?;
243243
244- let mut builder = InstructionBuilder :: default ( ) ;
244+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
245245 builder
246246 . maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
247247 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -269,7 +269,7 @@ impl<'a> MessageBuilder<'a> {
269269 custodian_account,
270270 ) ;
271271
272- let mut builder = InstructionBuilder :: default ( ) ;
272+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
273273 builder
274274 . maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
275275 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -303,7 +303,7 @@ impl<'a> MessageBuilder<'a> {
303303 } )
304304 . collect :: < SigningResult < Vec < _ > > > ( ) ?;
305305
306- let mut builder = InstructionBuilder :: default ( ) ;
306+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
307307 builder
308308 . maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
309309 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -337,7 +337,7 @@ impl<'a> MessageBuilder<'a> {
337337 token_address,
338338 match_program_id ( create_token_acc. token_program_id ) ,
339339 ) ;
340- let mut builder = InstructionBuilder :: default ( ) ;
340+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
341341 builder
342342 . maybe_advance_nonce ( self . nonce_account ( ) ?, funding_account)
343343 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -384,7 +384,7 @@ impl<'a> MessageBuilder<'a> {
384384 )
385385 . with_references ( references) ;
386386
387- let mut builder = InstructionBuilder :: default ( ) ;
387+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
388388 builder
389389 . maybe_advance_nonce ( self . nonce_account ( ) ?, signer)
390390 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -448,7 +448,7 @@ impl<'a> MessageBuilder<'a> {
448448 )
449449 . with_references ( references) ;
450450
451- let mut builder = InstructionBuilder :: default ( ) ;
451+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
452452 builder
453453 . maybe_advance_nonce ( self . nonce_account ( ) ?, signer)
454454 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -479,7 +479,7 @@ impl<'a> MessageBuilder<'a> {
479479 . context ( "Invalid nonce account" ) ?
480480 } ;
481481
482- let mut builder = InstructionBuilder :: default ( ) ;
482+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
483483 builder
484484 . maybe_advance_nonce ( prev_nonce_account, signer)
485485 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -506,7 +506,7 @@ impl<'a> MessageBuilder<'a> {
506506 . into_tw ( )
507507 . context ( "Invalid recipient" ) ?;
508508
509- let mut builder = InstructionBuilder :: default ( ) ;
509+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
510510 builder
511511 . maybe_advance_nonce ( self . nonce_account ( ) ?, signer)
512512 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -529,7 +529,7 @@ impl<'a> MessageBuilder<'a> {
529529 . into_tw ( )
530530 . context ( "Invalid nonce account" ) ?;
531531
532- let mut builder = InstructionBuilder :: default ( ) ;
532+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
533533 builder
534534 . maybe_advance_nonce ( Some ( nonce_account) , signer)
535535 . maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -580,6 +580,48 @@ impl<'a> MessageBuilder<'a> {
580580 self . signer_address ( )
581581 }
582582
583+ fn builder_with_token_transfer_to_fee_payer_if_applicable (
584+ & self ,
585+ ) -> SigningResult < InstructionBuilder > {
586+ let Some ( sponsored_transfer_token) = self . input . token_transfer_to_fee_payer . as_ref ( ) else {
587+ return Ok ( InstructionBuilder :: default ( ) ) ;
588+ } ;
589+ let signer = self . signer_address ( ) ?;
590+
591+ let fee_mint_address =
592+ SolanaAddress :: from_str ( sponsored_transfer_token. fee_token_mint_address . as_ref ( ) )
593+ . into_tw ( )
594+ . context ( "Invalid fee mint address" ) ?;
595+
596+ let sponsor_token_address =
597+ SolanaAddress :: from_str ( sponsored_transfer_token. fee_sponsor_token_address . as_ref ( ) )
598+ . into_tw ( )
599+ . context ( "Invalid sponsor token address" ) ?;
600+
601+ let fee_sender_token_address =
602+ SolanaAddress :: from_str ( sponsored_transfer_token. fee_sender_token_address . as_ref ( ) )
603+ . into_tw ( )
604+ . context ( "Invalid fee sender token address" ) ?;
605+
606+ let fee_decimals = sponsored_transfer_token
607+ . fee_decimals
608+ . try_into ( )
609+ . tw_err ( SigningErrorType :: Error_invalid_params )
610+ . context ( "Invalid fee decimals. Expected lower than 256" ) ?;
611+
612+ let mut builder = InstructionBuilder :: default ( ) ;
613+ builder. add_instruction ( TokenInstructionBuilder :: transfer_checked (
614+ fee_sender_token_address,
615+ fee_mint_address,
616+ sponsor_token_address,
617+ signer,
618+ sponsored_transfer_token. fee_amount ,
619+ fee_decimals,
620+ match_program_id ( sponsored_transfer_token. fee_token_program_id ) ,
621+ ) ) ;
622+ Ok ( builder)
623+ }
624+
583625 fn recent_blockhash ( & self ) -> SigningResult < Blockhash > {
584626 Blockhash :: from_str ( & self . input . recent_blockhash )
585627 . map_err ( SigningError :: from)
0 commit comments