2

I am creating pda accounts with a variable seed. To do this I created an account with a counter u64. For every pda account created, the counter will increment in 1, so the seeds of the account created will be "seed"+counter (1, 2, 3...)

I can succesfully initiate the pda like this: Rust:

#[derive(Accounts)]
pub struct InitiatePda<'info> {
...
    #[account(init, seeds = [b"seed1".as_ref(), counter_pda.counter.to_be_bytes().as_ref()], bump, payer=payer, space = 50)]
    account_pda: Account<'info, SomeStruct>,
    #[account(mut, seeds = [b"counter_account".as_ref()], bump)]
    counter_pda: Account<'info, CounterInfo>,
...
}

#[account]
#[derive(Default)]
pub struct CounterInfo {
    pub counter: u64,
}

In Js, to find the PDA, I want to pass a number a get the account pubkey

async function getPda(id) {
    return await web3.PublicKey.findProgramAddress(
        [Buffer.from("seed1"), new BN(id).toArrayLike(Buffer, "be", 8)],
        PROGRAM_ID
    );
}

Up to here it works fine, the Pda is created succesfully.

The problem is when I want to use the account_pda in another instruction. I cant make the getPda function on Js find the same account as the one in Rust.

My code: Rust:

    pub fn set_account_config(
        ctx: Context<AccountConfig>,
        id: u64,
    ) -> Result<()> {
...
...
        Ok(())
    }

#[derive(Accounts)]
#[instruction(id: u64)]
pub struct AccountConfig<'info> {
    #[account(mut, seeds = [b"seed1".as_ref(), id.to_be_bytes().as_ref()], bump = account_pda.bump)]
    account_pda: Account<'info, SomeStruct>,
    /// CHECK: Just testing
    #[account(mut)]
    pub payer: Signer<'info>,
}

Js:

const id = 5 //testing if can set the fifth account config
const [account_pda] = await getPda(id)

    instructions.push(
        program.instruction.setAccountConfig(
            new BN(id),
            {
                accounts: {
                    payer: wallet.publicKey,
                    accountPda: account_pda,
                },
            }
        )
    );

Im getting this error, its like the pda found on js is different than the one on Rust. I think maybe I have to use another thing instead of id.to_be_bytes().

> Program logged: "Instruction: SetAccountConfig"
> Program logged: "AnchorError caused by account: account_pda. Error Code: ConstraintSeeds. Error Number: 2006. Error Message: A seeds constraint was violated."
> Program logged: "Left:"
> Program logged: "5Dq6kPGZKfGbWo1TgPjCFNXAryikhLoaRkM2LiSCqzbc"
> Program logged: "Right:"
> Program logged: "3FDBrtJKDyZSU2iFLvWnnyHw2Gusfv8ADTDg3hpkVVRx"

Any thoughts? Thanks

1 Answer 1

5

The seeds should be:

#[account(init, seeds = [b"seed1".as_ref(), &id.to_le_bytes()], bump, payer=payer, space = 50)]
async function getPda(id) {
  return await web3.PublicKey.findProgramAddress(
    [
      Buffer.from("seed1"),
      new BN(id).toArrayLike(Buffer, "le", 8),
    ],
    PROGRAM_ID
  );
}
7
  • When using 'le', I get an error when initializing the account_pda: > 9LyEyfeTyP9C4XzF4pkZXWs3oZRTsGwYxQnoSSv5UeQk's signer privilege escalated. Its like the pda account passed doesnt match the one on Rust Commented Sep 2, 2022 at 6:16
  • I missed something on rust side, editing the answer now.
    – James
    Commented Sep 2, 2022 at 6:29
  • Please try to change it as &counter_pda.counter.to_le_bytes()
    – James
    Commented Sep 2, 2022 at 6:32
  • Nice, the pda initializes but still getting an error when trying to use that pda in another instruction (Error Number: 2006. Error Message: A seeds constraint was violated.). I changed to 'le' in AccountInfo too. Maybe something here: id.to_le_bytes().as_ref().. Commented Sep 2, 2022 at 6:46
  • Yeah, the main point is that the u64 should be converted to_le_bytes() in account seeds.
    – James
    Commented Sep 2, 2022 at 7:02

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.