#![cfg(feature = "test-sbf")]
pub mod setup;
use mpl_core::{
errors::MplCoreError,
instructions::{BurnV1Builder, ExecuteV1Builder},
types::{FreezeExecute, Plugin, PluginAuthority, PluginAuthorityPair},
};
use setup::*;
use solana_program::pubkey::Pubkey;
use solana_program_test::tokio;
use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction};
use solana_system_interface::{instruction as system_instruction, program as system_program};
const FREEZE_EXECUTE_PREFIX: &str = "mpl-core-execute";
#[tokio::test]
async fn test_freeze_execute_backed_nft_flow() {
let mut context = program_test().start_with_context().await;
let payer_key = context.payer.pubkey();
airdrop(&mut context, &payer_key, 2_000_000_000)
.await
.unwrap();
let asset = Keypair::new();
create_asset(
&mut context,
CreateAssetHelperArgs {
owner: None,
payer: None,
asset: &asset,
data_state: None,
name: None,
uri: None,
authority: None,
update_authority: None,
collection: None,
plugins: vec![PluginAuthorityPair {
plugin: Plugin::FreezeExecute(FreezeExecute { frozen: true }),
authority: None,
}],
external_plugin_adapters: vec![],
},
)
.await
.unwrap();
assert_asset(
&mut context,
AssertAssetHelperArgs {
asset: asset.pubkey(),
owner: payer_key,
update_authority: None,
name: None,
uri: None,
plugins: vec![PluginAuthorityPair {
plugin: Plugin::FreezeExecute(FreezeExecute { frozen: true }),
authority: Some(PluginAuthority::Owner),
}],
external_plugin_adapters: vec![],
},
)
.await;
let backing_amount: u64 = 500_000_000; let transfer_ix = system_instruction::transfer(&payer_key, &asset.pubkey(), backing_amount);
let tx = Transaction::new_signed_with_payer(
&[transfer_ix],
Some(&payer_key),
&[&context.payer],
context.last_blockhash,
);
context.banks_client.process_transaction(tx).await.unwrap();
let asset_account_after_deposit = context
.banks_client
.get_account(asset.pubkey())
.await
.expect("get_account")
.expect("asset account not found");
let lamports_in_asset = asset_account_after_deposit.lamports;
let (asset_signer, _) = Pubkey::find_program_address(
&[FREEZE_EXECUTE_PREFIX.as_bytes(), asset.pubkey().as_ref()],
&mpl_core::ID,
);
let execute_ix = ExecuteV1Builder::new()
.asset(asset.pubkey())
.collection(None)
.asset_signer(asset_signer)
.payer(payer_key, true)
.authority(Some(payer_key))
.system_program(system_program::ID)
.program_id(system_program::ID) .instruction_data(Vec::new())
.instruction();
let tx = Transaction::new_signed_with_payer(
&[execute_ix],
Some(&payer_key),
&[&context.payer],
context.last_blockhash,
);
let error = context
.banks_client
.process_transaction(tx)
.await
.unwrap_err();
assert_custom_instruction_error!(0, error, MplCoreError::InvalidAuthority);
let payer_balance_before_burn = context.banks_client.get_balance(payer_key).await.unwrap();
let burn_ix = BurnV1Builder::new()
.asset(asset.pubkey())
.collection(None)
.payer(payer_key)
.authority(Some(payer_key))
.system_program(Some(system_program::ID))
.instruction();
let tx = Transaction::new_signed_with_payer(
&[burn_ix],
Some(&payer_key),
&[&context.payer],
context.last_blockhash,
);
context.banks_client.process_transaction(tx).await.unwrap();
let _asset_account_after_burn = context
.banks_client
.get_account(asset.pubkey())
.await
.unwrap();
let payer_balance_after_burn = context.banks_client.get_balance(payer_key).await.unwrap();
assert!(
payer_balance_after_burn > payer_balance_before_burn,
"Payer balance did not increase after burn refund"
);
}