light_token/compressed_token/v2/transfer2/
account_metas.rs1use light_sdk::constants::LIGHT_SYSTEM_PROGRAM_ID;
2use light_token_types::CPI_AUTHORITY_PDA;
3use solana_instruction::AccountMeta;
4use solana_pubkey::Pubkey;
5
6use crate::utils::TokenDefaultAccounts;
7
8#[derive(Debug, Default, Clone, PartialEq)]
10pub struct Transfer2AccountsMetaConfig {
11 pub fee_payer: Option<Pubkey>,
12 pub sol_pool_pda: Option<Pubkey>,
13 pub sol_decompression_recipient: Option<Pubkey>,
14 pub cpi_context: Option<Pubkey>,
15 pub with_sol_pool: bool,
16 pub decompressed_accounts_only: bool,
17 pub packed_accounts: Option<Vec<AccountMeta>>, }
19
20impl Transfer2AccountsMetaConfig {
21 pub fn new(fee_payer: Pubkey, packed_accounts: Vec<AccountMeta>) -> Self {
22 Self {
23 fee_payer: Some(fee_payer),
24 decompressed_accounts_only: false,
25 sol_pool_pda: None,
26 sol_decompression_recipient: None,
27 cpi_context: None,
28 with_sol_pool: false,
29 packed_accounts: Some(packed_accounts),
30 }
31 }
32
33 pub fn new_decompressed_accounts_only(
34 fee_payer: Pubkey,
35 packed_accounts: Vec<AccountMeta>,
36 ) -> Self {
37 Self {
38 fee_payer: Some(fee_payer),
39 sol_pool_pda: None,
40 sol_decompression_recipient: None,
41 cpi_context: None,
42 with_sol_pool: false,
43 decompressed_accounts_only: true,
44 packed_accounts: Some(packed_accounts),
45 }
46 }
47}
48
49pub fn get_transfer2_instruction_account_metas(
51 config: Transfer2AccountsMetaConfig,
52) -> Vec<AccountMeta> {
53 let default_pubkeys = TokenDefaultAccounts::default();
54 let packed_accounts_len = if let Some(packed_accounts) = config.packed_accounts.as_ref() {
55 packed_accounts.len()
56 } else {
57 0
58 };
59
60 let mut metas = Vec::with_capacity(10 + packed_accounts_len);
62 if !config.decompressed_accounts_only {
63 metas.push(AccountMeta::new_readonly(
64 Pubkey::new_from_array(LIGHT_SYSTEM_PROGRAM_ID),
65 false,
66 ));
67 if let Some(fee_payer) = config.fee_payer {
69 metas.push(AccountMeta::new(fee_payer, true));
70 }
71
72 metas.extend([
74 AccountMeta::new_readonly(Pubkey::new_from_array(CPI_AUTHORITY_PDA), false),
75 AccountMeta::new_readonly(default_pubkeys.registered_program_pda, false),
77 AccountMeta::new_readonly(default_pubkeys.account_compression_authority, false),
79 AccountMeta::new_readonly(default_pubkeys.account_compression_program, false),
81 ]);
82
83 metas.push(AccountMeta::new_readonly(
85 default_pubkeys.system_program,
86 false,
87 ));
88
89 if config.with_sol_pool {
91 if let Some(sol_pool_pda) = config.sol_pool_pda {
92 metas.push(AccountMeta::new(sol_pool_pda, false));
93 }
94 if let Some(sol_decompression_recipient) = config.sol_decompression_recipient {
95 metas.push(AccountMeta::new(sol_decompression_recipient, false));
96 }
97 }
98 if let Some(cpi_context) = config.cpi_context {
99 metas.push(AccountMeta::new(cpi_context, false));
100 }
101 } else if config.cpi_context.is_some() || config.with_sol_pool {
102 unimplemented!(
104 "config.cpi_context.is_some() {}, config.with_sol_pool {} must both be false",
105 config.cpi_context.is_some(),
106 config.with_sol_pool
107 );
108 } else {
109 metas.push(AccountMeta::new_readonly(
111 Pubkey::new_from_array(CPI_AUTHORITY_PDA),
112 false,
113 ));
114 if let Some(fee_payer) = config.fee_payer {
116 metas.push(AccountMeta::new(fee_payer, true));
117 }
118 }
119 if let Some(packed_accounts) = config.packed_accounts.as_ref() {
120 for account in packed_accounts {
121 metas.push(account.clone());
122 }
123 }
124
125 metas
126}