1use light_zero_copy::ZeroCopyMut;
2
3use crate::{
4 compressed_account::{CompressedAccount, PackedCompressedAccountWithMerkleContext},
5 discriminators::DISCRIMINATOR_INVOKE,
6 instruction_data::{compressed_proof::CompressedProof, traits::LightInstructionData},
7 InstructionDiscriminator, Pubkey, Vec,
8};
9
10#[cfg_attr(
11 all(feature = "std", feature = "anchor"),
12 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
13)]
14#[cfg_attr(
15 not(feature = "anchor"),
16 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
17)]
18#[derive(Debug, PartialEq, Default, Clone)]
19pub struct InstructionDataInvoke {
20 pub proof: Option<CompressedProof>,
21 pub input_compressed_accounts_with_merkle_context:
22 Vec<PackedCompressedAccountWithMerkleContext>,
23 pub output_compressed_accounts: Vec<OutputCompressedAccountWithPackedContext>,
24 pub relay_fee: Option<u64>,
25 pub new_address_params: Vec<NewAddressParamsPacked>,
26 pub compress_or_decompress_lamports: Option<u64>,
27 pub is_compress: bool,
28}
29
30impl InstructionDataInvoke {
31 pub fn new(proof: Option<CompressedProof>) -> Self {
32 Self {
33 proof,
34 ..Default::default()
35 }
36 }
37
38 pub fn with_input_compressed_accounts_with_merkle_context(
39 mut self,
40 input_compressed_accounts_with_merkle_context: &[PackedCompressedAccountWithMerkleContext],
41 ) -> Self {
42 if !input_compressed_accounts_with_merkle_context.is_empty() {
43 self.input_compressed_accounts_with_merkle_context
44 .extend_from_slice(input_compressed_accounts_with_merkle_context);
45 }
46 self
47 }
48
49 pub fn with_output_compressed_accounts(
50 mut self,
51 output_compressed_accounts: &[OutputCompressedAccountWithPackedContext],
52 ) -> Self {
53 if !output_compressed_accounts.is_empty() {
54 self.output_compressed_accounts
55 .extend_from_slice(output_compressed_accounts);
56 }
57 self
58 }
59
60 pub fn with_new_addresses(mut self, new_address_params: &[NewAddressParamsPacked]) -> Self {
61 if !new_address_params.is_empty() {
62 self.new_address_params
63 .extend_from_slice(new_address_params);
64 }
65 self
66 }
67
68 pub fn compress_lamports(mut self, lamports: u64) -> Self {
69 self.compress_or_decompress_lamports = Some(lamports);
70 self.is_compress = true;
71 self
72 }
73
74 pub fn decompress_lamports(mut self, lamports: u64) -> Self {
75 self.compress_or_decompress_lamports = Some(lamports);
76 self.is_compress = false;
77 self
78 }
79}
80
81impl InstructionDiscriminator for InstructionDataInvoke {
82 fn discriminator(&self) -> &'static [u8] {
83 &DISCRIMINATOR_INVOKE
84 }
85}
86
87impl LightInstructionData for InstructionDataInvoke {}
88
89#[cfg_attr(
90 all(feature = "std", feature = "anchor"),
91 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
92)]
93#[cfg_attr(
94 not(feature = "anchor"),
95 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
96)]
97#[derive(Debug, PartialEq, Default, Clone)]
98pub struct OutputCompressedAccountWithContext {
99 pub compressed_account: CompressedAccount,
100 pub merkle_tree: Pubkey,
101}
102
103#[repr(C)]
104#[cfg_attr(
105 all(feature = "std", feature = "anchor"),
106 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
107)]
108#[cfg_attr(
109 not(feature = "anchor"),
110 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
111)]
112#[derive(Debug, PartialEq, Default, Clone, ZeroCopyMut)]
113pub struct OutputCompressedAccountWithPackedContext {
114 pub compressed_account: CompressedAccount,
115 pub merkle_tree_index: u8,
116}
117
118#[repr(C)]
119#[cfg_attr(
120 all(feature = "std", feature = "anchor"),
121 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
122)]
123#[cfg_attr(
124 not(feature = "anchor"),
125 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
126)]
127#[derive(Debug, PartialEq, Default, Clone, Copy, ZeroCopyMut)]
128pub struct NewAddressParamsPacked {
129 pub seed: [u8; 32],
130 pub address_queue_account_index: u8,
131 pub address_merkle_tree_account_index: u8,
132 pub address_merkle_tree_root_index: u16,
133}
134
135#[repr(C)]
136#[cfg_attr(
137 all(feature = "std", feature = "anchor"),
138 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
139)]
140#[cfg_attr(
141 not(feature = "anchor"),
142 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
143)]
144#[derive(Debug, PartialEq, Default, Clone, Copy, ZeroCopyMut)]
145pub struct NewAddressParamsAssignedPacked {
146 pub seed: [u8; 32],
147 pub address_queue_account_index: u8,
148 pub address_merkle_tree_account_index: u8,
149 pub address_merkle_tree_root_index: u16,
150 pub assigned_to_account: bool,
151 pub assigned_account_index: u8,
152}
153
154impl NewAddressParamsAssignedPacked {
155 pub fn new(address_params: NewAddressParamsPacked, index: Option<u8>) -> Self {
156 Self {
157 seed: address_params.seed,
158 address_queue_account_index: address_params.address_queue_account_index,
159 address_merkle_tree_account_index: address_params.address_merkle_tree_account_index,
160 address_merkle_tree_root_index: address_params.address_merkle_tree_root_index,
161 assigned_to_account: index.is_some(),
162 assigned_account_index: index.unwrap_or_default(),
163 }
164 }
165
166 pub fn assigned_account_index(&self) -> Option<u8> {
167 if self.assigned_to_account {
168 Some(self.assigned_account_index)
169 } else {
170 None
171 }
172 }
173}
174
175#[repr(C)]
178#[cfg_attr(
179 all(feature = "std", feature = "anchor"),
180 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
181)]
182#[cfg_attr(
183 not(feature = "anchor"),
184 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
185)]
186#[derive(Debug, Clone, Copy, PartialEq, Default, ZeroCopyMut, light_zero_copy::ZeroCopy)]
187pub struct PackedAddressTreeInfo {
188 pub address_merkle_tree_pubkey_index: u8,
189 pub address_queue_pubkey_index: u8,
190 pub root_index: u16,
191}
192
193impl PackedAddressTreeInfo {
194 pub fn into_new_address_params_packed(
195 self,
196 seed: crate::address::AddressSeed,
197 ) -> NewAddressParamsPacked {
198 NewAddressParamsPacked {
199 address_merkle_tree_account_index: self.address_merkle_tree_pubkey_index,
200 address_queue_account_index: self.address_queue_pubkey_index,
201 address_merkle_tree_root_index: self.root_index,
202 seed: seed.0,
203 }
204 }
205
206 pub fn into_new_address_params_assigned_packed(
207 self,
208 seed: crate::address::AddressSeed,
209 assigned_account_index: Option<u8>,
210 ) -> NewAddressParamsAssignedPacked {
211 NewAddressParamsAssignedPacked {
212 address_merkle_tree_account_index: self.address_merkle_tree_pubkey_index,
213 address_queue_account_index: self.address_queue_pubkey_index,
214 address_merkle_tree_root_index: self.root_index,
215 seed: seed.0,
216 assigned_account_index: assigned_account_index.unwrap_or_default(),
217 assigned_to_account: assigned_account_index.is_some(),
218 }
219 }
220}
221
222#[cfg_attr(
223 all(feature = "std", feature = "anchor"),
224 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
225)]
226#[cfg_attr(
227 not(feature = "anchor"),
228 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
229)]
230#[derive(Debug, PartialEq, Default, Clone)]
231pub struct NewAddressParams {
232 pub seed: [u8; 32],
233 pub address_queue_pubkey: Pubkey,
234 pub address_merkle_tree_pubkey: Pubkey,
235 pub address_merkle_tree_root_index: u16,
236}
237
238#[cfg_attr(
239 all(feature = "std", feature = "anchor"),
240 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
241)]
242#[cfg_attr(
243 not(feature = "anchor"),
244 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
245)]
246#[derive(Debug, PartialEq, Default, Clone)]
247pub struct NewAddressParamsAssigned {
248 pub seed: [u8; 32],
249 pub address_queue_pubkey: Pubkey,
250 pub address_merkle_tree_pubkey: Pubkey,
251 pub address_merkle_tree_root_index: u16,
252 pub assigned_account_index: Option<u8>,
253}
254
255#[repr(C)]
256#[cfg_attr(
257 all(feature = "std", feature = "anchor"),
258 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
259)]
260#[cfg_attr(
261 not(feature = "anchor"),
262 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
263)]
264#[derive(Debug, PartialEq, Default, Clone, Copy, ZeroCopyMut)]
265pub struct PackedReadOnlyAddress {
266 pub address: [u8; 32],
267 pub address_merkle_tree_root_index: u16,
268 pub address_merkle_tree_account_index: u8,
269}
270
271#[cfg_attr(
272 all(feature = "std", feature = "anchor"),
273 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
274)]
275#[cfg_attr(
276 not(feature = "anchor"),
277 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
278)]
279#[derive(Debug, PartialEq, Default, Clone)]
280pub struct ReadOnlyAddress {
281 pub address: [u8; 32],
282 pub address_merkle_tree_pubkey: Pubkey,
283 pub address_merkle_tree_root_index: u16,
284}