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