light_sdk/cpi/v1/
invoke.rs1use light_compressed_account::instruction_data::{
2 compressed_proof::ValidityProof, invoke_cpi::InstructionDataInvokeCpi,
3};
4
5use crate::{
6 account::{poseidon::LightAccount as LightAccountPoseidon, LightAccount},
7 cpi::{instruction::LightCpiInstruction, invoke::LightInstructionData, CpiSigner},
8 error::LightSdkError,
9 instruction::account_info::CompressedAccountInfoTrait,
10 AnchorDeserialize, AnchorSerialize, DataHasher, LightDiscriminator, ProgramError,
11};
12
13#[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_compressed_account::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_compressed_account::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_compressed_account::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_compressed_account::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_compressed_account::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 fn with_light_account_poseidon<A>(
260 mut self,
261 account: LightAccountPoseidon<'_, A>,
262 ) -> Result<Self, ProgramError>
263 where
264 A: AnchorSerialize + AnchorDeserialize + LightDiscriminator + DataHasher + Default,
265 {
266 use light_compressed_account::compressed_account::PackedCompressedAccountWithMerkleContext;
267
268 let account_info = account.to_account_info()?;
270
271 if let Some(input_account) = account_info
273 .input_compressed_account(self.cpi_signer.program_id.into())
274 .map_err(LightSdkError::from)
275 .map_err(ProgramError::from)?
276 {
277 let packed_input = PackedCompressedAccountWithMerkleContext {
278 compressed_account: input_account.compressed_account,
279 merkle_context: input_account.merkle_context,
280 root_index: input_account.root_index,
281 read_only: false, };
283 self.instruction_data
284 .input_compressed_accounts_with_merkle_context
285 .push(packed_input);
286 }
287
288 if let Some(output_account) = account_info
290 .output_compressed_account(self.cpi_signer.program_id.into())
291 .map_err(LightSdkError::from)
292 .map_err(ProgramError::from)?
293 {
294 self.instruction_data
295 .output_compressed_accounts
296 .push(output_account);
297 }
298
299 Ok(self)
300 }
301
302 fn get_mode(&self) -> u8 {
303 0 }
305
306 fn get_bump(&self) -> u8 {
307 self.cpi_signer.bump
308 }
309
310 #[cfg(feature = "cpi-context")]
311 fn write_to_cpi_context_first(mut self) -> Self {
312 self.instruction_data = self.instruction_data.write_to_cpi_context_first();
313 self
314 }
315
316 #[cfg(feature = "cpi-context")]
317 fn write_to_cpi_context_set(mut self) -> Self {
318 self.instruction_data = self.instruction_data.write_to_cpi_context_set();
319 self
320 }
321
322 #[cfg(feature = "cpi-context")]
323 fn execute_with_cpi_context(self) -> Self {
324 self
327 }
328
329 #[cfg(feature = "cpi-context")]
330 fn get_with_cpi_context(&self) -> bool {
331 self.instruction_data.cpi_context.is_some()
332 }
333
334 #[cfg(feature = "cpi-context")]
335 fn get_cpi_context(
336 &self,
337 ) -> &light_compressed_account::instruction_data::cpi_context::CompressedCpiContext {
338 use light_compressed_account::instruction_data::cpi_context::CompressedCpiContext;
339 static DEFAULT: CompressedCpiContext = CompressedCpiContext {
341 set_context: false,
342 first_set_context: false,
343 cpi_context_account_index: 0,
344 };
345 self.instruction_data
346 .cpi_context
347 .as_ref()
348 .unwrap_or(&DEFAULT)
349 }
350}
351
352impl AnchorSerialize for LightSystemProgramCpi {
354 fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
355 self.instruction_data.serialize(writer)
356 }
357}
358
359impl light_compressed_account::InstructionDiscriminator for LightSystemProgramCpi {
360 fn discriminator(&self) -> &'static [u8] {
361 self.instruction_data.discriminator()
362 }
363}
364
365impl LightInstructionData for LightSystemProgramCpi {
366 fn data(&self) -> Result<Vec<u8>, light_compressed_account::CompressedAccountError> {
367 self.instruction_data.data()
368 }
369}