The builder pattern has its place, but it does not make sense to make building an instruction hit potential runtime errors when the set of necessary accounts is well known at compile time.
Idea
Keep the builder pattern but accounts are specified initially, maybe as PartialAccounts, optional can be None, focus on preventing compilation
A more sensible approach would be to have all the provided, here is an example usage below which bypasses the builder pattern, but loses the ability to get specified addresses autofilled.
let accounts = Swap {
pool_authority, // this is a constant address
pool,
input_token_account,
output_token_account,
token_a_vault,
token_b_vault,
payer: user,
token_program: spl_token_interface::ID,
referral: None,
};
let ix = accounts.instruction(SwapInstructionArgs {
amount: payload,
limit,
});
let accounts = SwapPartialAccounts {
pool,
input_token_account,
output_token_account,
token_a_vault,
token_b_vault,
payer: user,
token_program: spl_token_interface::ID,
};
...
additionally this setup could be more convenient if the PDAs can be derived from the seeds
The builder pattern has its place, but it does not make sense to make building an instruction hit potential runtime errors when the set of necessary accounts is well known at compile time.
Idea
Keep the builder pattern but accounts are specified initially, maybe as PartialAccounts, optional can be
None, focus on preventing compilationA more sensible approach would be to have all the provided, here is an example usage below which bypasses the builder pattern, but loses the ability to get specified addresses autofilled.
additionally this setup could be more convenient if the PDAs can be derived from the seeds