spl_token_2022/extension/default_account_state/
processor.rs1use {
2 crate::processor::Processor,
3 solana_account_info::{next_account_info, AccountInfo},
4 solana_msg::msg,
5 solana_program_error::ProgramResult,
6 solana_pubkey::Pubkey,
7 spl_token_2022_interface::{
8 check_program_account,
9 error::TokenError,
10 extension::{
11 default_account_state::{
12 instruction::{decode_instruction, DefaultAccountStateInstruction},
13 DefaultAccountState,
14 },
15 BaseStateWithExtensionsMut, PodStateWithExtensionsMut,
16 },
17 pod::{PodCOption, PodMint},
18 state::AccountState,
19 },
20};
21
22fn check_valid_default_state(state: AccountState) -> ProgramResult {
23 match state {
24 AccountState::Uninitialized => Err(TokenError::InvalidState.into()),
25 _ => Ok(()),
26 }
27}
28
29fn process_initialize_default_account_state(
30 accounts: &[AccountInfo],
31 state: AccountState,
32) -> ProgramResult {
33 check_valid_default_state(state)?;
34 let account_info_iter = &mut accounts.iter();
35 let mint_account_info = next_account_info(account_info_iter)?;
36 let mut mint_data = mint_account_info.data.borrow_mut();
37 let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack_uninitialized(&mut mint_data)?;
38 let extension = mint.init_extension::<DefaultAccountState>(true)?;
39 extension.state = state.into();
40 Ok(())
41}
42
43fn process_update_default_account_state(
44 program_id: &Pubkey,
45 accounts: &[AccountInfo],
46 state: AccountState,
47) -> ProgramResult {
48 check_valid_default_state(state)?;
49 let account_info_iter = &mut accounts.iter();
50 let mint_account_info = next_account_info(account_info_iter)?;
51 let freeze_authority_info = next_account_info(account_info_iter)?;
52 let freeze_authority_info_data_len = freeze_authority_info.data_len();
53
54 let mut mint_data = mint_account_info.data.borrow_mut();
55 let mut mint = PodStateWithExtensionsMut::<PodMint>::unpack(&mut mint_data)?;
56
57 match &mint.base.freeze_authority {
58 PodCOption {
59 option: PodCOption::<Pubkey>::SOME,
60 value: freeze_authority,
61 } => Processor::validate_owner(
62 program_id,
63 freeze_authority,
64 freeze_authority_info,
65 freeze_authority_info_data_len,
66 account_info_iter.as_slice(),
67 ),
68 _ => Err(TokenError::NoAuthorityExists.into()),
69 }?;
70
71 let extension = mint.get_extension_mut::<DefaultAccountState>()?;
72 extension.state = state.into();
73 Ok(())
74}
75
76pub(crate) fn process_instruction(
77 program_id: &Pubkey,
78 accounts: &[AccountInfo],
79 input: &[u8],
80) -> ProgramResult {
81 check_program_account(program_id)?;
82
83 let (instruction, state) = decode_instruction(input)?;
84 match instruction {
85 DefaultAccountStateInstruction::Initialize => {
86 msg!("DefaultAccountStateInstruction::Initialize");
87 process_initialize_default_account_state(accounts, state)
88 }
89 DefaultAccountStateInstruction::Update => {
90 msg!("DefaultAccountStateInstruction::Update");
91 process_update_default_account_state(program_id, accounts, state)
92 }
93 }
94}