light_compressed_account/instruction_data/
data.rs

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/// Packed address tree info for instruction data.
176/// Contains indices to address tree accounts and root index.
177#[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}