@@ -160,7 +160,7 @@ impl<'a> MessageBuilder<'a> {
160
160
let transfer_ix = SystemInstructionBuilder :: transfer ( from, to, transfer. value )
161
161
. with_references ( references) ;
162
162
163
- let mut builder = InstructionBuilder :: default ( ) ;
163
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
164
164
builder
165
165
. maybe_advance_nonce ( self . nonce_account ( ) ?, from)
166
166
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -197,7 +197,7 @@ impl<'a> MessageBuilder<'a> {
197
197
space : DEFAULT_SPACE ,
198
198
} ) ;
199
199
200
- let mut builder = InstructionBuilder :: default ( ) ;
200
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
201
201
builder
202
202
. maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
203
203
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -217,7 +217,7 @@ impl<'a> MessageBuilder<'a> {
217
217
218
218
let deactivate_ix = StakeInstructionBuilder :: deactivate ( stake_account, sender) ;
219
219
220
- let mut builder = InstructionBuilder :: default ( ) ;
220
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
221
221
builder
222
222
. maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
223
223
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -241,7 +241,7 @@ impl<'a> MessageBuilder<'a> {
241
241
. collect :: < SigningResult < Vec < _ > > > ( )
242
242
. context ( "Invalid stake account(s)" ) ?;
243
243
244
- let mut builder = InstructionBuilder :: default ( ) ;
244
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
245
245
builder
246
246
. maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
247
247
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -269,7 +269,7 @@ impl<'a> MessageBuilder<'a> {
269
269
custodian_account,
270
270
) ;
271
271
272
- let mut builder = InstructionBuilder :: default ( ) ;
272
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
273
273
builder
274
274
. maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
275
275
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -303,7 +303,7 @@ impl<'a> MessageBuilder<'a> {
303
303
} )
304
304
. collect :: < SigningResult < Vec < _ > > > ( ) ?;
305
305
306
- let mut builder = InstructionBuilder :: default ( ) ;
306
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
307
307
builder
308
308
. maybe_advance_nonce ( self . nonce_account ( ) ?, sender)
309
309
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -337,7 +337,7 @@ impl<'a> MessageBuilder<'a> {
337
337
token_address,
338
338
match_program_id ( create_token_acc. token_program_id ) ,
339
339
) ;
340
- let mut builder = InstructionBuilder :: default ( ) ;
340
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
341
341
builder
342
342
. maybe_advance_nonce ( self . nonce_account ( ) ?, funding_account)
343
343
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -384,7 +384,7 @@ impl<'a> MessageBuilder<'a> {
384
384
)
385
385
. with_references ( references) ;
386
386
387
- let mut builder = InstructionBuilder :: default ( ) ;
387
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
388
388
builder
389
389
. maybe_advance_nonce ( self . nonce_account ( ) ?, signer)
390
390
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -448,7 +448,7 @@ impl<'a> MessageBuilder<'a> {
448
448
)
449
449
. with_references ( references) ;
450
450
451
- let mut builder = InstructionBuilder :: default ( ) ;
451
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
452
452
builder
453
453
. maybe_advance_nonce ( self . nonce_account ( ) ?, signer)
454
454
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -479,7 +479,7 @@ impl<'a> MessageBuilder<'a> {
479
479
. context ( "Invalid nonce account" ) ?
480
480
} ;
481
481
482
- let mut builder = InstructionBuilder :: default ( ) ;
482
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
483
483
builder
484
484
. maybe_advance_nonce ( prev_nonce_account, signer)
485
485
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -506,7 +506,7 @@ impl<'a> MessageBuilder<'a> {
506
506
. into_tw ( )
507
507
. context ( "Invalid recipient" ) ?;
508
508
509
- let mut builder = InstructionBuilder :: default ( ) ;
509
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
510
510
builder
511
511
. maybe_advance_nonce ( self . nonce_account ( ) ?, signer)
512
512
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -529,7 +529,7 @@ impl<'a> MessageBuilder<'a> {
529
529
. into_tw ( )
530
530
. context ( "Invalid nonce account" ) ?;
531
531
532
- let mut builder = InstructionBuilder :: default ( ) ;
532
+ let mut builder = self . builder_with_token_transfer_to_fee_payer_if_applicable ( ) ? ;
533
533
builder
534
534
. maybe_advance_nonce ( Some ( nonce_account) , signer)
535
535
. maybe_priority_fee_price ( self . priority_fee_price ( ) )
@@ -580,6 +580,48 @@ impl<'a> MessageBuilder<'a> {
580
580
self . signer_address ( )
581
581
}
582
582
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
+
583
625
fn recent_blockhash ( & self ) -> SigningResult < Blockhash > {
584
626
Blockhash :: from_str ( & self . input . recent_blockhash )
585
627
. map_err ( SigningError :: from)
0 commit comments