diff --git a/.changeset/cool-rockets-smash.md b/.changeset/cool-rockets-smash.md new file mode 100644 index 00000000..77d7bdd4 --- /dev/null +++ b/.changeset/cool-rockets-smash.md @@ -0,0 +1,5 @@ +--- +"@metaplex-foundation/kinobi": patch +--- + +Support nested instruction accounts from IDL diff --git a/src/idl/IdlInstruction.ts b/src/idl/IdlInstruction.ts index 891d3311..e058b8d3 100644 --- a/src/idl/IdlInstruction.ts +++ b/src/idl/IdlInstruction.ts @@ -2,7 +2,7 @@ import type { IdlType } from './IdlType'; export type IdlInstruction = { name: string; - accounts: IdlInstructionAccount[]; + accounts: (IdlInstructionAccount | IdlInstructionNestedAccounts)[]; args: IdlInstructionArg[]; defaultOptionalAccounts?: boolean; legacyOptionalAccountsStrategy?: boolean; @@ -21,6 +21,11 @@ export type IdlInstructionAccount = { desc?: string; }; +export type IdlInstructionNestedAccounts = { + name: string; + accounts: (IdlInstructionAccount | IdlInstructionNestedAccounts)[]; +}; + export type IdlInstructionArg = { name: string; type: IdlType; diff --git a/src/nodes/InstructionAccountNode.ts b/src/nodes/InstructionAccountNode.ts index 68d2b5bd..2cd3dc44 100644 --- a/src/nodes/InstructionAccountNode.ts +++ b/src/nodes/InstructionAccountNode.ts @@ -1,4 +1,4 @@ -import { IdlInstructionAccount } from '../idl'; +import { IdlInstructionAccount, IdlInstructionNestedAccounts } from '../idl'; import { MainCaseString, PartialExcept, mainCase } from '../shared'; import { InstructionInputValueNode } from './contextualValueNodes'; @@ -50,6 +50,16 @@ export function instructionAccountNode< }; } +export function instructionAccountNodesFromIdl( + idl: (IdlInstructionAccount | IdlInstructionNestedAccounts)[] +): InstructionAccountNode[] { + return idl.flatMap((account) => + 'accounts' in account + ? instructionAccountNodesFromIdl(account.accounts) + : [instructionAccountNodeFromIdl(account)] + ); +} + export function instructionAccountNodeFromIdl( idl: IdlInstructionAccount ): InstructionAccountNode { diff --git a/src/nodes/InstructionNode.ts b/src/nodes/InstructionNode.ts index 650a2c54..f81d7dde 100644 --- a/src/nodes/InstructionNode.ts +++ b/src/nodes/InstructionNode.ts @@ -2,7 +2,7 @@ import type { IdlInstruction } from '../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; import { InstructionAccountNode, - instructionAccountNodeFromIdl, + instructionAccountNodesFromIdl, } from './InstructionAccountNode'; import { InstructionArgumentNode, @@ -171,9 +171,7 @@ export function instructionNodeFromIdl( name, idlName, docs: idl.docs ?? [], - accounts: (idl.accounts ?? []).map((account) => - instructionAccountNodeFromIdl(account) - ), + accounts: instructionAccountNodesFromIdl(idl.accounts ?? []), arguments: dataArguments, discriminators, optionalAccountStrategy: idl.legacyOptionalAccountsStrategy