token_acl/instructions/
set_gating_program.rs1use 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}