pinocchio_token/instructions/
transfer_checked.rs1use core::slice::from_raw_parts;
2
3use pinocchio::{
4 account_info::AccountInfo,
5 instruction::{AccountMeta, Instruction, Signer},
6 program::invoke_signed,
7 ProgramResult,
8};
9
10use crate::{write_bytes, UNINIT_BYTE};
11
12pub struct TransferChecked<'a> {
20 pub from: &'a AccountInfo,
22 pub mint: &'a AccountInfo,
24 pub to: &'a AccountInfo,
26 pub authority: &'a AccountInfo,
28 pub amount: u64,
30 pub decimals: u8,
32}
33
34impl TransferChecked<'_> {
35 #[inline(always)]
36 pub fn invoke(&self) -> ProgramResult {
37 self.invoke_signed(&[])
38 }
39
40 pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
41 let account_metas: [AccountMeta; 4] = [
43 AccountMeta::writable(self.from.key()),
44 AccountMeta::readonly(self.mint.key()),
45 AccountMeta::writable(self.to.key()),
46 AccountMeta::readonly_signer(self.authority.key()),
47 ];
48
49 let mut instruction_data = [UNINIT_BYTE; 10];
54
55 write_bytes(&mut instruction_data, &[12]);
57 write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes());
59 write_bytes(&mut instruction_data[9..], &[self.decimals]);
61
62 let instruction = Instruction {
63 program_id: &crate::ID,
64 accounts: &account_metas,
65 data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) },
66 };
67
68 invoke_signed(
69 &instruction,
70 &[self.from, self.mint, self.to, self.authority],
71 signers,
72 )
73 }
74}