light_system_program/invoke/
address.rs1use account_compression::utils::constants::CPI_AUTHORITY_PDA_SEED;
2use anchor_lang::{prelude::*, Bumps};
3
4use crate::{
5 constants::CPI_AUTHORITY_PDA_BUMP,
6 invoke_cpi::verify_signer::check_program_owner_address_merkle_tree,
7 sdk::{
8 accounts::{InvokeAccounts, SignerAccounts},
9 address::derive_address,
10 },
11 NewAddressParamsPacked,
12};
13
14pub fn derive_new_addresses(
15 new_address_params: &[NewAddressParamsPacked],
16 num_input_compressed_accounts: usize,
17 remaining_accounts: &[AccountInfo],
18 compressed_account_addresses: &mut [Option<[u8; 32]>],
19 new_addresses: &mut [[u8; 32]],
20) -> Result<()> {
21 new_address_params
22 .iter()
23 .enumerate()
24 .try_for_each(|(i, new_address_params)| {
25 let address = derive_address(
26 &remaining_accounts[new_address_params.address_merkle_tree_account_index as usize]
27 .key(),
28 &new_address_params.seed,
29 )
30 .map_err(ProgramError::from)?;
31 compressed_account_addresses[i + num_input_compressed_accounts] = Some(address);
34 new_addresses[i] = address;
35 Ok(())
36 })
37}
38
39pub fn insert_addresses_into_address_merkle_tree_queue<
40 'a,
41 'b,
42 'c: 'info,
43 'info,
44 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
45>(
46 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
47 addresses: &'a [[u8; 32]],
48 new_address_params: &'a [NewAddressParamsPacked],
49 invoking_program: &Option<Pubkey>,
50) -> anchor_lang::Result<Option<(u8, u64)>> {
51 let mut remaining_accounts = Vec::<AccountInfo>::with_capacity(new_address_params.len() * 2);
52 let mut network_fee_bundle = None;
53
54 new_address_params.iter().try_for_each(|params| {
55 remaining_accounts
56 .push(ctx.remaining_accounts[params.address_queue_account_index as usize].clone());
57
58 remaining_accounts.push(
59 ctx.remaining_accounts[params.address_merkle_tree_account_index as usize].clone(),
60 );
61 let network_fee = check_program_owner_address_merkle_tree(
67 &ctx.remaining_accounts[params.address_merkle_tree_account_index as usize],
68 invoking_program,
69 )?;
70 if network_fee_bundle.is_none() && network_fee.is_some() {
73 network_fee_bundle = Some((params.address_queue_account_index, network_fee.unwrap()));
74 }
75 anchor_lang::Result::Ok(())
76 })?;
77
78 insert_addresses_cpi(
79 ctx.accounts.get_account_compression_program(),
80 &ctx.accounts.get_fee_payer().to_account_info(),
81 ctx.accounts.get_account_compression_authority(),
82 &ctx.accounts.get_registered_program_pda().to_account_info(),
83 &ctx.accounts.get_system_program().to_account_info(),
84 remaining_accounts,
85 addresses.to_vec(),
86 )?;
87 Ok(network_fee_bundle)
88}
89
90#[allow(clippy::too_many_arguments)]
91pub fn insert_addresses_cpi<'a, 'b>(
92 account_compression_program_id: &'b AccountInfo<'a>,
93 fee_payer: &'b AccountInfo<'a>,
94 authority: &'b AccountInfo<'a>,
95 registered_program_pda: &'b AccountInfo<'a>,
96 system_program: &'b AccountInfo<'a>,
97 remaining_accounts: Vec<AccountInfo<'a>>,
98 addresses: Vec<[u8; 32]>,
99) -> Result<()> {
100 let bump = &[CPI_AUTHORITY_PDA_BUMP];
101 let seeds = &[&[CPI_AUTHORITY_PDA_SEED, bump][..]];
102 let accounts = account_compression::cpi::accounts::InsertIntoQueues {
103 fee_payer: fee_payer.to_account_info(),
104 authority: authority.to_account_info(),
105 registered_program_pda: Some(registered_program_pda.to_account_info()),
106 system_program: system_program.to_account_info(),
107 };
108
109 let mut cpi_ctx =
110 CpiContext::new_with_signer(account_compression_program_id.clone(), accounts, seeds);
111 cpi_ctx.remaining_accounts.extend(remaining_accounts);
112
113 account_compression::cpi::insert_addresses(cpi_ctx, addresses)
114}