Skip to main content

token_acl_interface/
instruction.rs

1use solana_instruction::{AccountMeta, Instruction};
2use solana_program_error::ProgramError;
3use solana_pubkey::Pubkey;
4use spl_discriminator::{ArrayDiscriminator, SplDiscriminate};
5
6pub enum EfficientBlockAllowInstruction {
7    CanThawPermissionless,
8    CanFreezePermissionless,
9}
10
11#[derive(SplDiscriminate)]
12#[discriminator_hash_input("efficient-allow-block-list-standard:can-thaw-permissionless")]
13pub struct CanThawPermissionlessInstruction;
14
15#[derive(SplDiscriminate)]
16#[discriminator_hash_input("efficient-allow-block-list-standard:can-freeze-permissionless")]
17pub struct CanFreezePermissionlessInstruction;
18
19impl EfficientBlockAllowInstruction {
20    pub fn unpack(data: &[u8]) -> Result<Self, ProgramError> {
21        if data.len() < ArrayDiscriminator::LENGTH {
22            return Err(ProgramError::InvalidInstructionData);
23        }
24        let (discriminator, _) = data.split_at(ArrayDiscriminator::LENGTH);
25        match discriminator {
26            CanThawPermissionlessInstruction::SPL_DISCRIMINATOR_SLICE => {
27                Ok(Self::CanThawPermissionless)
28            }
29            CanFreezePermissionlessInstruction::SPL_DISCRIMINATOR_SLICE => {
30                Ok(Self::CanFreezePermissionless)
31            }
32            _ => Err(ProgramError::InvalidInstructionData),
33        }
34    }
35
36    pub fn pack(&self) -> Vec<u8> {
37        match self {
38            Self::CanThawPermissionless => {
39                CanThawPermissionlessInstruction::SPL_DISCRIMINATOR_SLICE.to_vec()
40            }
41            Self::CanFreezePermissionless => {
42                CanFreezePermissionlessInstruction::SPL_DISCRIMINATOR_SLICE.to_vec()
43            }
44        }
45    }
46}
47
48pub fn can_thaw_permissionless(
49    program_id: &Pubkey,
50    signer: &Pubkey,
51    token_account: &Pubkey,
52    mint: &Pubkey,
53    token_account_owner: &Pubkey,
54    flag_account: &Pubkey,
55) -> Instruction {
56    let data = EfficientBlockAllowInstruction::CanThawPermissionless.pack();
57    let accounts = vec![
58        AccountMeta::new_readonly(*signer, false),
59        AccountMeta::new_readonly(*token_account, false),
60        AccountMeta::new_readonly(*mint, false),
61        AccountMeta::new_readonly(*token_account_owner, false),
62        AccountMeta::new_readonly(*flag_account, false),
63    ];
64
65    Instruction {
66        program_id: *program_id,
67        accounts,
68        data,
69    }
70}
71
72pub fn can_freeze_permissionless(
73    program_id: &Pubkey,
74    signer: &Pubkey,
75    token_account: &Pubkey,
76    mint: &Pubkey,
77    token_account_owner: &Pubkey,
78    flag_account: &Pubkey,
79) -> Instruction {
80    let data = EfficientBlockAllowInstruction::CanFreezePermissionless.pack();
81    let accounts = vec![
82        AccountMeta::new_readonly(*signer, false),
83        AccountMeta::new_readonly(*token_account, false),
84        AccountMeta::new_readonly(*mint, false),
85        AccountMeta::new_readonly(*token_account_owner, false),
86        AccountMeta::new_readonly(*flag_account, false),
87    ];
88
89    Instruction {
90        program_id: *program_id,
91        accounts,
92        data,
93    }
94}