| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- use core::slice::from_raw_parts;
- use pinocchio::{
- account_info::AccountInfo,
- instruction::{AccountMeta, Instruction, Signer},
- program::invoke_signed,
- pubkey::Pubkey,
- ProgramResult,
- };
- use crate::{write_bytes, UNINIT_BYTE};
- /// Transfer Tokens from one Token Account to another.
- ///
- /// ### Accounts:
- /// 0. `[WRITE]` The source account.
- /// 1. `[]` The token mint.
- /// 2. `[WRITE]` The destination account.
- /// 3. `[SIGNER]` The source account's owner/delegate.
- pub struct TransferChecked<'a, 'b> {
- /// Sender account.
- pub from: &'a AccountInfo,
- /// Mint Account
- pub mint: &'a AccountInfo,
- /// Recipient account.
- pub to: &'a AccountInfo,
- /// Authority account.
- pub authority: &'a AccountInfo,
- /// Amount of micro-tokens to transfer.
- pub amount: u64,
- /// Decimal for the Token
- pub decimals: u8,
- /// Token Program
- pub token_program: &'b Pubkey,
- }
- impl TransferChecked<'_, '_> {
- #[inline(always)]
- pub fn invoke(&self) -> ProgramResult {
- self.invoke_signed(&[])
- }
- #[inline(always)]
- pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
- // account metadata
- let account_metas: [AccountMeta; 4] = [
- AccountMeta::writable(self.from.key()),
- AccountMeta::readonly(self.mint.key()),
- AccountMeta::writable(self.to.key()),
- AccountMeta::readonly_signer(self.authority.key()),
- ];
- // Instruction data layout:
- // - [0]: instruction discriminator (1 byte, u8)
- // - [1..9]: amount (8 bytes, u64)
- // - [9]: decimals (1 byte, u8)
- let mut instruction_data = [UNINIT_BYTE; 10];
- // Set discriminator as u8 at offset [0]
- write_bytes(&mut instruction_data, &[12]);
- // Set amount as u64 at offset [1..9]
- write_bytes(&mut instruction_data[1..9], &self.amount.to_le_bytes());
- // Set decimals as u8 at offset [9]
- write_bytes(&mut instruction_data[9..], &[self.decimals]);
- let instruction = Instruction {
- program_id: self.token_program,
- accounts: &account_metas,
- data: unsafe { from_raw_parts(instruction_data.as_ptr() as _, 10) },
- };
- invoke_signed(
- &instruction,
- &[self.from, self.mint, self.to, self.authority],
- signers,
- )
- }
- }
|