Skip to content

feat: add dynamic-instructions#987

Open
mikhd wants to merge 1 commit intocodama-idl:mainfrom
hoodieshq:main-dynamic-instructions
Open

feat: add dynamic-instructions#987
mikhd wants to merge 1 commit intocodama-idl:mainfrom
hoodieshq:main-dynamic-instructions

Conversation

@mikhd
Copy link
Copy Markdown

@mikhd mikhd commented Mar 25, 2026

Summary

Adds @codama/dynamic-instructions runtime instruction builder that creates Instruction from Codama IDLs without code generation.

Key Features

  • Anchor-like builder APIprogramClient.methods.transfer({}).accounts({}).instruction().
  • Auto-resolution — Accounts with defaultValue (PDAs, program IDs, constants) are resolved automatically.
  • Typed & untyped — Use without or with types createProgramClient<MyProgramClient>(idl).
  • Standalone PDA derivationprogramClient.pdas.myPda({seeds}).
  • CLI — Generate ProgramClient TypeScript types with npx @codama/dynamic-instructions generate-client-types <idl.json> <output-dir> for a given program.

Package Structure

  packages/dynamic-instructions/
  ├── src/
  │   ├── index.ts                      # Public API entry point
  │   ├── types/                        # Type re-exports
  │   ├── program-client/               # Public API client
  │   │   ├── create-program-client.ts  #   Client creation entry point
  │   │   ├── methods-builder.ts        #   Client methods builder for creating Instruction
  │   │   ├── collect-pdas.ts           #   PDA collection from IDL
  │   │   └── derive-standalone-pda.ts  #   Standalone PDA derivation
  │   ├── instruction-encoding/         # Instruction creation
  │   │   ├── instructions.ts           #   Instruction encoding pipeline
  │   │   ├── validators.ts             #   Validators for accounts, arguments and nodes (superstruct)
  │   │   ├── accounts/                 #   AccountMeta creation and validation
  │   │   ├── arguments/                #   Arguments encoding and validation
  │   │   ├── resolvers/                #   Account/PDA/conditional resolution
  │   │   └── visitors/                 #   IDL tree-traversal visitors
  │   ├── shared/                       # Utilities
  │   └── cli/                          # CLI with type generation (commanderjs)
  │       └── commands/
  ├── test/
  │   ├── unit/                         # Unit tests
  │   ├── programs/                     # Program integration tests via LiteSVM
  │   │   ├── system-program/           #   System program
  │   │   ├── token/                    #   SPL Token program
  │   │   ├── token-2022/               #   Token-2022 program
  │   │   ├── associated-token-account/ #   ATA program
  │   │   ├── mpl-token-metadata/       #   MPL Token Metadata program
  │   │   ├── pmp/                      #   PMP program
  │   │   ├── sas/                      #   SAS program
  │   │   ├── anchor/                   #   Custom Anchor program (custom and edge cases)
  │   │   ├── circular-account-refs/    #   Circular dependency edge case
  │   │   ├── custom-resolvers/         #   Custom resolver integration
  │   │   ├── idls/                     #   Codama IDL JSONs
  │   │   ├── generated/                #   Auto-generated types from Codama idls/
  │   │   └── dumps/                    #   Program .so dumps for LiteSVM
  │   └── svm-test-context.ts           # LiteSVM wrapper

Instruction Building Pipeline

const client = createProgramClient<MyProgramClientType>(idl) // ProgramClient

client.methods.<instructionName>(arguments)
    .accounts({}) // required accounts
    .signers([]) // clarified "either" signers
    .resolvers({}) // resolvers for ResolverValueNode
    .instruction() // Instruction

Under the hood it:

  1. Validates arguments and accounts input.
  2. Resolves arguments from custom resolvers (optionally).
  3. Encodes arguments to bytes.
  4. Resolves account addresses (PDAs, program IDs, conditionals).
  5. Returns final Instruction { programAddress, accounts, data }.

Tests

  • test/unit — contains tests for the package.
  • test/program — contains tests of ProgramClient public interface in LiteSVM environment. ProgramClient is used for building and sending instructions to Solana programs.

Notes:

  • CI/CD update:
    • We're using [email protected] for simulation of some custom IDL cases, thus Anchor and Rust are required during tests.
    • Solana version was updated v2 to v3 due to issues with anchor spl-token compilation.

---------

Co-authored-by: Alex S <[email protected]>
Co-authored-by: Sergo <[email protected]>
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 25, 2026

⚠️ No Changeset found

Latest commit: 415210b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

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.

1 participant