pinocchio_token/instructions/
mint_to_checked.rs

1use core::slice::from_raw_parts;
2
3use solana_account_view::AccountView;
4use solana_instruction_view::{
5    cpi::{invoke_signed, Signer},
6    InstructionAccount, InstructionView,
7};
8use solana_program_error::ProgramResult;
9
10use crate::{write_bytes, UNINIT_BYTE};
11
12/// Mints new tokens to an account.
13///
14/// ### Accounts:
15///   0. `[WRITE]` The mint.
16///   1. `[WRITE]` The account to mint tokens to.
17///   2. `[SIGNER]` The mint's minting authority.
18pub struct MintToChecked<'a> {
19    /// Mint Account.
20    pub mint: &'a AccountView,
21    /// Token Account.
22    pub account: &'a AccountView,
23    /// Mint Authority
24    pub mint_authority: &'a AccountView,
25    /// Amount
26    pub amount: u64,
27    /// Decimals
28    pub decimals: u8,
29}
30
31impl MintToChecked<'_> {
32    #[inline(always)]
33    pub fn invoke(&self) -> ProgramResult {
34        self.invoke_signed(&[])
35    }
36
37    #[inline(always)]
38    pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
39        // Instruction accounts
40        let instruction_accounts: [InstructionAccount; 3] = [
41            InstructionAccount::writable(self.mint.address()),
42            InstructionAccount::writable(self.account.address()),
43            InstructionAccount::readonly_signer(self.mint_authority.address()),
44        ];
45
46        // Instruction data layout:
47        // -  [0]: instruction discriminator (1 byte, u8)
48        // -  [1..9]: amount (8 bytes, u64)
49        // -  [9]: decimals (1 byte, u8)
50        let mut instruction_data = [UNINIT_BYTE; 10];
51
52        // Set discriminator as u8 at offset [0]
53        write_bytes(&mut instruction_data, &[14]);
54        // Set amount as u64 at offset [1..9]
55        write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes());
56        // Set decimals as u8 at offset [9]
57        write_bytes(&mut instruction_data[9..], &[self.decimals]);
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 _, 10) },
63        };
64
65        invoke_signed(
66            &instruction,
67            &[self.mint, self.account, self.mint_authority],
68            signers,
69        )
70    }
71}