light_sdk/cpi/v1/
accounts.rs1pub use light_sdk_types::cpi_accounts::v1::SYSTEM_ACCOUNTS_LEN;
2use light_sdk_types::{
3 cpi_accounts::v1::CpiAccounts as GenericCpiAccounts, ACCOUNT_COMPRESSION_AUTHORITY_PDA,
4 ACCOUNT_COMPRESSION_PROGRAM_ID, LIGHT_SYSTEM_PROGRAM_ID, NOOP_PROGRAM_ID,
5 REGISTERED_PROGRAM_PDA,
6};
7
8use crate::{
9 error::{LightSdkError, Result},
10 AccountInfo, AccountMeta, Pubkey,
11};
12
13#[derive(Debug)]
14pub struct CpiInstructionConfig<'a, 'info> {
15 pub fee_payer: Pubkey,
16 pub cpi_signer: Pubkey,
17 pub invoking_program: Pubkey,
18 pub sol_pool_pda_pubkey: Option<Pubkey>,
19 pub sol_compression_recipient_pubkey: Option<Pubkey>,
20 pub cpi_context_pubkey: Option<Pubkey>,
21 pub packed_accounts: &'a [AccountInfo<'info>],
22}
23
24pub type CpiAccounts<'c, 'info> = GenericCpiAccounts<'c, AccountInfo<'info>>;
28
29pub fn get_account_metas_from_config(config: CpiInstructionConfig<'_, '_>) -> Vec<AccountMeta> {
30 let mut account_metas = Vec::with_capacity(1 + SYSTEM_ACCOUNTS_LEN);
31
32 account_metas.push(AccountMeta {
34 pubkey: config.fee_payer,
35 is_signer: true,
36 is_writable: true,
37 });
38
39 account_metas.push(AccountMeta {
41 pubkey: config.cpi_signer,
42 is_signer: true,
43 is_writable: false,
44 });
45
46 account_metas.push(AccountMeta {
48 pubkey: Pubkey::from(REGISTERED_PROGRAM_PDA),
49 is_signer: false,
50 is_writable: false,
51 });
52
53 account_metas.push(AccountMeta {
55 pubkey: Pubkey::from(NOOP_PROGRAM_ID),
56 is_signer: false,
57 is_writable: false,
58 });
59
60 account_metas.push(AccountMeta {
62 pubkey: Pubkey::from(ACCOUNT_COMPRESSION_AUTHORITY_PDA),
63 is_signer: false,
64 is_writable: false,
65 });
66
67 account_metas.push(AccountMeta {
69 pubkey: Pubkey::from(ACCOUNT_COMPRESSION_PROGRAM_ID),
70 is_signer: false,
71 is_writable: false,
72 });
73
74 account_metas.push(AccountMeta {
76 pubkey: config.invoking_program,
77 is_signer: false,
78 is_writable: false,
79 });
80
81 let create_light_system_meta = || AccountMeta {
83 pubkey: Pubkey::from(LIGHT_SYSTEM_PROGRAM_ID),
84 is_signer: false,
85 is_writable: false,
86 };
87
88 if let Some(sol_pool_pda_pubkey) = config.sol_pool_pda_pubkey {
90 account_metas.push(AccountMeta {
91 pubkey: sol_pool_pda_pubkey,
92 is_signer: false,
93 is_writable: true,
94 });
95 } else {
96 account_metas.push(create_light_system_meta());
97 }
98
99 if let Some(sol_compression_recipient_pubkey) = config.sol_compression_recipient_pubkey {
101 account_metas.push(AccountMeta {
102 pubkey: sol_compression_recipient_pubkey,
103 is_signer: false,
104 is_writable: true,
105 });
106 } else {
107 account_metas.push(create_light_system_meta());
108 }
109
110 account_metas.push(AccountMeta {
112 pubkey: Pubkey::default(),
113 is_signer: false,
114 is_writable: false,
115 });
116
117 if let Some(cpi_context_pubkey) = config.cpi_context_pubkey {
119 account_metas.push(AccountMeta {
120 pubkey: cpi_context_pubkey,
121 is_signer: false,
122 is_writable: true,
123 });
124 } else {
125 account_metas.push(create_light_system_meta());
126 }
127
128 for acc in config.packed_accounts {
129 account_metas.push(AccountMeta {
130 pubkey: *acc.key,
131 is_signer: false,
132 is_writable: acc.is_writable,
133 });
134 }
135
136 account_metas
137}
138
139impl<'a, 'info> TryFrom<&'a CpiAccounts<'a, 'info>> for CpiInstructionConfig<'a, 'info> {
140 type Error = LightSdkError;
141
142 fn try_from(cpi_accounts: &'a CpiAccounts<'a, 'info>) -> Result<Self> {
143 Ok(CpiInstructionConfig {
144 fee_payer: *cpi_accounts.fee_payer().key,
145 cpi_signer: cpi_accounts.config().cpi_signer().into(),
146 invoking_program: cpi_accounts.config().cpi_signer.program_id.into(),
147 sol_pool_pda_pubkey: if cpi_accounts.config().sol_pool_pda {
148 Some(*cpi_accounts.sol_pool_pda()?.key)
149 } else {
150 None
151 },
152 sol_compression_recipient_pubkey: if cpi_accounts.config().sol_compression_recipient {
153 Some(*cpi_accounts.decompression_recipient()?.key)
154 } else {
155 None
156 },
157 cpi_context_pubkey: if cpi_accounts.config().cpi_context {
158 Some(*cpi_accounts.cpi_context()?.key)
159 } else {
160 None
161 },
162 packed_accounts: cpi_accounts.tree_accounts().unwrap_or(&[]),
163 })
164 }
165}