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