Skip to content

Proposed: PDA generation, compile-time safety, etc#95

Closed
ioxde wants to merge 25 commits into
codama-idl:mainfrom
ioxde:solana-v3
Closed

Proposed: PDA generation, compile-time safety, etc#95
ioxde wants to merge 25 commits into
codama-idl:mainfrom
ioxde:solana-v3

Conversation

@ioxde

@ioxde ioxde commented Apr 9, 2026

Copy link
Copy Markdown

@changeset-bot

changeset-bot Bot commented Apr 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5eb8ad7

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

This PR includes changesets to release 1 package
Name Type
@codama/renderers-rust 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

ioxde and others added 24 commits April 14, 2026 10:21
Generated event codegen output for the Raydium Launchpad e2e fixture after
rebasing onto event codegen support.
Generated event parsers now validate the shared Anchor event CPI
discriminator before the per-event discriminator, matching how the
program actually emits framed events.
When an instruction account has a pdaValueNode default (linked or
inline), the builder now auto-derives the address instead of requiring
it to be set explicitly. PDA-defaulted accounts are emitted as
sequential let bindings, topologically sorted by seed dependencies,
so accounts that reference other PDA-defaulted accounts resolve
correctly. Constant seed rendering dispatches by value type: strings
produce b"...", byte arrays &[...], and numbers &Nu64.to_le_bytes().

Bumps @codama/nodes-from-anchor to ^1.4.0 for extractPdasVisitor
support (codama-idl/codama#984).
The generated from_bytes() blindly deserialized without checking that the
discriminator bytes matched, silently accepting wrong account data.
The TryFrom<&AccountInfo> and fetch_* helpers had no owner validation,
and the Anchor AccountDeserialize::try_deserialize defaulted to unchecked
deserialization with no discriminator gate.

- from_bytes() now rejects data with a mismatched discriminator prefix
- TryFrom<&AccountInfo> checks account_info.owner before deserializing
- fetch_all_* and fetch_all_maybe_* check account.owner before deserializing
- TryFrom delegates to from_bytes() instead of duplicating deserialization
- Anchor try_deserialize checks the discriminator before calling unchecked
- Anchor Discriminator trait uses the real constant instead of [0; 8]
…rams

Move required accounts (no defaults, not IDL-optional) and required args
(no defaults, not Option types) from Option fields with setter methods
into mandatory constructor parameters on both Builder and CpiBuilder.
This shifts missing-field errors from runtime .expect() panics to
compile-time type errors.

Accounts with defaults (PDA, publicKey, programId) remain optional with
setters. PDA seed resolution uses direct field access for required fields
instead of .expect(). programIdValueNode accounts unwrap with the
program's own ID as fallback.
# Conflicts:
#	package.json
#	pnpm-lock.yaml
#	src/getRenderMapVisitor.ts
- Honor pdaValueNode.programId: builders derive PDAs against runtime
  account/argument program refs; helpers for dynamic-only PDAs take a
  program_address parameter, or bake in the IDL-pinned canonical
  address as a _PROGRAM_ADDRESS constant
- Render instruction extraArguments (Anchor account-data seeds lowered
  to argument values) as required builder fields that feed PDA
  derivation without entering instruction data
- Replace the local topological sort with codama's
  getResolvedInstructionInputsVisitor for dependency-first ordering;
  unresolvable PDAs (cycles, missing seed args) now hard-error instead
  of silently falling back to required accounts
- Extract renderConstantSeedBytes and support publicKeyValueNode
  constant seeds as decoded 32-byte arrays
- Regenerate anchor and raydium-launchpad e2e fixtures
Replace offset + CONST.len() arithmetic in generated event code with
ranges and skips precomputed at generation time, keeping
clippy::arithmetic_side_effects out of generated crates:

- Fold discriminator checks to literal ranges (data.get(8..16)) when
  the byte size is statically known, falling back to a starts_with
  tail probe for link-typed constants of unknown size.
- Compare scalar number constants via to_le/be_bytes instead of
  emitting non-compiling slice operations on them.
- Fold CPI-framed skips to a single literal (&data[16..]) with a
  provenance comment, chaining [CONST.len()..] slices only for
  unknown-size discriminators.
- Unify all condition rendering in renderByteCheck, shared by the
  events template, identify conditions, and field discriminators.
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.

2 participants