spl_token_2022_interface/extension/cpi_guard/
instruction.rs

1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3use {
4    crate::{
5        check_program_account,
6        instruction::{encode_instruction, TokenInstruction},
7    },
8    num_enum::{IntoPrimitive, TryFromPrimitive},
9    solana_instruction::{AccountMeta, Instruction},
10    solana_program_error::ProgramError,
11    solana_pubkey::Pubkey,
12};
13
14/// CPI Guard extension instructions
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
17#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
18#[repr(u8)]
19pub enum CpiGuardInstruction {
20    /// Lock certain token operations from taking place within CPI for this
21    /// Account, namely:
22    /// * `Transfer` and `Burn` must go through a delegate.
23    /// * `CloseAccount` can only return lamports to owner.
24    /// * `SetAuthority` can only be used to remove an existing close authority.
25    /// * `Approve` is disallowed entirely.
26    ///
27    /// In addition, CPI Guard cannot be enabled or disabled via CPI.
28    ///
29    /// Accounts expected by this instruction:
30    ///
31    ///   0. `[writable]` The account to update.
32    ///   1. `[signer]` The account's owner.
33    ///
34    ///   * Multisignature authority
35    ///   0. `[writable]` The account to update.
36    ///   1. `[]` The account's multisignature owner.
37    ///   2. `..2+M` `[signer]` M signer accounts.
38    Enable,
39    /// Allow all token operations to happen via CPI as normal.
40    ///
41    /// Implicitly initializes the extension in the case where it is not
42    /// present.
43    ///
44    /// Accounts expected by this instruction:
45    ///
46    ///   0. `[writable]` The account to update.
47    ///   1. `[signer]` The account's owner.
48    ///
49    ///   * Multisignature authority
50    ///   0. `[writable]` The account to update.
51    ///   1. `[]`  The account's multisignature owner.
52    ///   2. `..2+M` `[signer]` M signer accounts.
53    Disable,
54}
55
56/// Create an `Enable` instruction
57pub fn enable_cpi_guard(
58    token_program_id: &Pubkey,
59    account: &Pubkey,
60    owner: &Pubkey,
61    signers: &[&Pubkey],
62) -> Result<Instruction, ProgramError> {
63    check_program_account(token_program_id)?;
64    let mut accounts = vec![
65        AccountMeta::new(*account, false),
66        AccountMeta::new_readonly(*owner, signers.is_empty()),
67    ];
68    for signer_pubkey in signers.iter() {
69        accounts.push(AccountMeta::new_readonly(**signer_pubkey, true));
70    }
71    Ok(encode_instruction(
72        token_program_id,
73        accounts,
74        TokenInstruction::CpiGuardExtension,
75        CpiGuardInstruction::Enable,
76        &(),
77    ))
78}
79
80/// Create a `Disable` instruction
81pub fn disable_cpi_guard(
82    token_program_id: &Pubkey,
83    account: &Pubkey,
84    owner: &Pubkey,
85    signers: &[&Pubkey],
86) -> Result<Instruction, ProgramError> {
87    check_program_account(token_program_id)?;
88    let mut accounts = vec![
89        AccountMeta::new(*account, false),
90        AccountMeta::new_readonly(*owner, signers.is_empty()),
91    ];
92    for signer_pubkey in signers.iter() {
93        accounts.push(AccountMeta::new_readonly(**signer_pubkey, true));
94    }
95    Ok(encode_instruction(
96        token_program_id,
97        accounts,
98        TokenInstruction::CpiGuardExtension,
99        CpiGuardInstruction::Disable,
100        &(),
101    ))
102}