tensor_toolbox/token_2022/
transfer.rs

1//! Transfer CPI for SPL Token 2022 that requires remaining accounts to be passed.
2//!
3//! This is a workaround for the current limitation of the Anchor framework.
4
5use anchor_lang::{
6    context::CpiContext,
7    solana_program::{instruction::AccountMeta, program::invoke_signed},
8    Result,
9};
10use anchor_spl::token_interface::{spl_token_2022, TransferChecked};
11
12pub fn transfer_checked<'info>(
13    ctx: CpiContext<'_, '_, '_, 'info, TransferChecked<'info>>,
14    amount: u64,
15    decimals: u8,
16) -> Result<()> {
17    let mut ix = spl_token_2022::instruction::transfer_checked(
18        ctx.program.key,
19        ctx.accounts.from.key,
20        ctx.accounts.mint.key,
21        ctx.accounts.to.key,
22        ctx.accounts.authority.key,
23        &[],
24        amount,
25        decimals,
26    )?;
27
28    let (from, mint, to, authority, remaining) = (
29        ctx.accounts.from,
30        ctx.accounts.mint,
31        ctx.accounts.to,
32        ctx.accounts.authority,
33        ctx.remaining_accounts,
34    );
35
36    let mut accounts = vec![from, mint, to, authority];
37
38    remaining.into_iter().for_each(|account| {
39        ix.accounts.push(AccountMeta {
40            pubkey: *account.key,
41            is_signer: account.is_signer,
42            is_writable: account.is_writable,
43        });
44        accounts.push(account);
45    });
46
47    invoke_signed(&ix, &accounts, ctx.signer_seeds).map_err(Into::into)
48}