[2.x] Adapt nodes-from-anchor to Codama v2 - #1180
Conversation
|
trevor-cortex
left a comment
There was a problem hiding this comment.
Summary
Ports @codama/nodes-from-anchor (v00 + v01) to the v2 node model: raw-cased identifiers, instructionNode.data as a structTypeNode with a leading discriminator field, wrapper nodes replaced by transforms (sizePrefixTransformNode, fixedSizeTransformNode, hiddenPrefixTransformNode), numberTypeNode split into integerTypeNode/floatTypeNode with string-backed value nodes, unified enumVariantTypeNode, and docs joined into a single string. Along the way it fixes a handful of latent bugs (extractPdas fingerprint throwing on '', snake_case arg seeds, odd-length Shank discriminators, missing generic crash, empty-docs artifacts).
The refactor is clean and consistent across both IDL versions — the shared helpers in utils.ts (docsFromAnchor, fixedSizeBytesTypeNode, borshSizePrefixedTypeNode, removeBorshSizePrefix) remove a lot of duplication, and the test coverage for the new behaviours (lossless integers, raw-casing collisions, Shank padding, missing arg seeds, joined docs) is solid.
Things worth a look
canonicalFloatcanonicalises throughNumber()— see inline. TheDecimalStringdocs say canonicalisation is about spelling, not the f64 the string rounds to, and the current approach both silently mangles high-precision / large-magnitude decimals and downgrades small ones (0.0000001→1e-7→ string constant). A purely textual canonicaliser is a few lines and avoids both. Not blocking, but I'd fix it before merge since it's a new helper.camelCaseis still imported in bothInstructionAccountNode.tsfiles. That's intentional —hasDuplicateAccountNamesuses it to detect collisions under the spec's casing-collision rule (the newtoken_mintvstokenMinttest covers it). Flagging so nobody treats it as a leftover from the camelCasing removal.originis dropped fromprogramNode. Correct for v2 (ProgramNodehas noorigin), but it means the Shank/Anchor distinction is no longer carried anywhere on the output tree. If a renderer ever needs it, apluginNodeis presumably the home — just noting it as a deliberate loss of information.- Changeset: none in the PR. Per
CONTRIBUTING.mdthe seeded major changeset on the 2.x line covers all public packages, so this may be intentional — worth confirming that's the convention being followed for this branch given the removed exports (instructionArgumentNodeFromAnchorV0x, per-kind enum variant helpers).
For subsequent reviewers
removeBorshSizePrefixrequires exactly one transform (transforms?.length === 1). That's fine for what this parser emits, but it's stricter than the v1 logic it replaces conceptually; anything decorating fields with extra transforms before PDA extraction would keep the prefix.- Nested account seeds are prefixed with the current group prefix (
pdaSeedNodeFromAnchorV01→${prefix}_${accountName}), so a nested PDA referencing a top-level account still gets the wrong name. Pre-existing, unchanged here. IdlV01Metadata.descriptionexists and could serve as program-docs fallback — optional nit inline.
146deb5 to
662e982
Compare
trevor-cortex
left a comment
There was a problem hiding this comment.
Re-review
Only utils.ts and the two ConstantNode test files changed since my last pass.
canonicalFloat is now textual — the regex-based canonicaliser replaces the String(Number(x)) round-trip, so high-precision, large-magnitude and small-fraction decimals all keep their exact spelling (3.14159265358979323846, 123456789012345678901.5, 0.0000001 are now covered by test.each cases in both v00 and v01). Output still matches DECIMAL_REGEX: leading zeros are stripped down to a single 0, trailing fraction zeros are dropped, and -0.00 → -0 is allowed by the spec since floats have signed zero. Non-decimal spellings like 1e3 still fall back to a string constant, which is the right call given the spec forbids exponent notation.
The optional metadata.description fallback for program docs wasn't taken, which is fine — that was a nit.
Everything else from the previous review stands; nothing new to flag. Good to merge.
fcc8af3 to
566f28f
Compare
662e982 to
3c21987
Compare
566f28f to
621d4b9
Compare
3c21987 to
822c4db
Compare
621d4b9 to
90e3656
Compare
822c4db to
35fe188
Compare
90e3656 to
dcf7a0d
Compare
7ada96f to
b5a4252
Compare
dcf7a0d to
015a2ca
Compare
b5a4252 to
d1a13ad
Compare
6ef73f4 to
b8ab0fe
Compare
d1a13ad to
031ad68
Compare
6ef73f4 to
b8ab0fe
Compare
031ad68 to
e51263e
Compare
45f5d3f to
f8d92f5
Compare
e51263e to
d435238
Compare
d435238 to
563892d
Compare

This PR adapts
@codama/nodes-from-anchorto the Codama v2 node model, for both legacy (v00) and current (v01) Anchor IDLs.Behaviour
definedTypeLinkNodes and PDA seeds) matches the IDL exactly. Accounts flattened from nested groups are prefixed as${group}_${account}, e.g.token_program_mint.instructionNode.data, astructTypeNodewhose first field is the discriminator (with afieldDiscriminatorNode). PDA seeds referencing arguments usedataValueNodes.u32sizePrefixTransformNode, discriminators usefixedSizeTransformNodes and event data uses ahiddenPrefixTransformNode.integerTypeNodeorfloatTypeNode(f32/f64). Integer constants are kept as lossless strings, so 64- and 128-bit values no longer lose precision, and float constants are canonicalised textually (e.g.007.50→7.5) without losing precision.enumVariantTypeNodes whose data is absent, a struct or a tuple.Removed exports
instructionArgumentNodeFromAnchorV00andinstructionArgumentNodeFromAnchorV01: usestructFieldTypeNodeFromAnchorV00andstructFieldTypeNodeFromAnchorV01instead.enumEmptyVariantTypeNodeFromAnchorV0x,enumStructVariantTypeNodeFromAnchorV0x,enumTupleVariantTypeNodeFromAnchorV0x), replaced byenumVariantTypeNodeFromAnchorV0x.Bug fixes
extractPdasVisitorno longer throws when fingerprinting PDAs.v01argument seeds are matched by their exact identifier, so snake_case arguments no longer throwARGUMENT_TYPE_MISSING.GENERIC_TYPE_MISSINGinstead of crashing.v01errors without a message no longer get"name: "as docs, and emptyv00seed descriptions no longer produce empty docs.Tests
All tests are ported to v2 nodes and raw casing, with new cases for joined docs, lossless and normalised constants, Shank discriminators, raw PDA collision renames and missing argument seeds.