Skip to main content

light_token/instruction/
revoke.rs

1use light_sdk_types::LIGHT_TOKEN_PROGRAM_ID;
2use solana_account_info::AccountInfo;
3use solana_cpi::{invoke, invoke_signed};
4use solana_instruction::{AccountMeta, Instruction};
5use solana_program_error::ProgramError;
6use solana_pubkey::Pubkey;
7
8/// # Revoke delegation for a Light Token account:
9/// ```rust
10/// # use solana_pubkey::Pubkey;
11/// # use light_token::instruction::Revoke;
12/// # let token_account = Pubkey::new_unique();
13/// # let owner = Pubkey::new_unique();
14/// # let fee_payer = Pubkey::new_unique();
15/// let instruction = Revoke {
16///     token_account,
17///     owner,
18///     fee_payer,
19/// }.instruction()?;
20/// # Ok::<(), solana_program_error::ProgramError>(())
21/// ```
22pub struct Revoke {
23    /// Light Token account to revoke delegation for
24    pub token_account: Pubkey,
25    /// Owner of the Light Token account (readonly signer)
26    pub owner: Pubkey,
27    /// Fee payer for rent top-ups.
28    pub fee_payer: Pubkey,
29}
30
31/// # Revoke Light Token via CPI:
32/// ```rust,no_run
33/// # use light_token::instruction::RevokeCpi;
34/// # use solana_account_info::AccountInfo;
35/// # let token_account: AccountInfo = todo!();
36/// # let owner: AccountInfo = todo!();
37/// # let system_program: AccountInfo = todo!();
38/// # let fee_payer: AccountInfo = todo!();
39/// RevokeCpi {
40///     token_account,
41///     owner,
42///     system_program,
43///     fee_payer,
44/// }
45/// .invoke()?;
46/// # Ok::<(), solana_program_error::ProgramError>(())
47/// ```
48pub struct RevokeCpi<'info> {
49    pub token_account: AccountInfo<'info>,
50    pub owner: AccountInfo<'info>,
51    pub system_program: AccountInfo<'info>,
52    /// Fee payer for rent top-ups.
53    pub fee_payer: AccountInfo<'info>,
54}
55
56impl<'info> RevokeCpi<'info> {
57    pub fn instruction(&self) -> Result<Instruction, ProgramError> {
58        Revoke::from(self).instruction()
59    }
60
61    pub fn invoke(self) -> Result<(), ProgramError> {
62        let instruction = Revoke::from(&self).instruction()?;
63        let account_infos = [
64            self.token_account,
65            self.owner,
66            self.system_program,
67            self.fee_payer,
68        ];
69        invoke(&instruction, &account_infos)
70    }
71
72    pub fn invoke_signed(self, signer_seeds: &[&[&[u8]]]) -> Result<(), ProgramError> {
73        let instruction = Revoke::from(&self).instruction()?;
74        let account_infos = [
75            self.token_account,
76            self.owner,
77            self.system_program,
78            self.fee_payer,
79        ];
80        invoke_signed(&instruction, &account_infos, signer_seeds)
81    }
82}
83
84impl<'info> From<&RevokeCpi<'info>> for Revoke {
85    fn from(cpi: &RevokeCpi<'info>) -> Self {
86        Self {
87            token_account: *cpi.token_account.key,
88            owner: *cpi.owner.key,
89            fee_payer: *cpi.fee_payer.key,
90        }
91    }
92}
93
94impl Revoke {
95    pub fn instruction(self) -> Result<Instruction, ProgramError> {
96        Ok(Instruction {
97            program_id: Pubkey::from(LIGHT_TOKEN_PROGRAM_ID),
98            accounts: vec![
99                AccountMeta::new(self.token_account, false),
100                AccountMeta::new_readonly(self.owner, true),
101                AccountMeta::new_readonly(Pubkey::default(), false),
102                AccountMeta::new(self.fee_payer, true),
103            ],
104            data: vec![5u8], // CTokenRevoke discriminator
105        })
106    }
107}