#![cfg(feature = "test-sbf")] mod program_test; use { program_test::TestContext, solana_program_test::tokio, solana_sdk::{ instruction::InstructionError, program_pack::Pack, pubkey::Pubkey, signature::Signer, signer::keypair::Keypair, system_instruction, transaction::TransactionError, transport::TransportError, }, spl_token_2022::{instruction, state::Account}, spl_token_client::token::{ExtensionInitializationParams, TokenError as TokenClientError}, }; #[tokio::test] async fn success_init_after_close_account() { let mut context = TestContext::new().await; let payer = Keypair::from_bytes(&context.context.lock().await.payer.to_bytes()).unwrap(); context.init_token_with_mint(vec![]).await.unwrap(); let token = context.token_context.take().unwrap().token; let token_program_id = spl_token_2022::id(); let owner = Keypair::new(); let token_account_keypair = Keypair::new(); let token_account = token .create_auxiliary_token_account(&token_account_keypair, &owner.pubkey()) .await .unwrap(); let destination = Pubkey::new_unique(); token .process_ixs( &[ instruction::close_account( &token_program_id, &token_account, &destination, &owner.pubkey(), &[], ) .unwrap(), system_instruction::create_account( &payer.pubkey(), &token_account, 1_000_000_000, Account::LEN as u64, &token_program_id, ), instruction::initialize_account( &token_program_id, &token_account, token.get_address(), &owner.pubkey(), ) .unwrap(), ], &[&owner, &payer, &token_account_keypair], ) .await .unwrap(); let destination = token.get_account(&destination).await.unwrap(); assert!(destination.lamports > 0); } #[tokio::test] async fn fail_init_after_close_account() { let mut context = TestContext::new().await; let payer = Keypair::from_bytes(&context.context.lock().await.payer.to_bytes()).unwrap(); context.init_token_with_mint(vec![]).await.unwrap(); let token = context.token_context.take().unwrap().token; let token_program_id = spl_token_2022::id(); let owner = Keypair::new(); let token_account = token .create_auxiliary_token_account(&Keypair::new(), &owner.pubkey()) .await .unwrap(); let destination = Pubkey::new_unique(); let error = token .process_ixs( &[ instruction::close_account( &token_program_id, &token_account, &destination, &owner.pubkey(), &[], ) .unwrap(), system_instruction::transfer(&payer.pubkey(), &token_account, 1_000_000_000), instruction::initialize_account( &token_program_id, &token_account, token.get_address(), &owner.pubkey(), ) .unwrap(), ], &[&owner, &payer], ) .await .unwrap_err(); assert_eq!( error, TokenClientError::Client(Box::new(TransportError::TransactionError( TransactionError::InstructionError(2, InstructionError::InvalidAccountData,) ))) ); let error = token.get_account(&destination).await.unwrap_err(); assert_eq!(error, TokenClientError::AccountNotFound); } #[tokio::test] async fn fail_init_after_close_mint() { let close_authority = Keypair::new(); let mut context = TestContext::new().await; let payer = Keypair::from_bytes(&context.context.lock().await.payer.to_bytes()).unwrap(); context .init_token_with_mint(vec![ExtensionInitializationParams::MintCloseAuthority { close_authority: Some(close_authority.pubkey()), }]) .await .unwrap(); let token = context.token_context.take().unwrap().token; let token_program_id = spl_token_2022::id(); let destination = Pubkey::new_unique(); let error = token .process_ixs( &[ instruction::close_account( &token_program_id, token.get_address(), &destination, &close_authority.pubkey(), &[], ) .unwrap(), system_instruction::transfer(&payer.pubkey(), token.get_address(), 1_000_000_000), instruction::initialize_mint_close_authority( &token_program_id, token.get_address(), None, ) .unwrap(), instruction::initialize_mint( &token_program_id, token.get_address(), &close_authority.pubkey(), None, 0, ) .unwrap(), ], &[&close_authority, &payer], ) .await .unwrap_err(); assert_eq!( error, TokenClientError::Client(Box::new(TransportError::TransactionError( TransactionError::InstructionError(2, InstructionError::InvalidAccountData,) ))) ); let error = token.get_account(&destination).await.unwrap_err(); assert_eq!(error, TokenClientError::AccountNotFound); }