Skip to main content
added 1176 characters in body
Source Link
0xShuk
  • 2k
  • 3
  • 11

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.

Use null for the optional accounts:

await program.methods
  .updateAccount({num: 10})
  .accounts({
      payer: signer.publicKey,
      optionalAta: null
  })

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.

Source Link
0xShuk
  • 2k
  • 3
  • 11

Use null for the optional accounts:

await program.methods
  .updateAccount({num: 10})
  .accounts({
      payer: signer.publicKey,
      optionalAta: null
  })