When I am running an anchor test, I am getting the following error, of invalid arguments when calling function transferSolFromPda. This is my anchor program
use anchor_lang::prelude::*;
use anchor_lang::solana_program::system_instruction;
use anchor_lang::solana_program::program::{invoke, invoke_signed};
declare_id!("CCsXFXn6noPhKG4Y3QPAxsFg6RroKKSd8aRajPT3a8dr");
#[program]
mod anchor_test_lamports {
use super::*;
pub fn transfer_sol_from_pda(ctx: Context<TransferSol>, amount: u64, bump: u8) -> Result<()> {
let binding = ctx.accounts.sender.key();
let pda_signer_seeds: &[&[_]] = &[
b"pda_seed",
&binding.as_ref(),
&[bump],
];
let ix = system_instruction::transfer(
&ctx.accounts.pda_account.key(),
&ctx.accounts.receiver.key(),
amount,
);
invoke_signed(
&ix,
&[
ctx.accounts.pda_account.to_account_info(),
ctx.accounts.receiver.to_account_info(),
],
&[pda_signer_seeds],
)?;
Ok(())
}
pub fn transfer_sol_to_pda(ctx: Context<TransferSolToPda>, amount: u64) -> Result<()> {
let ix = system_instruction::transfer(
&ctx.accounts.sender.key(),
&ctx.accounts.pda_account.key(),
amount,
);
invoke(
&ix,
&[
ctx.accounts.sender.to_account_info(),
ctx.accounts.pda_account.to_account_info(),
],
)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct TransferSol<'info> {
#[account(mut)]
pub sender: Signer<'info>,
/// CHECK: This is safe because we are only transferring SOL to this account. No need to deserialize or perform any operations on it.
#[account(mut)]
pub pda_account: AccountInfo<'info>,
/// CHECK: This is safe because we are only transferring SOL to this account. No need to deserialize or perform any operations on it.
#[account(mut)]
pub receiver: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct TransferSolToPda<'info> {
#[account(mut)]
pub sender: Signer<'info>,
/// CHECK: This is safe because we are only transferring SOL to this account. No need to deserialize or perform any operations on it.
#[account(
init_if_needed,
payer = sender,
seeds = [b"pda_seed".as_ref(), sender.key().as_ref()],
bump,
space = 50
)]
pub pda_account: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
This is my test
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { AnchorTestLamports } from "../target/types/anchor_test_lamports";
import {
PublicKey, SystemProgram, LAMPORTS_PER_SOL, Keypair, Connection, Signer
} from "@solana/web3.js";
describe("anchor-test-lamports", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const connection = new Connection("http://localhost:8899", 'recent');
const program = anchor.workspace.AnchorTestLamports as Program<AnchorTestLamports>;
let sender;
let pdaAccount;
it('transfers SOL to PDA', async () => {
// Generate a new keypair for the test sender account.
sender = await createUserWithLamports(connection, 10);
pdaAccount = PublicKey.findProgramAddressSync(
[Buffer.from("pda_seed"), sender.publicKey.toBuffer()],
program.programId
)[0];
await program.methods
.transferSolToPda(new anchor.BN(1 * LAMPORTS_PER_SOL))
.accounts({ pdaAccount: pdaAccount, sender: sender.publicKey, systemProgram: SystemProgram.programId })
.signers([sender])
.rpc();
// Verify the balance of the PDA after the transfer.
const pdaBalance = await program.provider.connection.getBalance(pdaAccount);
console.log(`PDA balance: ${pdaBalance / LAMPORTS_PER_SOL} SOL`);
// Assert that the PDA received the SOL (this assertion might need adjustment based on the actual balance).
});
it('transfer back SOL to PDA', async () => {
const receiver = await createUserWithLamports(connection, 10);
const senderBalance = await program.provider.connection.getBalance(sender.publicKey);
console.log(`PDA balance: ${senderBalance / LAMPORTS_PER_SOL} SOL`);
await program.methods
.transferSolFromPda(new anchor.BN(0.1 * LAMPORTS_PER_SOL), 255)
.accounts({ pdaAccount: pdaAccount, sender: sender.publicKey,receiver: receiver.publicKey, systemProgram: SystemProgram.programId })
.signers([sender])
.rpc({
skipPreflight:true
});
// Verify the balance of the PDA after the transfer.
// Assert that the PDA received the SOL (this assertion might need adjustment based on the actual balance).
});
});
export async function createUserWithLamports(
connection: Connection,
lamports: number,
): Promise<Signer> {
const account = Keypair.generate();
const signature = await connection.requestAirdrop(
account.publicKey,
lamports * LAMPORTS_PER_SOL
);
const block = await connection.getLatestBlockhash();
await connection.confirmTransaction({ ...block, signature });
return account;
}