use mpl_utils::assert_signer;
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
pubkey::Pubkey,
};
use spl_token::state::Account as TokenAccount;
use crate::{
assertions::assert_owned_by,
error::MetadataError,
instruction::{Burn, Context},
state::{Metadata, TokenMetadataAccount},
utils::assert_initialized,
};
use super::nonfungible_edition::burn_nonfungible_edition;
pub fn process_burn_edition_nft<'a>(
program_id: &Pubkey,
accounts: &'a [AccountInfo<'a>],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let metadata_info = next_account_info(account_info_iter)?;
let owner_info = next_account_info(account_info_iter)?;
let print_edition_mint_info = next_account_info(account_info_iter)?;
let master_edition_mint_info = next_account_info(account_info_iter)?;
let print_edition_token_info = next_account_info(account_info_iter)?;
let master_edition_token_info = next_account_info(account_info_iter)?;
let master_edition_info = next_account_info(account_info_iter)?;
let print_edition_info = next_account_info(account_info_iter)?;
let edition_marker_info = next_account_info(account_info_iter)?;
let spl_token_program_info = next_account_info(account_info_iter)?;
assert_signer(owner_info)?;
assert_owned_by(metadata_info, program_id)?;
assert_owned_by(master_edition_info, program_id)?;
assert_owned_by(print_edition_info, program_id)?;
assert_owned_by(edition_marker_info, program_id)?;
assert_owned_by(master_edition_mint_info, &spl_token::ID)?;
assert_owned_by(master_edition_token_info, &spl_token::ID)?;
assert_owned_by(print_edition_mint_info, &spl_token::ID)?;
assert_owned_by(print_edition_token_info, &spl_token::ID)?;
let metadata = Metadata::from_account_info(metadata_info)?;
let token: TokenAccount = assert_initialized(print_edition_token_info)?;
if token.owner != *owner_info.key {
return Err(MetadataError::InvalidOwner.into());
}
if &token.mint != print_edition_mint_info.key {
return Err(MetadataError::MintMismatch.into());
}
if token.amount != 1 {
return Err(MetadataError::InsufficientTokenBalance.into());
}
if token.mint != metadata.mint {
return Err(MetadataError::MintMismatch.into());
}
let accounts = Burn {
authority_info: owner_info,
collection_metadata_info: None,
metadata_info,
edition_info: Some(print_edition_info),
mint_info: print_edition_mint_info,
token_info: print_edition_token_info,
master_edition_info: Some(master_edition_info),
master_edition_mint_info: Some(master_edition_mint_info),
master_edition_token_info: Some(master_edition_token_info),
edition_marker_info: Some(edition_marker_info),
token_record_info: None,
system_program_info: spl_token_program_info,
sysvar_instructions_info: spl_token_program_info,
spl_token_program_info,
};
let context = Context {
accounts,
remaining_accounts: vec![],
};
burn_nonfungible_edition(&context)
}