Skip to content

feat: Auto-extract inline PDAs from v01 Anchor instruction accounts#984

Merged
lorisleiva merged 13 commits intocodama-idl:mainfrom
amilz:feat/auto-extract-pdas-v01
Mar 24, 2026
Merged

feat: Auto-extract inline PDAs from v01 Anchor instruction accounts#984
lorisleiva merged 13 commits intocodama-idl:mainfrom
amilz:feat/auto-extract-pdas-v01

Conversation

@amilz
Copy link
Contributor

@amilz amilz commented Mar 18, 2026

  • Auto-extract inline PDA definitions from v01 Anchor instruction accounts into program-level PdaNodes
  • Instruction accounts are rewritten to reference extracted PDAs via pdaLinkNode
  • Deduplicate PDAs across instructions by seed structure fingerprint
  • Exclude ATA program PDAs from extraction (they should still auto-derive in the ix)
  • Handle name collisions (same name, different seeds) with instruction-name suffix + warning
  • Opt-out via extractPdas: false option on rootNodeFromAnchor(in case someone has a addPdasVisitor setup and doesn't want to change).

Resolves #70 (Part A)

How it works

After building instruction nodes from the Anchor IDL, extractPdasFromProgram post-processes the ProgramNode:

  1. Walks all instruction accounts looking for pdaValueNode with inline pdaNode
  2. Fingerprints each PDA by { seeds, programId } for structural dedup
  3. Promotes unique PDAs to the program's pdas array
  4. Replaces inline pdaNode with pdaLinkNode on each instruction account

Downstream renderers already generate findXPda() helpers from program-level PdaNodes — no renderer changes needed. addPdasVisitor continues to take precedence since it runs after extraction.

Test plan

  • Single PDA extracted to program level, account uses pdaLinkNode
  • Same PDA across multiple instructions deduplicates to one PdaNode
  • Same seeds with different account names keeps first name
  • Same name with different seeds warns and suffixes
  • ATA program PDAs excluded
  • Cross-program PDA with static programId preserved on PdaNode
  • Dynamic programId stays on pdaValueNode, not on PdaNode
  • extractPdas: false preserves inline pdaNodes
  • No PDA accounts → empty pdas array
  • Verified against real-world IDL (let_me_buy — 8 instructions, 1 deduplicated PDA, ATA accounts correctly filtered)

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-bot
Copy link

changeset-bot bot commented Mar 18, 2026

🦋 Changeset detected

Latest commit: a276d74

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@codama/nodes-from-anchor Minor

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

amilz added 2 commits March 18, 2026 13:02
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
@amilz amilz marked this pull request as ready for review March 19, 2026 14:41
- 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
Copy link
Member

@lorisleiva lorisleiva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

amilz added 8 commits March 23, 2026 07:38
…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().
Copy link
Member

@lorisleiva lorisleiva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Just a few small comments and LGTM! 🍺

@amilz
Copy link
Contributor Author

amilz commented Mar 24, 2026

Pushed the test cleanup. Thank you!

Copy link
Member

@lorisleiva lorisleiva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@lorisleiva lorisleiva merged commit a644f59 into codama-idl:main Mar 24, 2026
4 checks passed
@github-actions github-actions bot mentioned this pull request Mar 24, 2026
@amilz amilz deleted the feat/auto-extract-pdas-v01 branch March 24, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[nodes-from-anchor] Improve node data for inlined PdaValueNodes

2 participants