light_client/interface/
pack.rs1use light_sdk::instruction::{PackedAccounts, SystemAccountMetaConfig};
4pub use light_sdk::instruction::{PackedAddressTreeInfo, PackedStateTreeInfo};
5use solana_instruction::AccountMeta;
6use solana_pubkey::Pubkey;
7use thiserror::Error;
8
9use crate::indexer::{TreeInfo, ValidityProofWithContext};
10
11#[derive(Debug, Error)]
12pub enum PackError {
13 #[error("Failed to add system accounts: {0}")]
14 SystemAccounts(#[from] light_sdk::error::LightSdkError),
15}
16
17#[derive(Clone, Default, Debug)]
19pub struct PackedStateTreeInfos {
20 pub packed_tree_infos: Vec<PackedStateTreeInfo>,
21 pub output_tree_index: u8,
22}
23
24#[derive(Clone, Default, Debug)]
26pub struct PackedTreeInfos {
27 pub state_trees: Option<PackedStateTreeInfos>,
28 pub address_trees: Vec<PackedAddressTreeInfo>,
29}
30
31pub struct PackedProofResult {
33 pub remaining_accounts: Vec<AccountMeta>,
35 pub packed_tree_infos: PackedTreeInfos,
37 pub output_tree_index: u8,
39 pub state_tree_index: Option<u8>,
41 pub system_accounts_offset: u8,
43}
44
45pub fn pack_proof(
47 program_id: &Pubkey,
48 proof: ValidityProofWithContext,
49 output_tree: &TreeInfo,
50 cpi_context: Option<Pubkey>,
51) -> Result<PackedProofResult, PackError> {
52 pack_proof_internal(program_id, proof, output_tree, cpi_context, false)
53}
54
55pub fn pack_proof_for_mints(
57 program_id: &Pubkey,
58 proof: ValidityProofWithContext,
59 output_tree: &TreeInfo,
60 cpi_context: Option<Pubkey>,
61) -> Result<PackedProofResult, PackError> {
62 pack_proof_internal(program_id, proof, output_tree, cpi_context, true)
63}
64
65fn pack_proof_internal(
66 program_id: &Pubkey,
67 proof: ValidityProofWithContext,
68 output_tree: &TreeInfo,
69 cpi_context: Option<Pubkey>,
70 include_state_tree: bool,
71) -> Result<PackedProofResult, PackError> {
72 let mut packed = PackedAccounts::default();
73
74 let system_config = match cpi_context {
75 Some(ctx) => SystemAccountMetaConfig::new_with_cpi_context(*program_id, ctx),
76 None => SystemAccountMetaConfig::new(*program_id),
77 };
78 packed.add_system_accounts_v2(system_config)?;
79
80 let output_queue = output_tree
81 .next_tree_info
82 .as_ref()
83 .map(|n| n.queue)
84 .unwrap_or(output_tree.queue);
85 let output_tree_index = packed.insert_or_get(output_queue);
86
87 let (client_packed_tree_infos, state_tree_index) = if include_state_tree {
89 let tree_infos = proof.pack_tree_infos(&mut packed);
91
92 let state_tree = output_tree
94 .next_tree_info
95 .as_ref()
96 .map(|n| n.tree)
97 .unwrap_or(output_tree.tree);
98 let state_idx = packed.insert_or_get(state_tree);
99
100 (tree_infos, Some(state_idx))
101 } else {
102 let tree_infos = proof.pack_tree_infos(&mut packed);
103 (tree_infos, None)
104 };
105 let (remaining_accounts, system_offset, _) = packed.to_account_metas();
106
107 let packed_tree_infos = PackedTreeInfos {
109 state_trees: client_packed_tree_infos
110 .state_trees
111 .map(|st| PackedStateTreeInfos {
112 packed_tree_infos: st.packed_tree_infos,
113 output_tree_index: st.output_tree_index,
114 }),
115 address_trees: client_packed_tree_infos.address_trees,
116 };
117
118 Ok(PackedProofResult {
119 remaining_accounts,
120 packed_tree_infos,
121 output_tree_index,
122 state_tree_index,
123 system_accounts_offset: system_offset as u8,
124 })
125}