I'm writing a Solana program which uses PDAs to store auction positions and I have a question about passing the accounts from client when calling instructions. My positions use a numeric counter as a seed (because all other properties are not unique) and when creating a new position account, this counter is taken from the another (state
) account as shown below:
pub fn start_auction(ctx: Context<StartAuction>) -> Result<()> {
let state = &mut ctx.accounts.state;
// ...
state.positions_count = state.positions_count + 1;
Ok(())
}
#[derive(Accounts)]
pub struct StartAuction<'info> {
#[account(init, seeds=[&state.positions_count.to_ne_bytes()], bump, payer = authority, space = 5000)]
pub position: Account<'info, Position>,
#[account(mut, seeds=[b"state"], bump)]
pub state: Account<'info, State>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>
}
#[account]
#[derive(Default)]
pub struct State {
pub positions_count: u32
}
What surprises me is that I must pass the position
account (with its seeds) from the javascript client code that calls the start_auction
instruction. It's not clear why - because the program itself already knows where to get the seed (from state
) to init the account. But this is not only about code cleanliness - on client side I don't know the current counter at the time of calling. Of course I can fetch state
and retrieve the counter, but what if in between of fetching and calling another user calls the same instruction and the counter becomes incremented in the meantime? Is there a way to avoid passing the accounts from client code and if no, how Solana developers would deal with the above described counter problem?
P.S. I can think of another problem caused by the need to pass the accounts from client. Imagine I'm creating a program that stores some list of addresses to which it should send tokens at certain conditions. And the addresses (accounts) to which tokens need to be sent are determined by the program's logic and cannot be known on the client side. How to implement such functionality in Solana?