spl_token_2022/extension/cpi_guard/
instruction.rs

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