Skip to main content
2 of 2
added 1876 characters in body

Transfer SOL out of PDA owned wallet account

Basically I'm trying to figure out to transfer SOL out of a wallet account which is owned by a PDA. the PDA is in turn owned by my program.

I've tried invoke_signed, my seeds are all correct, and I keep getting signer escalation on the wallet account pubkey itself when trying to transfer that way. I understand that system program transfer function requires the account where lamports are being sent from to be a signer.

And the method that uses try borrow mut lamports also doesnt work because the program isnt the owner of the wallet account, the PDA is. I'm really stuck, does anyone know how to do this?

creating the pda:

invoke_signed(
            &system_instruction::create_account(
                initializer.key,
                pda_account.key,
                lamports,
                space as u64,
                program_id,
            ),
            &[initializer.clone(), pda_account.clone(), system_program.clone()],
            &[&[seed.as_bytes(), initializer.key.as_ref(), &[bump]]],
        )?;

assigning ownership to the pda:

            let instruction = system_instruction::assign(&initializer.key, pda_account.key);
        invoke(
            &instruction,
            &[initializer.clone(), pda_account.clone()],
        )?;

when trying to transfer lamports from the initializer to the pda via "try_borrow_mut_lamports", it doesnt work. Neither does using an invoke_signed transfer instruction.

**wallet_account.try_borrow_mut_lamports()? -= lamports_to_transfer;
**_pda_account.try_borrow_mut_lamports()? += lamports_to_transfer;

when using "invoke_signed" transfer, I get a signer escalation error, the runtime thinks the wallet_account should have signed the transaction, but it cant as i dont have access to the users keys to sign on the frontend.

let lamports_to_transfer = wallet_account.lamports();

let ix = system_instruction::transfer(
    wallet_account.key,
    pda_account.key,
    lamports_to_transfer,
);

invoke_signed(
    &ix,
    &[ wallet_account.clone(), pda_account.clone() system_program.clone()],
    &[&[seed.as_bytes(), &wallet_account.key.as_ref(), &[bump3]]],
)?;

shouldnt signing it with the PDA seeds be enough?

I am certain i am deriving the keys correctly, i have msg!'s littered throughout to debug line by line.

is this even possible?