1#[cfg(not(feature = "std"))]
19pub use alloc::{vec, vec::Vec};
20use core::fmt::Display;
21#[cfg(feature = "std")]
22pub use std::{vec, vec::Vec};
23
24use light_hasher::HasherError;
25use thiserror::Error;
26
27pub mod address;
28pub mod compressed_account;
29pub mod constants;
30pub mod discriminators;
31pub use light_hasher::hash_chain;
32pub mod instruction_data;
33pub mod nullifier;
34pub mod pubkey;
35pub use instruction_data::traits::{InstructionDiscriminator, LightInstructionData};
36pub use light_hasher::bigint::bigint_to_be_bytes_array;
37#[cfg(feature = "alloc")]
38pub use light_hasher::hash_to_field_size::{
39 hash_to_bn254_field_size_be, hashv_to_bn254_field_size_be,
40};
41pub use pubkey::Pubkey;
42
43#[derive(Debug, Error, PartialEq)]
44pub enum CompressedAccountError {
45 #[error("Invalid input size, expected at most {0}")]
46 InputTooLarge(usize),
47 #[error("Invalid chunk size")]
48 InvalidChunkSize,
49 #[error("Invalid seeds")]
50 InvalidSeeds,
51 #[error("Invalid rollover threshold")]
52 InvalidRolloverThreshold,
53 #[error("Invalid input length")]
54 InvalidInputLength,
55 #[error("Hasher error {0}")]
56 HasherError(#[from] HasherError),
57 #[error("Invalid Account size.")]
58 InvalidAccountSize,
59 #[error("Account is mutable.")]
60 AccountMutable,
61 #[error("Account is already initialized.")]
62 AlreadyInitialized,
63 #[error("Invalid account balance.")]
64 InvalidAccountBalance,
65 #[error("Failed to borrow rent sysvar.")]
66 FailedBorrowRentSysvar,
67 #[error("Derive address error.")]
68 DeriveAddressError,
69 #[error("Invalid argument.")]
70 InvalidArgument,
71 #[error("Expected address for compressed account got None.")]
72 ZeroCopyExpectedAddress,
73 #[error("Expected address for compressed account got None.")]
74 InstructionDataExpectedAddress,
75 #[error("Compressed account data not initialized.")]
76 CompressedAccountDataNotInitialized,
77 #[error(
78 "Invalid CPI context configuration: cannot write to CPI context without valid context"
79 )]
80 InvalidCpiContext,
81 #[error("Expected discriminator for compressed account got None.")]
82 ExpectedDiscriminator,
83 #[error("Expected data hash for compressed account got None.")]
84 ExpectedDataHash,
85 #[error("Expected proof for compressed account got None.")]
86 InstructionDataExpectedProof,
87 #[error("Expected proof for compressed account got None.")]
88 ZeroCopyExpectedProof,
89 #[error("Invalid proof size: expected 128 bytes, got {0}")]
90 InvalidProofSize(usize),
91}
92
93impl From<CompressedAccountError> for u32 {
96 fn from(e: CompressedAccountError) -> u32 {
97 match e {
98 CompressedAccountError::InputTooLarge(_) => 12001,
99 CompressedAccountError::InvalidChunkSize => 12002,
100 CompressedAccountError::InvalidSeeds => 12003,
101 CompressedAccountError::InvalidRolloverThreshold => 12004,
102 CompressedAccountError::InvalidInputLength => 12005,
103 CompressedAccountError::InvalidAccountSize => 12010,
104 CompressedAccountError::AccountMutable => 12011,
105 CompressedAccountError::AlreadyInitialized => 12012,
106 CompressedAccountError::InvalidAccountBalance => 12013,
107 CompressedAccountError::FailedBorrowRentSysvar => 12014,
108 CompressedAccountError::DeriveAddressError => 12015,
109 CompressedAccountError::InvalidArgument => 12016,
110 CompressedAccountError::ZeroCopyExpectedAddress => 12017,
111 CompressedAccountError::InstructionDataExpectedAddress => 12018,
112 CompressedAccountError::CompressedAccountDataNotInitialized => 12019,
113 CompressedAccountError::ExpectedDiscriminator => 12020,
114 CompressedAccountError::InstructionDataExpectedProof => 12021,
115 CompressedAccountError::ZeroCopyExpectedProof => 12022,
116 CompressedAccountError::ExpectedDataHash => 12023,
117 CompressedAccountError::InvalidCpiContext => 12024,
118 CompressedAccountError::InvalidProofSize(_) => 12025,
119 CompressedAccountError::HasherError(e) => u32::from(e),
120 }
121 }
122}
123
124#[cfg(feature = "solana")]
125impl From<CompressedAccountError> for solana_program_error::ProgramError {
126 fn from(e: CompressedAccountError) -> Self {
127 solana_program_error::ProgramError::Custom(e.into())
128 }
129}
130
131#[cfg(feature = "pinocchio")]
132impl From<CompressedAccountError> for pinocchio::program_error::ProgramError {
133 fn from(e: CompressedAccountError) -> Self {
134 pinocchio::program_error::ProgramError::Custom(e.into())
135 }
136}
137
138pub const NULLIFIER_QUEUE_TYPE_V1: u64 = 1;
139pub const ADDRESS_QUEUE_TYPE_V1: u64 = 2;
140pub const INPUT_STATE_QUEUE_TYPE_V2: u64 = 3;
141pub const ADDRESS_QUEUE_TYPE_V2: u64 = 4;
142pub const OUTPUT_STATE_QUEUE_TYPE_V2: u64 = 5;
143
144#[cfg_attr(
145 all(feature = "std", feature = "anchor"),
146 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
147)]
148#[cfg_attr(
149 not(feature = "anchor"),
150 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
151)]
152#[derive(Debug, PartialEq, Clone, Copy)]
153#[repr(u64)]
154#[cfg_attr(
155 any(all(feature = "std", feature = "anchor"), not(feature = "anchor")),
156 borsh(use_discriminant = false)
157)]
158pub enum QueueType {
159 NullifierV1 = NULLIFIER_QUEUE_TYPE_V1,
160 AddressV1 = ADDRESS_QUEUE_TYPE_V1,
161 InputStateV2 = INPUT_STATE_QUEUE_TYPE_V2,
162 AddressV2 = ADDRESS_QUEUE_TYPE_V2,
163 OutputStateV2 = OUTPUT_STATE_QUEUE_TYPE_V2,
164}
165
166impl From<u64> for QueueType {
167 fn from(value: u64) -> Self {
168 match value {
169 1 => QueueType::NullifierV1,
170 2 => QueueType::AddressV1,
171 3 => QueueType::InputStateV2,
172 4 => QueueType::AddressV2,
173 5 => QueueType::OutputStateV2,
174 _ => panic!("Invalid queue type"),
175 }
176 }
177}
178
179pub const STATE_MERKLE_TREE_TYPE_V1: u64 = 1;
180pub const ADDRESS_MERKLE_TREE_TYPE_V1: u64 = 2;
181pub const STATE_MERKLE_TREE_TYPE_V2: u64 = 3;
182pub const ADDRESS_MERKLE_TREE_TYPE_V2: u64 = 4;
183
184#[cfg_attr(
185 all(feature = "std", feature = "anchor"),
186 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
187)]
188#[cfg_attr(
189 not(feature = "anchor"),
190 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
191)]
192#[derive(Debug, Ord, PartialEq, PartialOrd, Eq, Clone, Copy)]
193#[repr(u64)]
194#[cfg_attr(
195 any(all(feature = "std", feature = "anchor"), not(feature = "anchor")),
196 borsh(use_discriminant = false)
197)]
198pub enum TreeType {
199 StateV1 = STATE_MERKLE_TREE_TYPE_V1,
200 AddressV1 = ADDRESS_MERKLE_TREE_TYPE_V1,
201 StateV2 = STATE_MERKLE_TREE_TYPE_V2,
202 AddressV2 = ADDRESS_MERKLE_TREE_TYPE_V2,
203 Unknown = 255,
204}
205
206impl Display for TreeType {
207 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
208 match self {
209 TreeType::StateV1 => write!(f, "StateV1"),
210 TreeType::AddressV1 => write!(f, "AddressV1"),
211 TreeType::StateV2 => write!(f, "StateV2"),
212 TreeType::AddressV2 => write!(f, "AddressV2"),
213 TreeType::Unknown => write!(f, "Unknown"),
214 }
215 }
216}
217
218#[allow(clippy::derivable_impls)]
219impl core::default::Default for TreeType {
220 fn default() -> Self {
221 TreeType::StateV2
222 }
223}
224
225impl From<u64> for TreeType {
227 fn from(value: u64) -> Self {
228 match value {
229 1 => TreeType::StateV1,
230 2 => TreeType::AddressV1,
231 3 => TreeType::StateV2,
232 4 => TreeType::AddressV2,
233 255 => TreeType::Unknown,
234 _ => panic!("Invalid TreeType"),
235 }
236 }
237}
238
239#[derive(Debug, Clone, Copy, PartialEq, Eq)]
241pub struct CpiSigner {
242 pub program_id: [u8; 32],
243 pub cpi_signer: [u8; 32],
244 pub bump: u8,
245}