1

Check out the code I use to understand PDA accounts.

Program,

entrypoint!(game);

pub fn game(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    _instruction_data: &[u8],
) -> ProgramResult {
    let (pda, seed) = Pubkey::find_program_address(&[b"test"], program_id);
    let account_space: u64 = 4;
    let lamports = Rent::default().minimum_balance(account_space as usize);
    let account_info = accounts.iter().next().unwrap();
    let accountkey = account_info.key;
    let ix = system_instruction::create_account(accountkey, &pda, lamports, account_space, program_id);
    invoke_signed(&ix, &[account_info.clone()], &[&[b"test", &[seed]]]).unwrap();
    msg!("{}", pda);
    Ok(())
}

Client

run();

async function run() {
  const key = {
    isSigner: true,
    isWritable: true,
    pubkey: pg.wallet.publicKey
  };

  const programId = new web3.PublicKey('xxxxxxxxxxxxxxxxxxxxx');
  const keys = [key];
  const tx = new web3.Transaction().add(
    new web3.TransactionInstruction({ programId, keys })
  );

  const connection = new web3.Connection(web3.clusterApiUrl('devnet'));
  const res = await web3.sendAndConfirmTransaction(connection, tx, [pg.wallet.keypair]);
  console.log(res);
}

It fails. Why?

Edit *********************

This is the error shown

Uncaught error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing
2
  • please post the error that you are getting. On solana you need to pass in all accounts you want to interact with so you need to pass in the PDA account from the client already.
    – Jonas H.
    Mar 15 at 9:51
  • @JonasH. How do I generate the PDA account at the client side? Also, why does the "create account" procedure needs the account details before it's created?
    – Manu Soman
    Mar 15 at 10:59

1 Answer 1

0

You need to pass in the PDA into the transaction. On Solana you always need to put in all accounts that you want to interact with.

in js you can find the PDA in the client like this

const counter_checked = PublicKey.findProgramAddressSync([Buffer.from("counter")], program.programId);

In your program you can then get it from the account array and use it.

You can also use

pnpm create solana-program 

or

npx create-solana-dapp 

to get a counter example preset that you can use as reference.

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.