-
Notifications
You must be signed in to change notification settings - Fork 64
Open
Labels
anchorImproves conversion from Anchor IDLImproves conversion from Anchor IDL
Description
If one has an Anchor program with two separate nested accounts with the same account name, Codama generates TypeScript code with duplicate property names.
Below is my fix for this issue-- is there a recommended place for this to go in the codebase?
import type {
AnchorIdl,
IdlV01InstructionAccountItem,
} from "@codama/nodes-from-anchor";
import { instructionAccountNodeFromAnchorV01 } from "@codama/nodes-from-anchor";
import type {
AccountNode,
InstructionAccountNode,
InstructionArgumentNode,
} from "codama";
import {
assertIsNode,
bottomUpTransformerVisitor,
camelCase,
rootNodeVisitor,
visit,
} from "codama";
function instructionAccountNodesFromAnchorV01(
allAccounts: AccountNode[],
instructionArguments: InstructionArgumentNode[],
idl: IdlV01InstructionAccountItem[],
parent: string | null = null,
): InstructionAccountNode[] {
return idl.flatMap((account) =>
"accounts" in account
? instructionAccountNodesFromAnchorV01(
allAccounts,
instructionArguments,
account.accounts,
// null,
parent ? `${parent}_${account.name}` : account.name,
)
: [
instructionAccountNodeFromAnchorV01(
allAccounts,
instructionArguments,
{
...account,
name: parent ? `${parent}_${account.name}` : account.name,
pda:
account.pda && parent
? {
...account.pda,
seeds: account.pda.seeds.map((seed) => {
if (seed.kind === "account") {
return {
...seed,
path: `${parent}_${seed.path}`,
};
}
return seed;
}),
}
: undefined,
},
idl,
),
],
);
}
export function instructionAccountsDedupeVisitor(idl: AnchorIdl) {
return rootNodeVisitor((node) => {
const accountNodes = node.program.accounts;
const instructionVisitor = bottomUpTransformerVisitor([
{
select: "[instructionNode]",
transform: (node, _stack) => {
assertIsNode(node, "instructionNode");
const idlIx = idl.instructions.find(
(ix) => camelCase(ix.name) === node.name,
);
if (!idlIx) {
throw new Error(`Instruction ${node.name} not found in Idl`);
}
return {
...node,
accounts: instructionAccountNodesFromAnchorV01(
accountNodes,
node.arguments,
idlIx.accounts,
),
};
},
},
]);
return visit(node, instructionVisitor);
});
}Metadata
Metadata
Assignees
Labels
anchorImproves conversion from Anchor IDLImproves conversion from Anchor IDL