-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Summary
Even though #94 solved part of the optional
accounts requirement (allowing to set optional accounts out of order), it doesn't cover all
needs.
What is Covered
- a way to default all optional accounts to
program_idif they are not set - either of those optional accounts can be set to something but if it isn't, it is set to
program_idby solita - the Rust code then magically understands that this actually signals a
Nonefor that account
What Else do devs Need
- in some cases a way to default some optional accounts to a value and make it
impossible to override via the generated client code, i.e. the value is hard-coded - in other cases provide a way to set an account as optional but specify for each specific account what
it should default to when it isn't set
Solution
Best explained with examples:
#[account(optional)]
- this account is optional and will not be included in the accounts array if it is omitted
#[account(optional(program_id))]
- this account is optional and defaults to the
program_idif it is not set
#[account(optional(system_account))]
- this account is optional and defaults to the
system_accountif it is not set
#[account(optional(spl_token))]
- this account is optional and defaults to the
spl_tokenif it is not set - there could be more known accounts like that
#[account(optional("my-custom-pubkey"))]
- this account is optional and defaults to the
new Pubkey("my-custom-pubkey")if it is not set
#[account(set_to(system_account))]
- this account needs to always be set to the
system_accountby the SDK - thus it is like an optional account, just that it always takes on the default and is not
overridable by the user - this account will not be part of the accounts type provided by the SDK
The above should cover all the cases that Sam needs (which are more generic).
Additionally at this point the existing solution can simply be re-implemented on top of the
above and becomes something akin to syntactic sugar as the below:
#[default_optional_accounts]
#[account(6, optional, ...)]
#[account(7, optional, ...)]
#[account(8, optional, ...)]
simply expands to:
#[account(6, optional(program_id), ...)]
#[account(7, optional(program_id), ...)]
#[account(8, optional(program_id), ...)]
Also anchor's isOptional at this point is equivalent to optional(program_id) and we write a
simple preprocessor to solita that treats it as such.
To be clear the defaultOptionalAccounts property would never appear in the IDL as shank
pre-expands it to have a detailed optional property per instruction account instead.
Questions
Not all of these have to be answered for the first implementation as we can default to the one
we believe is most common, but going forward we may extend the solution to provide more
flexibility.
Do we allow devs to turn off that check all together via a solita config property?
Do we allow mixing optional with optional(default) and/or set_to(some_key)?
Do we add a config option to .solitarc.js to allow users to decide what is allowed and how
missing optionals are treated?