safe_token_2022/extension/default_account_state/
instruction.rs1use {
2 crate::{
3 check_program_account, error::TokenError, instruction::TokenInstruction,
4 state::AccountState,
5 },
6 num_enum::{IntoPrimitive, TryFromPrimitive},
7 solana_program::{
8 instruction::{AccountMeta, Instruction},
9 program_error::ProgramError,
10 pubkey::Pubkey,
11 },
12 std::convert::TryFrom,
13};
14
15#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
17#[repr(u8)]
18pub enum DefaultAccountStateInstruction {
19 Initialize,
36 Update,
54}
55
56pub fn decode_instruction(
58 input: &[u8],
59) -> Result<(DefaultAccountStateInstruction, AccountState), ProgramError> {
60 if input.len() != 2 {
61 return Err(TokenError::InvalidInstruction.into());
62 }
63 Ok((
64 DefaultAccountStateInstruction::try_from(input[0])
65 .or(Err(TokenError::InvalidInstruction))?,
66 AccountState::try_from(input[1]).or(Err(TokenError::InvalidInstruction))?,
67 ))
68}
69
70fn encode_instruction(
71 token_program_id: &Pubkey,
72 accounts: Vec<AccountMeta>,
73 instruction_type: DefaultAccountStateInstruction,
74 state: &AccountState,
75) -> Instruction {
76 let mut data = TokenInstruction::DefaultAccountStateExtension.pack();
77 data.push(instruction_type.into());
78 data.push((*state).into());
79 Instruction {
80 program_id: *token_program_id,
81 accounts,
82 data,
83 }
84}
85
86pub fn initialize_default_account_state(
88 token_program_id: &Pubkey,
89 mint: &Pubkey,
90 state: &AccountState,
91) -> Result<Instruction, ProgramError> {
92 check_program_account(token_program_id)?;
93 let accounts = vec![AccountMeta::new(*mint, false)];
94 Ok(encode_instruction(
95 token_program_id,
96 accounts,
97 DefaultAccountStateInstruction::Initialize,
98 state,
99 ))
100}
101
102pub fn update_default_account_state(
104 token_program_id: &Pubkey,
105 mint: &Pubkey,
106 freeze_authority: &Pubkey,
107 signers: &[&Pubkey],
108 state: &AccountState,
109) -> Result<Instruction, ProgramError> {
110 check_program_account(token_program_id)?;
111 let mut accounts = vec![
112 AccountMeta::new(*mint, false),
113 AccountMeta::new_readonly(*freeze_authority, signers.is_empty()),
114 ];
115 for signer_pubkey in signers.iter() {
116 accounts.push(AccountMeta::new_readonly(**signer_pubkey, true));
117 }
118 Ok(encode_instruction(
119 token_program_id,
120 accounts,
121 DefaultAccountStateInstruction::Update,
122 state,
123 ))
124}