0

I'm newest here and i would like to do transfer USDC from defined wallet to defined another wallet. From account could be Signer account. I'm really confused and i don't know what should i do. With my knowledge i guess i should transfer wallet adress to ATA.

I'm running these Anchor funtction on Next.JS & TSX. I have no problem with transfering solana from to destinate but i couldn't understand how can i do for USDC.

Here is my example code for transferin solana from to other.

    system_program::transfer(
        CpiContext::new(
            ctx.accounts.system_program.to_account_info(),
            system_program::Transfer {
                from: ctx.accounts.authority.to_account_info(),
                to: contract_account.to_account_info(),
            },
        ),


    Ok(())

I would like to do same thing for USDC. I made this function basicly for get money from signer to Account PDA and after contract has been done. I transfer money like that to who will get money:

        **ctx
        .accounts
        .moneyto
        .to_account_info()
        .try_borrow_mut_lamports()? += ctx.accounts.contract_account.price;

Thank you so much !

1

1 Answer 1

1

It's a bit more complicated for SPL token, since, you need the source and destination token accounts, along with an authority (or owner) on the source token account.

Copying the example at https://github.com/solana-labs/solana-program-library/blob/master/examples/rust/transfer-tokens/src/processor.rs, and assuming you receive all the proper accounts, you would do:

use {
    solana_program::{
        account_info::{next_account_info, AccountInfo},
        entrypoint::ProgramResult,
        msg,
        program::invoke,
        program_error::ProgramError,
        program_pack::Pack,
        pubkey::Pubkey,
    },
    spl_token::{
        instruction::transfer_checked,
        state::{Account, Mint},
    },
};

/// Instruction processor
pub fn process_instruction(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    _instruction_data: &[u8],
) -> ProgramResult {
    // Create an iterator to safely reference accounts in the slice
    let account_info_iter = &mut accounts.iter();

    // As part of the program specification the instruction gives:
    let source_info = next_account_info(account_info_iter)?; // 1.
    let mint_info = next_account_info(account_info_iter)?; // 2.
    let destination_info = next_account_info(account_info_iter)?; // 3.
    let authority_info = next_account_info(account_info_iter)?; // 4.
    let token_program_info = next_account_info(account_info_iter)?; // 5.

    // The program transfers everything out of its account, so extract that from
    // the account data.
    let source_account = Account::unpack(&source_info.try_borrow_data()?)?;
    let amount = source_account.amount;

    // The program uses `transfer_checked`, which requires the number of decimals
    // in the mint, so extract that from the account data too.
    let mint = Mint::unpack(&mint_info.try_borrow_data()?)?;
    let decimals = mint.decimals;

    // Invoke the transfer
    msg!("Attempting to transfer {} tokens", amount);
    invoke(
        &transfer_checked(
            token_program_info.key,
            source_info.key,
            mint_info.key,
            destination_info.key,
            authority_info.key,
            &[], // no multisig allowed
            amount,
            decimals,
        )
        .unwrap(),
        &[
            source_info.clone(),
            mint_info.clone(),
            destination_info.clone(),
            authority_info.clone(),
            token_program_info.clone(), // not required, but better for clarity
        ],
    )
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.