Codama Solana Framework
Codama is a Solana framework designed to facilitate the building of standardized programs through specifications and code generation. It aims to streamline the development of on-chain programs by providing a structured approach to defining program interfaces and interactions. The package `codama` (currently at version 1.6.0) serves as the main entry point, re-exporting core modules like `@codama/errors`, `@codama/nodes`, `@codama/validators`, and `@codama/visitors`, bundling them into a cohesive API. It offers utilities for managing Solana IDLs, allowing developers to create, manipulate, and validate program definitions from a `RootNode` or JSON representation. The project appears to have an active release cadence, with recent minor updates introducing new node types (e.g., `EventNode`) and functionality like a dynamic client for instruction building, indicating ongoing development and feature expansion within the Solana ecosystem.
Common errors
-
Error: Cannot find module 'codama' or its corresponding type declarations.
cause The 'codama' package was not installed or is incorrectly referenced in the project.fixRun `npm install codama` or `pnpm install codama` to add the package to your project's dependencies. Ensure your `tsconfig.json` includes `node_modules/@types` if using TypeScript. -
TypeError: createFromJson is not a function
cause Attempting to import `createFromJson` using a CommonJS `require` statement in an ESM context, or using a default import syntax for a named export.fixEnsure you are using ESM `import { createFromJson } from 'codama'` for TypeScript/modern JavaScript projects. If forced to use CommonJS, consider transpiling your code or using dynamic `import()`. -
Argument of type '{ name: string; version: string; instructions: never[]; accounts: never[]; errors: never[]; types: never[]; }' is not assignable to parameter of type 'ProgramNode'.cause Incorrectly providing an object literal that doesn't fully conform to the `ProgramNode` interface or using an outdated schema when trying to create a `RootNode`.fixEnsure the object passed to `programNode` or `createFromRoot` strictly adheres to the `ProgramNode` definition from `@codama/nodes` (or re-exported by `codama`), including all required fields and types. Check the latest `@codama/node-types` for schema updates, especially after major/minor version bumps.
Warnings
- gotcha The Codama framework (specifically `@codama/nodes` and `@codama/node-types`) introduced a new `EventNode` to `ProgramNode` in version 1.6.0. While this is a minor addition and typically backward-compatible, consumers relying on a strict, fixed schema for IDL parsing or code generation might need to update their tooling to properly handle the new node type.
- gotcha The `@codama/errors` package, part of the core Codama monorepo, added a new 'dynamic-client' feature in version 1.6.0 for runtime Solana instruction building. While new functionality, users should be aware of potential integration impacts or new APIs to learn if they manage instruction building manually or through other libraries.
- gotcha Codama leverages a monorepo structure, and the main `codama` package primarily re-exports functionalities from its sub-packages (e.g., `@codama/nodes`, `@codama/visitors`). Direct imports from sub-packages might be necessary for specific, granular access, or if the main `codama` package doesn't re-export a specific symbol.
Install
-
npm install codama -
yarn add codama -
pnpm add codama
Imports
- Codama
import type { Codama } from 'codama' - createFromRoot
const { createFromRoot } = require('codama')import { createFromRoot } from 'codama' - createFromJson
import createFromJson from 'codama'
import { createFromJson } from 'codama' - ProgramNode
import { ProgramNode } from 'codama'import { programNode } from '@codama/nodes'; // or direct from main package if re-exported import { programNode } from 'codama'
Quickstart
import { createFromJson, createFromRoot, programNode, type RootNode } from 'codama';
import { getDebugStringVisitor, consoleLogVisitor } from '@codama/visitors';
// Example 1: Creating from a JSON string
const jsonIdlString = JSON.stringify({
version: '0.1.0',
name: 'my_program',
instructions: [
{
name: 'initialize',
accounts: [],
args: []
}
],
accounts: [],
events: []
});
const codamaFromJson = createFromJson(jsonIdlString);
console.log('Codama from JSON:');
codamaFromJson.accept(consoleLogVisitor(getDebugStringVisitor({ indent: true })));
// Example 2: Creating from a RootNode programmatically
const myProgramNode: RootNode = programNode({
name: 'myProgram',
version: '1.0.0',
docs: ['My example program.'],
instructions: [],
accounts: [],
errors: [],
types: [],
events: []
});
const codamaFromRoot = createFromRoot(myProgramNode);
console.log('\nCodama from RootNode:');
codamaFromRoot.accept(consoleLogVisitor(getDebugStringVisitor({ indent: true })));
// Example 3: Modifying a Codama instance (e.g., cloning)
const clonedCodama = codamaFromRoot.clone();
console.log('\nCloned Codama JSON:');
console.log(clonedCodama.getJson());