light_token/compressed_token/v2/create_compressed_mint/
account_metas.rs

1use solana_instruction::AccountMeta;
2use solana_pubkey::Pubkey;
3
4use crate::utils::TokenDefaultAccounts;
5
6/// Account metadata configuration for create cMint instruction
7#[derive(Debug, Copy, Clone)]
8pub struct CreateMintMetaConfig {
9    pub fee_payer: Option<Pubkey>,
10    pub mint_signer: Option<Pubkey>,
11    pub address_tree_pubkey: Pubkey,
12    pub output_queue: Pubkey,
13}
14
15impl CreateMintMetaConfig {
16    /// Create a new CreateMintMetaConfig for direct invocation
17    pub fn new(
18        fee_payer: Pubkey,
19        mint_signer: Pubkey,
20        address_tree_pubkey: Pubkey,
21        output_queue: Pubkey,
22    ) -> Self {
23        Self {
24            fee_payer: Some(fee_payer),
25            mint_signer: Some(mint_signer),
26            address_tree_pubkey,
27            output_queue,
28        }
29    }
30
31    /// Create a new CreateMintMetaConfig for client-side (CPI) usage
32    pub fn new_client(
33        mint_seed: Pubkey,
34        address_tree_pubkey: Pubkey,
35        output_queue: Pubkey,
36    ) -> Self {
37        Self {
38            fee_payer: None,
39            mint_signer: Some(mint_seed),
40            address_tree_pubkey,
41            output_queue,
42        }
43    }
44}
45
46/// Get the standard account metas for a create cMint instruction
47pub fn get_create_compressed_mint_instruction_account_metas(
48    config: CreateMintMetaConfig,
49) -> Vec<AccountMeta> {
50    let default_pubkeys = TokenDefaultAccounts::default();
51
52    // Calculate capacity based on configuration
53    // Static accounts: mint_signer + light_system_program (2)
54    // LightSystemAccounts: fee_payer + cpi_authority_pda + registered_program_pda +
55    //                      account_compression_authority + account_compression_program + system_program (6)
56    // Tree accounts: address_merkle_tree + output_queue (2)
57    let base_capacity = 9; // 2 static + 5 LightSystemAccounts (excluding fee_payer since it's counted separately) + 2 tree
58
59    // Optional fee_payer account
60    let fee_payer_capacity = if config.fee_payer.is_some() { 1 } else { 0 };
61
62    let total_capacity = base_capacity + fee_payer_capacity;
63
64    let mut metas = Vec::with_capacity(total_capacity);
65
66    // First two accounts are static non-CPI accounts as expected by CPI_ACCOUNTS_OFFSET = 2
67    // mint_signer (always required)
68    if let Some(mint_signer) = config.mint_signer {
69        metas.push(AccountMeta::new_readonly(mint_signer, true));
70    }
71
72    // light_system_program (always required)
73    metas.push(AccountMeta::new_readonly(
74        default_pubkeys.light_system_program,
75        false,
76    ));
77
78    // CPI accounts start here (matching system program expectations)
79    // fee_payer (signer, mutable) - only add if provided
80    if let Some(fee_payer) = config.fee_payer {
81        metas.push(AccountMeta::new(fee_payer, true));
82    }
83
84    // cpi_authority_pda
85    metas.push(AccountMeta::new_readonly(
86        default_pubkeys.cpi_authority_pda,
87        false,
88    ));
89
90    // registered_program_pda
91    metas.push(AccountMeta::new_readonly(
92        default_pubkeys.registered_program_pda,
93        false,
94    ));
95
96    // account_compression_authority
97    metas.push(AccountMeta::new_readonly(
98        default_pubkeys.account_compression_authority,
99        false,
100    ));
101
102    // account_compression_program
103    metas.push(AccountMeta::new_readonly(
104        default_pubkeys.account_compression_program,
105        false,
106    ));
107
108    // system_program
109    metas.push(AccountMeta::new_readonly(
110        default_pubkeys.system_program,
111        false,
112    ));
113
114    // Tree accounts (mutable) - these are parsed by CreateCompressedAccountTreeAccounts
115    // address_merkle_tree (mutable)
116    metas.push(AccountMeta::new(config.address_tree_pubkey, false));
117
118    // output_queue (mutable)
119    metas.push(AccountMeta::new(config.output_queue, false));
120
121    metas
122}
123
124#[derive(Debug, Copy, Clone)]
125pub struct CreateMintMetaConfigCpiWrite {
126    pub fee_payer: Pubkey,
127    pub mint_signer: Pubkey,
128    pub cpi_context: Pubkey,
129}
130pub fn get_create_compressed_mint_instruction_account_metas_cpi_write(
131    config: CreateMintMetaConfigCpiWrite,
132) -> [AccountMeta; 5] {
133    let default_pubkeys = TokenDefaultAccounts::default();
134    [
135        AccountMeta::new_readonly(config.mint_signer, true),
136        AccountMeta::new_readonly(default_pubkeys.light_system_program, false),
137        AccountMeta::new(config.fee_payer, true),
138        AccountMeta::new_readonly(default_pubkeys.cpi_authority_pda, false),
139        AccountMeta::new(config.cpi_context, false),
140    ]
141}