light_compressed_account/instruction_data/
data.rs1use std::collections::HashMap;
2
3use light_zero_copy::ZeroCopyMut;
4
5use crate::{
6 compressed_account::{CompressedAccount, PackedCompressedAccountWithMerkleContext},
7 discriminators::DISCRIMINATOR_INVOKE,
8 instruction_data::{compressed_proof::CompressedProof, traits::LightInstructionData},
9 AnchorDeserialize, AnchorSerialize, InstructionDiscriminator, Pubkey,
10};
11
12#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize)]
13pub struct InstructionDataInvoke {
14 pub proof: Option<CompressedProof>,
15 pub input_compressed_accounts_with_merkle_context:
16 Vec<PackedCompressedAccountWithMerkleContext>,
17 pub output_compressed_accounts: Vec<OutputCompressedAccountWithPackedContext>,
18 pub relay_fee: Option<u64>,
19 pub new_address_params: Vec<NewAddressParamsPacked>,
20 pub compress_or_decompress_lamports: Option<u64>,
21 pub is_compress: bool,
22}
23
24impl InstructionDataInvoke {
25 pub fn new(proof: Option<CompressedProof>) -> Self {
26 Self {
27 proof,
28 ..Default::default()
29 }
30 }
31
32 pub fn with_input_compressed_accounts_with_merkle_context(
33 mut self,
34 input_compressed_accounts_with_merkle_context: &[PackedCompressedAccountWithMerkleContext],
35 ) -> Self {
36 if !input_compressed_accounts_with_merkle_context.is_empty() {
37 self.input_compressed_accounts_with_merkle_context
38 .extend_from_slice(input_compressed_accounts_with_merkle_context);
39 }
40 self
41 }
42
43 pub fn with_output_compressed_accounts(
44 mut self,
45 output_compressed_accounts: &[OutputCompressedAccountWithPackedContext],
46 ) -> Self {
47 if !output_compressed_accounts.is_empty() {
48 self.output_compressed_accounts
49 .extend_from_slice(output_compressed_accounts);
50 }
51 self
52 }
53
54 pub fn with_new_addresses(mut self, new_address_params: &[NewAddressParamsPacked]) -> Self {
55 if !new_address_params.is_empty() {
56 self.new_address_params
57 .extend_from_slice(new_address_params);
58 }
59 self
60 }
61
62 pub fn compress_lamports(mut self, lamports: u64) -> Self {
63 self.compress_or_decompress_lamports = Some(lamports);
64 self.is_compress = true;
65 self
66 }
67
68 pub fn decompress_lamports(mut self, lamports: u64) -> Self {
69 self.compress_or_decompress_lamports = Some(lamports);
70 self.is_compress = false;
71 self
72 }
73}
74
75impl InstructionDiscriminator for InstructionDataInvoke {
76 fn discriminator(&self) -> &'static [u8] {
77 &DISCRIMINATOR_INVOKE
78 }
79}
80
81impl LightInstructionData for InstructionDataInvoke {}
82
83#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize)]
84pub struct OutputCompressedAccountWithContext {
85 pub compressed_account: CompressedAccount,
86 pub merkle_tree: Pubkey,
87}
88
89#[repr(C)]
90#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize, ZeroCopyMut)]
91pub struct OutputCompressedAccountWithPackedContext {
92 pub compressed_account: CompressedAccount,
93 pub merkle_tree_index: u8,
94}
95
96#[repr(C)]
97#[derive(
98 Debug, PartialEq, Default, Clone, Copy, AnchorDeserialize, AnchorSerialize, ZeroCopyMut,
99)]
100pub struct NewAddressParamsPacked {
101 pub seed: [u8; 32],
102 pub address_queue_account_index: u8,
103 pub address_merkle_tree_account_index: u8,
104 pub address_merkle_tree_root_index: u16,
105}
106
107#[repr(C)]
108#[derive(
109 Debug, PartialEq, Default, Clone, Copy, AnchorDeserialize, AnchorSerialize, ZeroCopyMut,
110)]
111pub struct NewAddressParamsAssignedPacked {
112 pub seed: [u8; 32],
113 pub address_queue_account_index: u8,
114 pub address_merkle_tree_account_index: u8,
115 pub address_merkle_tree_root_index: u16,
116 pub assigned_to_account: bool,
117 pub assigned_account_index: u8,
118}
119
120impl NewAddressParamsAssignedPacked {
121 pub fn new(address_params: NewAddressParamsPacked, index: Option<u8>) -> Self {
122 Self {
123 seed: address_params.seed,
124 address_queue_account_index: address_params.address_queue_account_index,
125 address_merkle_tree_account_index: address_params.address_merkle_tree_account_index,
126 address_merkle_tree_root_index: address_params.address_merkle_tree_root_index,
127 assigned_to_account: index.is_some(),
128 assigned_account_index: index.unwrap_or_default(),
129 }
130 }
131
132 pub fn assigned_account_index(&self) -> Option<u8> {
133 if self.assigned_to_account {
134 Some(self.assigned_account_index)
135 } else {
136 None
137 }
138 }
139}
140
141#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize)]
142pub struct NewAddressParams {
143 pub seed: [u8; 32],
144 pub address_queue_pubkey: Pubkey,
145 pub address_merkle_tree_pubkey: Pubkey,
146 pub address_merkle_tree_root_index: u16,
147}
148
149#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize)]
150pub struct NewAddressParamsAssigned {
151 pub seed: [u8; 32],
152 pub address_queue_pubkey: Pubkey,
153 pub address_merkle_tree_pubkey: Pubkey,
154 pub address_merkle_tree_root_index: u16,
155 pub assigned_account_index: Option<u8>,
156}
157
158#[repr(C)]
159#[derive(
160 Debug, PartialEq, Default, Clone, Copy, AnchorDeserialize, AnchorSerialize, ZeroCopyMut,
161)]
162pub struct PackedReadOnlyAddress {
163 pub address: [u8; 32],
164 pub address_merkle_tree_root_index: u16,
165 pub address_merkle_tree_account_index: u8,
166}
167
168#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize)]
169pub struct ReadOnlyAddress {
170 pub address: [u8; 32],
171 pub address_merkle_tree_pubkey: Pubkey,
172 pub address_merkle_tree_root_index: u16,
173}
174pub fn pack_pubkey(pubkey: &Pubkey, hash_set: &mut HashMap<Pubkey, u8>) -> u8 {
176 match hash_set.get(pubkey) {
177 Some(index) => *index,
178 None => {
179 let index = hash_set.len() as u8;
180 hash_set.insert(*pubkey, index);
181 index
182 }
183 }
184}
185
186pub fn pack_pubkey_usize(pubkey: &Pubkey, hash_set: &mut HashMap<Pubkey, usize>) -> u8 {
187 match hash_set.get(pubkey) {
188 Some(index) => (*index) as u8,
189 None => {
190 let index = hash_set.len();
191 hash_set.insert(*pubkey, index);
192 index as u8
193 }
194 }
195}