light_compressed_account/instruction_data/
invoke_cpi.rs1use light_zero_copy::ZeroCopyMut;
2
3use super::{
4 cpi_context::CompressedCpiContext,
5 data::{NewAddressParamsPacked, OutputCompressedAccountWithPackedContext},
6};
7use crate::{
8 compressed_account::PackedCompressedAccountWithMerkleContext,
9 discriminators::DISCRIMINATOR_INVOKE_CPI,
10 instruction_data::{compressed_proof::CompressedProof, traits::LightInstructionData},
11 AnchorDeserialize, AnchorSerialize, CompressedAccountError, InstructionDiscriminator,
12};
13
14#[repr(C)]
15#[derive(Debug, PartialEq, Default, Clone, AnchorDeserialize, AnchorSerialize, ZeroCopyMut)]
16pub struct InstructionDataInvokeCpi {
17 pub proof: Option<CompressedProof>,
18 pub new_address_params: Vec<NewAddressParamsPacked>,
19 pub input_compressed_accounts_with_merkle_context:
20 Vec<PackedCompressedAccountWithMerkleContext>,
21 pub output_compressed_accounts: Vec<OutputCompressedAccountWithPackedContext>,
22 pub relay_fee: Option<u64>,
23 pub compress_or_decompress_lamports: Option<u64>,
24 pub is_compress: bool,
25 pub cpi_context: Option<CompressedCpiContext>,
26}
27
28impl LightInstructionData for InstructionDataInvokeCpi {
29 fn data(&self) -> Result<Vec<u8>, CompressedAccountError> {
30 let inputs = self
31 .try_to_vec()
32 .map_err(|_| CompressedAccountError::InvalidArgument)?;
33 let mut data = Vec::with_capacity(12 + inputs.len());
34 data.extend_from_slice(self.discriminator());
35 data.extend_from_slice(&(inputs.len() as u32).to_le_bytes());
36 data.extend_from_slice(inputs.as_slice());
37 Ok(data)
38 }
39}
40
41impl InstructionDataInvokeCpi {
42 pub fn new(proof: Option<CompressedProof>) -> Self {
43 Self {
44 proof,
45 ..Default::default()
46 }
47 }
48
49 #[must_use = "with_new_addresses returns a new value"]
50 pub fn with_new_addresses(mut self, new_address_params: &[NewAddressParamsPacked]) -> Self {
51 if !new_address_params.is_empty() {
52 self.new_address_params
53 .extend_from_slice(new_address_params);
54 }
55 self
56 }
57
58 #[must_use = "with_input_compressed_accounts_with_merkle_context returns a new value"]
59 pub fn with_input_compressed_accounts_with_merkle_context(
60 mut self,
61 input_compressed_accounts_with_merkle_context: &[PackedCompressedAccountWithMerkleContext],
62 ) -> Self {
63 if !input_compressed_accounts_with_merkle_context.is_empty() {
64 self.input_compressed_accounts_with_merkle_context
65 .extend_from_slice(input_compressed_accounts_with_merkle_context);
66 }
67 self
68 }
69
70 #[must_use = "with_output_compressed_accounts returns a new value"]
71 pub fn with_output_compressed_accounts(
72 mut self,
73 output_compressed_accounts: &[OutputCompressedAccountWithPackedContext],
74 ) -> Self {
75 if !output_compressed_accounts.is_empty() {
76 self.output_compressed_accounts
77 .extend_from_slice(output_compressed_accounts);
78 }
79 self
80 }
81
82 #[must_use = "compress_lamports returns a new value"]
83 pub fn compress_lamports(mut self, lamports: u64) -> Self {
84 self.compress_or_decompress_lamports = Some(lamports);
85 self.is_compress = true;
86 self
87 }
88
89 #[must_use = "decompress_lamports returns a new value"]
90 pub fn decompress_lamports(mut self, lamports: u64) -> Self {
91 self.compress_or_decompress_lamports = Some(lamports);
92 self.is_compress = false;
93 self
94 }
95
96 #[must_use = "write_to_cpi_context_set returns a new value"]
97 pub fn write_to_cpi_context_set(mut self) -> Self {
98 self.cpi_context = Some(CompressedCpiContext::set());
99 self
100 }
101
102 #[must_use = "write_to_cpi_context_first returns a new value"]
103 pub fn write_to_cpi_context_first(mut self) -> Self {
104 self.cpi_context = Some(CompressedCpiContext::first());
105 self
106 }
107
108 #[must_use = "with_cpi_context returns a new value"]
109 pub fn with_cpi_context(mut self, cpi_context: CompressedCpiContext) -> Self {
110 self.cpi_context = Some(cpi_context);
111 self
112 }
113}
114
115impl InstructionDiscriminator for InstructionDataInvokeCpi {
116 fn discriminator(&self) -> &'static [u8] {
117 &DISCRIMINATOR_INVOKE_CPI
118 }
119}