light_sdk/cpi/v1/
invoke.rs1use light_compressed_account::instruction_data::{
2 compressed_proof::ValidityProof, invoke_cpi::InstructionDataInvokeCpi,
3};
4
5#[cfg(feature = "poseidon")]
6use crate::{account::poseidon::LightAccount as LightAccountPoseidon, DataHasher};
7use crate::{
8 account::LightAccount,
9 cpi::{instruction::LightCpiInstruction, invoke::LightInstructionData, CpiSigner},
10 error::LightSdkError,
11 instruction::account_info::CompressedAccountInfoTrait,
12 AnchorDeserialize, AnchorSerialize, LightDiscriminator, ProgramError,
13};
14
15#[derive(Clone)]
137pub struct LightSystemProgramCpi {
138 cpi_signer: CpiSigner,
139 instruction_data: InstructionDataInvokeCpi,
140}
141
142impl LightSystemProgramCpi {
143 #[must_use = "with_new_addresses returns a new value"]
144 pub fn with_new_addresses(
145 mut self,
146 new_address_params: &[light_compressed_account::instruction_data::data::NewAddressParamsPacked],
147 ) -> Self {
148 self.instruction_data = self.instruction_data.with_new_addresses(new_address_params);
149 self
150 }
151
152 #[must_use = "with_input_compressed_accounts_with_merkle_context returns a new value"]
153 pub fn with_input_compressed_accounts_with_merkle_context(
154 mut self,
155 input_compressed_accounts_with_merkle_context: &[light_compressed_account::compressed_account::PackedCompressedAccountWithMerkleContext],
156 ) -> Self {
157 self.instruction_data = self
158 .instruction_data
159 .with_input_compressed_accounts_with_merkle_context(
160 input_compressed_accounts_with_merkle_context,
161 );
162 self
163 }
164
165 #[must_use = "with_output_compressed_accounts returns a new value"]
166 pub fn with_output_compressed_accounts(
167 mut self,
168 output_compressed_accounts: &[light_compressed_account::instruction_data::data::OutputCompressedAccountWithPackedContext],
169 ) -> Self {
170 self.instruction_data = self
171 .instruction_data
172 .with_output_compressed_accounts(output_compressed_accounts);
173 self
174 }
175
176 #[must_use = "compress_lamports returns a new value"]
177 pub fn compress_lamports(mut self, lamports: u64) -> Self {
178 self.instruction_data = self.instruction_data.compress_lamports(lamports);
179 self
180 }
181
182 #[must_use = "decompress_lamports returns a new value"]
183 pub fn decompress_lamports(mut self, lamports: u64) -> Self {
184 self.instruction_data = self.instruction_data.decompress_lamports(lamports);
185 self
186 }
187
188 #[cfg(feature = "cpi-context")]
189 #[must_use = "write_to_cpi_context_set returns a new value"]
190 pub fn write_to_cpi_context_set(mut self) -> Self {
191 self.instruction_data = self.instruction_data.write_to_cpi_context_set();
192 self
193 }
194
195 #[cfg(feature = "cpi-context")]
196 #[must_use = "write_to_cpi_context_first returns a new value"]
197 pub fn write_to_cpi_context_first(mut self) -> Self {
198 self.instruction_data = self.instruction_data.write_to_cpi_context_first();
199 self
200 }
201
202 #[cfg(feature = "cpi-context")]
203 #[must_use = "with_cpi_context returns a new value"]
204 pub fn with_cpi_context(
205 mut self,
206 cpi_context: light_compressed_account::instruction_data::cpi_context::CompressedCpiContext,
207 ) -> Self {
208 self.instruction_data = self.instruction_data.with_cpi_context(cpi_context);
209 self
210 }
211}
212
213impl LightCpiInstruction for LightSystemProgramCpi {
214 fn new_cpi(cpi_signer: CpiSigner, proof: ValidityProof) -> Self {
215 Self {
216 cpi_signer,
217 instruction_data: InstructionDataInvokeCpi::new(proof.into()),
218 }
219 }
220
221 fn with_light_account<A>(mut self, account: LightAccount<A>) -> Result<Self, ProgramError>
222 where
223 A: AnchorSerialize + AnchorDeserialize + LightDiscriminator + Default,
224 {
225 use light_compressed_account::compressed_account::PackedCompressedAccountWithMerkleContext;
226
227 let account_info = account.to_account_info()?;
229
230 if let Some(input_account) = account_info
232 .input_compressed_account(self.cpi_signer.program_id.into())
233 .map_err(LightSdkError::from)
234 .map_err(ProgramError::from)?
235 {
236 let packed_input = PackedCompressedAccountWithMerkleContext {
237 compressed_account: input_account.compressed_account,
238 merkle_context: input_account.merkle_context,
239 root_index: input_account.root_index,
240 read_only: false, };
242 self.instruction_data
243 .input_compressed_accounts_with_merkle_context
244 .push(packed_input);
245 }
246
247 if let Some(output_account) = account_info
249 .output_compressed_account(self.cpi_signer.program_id.into())
250 .map_err(LightSdkError::from)
251 .map_err(ProgramError::from)?
252 {
253 self.instruction_data
254 .output_compressed_accounts
255 .push(output_account);
256 }
257
258 Ok(self)
259 }
260
261 #[cfg(feature = "poseidon")]
262 fn with_light_account_poseidon<A>(
263 mut self,
264 account: LightAccountPoseidon<A>,
265 ) -> Result<Self, ProgramError>
266 where
267 A: AnchorSerialize + AnchorDeserialize + LightDiscriminator + DataHasher + Default,
268 {
269 use light_compressed_account::compressed_account::PackedCompressedAccountWithMerkleContext;
270
271 let account_info = account.to_account_info()?;
273
274 if let Some(input_account) = account_info
276 .input_compressed_account(self.cpi_signer.program_id.into())
277 .map_err(LightSdkError::from)
278 .map_err(ProgramError::from)?
279 {
280 let packed_input = PackedCompressedAccountWithMerkleContext {
281 compressed_account: input_account.compressed_account,
282 merkle_context: input_account.merkle_context,
283 root_index: input_account.root_index,
284 read_only: false, };
286 self.instruction_data
287 .input_compressed_accounts_with_merkle_context
288 .push(packed_input);
289 }
290
291 if let Some(output_account) = account_info
293 .output_compressed_account(self.cpi_signer.program_id.into())
294 .map_err(LightSdkError::from)
295 .map_err(ProgramError::from)?
296 {
297 self.instruction_data
298 .output_compressed_accounts
299 .push(output_account);
300 }
301
302 Ok(self)
303 }
304
305 fn get_mode(&self) -> u8 {
306 0 }
308
309 fn get_bump(&self) -> u8 {
310 self.cpi_signer.bump
311 }
312
313 #[cfg(feature = "cpi-context")]
314 fn write_to_cpi_context_first(mut self) -> Self {
315 self.instruction_data = self.instruction_data.write_to_cpi_context_first();
316 self
317 }
318
319 #[cfg(feature = "cpi-context")]
320 fn write_to_cpi_context_set(mut self) -> Self {
321 self.instruction_data = self.instruction_data.write_to_cpi_context_set();
322 self
323 }
324
325 #[cfg(feature = "cpi-context")]
326 fn execute_with_cpi_context(self) -> Self {
327 self
330 }
331
332 #[cfg(feature = "cpi-context")]
333 fn get_with_cpi_context(&self) -> bool {
334 self.instruction_data.cpi_context.is_some()
335 }
336
337 #[cfg(feature = "cpi-context")]
338 fn get_cpi_context(
339 &self,
340 ) -> &light_compressed_account::instruction_data::cpi_context::CompressedCpiContext {
341 use light_compressed_account::instruction_data::cpi_context::CompressedCpiContext;
342 static DEFAULT: CompressedCpiContext = CompressedCpiContext {
344 set_context: false,
345 first_set_context: false,
346 cpi_context_account_index: 0,
347 };
348 self.instruction_data
349 .cpi_context
350 .as_ref()
351 .unwrap_or(&DEFAULT)
352 }
353
354 #[cfg(feature = "cpi-context")]
355 fn has_read_only_accounts(&self) -> bool {
356 false
358 }
359}
360
361impl AnchorSerialize for LightSystemProgramCpi {
363 fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
364 self.instruction_data.serialize(writer)
365 }
366}
367
368impl light_compressed_account::InstructionDiscriminator for LightSystemProgramCpi {
369 fn discriminator(&self) -> &'static [u8] {
370 self.instruction_data.discriminator()
371 }
372}
373
374impl LightInstructionData for LightSystemProgramCpi {
375 fn data(&self) -> Result<Vec<u8>, light_compressed_account::CompressedAccountError> {
376 self.instruction_data.data()
377 }
378}