Search code examples
rustsolana

Solana Anchor: How to make #[account(seeds)] for/ read associated accounts?


in the Basic-5 tutorial of the project-serum/anchor repo How can I replace #[associated] with something like this:

#[account(seeds = [user_data.deposit_last.as_ref(), &[user_data.__nonce]])]

There is something not correct above, then Anchor fails to read the associated account's values

const userData = await program.account.userData.associated(wallet1, usdcMint);

So what is the correct way to replace this soon-to-be-deprecated #[associated] above the associated account struct?

#[associated]
#[derive(Default)]
pub struct UserData {
  pub authority: Pubkey,
  pub deposit_last: i64,
  pub shares: u64,
  pub reward_debt: u64,
}

//UserData is initialized here first
#[derive(Accounts)]
pub struct Initialize<'info> {
  #[account(init, associated = authority, with = usdc_mint)]
  pub user_data: ProgramAccount<'info, UserData>,
...
}

Solution

  • So the seed approach is a PDA, which is actually what #associated was using underneath the hood

    You will need a function that initializes the seed with the below init and payer trait. payer should also be the same user who is actually paying the for transaction.

    Please note that #[instruction(bump: u8] is matching the signature of the function here, hence you will need to pass in the bump in the signature as the first argument.

    #[instruction(bump: u8)]
    pub struct Ctx<'info> {
      #[account(init, seeds = [user_data.deposit_last.as_ref(), &[bump]], payer = payer)]
      pub user_data = ProgramAccount<'info, UserData>,
    }
    
    

    Later on for other functions if you want just want to read the account, you can just use

    #[account(seeds = [user_data.deposit_last.as_ref(), &[user_data.__nonce]])]
    pub user_data = ProgramAccount<'info, UserData>,
    

    Change your account data to use #[account] instead of #[associated]

    #[account]
    #[derive(Default)]
    pub struct UserData {
      pub authority: Pubkey,
      pub deposit_last: i64,
      pub shares: u64,
      pub reward_debt: u64,
    }
    

    Here is an example https://github.com/project-serum/anchor/blob/master/examples/misc/programs/misc/src/context.rs#L10