light_registry/account_compression_cpi/
initialize_tree_and_queue.rs1use account_compression::{
2 program::AccountCompression, utils::constants::CPI_AUTHORITY_PDA_SEED, AddressMerkleTreeConfig,
3 AddressQueueConfig, NullifierQueueConfig, StateMerkleTreeConfig,
4};
5use anchor_lang::prelude::*;
6use light_system_program::program::LightSystemProgram;
7
8use crate::{
9 errors::RegistryError,
10 protocol_config::state::{ProtocolConfig, ProtocolConfigPda},
11};
12
13#[derive(Accounts)]
14pub struct InitializeMerkleTreeAndQueue<'info> {
15 #[account(mut)]
17 pub authority: Signer<'info>,
18 #[account(mut)]
20 pub merkle_tree: AccountInfo<'info>,
21 #[account(mut)]
23 pub queue: AccountInfo<'info>,
24 pub registered_program_pda: AccountInfo<'info>,
26 #[account(mut, seeds = [CPI_AUTHORITY_PDA_SEED], bump)]
28 pub cpi_authority: AccountInfo<'info>,
29 pub account_compression_program: Program<'info, AccountCompression>,
30 pub protocol_config_pda: Account<'info, ProtocolConfigPda>,
31 pub cpi_context_account: Option<AccountInfo<'info>>,
33 pub light_system_program: Option<Program<'info, LightSystemProgram>>,
34}
35
36pub fn process_initialize_state_merkle_tree(
37 ctx: &Context<InitializeMerkleTreeAndQueue>,
38 bump: u8,
39 index: u64,
40 program_owner: Option<Pubkey>,
41 forester: Option<Pubkey>,
42 merkle_tree_config: StateMerkleTreeConfig,
43 queue_config: NullifierQueueConfig,
44) -> Result<()> {
45 let bump = &[bump];
46 let seeds = [CPI_AUTHORITY_PDA_SEED, bump];
47 let signer_seeds = &[&seeds[..]];
48 let accounts = account_compression::cpi::accounts::InitializeStateMerkleTreeAndNullifierQueue {
49 authority: ctx.accounts.cpi_authority.to_account_info(),
50 merkle_tree: ctx.accounts.merkle_tree.to_account_info(),
51 nullifier_queue: ctx.accounts.queue.to_account_info(),
52 registered_program_pda: Some(ctx.accounts.registered_program_pda.clone()),
53 };
54 let cpi_ctx = CpiContext::new_with_signer(
55 ctx.accounts.account_compression_program.to_account_info(),
56 accounts,
57 signer_seeds,
58 );
59
60 account_compression::cpi::initialize_state_merkle_tree_and_nullifier_queue(
61 cpi_ctx,
62 index,
63 program_owner,
64 forester,
65 merkle_tree_config,
66 queue_config,
67 0,
68 )
69}
70
71pub fn process_initialize_address_merkle_tree(
72 ctx: Context<InitializeMerkleTreeAndQueue>,
73 bump: u8,
74 index: u64,
75 program_owner: Option<Pubkey>,
76 forester: Option<Pubkey>,
77 merkle_tree_config: AddressMerkleTreeConfig,
78 queue_config: AddressQueueConfig,
79) -> Result<()> {
80 let bump = &[bump];
81 let seeds = [CPI_AUTHORITY_PDA_SEED, bump];
82 let signer_seeds = &[&seeds[..]];
83 let accounts = account_compression::cpi::accounts::InitializeAddressMerkleTreeAndQueue {
84 authority: ctx.accounts.cpi_authority.to_account_info(),
85 merkle_tree: ctx.accounts.merkle_tree.to_account_info(),
86 queue: ctx.accounts.queue.to_account_info(),
87 registered_program_pda: Some(ctx.accounts.registered_program_pda.clone()),
88 };
89 let cpi_ctx = CpiContext::new_with_signer(
90 ctx.accounts.account_compression_program.to_account_info(),
91 accounts,
92 signer_seeds,
93 );
94
95 account_compression::cpi::initialize_address_merkle_tree_and_queue(
96 cpi_ctx,
97 index,
98 program_owner,
99 forester,
100 merkle_tree_config,
101 queue_config,
102 )
103}
104
105pub fn process_initialize_cpi_context<'info>(
106 bump: u8,
107 fee_payer: AccountInfo<'info>,
108 cpi_context_account: AccountInfo<'info>,
109 associated_merkle_tree: AccountInfo<'info>,
110 light_system_program: AccountInfo<'info>,
111) -> Result<()> {
112 let bump = &[bump];
113 let seeds = [CPI_AUTHORITY_PDA_SEED, bump];
114 let signer_seeds = &[&seeds[..]];
115 let accounts = light_system_program::cpi::accounts::InitializeCpiContextAccount {
116 fee_payer,
117 cpi_context_account,
118 associated_merkle_tree,
119 };
120 let cpi_ctx = CpiContext::new_with_signer(light_system_program, accounts, signer_seeds);
121
122 light_system_program::cpi::init_cpi_context_account(cpi_ctx)
123}
124
125pub fn check_cpi_context(
126 account: AccountInfo<'_>,
127 protocol_config: &ProtocolConfig,
128) -> Result<u64> {
129 let config_cpi_context_account_len = protocol_config.cpi_context_size as usize;
130 if account.data_len() != config_cpi_context_account_len {
131 msg!(
132 "CPI context account data len: {}, expected: {}",
133 account.data_len(),
134 config_cpi_context_account_len
135 );
136 return err!(RegistryError::CpiContextAccountInvalidDataLen);
137 }
138 let rent = Rent::get()?;
139 Ok(rent.minimum_balance(config_cpi_context_account_len))
140}