mpl_candy_machine_core/state/
candy_machine.rs

1use anchor_lang::prelude::*;
2use arrayref::array_ref;
3use mpl_token_metadata::state::{Metadata, ProgrammableConfig};
4
5use crate::constants::{RULE_SET_LENGTH, SET};
6
7use super::candy_machine_data::CandyMachineData;
8
9/// Candy machine state and config data.
10#[account]
11#[derive(Default, Debug)]
12pub struct CandyMachine {
13    /// Version of the account.
14    pub version: AccountVersion,
15    /// Token standard to mint NFTs.
16    pub token_standard: u8,
17    /// Features flags.
18    pub features: [u8; 6],
19    /// Authority address.
20    pub authority: Pubkey,
21    /// Authority address allowed to mint from the candy machine.
22    pub mint_authority: Pubkey,
23    /// The collection mint for the candy machine.
24    pub collection_mint: Pubkey,
25    /// Number of assets redeemed.
26    pub items_redeemed: u64,
27    /// Candy machine configuration data.
28    pub data: CandyMachineData,
29    // hidden data section to avoid deserialisation:
30    //
31    // - (u32) how many actual lines of data there are currently (eventually
32    //   equals items available)
33    // - (ConfigLine * items_available) lines and lines of name + uri data
34    // - (item_available / 8) + 1 bit mask to keep track of which ConfigLines
35    //   have been added
36    // - (u32 * items_available) mint indices
37    // - for pNFT:
38    //   (u8) indicates whether to use a custom rule set
39    //   (Pubkey) custom rule set
40}
41
42impl CandyMachine {
43    pub fn get_rule_set(
44        &self,
45        account_data: &[u8],
46        collection_metadata: &Metadata,
47    ) -> Result<Option<Pubkey>> {
48        let required_length = self.data.get_space_for_candy()?;
49
50        if account_data.len() <= required_length {
51            return Ok(None);
52        }
53
54        if account_data[required_length] == SET {
55            let index = required_length + 1;
56
57            Ok(Some(Pubkey::from(*array_ref![
58                account_data,
59                index,
60                RULE_SET_LENGTH
61            ])))
62        } else if let Some(ProgrammableConfig::V1 { rule_set }) =
63            collection_metadata.programmable_config
64        {
65            Ok(rule_set)
66        } else {
67            Ok(None)
68        }
69    }
70}
71
72/// Config line struct for storing asset (NFT) data pre-mint.
73#[derive(AnchorSerialize, AnchorDeserialize, Debug)]
74pub struct ConfigLine {
75    /// Name of the asset.
76    pub name: String,
77    /// URI to JSON metadata.
78    pub uri: String,
79}
80
81/// Account versioning.
82#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default, Debug)]
83pub enum AccountVersion {
84    #[default]
85    V1,
86    V2,
87}