use account_compression::{program::AccountCompression, utils::constants::CPI_AUTHORITY_PDA_SEED};
use anchor_lang::prelude::*;
use anchor_spl::token::{Token, TokenAccount};
use light_system_program::{
self,
program::LightSystemProgram,
sdk::accounts::{InvokeAccounts, SignerAccounts},
};
use crate::program::LightCompressedToken;
#[derive(Accounts)]
pub struct TransferInstruction<'info> {
#[account(mut)]
pub fee_payer: Signer<'info>,
pub authority: Signer<'info>,
#[account(seeds = [CPI_AUTHORITY_PDA_SEED], bump,)]
pub cpi_authority_pda: UncheckedAccount<'info>,
pub light_system_program: Program<'info, LightSystemProgram>,
pub registered_program_pda: AccountInfo<'info>,
pub noop_program: UncheckedAccount<'info>,
pub account_compression_authority: UncheckedAccount<'info>,
pub account_compression_program: Program<'info, AccountCompression>,
pub self_program: Program<'info, LightCompressedToken>,
#[account(mut)]
pub token_pool_pda: Option<Account<'info, TokenAccount>>,
#[account(mut, constraint= if token_pool_pda.is_some() {Ok(token_pool_pda.as_ref().unwrap().key() != compress_or_decompress_token_account.key())}else {err!(crate::ErrorCode::TokenPoolPdaUndefined)}? @crate::ErrorCode::IsTokenPoolPda)]
pub compress_or_decompress_token_account: Option<Account<'info, TokenAccount>>,
pub token_program: Option<Program<'info, Token>>,
pub system_program: Program<'info, System>,
}
impl<'info> InvokeAccounts<'info> for TransferInstruction<'info> {
fn get_registered_program_pda(&self) -> &AccountInfo<'info> {
&self.registered_program_pda
}
fn get_noop_program(&self) -> &UncheckedAccount<'info> {
&self.noop_program
}
fn get_account_compression_authority(&self) -> &UncheckedAccount<'info> {
&self.account_compression_authority
}
fn get_account_compression_program(&self) -> &Program<'info, AccountCompression> {
&self.account_compression_program
}
fn get_system_program(&self) -> &Program<'info, System> {
&self.system_program
}
fn get_sol_pool_pda(&self) -> Option<&AccountInfo<'info>> {
None
}
fn get_decompression_recipient(&self) -> Option<&AccountInfo<'info>> {
None
}
}
impl<'info> SignerAccounts<'info> for TransferInstruction<'info> {
fn get_fee_payer(&self) -> &Signer<'info> {
&self.fee_payer
}
fn get_authority(&self) -> &Signer<'info> {
&self.authority
}
}