feat: Auto-extract inline PDAs from v01 Anchor instruction accounts#984
Merged
lorisleiva merged 13 commits intocodama-idl:mainfrom Mar 24, 2026
Merged
feat: Auto-extract inline PDAs from v01 Anchor instruction accounts#984lorisleiva merged 13 commits intocodama-idl:mainfrom
lorisleiva merged 13 commits intocodama-idl:mainfrom
Conversation
Walk instruction accounts after building the ProgramNode, collect inline pdaNode definitions, deduplicate by seed structure, and promote them to program-level PdaNodes. Instruction accounts are rewritten to use pdaLinkNode references. ATA program PDAs are excluded. Controlled via `extractPdas` option (default: true).
🦋 Changeset detectedLatest commit: a276d74 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Address feedback: - Convert extractPdasFromProgram into an extractPdasVisitor using bottomUpTransformerVisitor, matching the existing visitor pattern - Add it to the defaultVisitor pipeline alongside other post-processing visitors — opt-out is now via rootNodeFromAnchorWithoutDefaultVisitor - Use getUniqueHashStringVisitor for deterministic PDA fingerprinting instead of JSON.stringify on raw nodes - Remove option threading (extractPdas flag) from ProgramNode, RootNode, and public API since the defaultVisitor handles this naturally - Revert ProgramNode.test.ts to pre-extraction expectations since programNodeFromAnchorV01 no longer runs extraction
- Merge extracted PDAs with existing program.pdas instead of replacing, so v00 programs (which already populate pdas) are not regressed - Track all used PDA names (existing + extracted) and loop suffix until unique, preventing ambiguous link resolution
lorisleiva
requested changes
Mar 23, 2026
Member
lorisleiva
left a comment
There was a problem hiding this comment.
Thanks! I've requested quite a few changes but the base is really solid I think. I'll review the tests thoroughly after these changes.
…ngify
Uses visit(pdaNode({ ...pda, name: '' }), hashVisitor) which leverages
json-stable-stringify under the hood for deterministic output.
…Node
The resolved name is already set on the PdaNode before insertion,
so the { name, pdaNode } wrapper is unnecessary.
Replace hardcoded ATA_PROGRAM_ID check with generic filter: skip extraction when pda.programId is set and differs from the current program's publicKey.
initializeCounter reads more naturally than counterInitialize. Generated helpers like findInitializeCounterPda also read better.
Avoids duplicated guard conditions that could drift out of sync.
The visitor is version-agnostic (operates on generic ProgramNode), so it belongs at src/ level alongside defaultVisitor, not inside v01/. Keeps extractPdasVisitor() in the defaultVisitor pipeline so consumers can opt out via rootNodeFromAnchorWithoutDefaultVisitor().
lorisleiva
requested changes
Mar 24, 2026
Member
lorisleiva
left a comment
There was a problem hiding this comment.
Thanks! Just a few small comments and LGTM! 🍺
Contributor
Author
|
Pushed the test cleanup. Thank you! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PdaNodespdaLinkNodeextractPdas: falseoption onrootNodeFromAnchor(in case someone has aaddPdasVisitorsetup and doesn't want to change).Resolves #70 (Part A)
How it works
After building instruction nodes from the Anchor IDL,
extractPdasFromProgrampost-processes theProgramNode:pdaValueNodewith inlinepdaNode{ seeds, programId }for structural deduppdasarraypdaNodewithpdaLinkNodeon each instruction accountDownstream renderers already generate
findXPda()helpers from program-level PdaNodes — no renderer changes needed.addPdasVisitorcontinues to take precedence since it runs after extraction.Test plan
pdaLinkNodePdaNodeprogramIdpreserved onPdaNodeprogramIdstays onpdaValueNode, not onPdaNodeextractPdas: falsepreserves inlinepdaNodeslet_me_buy— 8 instructions, 1 deduplicated PDA, ATA accounts correctly filtered)