use anchor_lang::{prelude::*, solana_program::sysvar, Discriminator};
use crate::{
approve_asset_collection_delegate,
constants::{AUTHORITY_SEED, HIDDEN_SECTION},
state::{CandyMachine, CandyMachineData},
ApproveAssetDelegateHelperAccounts,
};
pub fn initialize(ctx: Context<Initialize>, data: CandyMachineData) -> Result<()> {
let candy_machine_account = &mut ctx.accounts.candy_machine;
let candy_machine = CandyMachine {
data,
authority: ctx.accounts.authority.key(),
mint_authority: ctx.accounts.authority.key(),
collection_mint: ctx.accounts.collection.key(),
items_redeemed: 0,
};
candy_machine.data.validate()?;
let mut struct_data = CandyMachine::discriminator().try_to_vec().unwrap();
struct_data.append(&mut candy_machine.try_to_vec().unwrap());
let mut account_data = candy_machine_account.data.borrow_mut();
account_data[0..struct_data.len()].copy_from_slice(&struct_data);
if candy_machine.data.hidden_settings.is_none() {
account_data[HIDDEN_SECTION..HIDDEN_SECTION + 4].copy_from_slice(&u32::MIN.to_le_bytes());
}
let delegate_accounts = ApproveAssetDelegateHelperAccounts {
payer: ctx.accounts.payer.to_account_info(),
authority_pda: ctx.accounts.authority_pda.to_account_info(),
collection: ctx.accounts.collection.to_account_info(),
collection_update_authority: ctx.accounts.collection_update_authority.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
sysvar_instructions: ctx.accounts.sysvar_instructions.to_account_info(),
mpl_core_program: ctx.accounts.mpl_core_program.to_account_info(),
};
approve_asset_collection_delegate(delegate_accounts)
}
#[derive(Accounts)]
#[instruction(data: CandyMachineData)]
pub struct Initialize<'info> {
#[account(
zero,
rent_exempt = skip,
constraint = candy_machine.to_account_info().owner == __program_id && candy_machine.to_account_info().data_len() >= data.get_space_for_candy()?
)]
candy_machine: UncheckedAccount<'info>,
#[account(
mut,
seeds = [AUTHORITY_SEED.as_bytes(), candy_machine.to_account_info().key.as_ref()],
bump
)]
authority_pda: UncheckedAccount<'info>,
authority: UncheckedAccount<'info>,
#[account(mut)]
payer: Signer<'info>,
#[account(mut)]
collection: UncheckedAccount<'info>,
#[account(mut)]
collection_update_authority: Signer<'info>,
#[account(address = mpl_core::ID)]
mpl_core_program: UncheckedAccount<'info>,
system_program: Program<'info, System>,
#[account(address = sysvar::instructions::id())]
sysvar_instructions: UncheckedAccount<'info>,
}