light_compressed_token/instructions/
transfer.rs

1use account_compression::program::AccountCompression;
2use anchor_lang::prelude::*;
3use anchor_spl::token_interface::{TokenAccount, TokenInterface};
4use light_system_program::{
5    self,
6    account_traits::{InvokeAccounts, SignerAccounts},
7    program::LightSystemProgram,
8};
9
10use crate::program::LightCompressedToken;
11
12#[derive(Accounts)]
13pub struct TransferInstruction<'info> {
14    /// UNCHECKED: only pays fees.
15    #[account(mut)]
16    pub fee_payer: Signer<'info>,
17    /// CHECK:
18    /// Authority is verified through proof since both owner and delegate
19    /// are included in the token data hash, which is a public input to the
20    /// validity proof.
21    pub authority: Signer<'info>,
22    /// CHECK: (seed constraint in cpi).
23    pub cpi_authority_pda: UncheckedAccount<'info>,
24    pub light_system_program: Program<'info, LightSystemProgram>,
25    /// CHECK: (account compression program).
26    pub registered_program_pda: AccountInfo<'info>,
27    /// CHECK: (account compression program) when emitting event.
28    pub noop_program: UncheckedAccount<'info>,
29    /// CHECK: (different program) is used to cpi account compression program from light system program.
30    pub account_compression_authority: UncheckedAccount<'info>,
31    pub account_compression_program: Program<'info, AccountCompression>,
32    /// CHECK:(system program) used to derive cpi_authority_pda and check that
33    /// this program is the signer of the cpi.
34    pub self_program: Program<'info, LightCompressedToken>,
35    #[account(mut)]
36    pub token_pool_pda: Option<InterfaceAccount<'info, TokenAccount>>,
37    #[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)]
38    pub compress_or_decompress_token_account: Option<InterfaceAccount<'info, TokenAccount>>,
39    pub token_program: Option<Interface<'info, TokenInterface>>,
40    pub system_program: Program<'info, System>,
41}
42
43// TODO: transform all to account info
44impl<'info> InvokeAccounts<'info> for TransferInstruction<'info> {
45    fn get_registered_program_pda(&self) -> &AccountInfo<'info> {
46        &self.registered_program_pda
47    }
48
49    fn get_noop_program(&self) -> &UncheckedAccount<'info> {
50        &self.noop_program
51    }
52
53    fn get_account_compression_authority(&self) -> &UncheckedAccount<'info> {
54        &self.account_compression_authority
55    }
56
57    fn get_account_compression_program(&self) -> &Program<'info, AccountCompression> {
58        &self.account_compression_program
59    }
60
61    fn get_system_program(&self) -> &Program<'info, System> {
62        &self.system_program
63    }
64
65    fn get_sol_pool_pda(&self) -> Option<&AccountInfo<'info>> {
66        None
67    }
68
69    fn get_decompression_recipient(&self) -> Option<&AccountInfo<'info>> {
70        None
71    }
72}
73
74impl<'info> SignerAccounts<'info> for TransferInstruction<'info> {
75    fn get_fee_payer(&self) -> &Signer<'info> {
76        &self.fee_payer
77    }
78
79    fn get_authority(&self) -> &Signer<'info> {
80        &self.authority
81    }
82}