UNPKG

@macalinao/codama-instruction-accounts-dedupe-visitor

Version:

Codama visitor for deduplicating instruction accounts from Anchor IDL

52 lines (51 loc) 2.46 kB
import { instructionAccountNodesFromAnchorV01 } from "./instruction-account-nodes-from-anchor-v01.js"; import { assertIsNode, bottomUpTransformerVisitor, camelCase, visit } from "codama"; //#region src/instruction-accounts-dedupe-program-visitor.ts /** * Creates a Codama program visitor that deduplicates and flattens nested instruction accounts from an Anchor IDL. * * This is a program-level visitor that can be composed with other visitors. It transforms * instruction nodes to have flattened account structures, removing nested account groups. * * @param idl - The Anchor IDL containing the instruction definitions with potentially nested accounts * @returns A visitor that transforms all instruction nodes to have flattened account structures * * @example * ```typescript * // Use with a single program * const programNode = programNodeFromAnchor(idl); * const visitor = instructionAccountsDedupeProgramVisitor(idl); * const transformedProgram = visit(programNode, visitor); * * // Or compose with other visitors * const composedVisitor = mergeVisitor( * instructionAccountsDedupeProgramVisitor(idl), * otherProgramVisitor(), * ); * ``` * * @remarks * - This visitor operates at the program level, not the root level * - Account names are joined with underscores to maintain parent-child relationships * - PDA seed paths are automatically updated to match the flattened structure * - All account metadata and constraints are preserved during flattening */ function instructionAccountsDedupeProgramVisitor(idl, programNode) { const accountNodes = programNode.accounts; return visit(programNode, bottomUpTransformerVisitor([{ select: "[instructionNode]", transform: (instructionNode) => { assertIsNode(instructionNode, "instructionNode"); const idlIx = idl.instructions.find((ix) => camelCase(ix.name) === instructionNode.name); if (!idlIx) throw new Error(`Instruction ${instructionNode.name} not found in IDL`); const hasDuplicates = instructionNode.accounts.some((account) => instructionNode.accounts.some((otherAccount) => otherAccount.name === account.name && otherAccount !== account)); return { ...instructionNode, accounts: hasDuplicates ? instructionAccountNodesFromAnchorV01(accountNodes, instructionNode.arguments, idlIx.accounts) : instructionNode.accounts }; } }])); } //#endregion export { instructionAccountsDedupeProgramVisitor }; //# sourceMappingURL=instruction-accounts-dedupe-program-visitor.js.map