'How to transfer SOL in anchor smart contract instruction

I am creating a dapp where multiple users can deposit SOL into an event account, and depending on whoever wins the event, they can redeem SOL back to their wallet.

How can I transfer native SOL (not any other spl-token) directly into the event account's vault address in an anchor smart contract instruction?

Would the following anchor instruction work? If yes, what should be the PROGRAM_ACCOUNT in the following? Presumably, it should be the account that handles native SOL, but I couldn't find it in the documentation.

token::transfer(
    CpiContext::new(
        PROGRAM_ACCOUNT,
        anchor_spl::token::Transfer {
            from: source_user_info,
            to: destination_user_info,
            authority: source_user_info,
        },
    ),
    1,
)?; 

Thanks in advance!



Solution 1:[1]

To send native SOL using Anchor, you can use the following code inside an instruction:

    let ix = anchor_lang::solana_program::system_instruction::transfer(
        &ctx.accounts.from.key(),
        &ctx.accounts.to.key(),
        amount,
    );
    anchor_lang::solana_program::program::invoke(
        &ix,
        &[
            ctx.accounts.from.to_account_info(),
            ctx.accounts.to.to_account_info(),
        ],
    );

Where amount is a number (u64) representing the Lamports (0.000000001 SOL).

You can check the Transfer function in the Solana Program documentation and the Solana Cookbook section of Sending SOL.

Solution 2:[2]

You have to do something like this

let lamports: u64  = 1000000;

let sol_transfer = anchor_lang::solana_program::system_instruction::transfer(
    &ctx.accounts.from.key,
    &ctx.accounts.to.key,
    lamports,
);
invoke(
    &sol_transfer,
    &[
        ctx.accounts.from.clone(),
        ctx.accounts.to.clone(),
        ctx.accounts.system_program.clone(),
    ],
)?;

Also, make sure to pass system_program to your program. For example

 #[derive(Accounts)]
pub struct SolSend<'info> {
    #[account(mut, signer)]
    /// CHECK: This is not dangerous because we don't read or write from this account
    pub from: AccountInfo<'info>,       
    /// CHECK: This is not dangerous because we don't read or write from this account
    #[account(mut)]
    pub to: AccountInfo<'info>,        
    /// CHECK: This is not dangerous because we don't read or write from this account
    pub system_program: AccountInfo<'info>,
}

Hope this helps.

Solution 3:[3]

For native SOL, you'll have to do something a bit different, calling system_instruction::transfer with the system program, and not the SPL token program.

There isn't a handy wrapper in Anchor (that I can find), so here's an example of doing it without Anchor: https://github.com/solana-labs/solana-program-library/blob/78cb32435296eb258ec3de76ee4ee2d391f397ee/associated-token-account/program/src/tools/account.rs#L29

Solution 4:[4]

To send native SOL with Anchor

#[program]
pub mod learn_solana_anchor {
    use super::*;

    pub fn transfer_native_sol(ctx: Context<Transfer>) -> Result<()> {
        let amount_of_lamports = 42; // could be an argument ;-)
        let from = ctx.accounts.from.to_account_info();
        let to = ctx.accounts.to.to_account_info();

        // Debit from_account and credit to_account
        **from.try_borrow_mut_lamports()? -= amount_of_lamports;
        **to.try_borrow_mut_lamports()? += amount_of_lamports;

        Ok(())
    }

}

#[derive(Accounts)]
pub struct Transfer<'info> {
    #[account(mut)]
    /// CHECK: This is not dangerous because its just a stackoverflow sample o.O
    pub from: AccountInfo<'info>,
    #[account(mut)]
    /// CHECK: This is not dangerous because we just pay to this account
    pub to: AccountInfo<'info>,
    #[account()]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

Ref

https://solanacookbook.com/references/programs.html#how-to-transfer-sol-in-a-program

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 patriciobcs
Solution 2 scripter
Solution 3 Jon C
Solution 4 Sr. Oshiro