Use null
for the optional accounts:
await program.methods
.updateAccount({num: 10})
.accounts({
payer: signer.publicKey,
optionalAta: null
})
Regularly, accounts
only accepts Address
type which is PublicKey | string
. But if isOptional
is turned true for the account in IDL, Anchor validates the account as Address | null
. What null
effectively does is that it replaces the optional account with the program ID.
Here is the logic for the same:
The key to make everything work is the fact that repeated accounts don't add to the size of the transaction due to how Solana serializes accounts in transactions. We use this fact to denote an optional account with the program Id. When the accounts are passed in, if an account should be ignored, clients will send the program Id instead. In addition, with this implementation, adding on optional accounts at the end of an Accounts struct wouldn't be a breaking change and the program will treat the missing account as None (since older clients will not be passing in this new account).
Source: https://github.com/coral-xyz/anchor/pull/2101
In your case, null
isn't working because of the type check. So, the perfect solution is to just pass program id
because null
is eventually going to do the same in the instruction under the hood.