9

I am trying to write a function which transfer sol tokens stored in PDA account to a user account. The PDA account is owned by the program account and program account owner is calling that function. I dont want the receiver to call this function. I just want the smart contract owner to call this function. The code that I am using is given below:

 invoke_signed(
            &anchor_lang::solana_program::system_instruction::transfer(&ctx.accounts.PDA.key(), &ctx.accounts.sendTo.key(),ctx.accounts.PDA.amount ),
            &[
                ctx.accounts.PDA.to_account_info(),
                ctx.accounts.sendTo.clone(),
                ctx.accounts.system_program.to_account_info(),
            ],
            &[&[
               b"pda_key".as_ref(),
                ctx.accounts.pda_signer.key().as_ref(),
                &[_bump],
            ]],
        )?;

I am getting the error cross program invocation failed

Is there any way to send sol from a PDA account to user account without the receiver signing the transaction?

2 Answers 2

6

Only the program that owns the account can debit its lamports. Since this is a program-owned account you're transferring from, the System Program wont be able to do the transfer, because it doesn't own the account.

Anyone can credit any account with lamports, so try the following:

let pda_account = ctx.accounts.PDA.to_account_info();
let send_to_account = ctx.accounts.sendTo.to_account_info();

**pda_account.try_borrow_mut_lamports()? -= ctx.accounts.PDA.amount;
**send_to_account.try_borrow_mut_lamports()? += ctx.accounts.PDA.amount;

Full example can be found here.

2
  • thanks for the response I actually meant to say that the PDA account is owned by the smart contract that I wrote can I use invoke sign in that case? Also do I need the send_to_account to sign this transaction? Aug 6, 2022 at 17:07
  • You can't use invoke signed as mentioned in my answer because your smart contract owns the account. so you have to do it manually like in my code example. The receiver never needs to sign.
    – C.OG
    Aug 6, 2022 at 17:15
0

Here is an example in anchor sending SOL from PDA.

    pub fn process(&mut self, bump: u8) -> Result<()> {

        // transfer from pda
        let seeds = &["sol_bank".as_bytes(), &[bump]];

        let ix = anchor_lang::solana_program::system_instruction::transfer(
            &sol_bank.key(),
            &payer.key(),
            offer.amount,
        );

        anchor_lang::solana_program::program::invoke_signed(
            &ix,
            &[sol_bank.to_account_info(), payer.to_account_info()],
            &[&seeds[..]],
        )?;
    }

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.