Skip to main content

token_acl/instructions/
set_gating_program.rs

1use solana_program::{account_info::AccountInfo, pubkey::Pubkey};
2use solana_program_error::{ProgramError, ProgramResult};
3
4use crate::{error::TokenAclError, state::load_mint_config_mut};
5
6pub struct SetGatingProgram<'a> {
7    pub authority: &'a AccountInfo<'a>,
8    pub mint_config: &'a AccountInfo<'a>,
9}
10
11impl SetGatingProgram<'_> {
12    pub const DISCRIMINATOR: u8 = 2;
13
14    pub fn process(&self, remaining_data: &[u8]) -> ProgramResult {
15        if remaining_data.len() != 32 {
16            return Err(ProgramError::InvalidInstructionData);
17        }
18        let new_gating_program =
19            Pubkey::try_from(remaining_data).map_err(|_| ProgramError::InvalidInstructionData)?;
20
21        let data = &mut self.mint_config.data.borrow_mut();
22        let config = load_mint_config_mut(data)?;
23
24        if config.freeze_authority != *self.authority.key {
25            return Err(TokenAclError::InvalidAuthority.into());
26        }
27
28        config.gating_program = new_gating_program;
29
30        Ok(())
31    }
32}
33
34impl<'a> TryFrom<&'a [AccountInfo<'a>]> for SetGatingProgram<'a> {
35    type Error = ProgramError;
36
37    fn try_from(accounts: &'a [AccountInfo<'a>]) -> Result<Self, Self::Error> {
38        let [authority, mint_config] = &accounts else {
39            return Err(ProgramError::InvalidInstructionData);
40        };
41
42        if !authority.is_signer {
43            return Err(TokenAclError::InvalidAuthority.into());
44        }
45
46        Ok(Self {
47            authority,
48            mint_config,
49        })
50    }
51}