use solana_instruction::AccountMeta;
use solana_pubkey::Pubkey;
use crate::utils::TokenDefaultAccounts;
#[derive(Debug, Default, Copy, Clone)]
pub struct TokenAccountsMetaConfig {
pub fee_payer: Option<Pubkey>,
pub authority: Option<Pubkey>,
pub spl_interface_pda: Option<Pubkey>,
pub compress_or_decompress_token_account: Option<Pubkey>,
pub token_program: Option<Pubkey>,
pub is_compress: bool,
pub is_decompress: bool,
pub with_anchor_none: bool,
}
impl TokenAccountsMetaConfig {
pub fn new(fee_payer: Pubkey, authority: Pubkey) -> Self {
Self {
fee_payer: Some(fee_payer),
authority: Some(authority),
spl_interface_pda: None,
compress_or_decompress_token_account: None,
token_program: None,
is_compress: false,
is_decompress: false,
with_anchor_none: false,
}
}
pub fn new_client() -> Self {
Self {
fee_payer: None,
authority: None,
spl_interface_pda: None,
compress_or_decompress_token_account: None,
token_program: None,
is_compress: false,
is_decompress: false,
with_anchor_none: false,
}
}
pub fn new_with_anchor_none() -> Self {
Self {
fee_payer: None,
authority: None,
spl_interface_pda: None,
compress_or_decompress_token_account: None,
token_program: None,
is_compress: false,
is_decompress: false,
with_anchor_none: true,
}
}
pub fn compress(
fee_payer: Pubkey,
authority: Pubkey,
spl_interface_pda: Pubkey,
sender_token_account: Pubkey,
spl_program_id: Pubkey,
) -> Self {
Self {
fee_payer: Some(fee_payer),
authority: Some(authority),
spl_interface_pda: Some(spl_interface_pda),
compress_or_decompress_token_account: Some(sender_token_account),
token_program: Some(spl_program_id),
is_compress: true,
is_decompress: false,
with_anchor_none: false,
}
}
pub fn compress_client(
spl_interface_pda: Pubkey,
sender_token_account: Pubkey,
spl_program_id: Pubkey,
) -> Self {
Self {
fee_payer: None,
authority: None,
spl_interface_pda: Some(spl_interface_pda),
compress_or_decompress_token_account: Some(sender_token_account),
token_program: Some(spl_program_id),
is_compress: true,
is_decompress: false,
with_anchor_none: false,
}
}
pub fn decompress(
fee_payer: Pubkey,
authority: Pubkey,
spl_interface_pda: Pubkey,
recipient_token_account: Pubkey,
spl_program_id: Pubkey,
) -> Self {
Self {
fee_payer: Some(fee_payer),
authority: Some(authority),
spl_interface_pda: Some(spl_interface_pda),
compress_or_decompress_token_account: Some(recipient_token_account),
token_program: Some(spl_program_id),
is_compress: false,
is_decompress: true,
with_anchor_none: false,
}
}
pub fn decompress_client(
spl_interface_pda: Pubkey,
recipient_token_account: Pubkey,
spl_program_id: Pubkey,
) -> Self {
Self {
fee_payer: None,
authority: None,
spl_interface_pda: Some(spl_interface_pda),
compress_or_decompress_token_account: Some(recipient_token_account),
token_program: Some(spl_program_id),
is_compress: false,
is_decompress: true,
with_anchor_none: false,
}
}
pub fn is_compress_or_decompress(&self) -> bool {
self.is_compress || self.is_decompress
}
}
pub fn get_transfer_instruction_account_metas(config: TokenAccountsMetaConfig) -> Vec<AccountMeta> {
let default_pubkeys = TokenDefaultAccounts::default();
let mut metas = if let Some(fee_payer) = config.fee_payer {
let authority = if let Some(authority) = config.authority {
authority
} else {
panic!("Missing authority");
};
vec![
AccountMeta::new(fee_payer, true),
AccountMeta::new_readonly(authority, true),
AccountMeta::new_readonly(default_pubkeys.cpi_authority_pda, false),
AccountMeta::new_readonly(default_pubkeys.light_system_program, false),
AccountMeta::new_readonly(default_pubkeys.registered_program_pda, false),
AccountMeta::new_readonly(default_pubkeys.noop_program, false),
AccountMeta::new_readonly(default_pubkeys.account_compression_authority, false),
AccountMeta::new_readonly(default_pubkeys.account_compression_program, false),
AccountMeta::new_readonly(default_pubkeys.self_program, false),
]
} else {
vec![
AccountMeta::new_readonly(default_pubkeys.cpi_authority_pda, false),
AccountMeta::new_readonly(default_pubkeys.light_system_program, false),
AccountMeta::new_readonly(default_pubkeys.registered_program_pda, false),
AccountMeta::new_readonly(default_pubkeys.noop_program, false),
AccountMeta::new_readonly(default_pubkeys.account_compression_authority, false),
AccountMeta::new_readonly(default_pubkeys.account_compression_program, false),
AccountMeta::new_readonly(default_pubkeys.self_program, false),
]
};
if let Some(spl_interface_pda) = config.spl_interface_pda {
metas.push(AccountMeta::new(spl_interface_pda, false));
} else if config.fee_payer.is_some() || config.with_anchor_none {
metas.push(AccountMeta::new_readonly(
default_pubkeys.compressed_token_program,
false,
));
}
println!("config.with_anchor_none {}", config.with_anchor_none);
if let Some(token_account) = config.compress_or_decompress_token_account {
metas.push(AccountMeta::new(token_account, false));
} else if config.fee_payer.is_some() || config.with_anchor_none {
metas.push(AccountMeta::new_readonly(
default_pubkeys.compressed_token_program,
false,
));
}
if let Some(token_program) = config.token_program {
metas.push(AccountMeta::new_readonly(token_program, false));
} else if config.fee_payer.is_some() || config.with_anchor_none {
metas.push(AccountMeta::new_readonly(
default_pubkeys.compressed_token_program,
false,
));
}
metas.push(AccountMeta::new_readonly(
default_pubkeys.system_program,
false,
));
metas
}