pinocchio_token/instructions/
initialize_mint_2.rs

1use core::slice::from_raw_parts;
2
3use solana_account_view::AccountView;
4use solana_address::Address;
5use solana_instruction_view::{cpi::invoke, InstructionAccount, InstructionView};
6use solana_program_error::ProgramResult;
7
8use crate::{write_bytes, UNINIT_BYTE};
9
10/// Initialize a new mint.
11///
12/// ### Accounts:
13///   0. `[WRITABLE]` Mint account
14pub struct InitializeMint2<'a> {
15    /// Mint Account.
16    pub mint: &'a AccountView,
17    /// Decimals.
18    pub decimals: u8,
19    /// Mint Authority.
20    pub mint_authority: &'a Address,
21    /// Freeze Authority.
22    pub freeze_authority: Option<&'a Address>,
23}
24
25impl InitializeMint2<'_> {
26    #[inline(always)]
27    pub fn invoke(&self) -> ProgramResult {
28        // Instruction accounts
29        let instruction_accounts: [InstructionAccount; 1] =
30            [InstructionAccount::writable(self.mint.address())];
31
32        // Instruction data layout:
33        // -  [0]: instruction discriminator (1 byte, u8)
34        // -  [1]: decimals (1 byte, u8)
35        // -  [2..34]: mint_authority (32 bytes, Address)
36        // -  [34]: freeze_authority presence flag (1 byte, u8)
37        // -  [35..67]: freeze_authority (optional, 32 bytes, Address)
38        let mut instruction_data = [UNINIT_BYTE; 67];
39        let mut length = instruction_data.len();
40
41        // Set discriminator as u8 at offset [0]
42        write_bytes(&mut instruction_data, &[20]);
43        // Set decimals as u8 at offset [1]
44        write_bytes(&mut instruction_data[1..2], &[self.decimals]);
45        // Set mint_authority as Address at offset [2..34]
46        write_bytes(&mut instruction_data[2..34], self.mint_authority.as_array());
47
48        if let Some(freeze_auth) = self.freeze_authority {
49            // Set Option = `true` & freeze_authority at offset [34..67]
50            write_bytes(&mut instruction_data[34..35], &[1]);
51            write_bytes(&mut instruction_data[35..], freeze_auth.as_array());
52        } else {
53            // Set Option = `false`
54            write_bytes(&mut instruction_data[34..35], &[0]);
55            // Adjust length if no freeze authority
56            length = 35;
57        }
58
59        let instruction = InstructionView {
60            program_id: &crate::ID,
61            accounts: &instruction_accounts,
62            data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, length) },
63        };
64
65        invoke(&instruction, &[self.mint])
66    }
67}