My intent here is to have account that can store data to be used by program. I will be passing this account in every call I make to my onchain program. And if I try to call allocate from onchain, then it's results in <pda-address>'s writable permission escalated
It seems that having an PDA is good idea for this as only my program will be able to make use of it. But I am not sure how do I do it exactly. This is what I tried so far
Error with above approach:
What am I missing here? I am new to solana so I might have missed even a simplest thing.
Client side
const deposit_instruction = new solana.TransactionInstruction({
keys: [
{ pubkey: system_account, isSigner: false, isWriteable: false },
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
{ pubkey: pdaAccount, isSigner: false, isWriteable: false },
{ pubkey: sender.publicKey, isSigner: true, isWriteable: true },
{ pubkey: receiver, isSigner: false, isWriteable: false },
],
programId: programId,
data: argument_ser,
});
return await callEntryPoint(deposit_instruction, [sender, payer]);
Onchain program
let instruction = system_instruction::allocate(pda_account.key, 100u64);
invoke_signed(
&instruction,
&[pda_account.clone(), system_account.clone()],
&[&[SEED], &[&[bump]]],
)?;
Make sure you derived that PDA from your on-chain program.
In the on-chain program use invoked_signed instead of invoked to system_program.
Since that's PDA derived from your program, only your program can sign that PDA.
Use PublicKey.findProgramAddress to get a program key and bump value. Send that to the instruction in your program.
Then within your program invoke the system_instruction::create_account to create the PDA with storage (up to 10k).