We're using Anchor to build our Solana Programs. It's a great framework to keep the instruction logic separate from all the Account checks that we have to do.
I've recently started using the init_if_needed
attribute to handle instructions where some Account initialization may be optional. We use an already initialized dummy account when the instruction should not initialize a new account, to avoid users paying unnecessary rent... The actual check whether a new account should be created is done within the program.
It works for our use case! It looks like something like this:
#[derive(Accounts)]
pub struct OurAccounts<'info> {
// ...
#[account(
init_if_needed,
payer = payer,
space = OurAccount::SIZE,
constraint = if condition ? {
account.key == dummy
} else {
account.key != dummy && !account.created
}
@ OurError::ConstraintNotSatisfied,
)]
pub account: Account<'info, OurAccount>,
// ...
}
However, init_if_needed
is intended for another use case. -> it only runs if the account does not exist yet.
So we're sort of abusing this attribute to conditionally create new accounts. Also, we need to have a dummy account for this to work and share this account's address private key with our users. What we need, we think, would be called the init_if_constraint
, where the init CPI to Solana's system program would be omitted if the constraint is not satisfied.
My question:
- Is there a better Anchor way to optionally
init
accounts within instructions? - If not, is this easy to do with a Solana system CPI, within the Anchor environment?