@@ -139,6 +139,7 @@ async fn main() {
139
139
async_trial!( group_pointer, test_validator, payer) ,
140
140
async_trial!( group_member_pointer, test_validator, payer) ,
141
141
async_trial!( transfer_hook, test_validator, payer) ,
142
+ async_trial!( transfer_hook_with_transfer_fee, test_validator, payer) ,
142
143
async_trial!( metadata, test_validator, payer) ,
143
144
async_trial!( group, test_validator, payer) ,
144
145
async_trial!( confidential_transfer_with_fee, test_validator, payer) ,
@@ -3872,6 +3873,107 @@ async fn transfer_hook(test_validator: &TestValidator, payer: &Keypair) {
3872
3873
assert_eq ! ( extension. program_id, None . try_into( ) . unwrap( ) ) ;
3873
3874
}
3874
3875
3876
+ async fn transfer_hook_with_transfer_fee ( test_validator : & TestValidator , payer : & Keypair ) {
3877
+ let program_id = spl_token_2022:: id ( ) ;
3878
+ let mut config = test_config_with_default_signer ( test_validator, payer, & program_id) ;
3879
+ let transfer_hook_program_id = Pubkey :: new_unique ( ) ;
3880
+
3881
+ let transfer_fee_basis_points = 100 ;
3882
+ let maximum_fee: u64 = 10_000_000_000 ;
3883
+
3884
+ let result = process_test_command (
3885
+ & config,
3886
+ payer,
3887
+ & [
3888
+ "spl-token" ,
3889
+ CommandName :: CreateToken . into ( ) ,
3890
+ "--program-id" ,
3891
+ & program_id. to_string ( ) ,
3892
+ "--transfer-hook" ,
3893
+ & transfer_hook_program_id. to_string ( ) ,
3894
+ "--transfer-fee" ,
3895
+ & transfer_fee_basis_points. to_string ( ) ,
3896
+ & maximum_fee. to_string ( ) ,
3897
+ ] ,
3898
+ )
3899
+ . await ;
3900
+
3901
+ // Check that the transfer-hook extension is correctly configured
3902
+ let value: serde_json:: Value = serde_json:: from_str ( & result. unwrap ( ) ) . unwrap ( ) ;
3903
+ let mint = Pubkey :: from_str ( value[ "commandOutput" ] [ "address" ] . as_str ( ) . unwrap ( ) ) . unwrap ( ) ;
3904
+ let account = config. rpc_client . get_account ( & mint) . await . unwrap ( ) ;
3905
+ let mint_state = StateWithExtensionsOwned :: < Mint > :: unpack ( account. data ) . unwrap ( ) ;
3906
+ let extension = mint_state. get_extension :: < TransferHook > ( ) . unwrap ( ) ;
3907
+ assert_eq ! (
3908
+ extension. program_id,
3909
+ Some ( transfer_hook_program_id) . try_into( ) . unwrap( )
3910
+ ) ;
3911
+
3912
+ // Check that the transfer-fee extension is correctly configured
3913
+ let extension = mint_state. get_extension :: < TransferFeeConfig > ( ) . unwrap ( ) ;
3914
+ assert_eq ! (
3915
+ u16 :: from( extension. older_transfer_fee. transfer_fee_basis_points) ,
3916
+ transfer_fee_basis_points
3917
+ ) ;
3918
+ assert_eq ! (
3919
+ u64 :: from( extension. older_transfer_fee. maximum_fee) ,
3920
+ maximum_fee
3921
+ ) ;
3922
+ assert_eq ! (
3923
+ u16 :: from( extension. newer_transfer_fee. transfer_fee_basis_points) ,
3924
+ transfer_fee_basis_points
3925
+ ) ;
3926
+ assert_eq ! (
3927
+ u64 :: from( extension. newer_transfer_fee. maximum_fee) ,
3928
+ maximum_fee
3929
+ ) ;
3930
+
3931
+ // Make sure that parsing transfer hook accounts and expected-fee works
3932
+ let blockhash = Hash :: default ( ) ;
3933
+ let program_client: Arc < dyn ProgramClient < ProgramRpcClientSendTransaction > > = Arc :: new (
3934
+ ProgramOfflineClient :: new ( blockhash, ProgramRpcClientSendTransaction ) ,
3935
+ ) ;
3936
+ config. program_client = program_client;
3937
+
3938
+ let _result = exec_test_cmd (
3939
+ & config,
3940
+ & [
3941
+ "spl-token" ,
3942
+ CommandName :: Transfer . into ( ) ,
3943
+ & mint. to_string ( ) ,
3944
+ "100" ,
3945
+ & Pubkey :: new_unique ( ) . to_string ( ) ,
3946
+ "--blockhash" ,
3947
+ & blockhash. to_string ( ) ,
3948
+ "--nonce" ,
3949
+ & Pubkey :: new_unique ( ) . to_string ( ) ,
3950
+ "--nonce-authority" ,
3951
+ & Pubkey :: new_unique ( ) . to_string ( ) ,
3952
+ "--sign-only" ,
3953
+ "--mint-decimals" ,
3954
+ & format ! ( "{}" , TEST_DECIMALS ) ,
3955
+ "--from" ,
3956
+ & Pubkey :: new_unique ( ) . to_string ( ) ,
3957
+ "--owner" ,
3958
+ & Pubkey :: new_unique ( ) . to_string ( ) ,
3959
+ "--transfer-hook-account" ,
3960
+ & format ! ( "{}:readonly" , Pubkey :: new_unique( ) ) ,
3961
+ "--transfer-hook-account" ,
3962
+ & format ! ( "{}:writable" , Pubkey :: new_unique( ) ) ,
3963
+ "--transfer-hook-account" ,
3964
+ & format ! ( "{}:readonly-signer" , Pubkey :: new_unique( ) ) ,
3965
+ "--transfer-hook-account" ,
3966
+ & format ! ( "{}:writable-signer" , Pubkey :: new_unique( ) ) ,
3967
+ "--expected-fee" ,
3968
+ "1" ,
3969
+ "--program-id" ,
3970
+ & program_id. to_string ( ) ,
3971
+ ] ,
3972
+ )
3973
+ . await
3974
+ . unwrap ( ) ;
3975
+ }
3976
+
3875
3977
async fn metadata ( test_validator : & TestValidator , payer : & Keypair ) {
3876
3978
let program_id = spl_token_2022:: id ( ) ;
3877
3979
let config = test_config_with_default_signer ( test_validator, payer, & program_id) ;
0 commit comments