mpl_candy_machine_core/instructions/
initialize.rs

1use anchor_lang::{prelude::*, Discriminator};
2use mpl_token_metadata::state::{TokenStandard, MAX_SYMBOL_LENGTH};
3
4use crate::{
5    approve_collection_authority_helper,
6    constants::{AUTHORITY_SEED, HIDDEN_SECTION},
7    state::{CandyMachine, CandyMachineData},
8    utils::fixed_length_string,
9    AccountVersion, ApproveCollectionAuthorityHelperAccounts,
10};
11
12pub fn initialize(ctx: Context<Initialize>, data: CandyMachineData) -> Result<()> {
13    msg!("(Deprecated as of 1.0.0) Use InitializeV2 instead");
14
15    let candy_machine_account = &mut ctx.accounts.candy_machine;
16
17    let mut candy_machine = CandyMachine {
18        data,
19        version: AccountVersion::V1,
20        token_standard: TokenStandard::NonFungible as u8,
21        features: [0u8; 6],
22        authority: ctx.accounts.authority.key(),
23        mint_authority: ctx.accounts.authority.key(),
24        collection_mint: ctx.accounts.collection_mint.key(),
25        items_redeemed: 0,
26    };
27
28    candy_machine.data.symbol = fixed_length_string(candy_machine.data.symbol, MAX_SYMBOL_LENGTH)?;
29    // validates the config lines settings
30    candy_machine.data.validate()?;
31
32    let mut struct_data = CandyMachine::discriminator().try_to_vec().unwrap();
33    struct_data.append(&mut candy_machine.try_to_vec().unwrap());
34
35    let mut account_data = candy_machine_account.data.borrow_mut();
36    account_data[0..struct_data.len()].copy_from_slice(&struct_data);
37
38    if candy_machine.data.hidden_settings.is_none() {
39        // set the initial number of config lines
40        account_data[HIDDEN_SECTION..HIDDEN_SECTION + 4].copy_from_slice(&u32::MIN.to_le_bytes());
41    }
42
43    let approve_accounts = ApproveCollectionAuthorityHelperAccounts {
44        payer: ctx.accounts.payer.to_account_info(),
45        authority_pda: ctx.accounts.authority_pda.to_account_info(),
46        collection_mint: ctx.accounts.collection_mint.to_account_info(),
47        collection_metadata: ctx.accounts.collection_metadata.to_account_info(),
48        collection_authority_record: ctx.accounts.collection_authority_record.to_account_info(),
49        token_metadata_program: ctx.accounts.token_metadata_program.to_account_info(),
50        system_program: ctx.accounts.system_program.to_account_info(),
51        collection_update_authority: ctx.accounts.collection_update_authority.to_account_info(),
52    };
53
54    approve_collection_authority_helper(approve_accounts)?;
55
56    Ok(())
57}
58
59/// Initializes a new candy machine.
60#[derive(Accounts)]
61#[instruction(data: CandyMachineData)]
62pub struct Initialize<'info> {
63    /// Candy Machine account. The account space must be allocated to allow accounts larger
64    /// than 10kb.
65    ///
66    /// CHECK: account constraints checked in account trait
67    #[account(
68        zero,
69        rent_exempt = skip,
70        constraint = candy_machine.to_account_info().owner == program_id && candy_machine.to_account_info().data_len() >= data.get_space_for_candy()?
71    )]
72    candy_machine: UncheckedAccount<'info>,
73
74    /// Authority PDA used to verify minted NFTs to the collection.
75    ///
76    /// CHECK: account checked in seeds constraint
77    #[account(
78        mut,
79        seeds = [AUTHORITY_SEED.as_bytes(), candy_machine.to_account_info().key.as_ref()],
80        bump
81    )]
82    authority_pda: UncheckedAccount<'info>,
83
84    /// Candy Machine authority. This is the address that controls the upate of the candy machine.
85    ///
86    /// CHECK: authority can be any account and is not written to or read
87    authority: UncheckedAccount<'info>,
88
89    /// Payer of the transaction.
90    payer: Signer<'info>,
91
92    /// Metadata account of the collection.
93    ///
94    /// CHECK: account checked in CPI
95    collection_metadata: UncheckedAccount<'info>,
96
97    /// Mint account of the collection.
98    ///
99    /// CHECK: account checked in CPI
100    collection_mint: UncheckedAccount<'info>,
101
102    /// Master Edition account of the collection.
103    ///
104    /// CHECK: account checked in CPI
105    collection_master_edition: UncheckedAccount<'info>,
106
107    /// Update authority of the collection. This needs to be a signer so the candy
108    /// machine can approve a delegate to verify minted NFTs to the collection.
109    #[account(mut)]
110    collection_update_authority: Signer<'info>,
111
112    /// Collection authority record. The delegate is used to verify NFTs.
113    ///
114    /// CHECK: account checked in CPI
115    #[account(mut)]
116    collection_authority_record: UncheckedAccount<'info>,
117
118    /// Token Metadata program.
119    ///
120    /// CHECK: account constraint checked in account trait
121    #[account(address = mpl_token_metadata::id())]
122    token_metadata_program: UncheckedAccount<'info>,
123
124    /// System program.
125    system_program: Program<'info, System>,
126}