Building Instructions
Construct typed instructions from generated Codama clients.
Recipe
import { getIncrementInstruction } from "./generated/clients/js";
import { appendTransactionMessageInstruction } from "@solana/kit";When to reach for this:
- Composing program calls in wallet flows.
- Server-built partial transactions.
- Multi-instruction DeFi routes.
Working Example
import {
createTransactionMessage,
pipe,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
createSolanaRpc,
} from "@solana/kit";
import { getIncrementInstruction } from "./generated/clients/js";
const rpc = createSolanaRpc(process.env.RPC_URL!);
const { value: bh } = await rpc.getLatestBlockhash().send();
const ix = getIncrementInstruction({
counter: counterAddress,
authority: walletSigner,
});
const message = pipe(
createTransactionMessage({ version: 0 }),
(m) => setTransactionMessageFeePayerSigner(walletSigner, m),
(m) => setTransactionMessageLifetimeUsingBlockhash(bh, m),
(m) => appendTransactionMessageInstruction(ix, m)
);What this demonstrates:
- Generated builder encodes discriminator + Borsh args.
- Signer objects satisfy authority meta requirements.
- Combine multiple program ixs in one message.
Deep Dive
How It Works
- Instruction data = 8-byte discriminator + serialized args.
- Account metas include signer/writable flags per IDL.
- Remaining accounts for CPI show in IDL as well.
- Simulate to catch constraint failures early.
Gotchas
- Wrong account order - program error 0x... Fix: never hand-reorder metas.
- Pubkey strings instead of signers - missing signature. Fix: pass Signer type for signers.
- Missing init accounts - needs system + rent. Fix: include init instructions from IDL helpers.
- Argument type mismatch - BN vs bigint. Fix: use generated TS types literally.
- CPI depth CU - simulation OOM. Fix: raise compute unit limit.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Anchor .methods | Legacy quick scripts | Kit message control |
| Raw Buffer layout | Learning only | Production |
FAQs
Anchor 0.32.1 IDL?
Run anchor build; point Codama at target/idl JSON.
Regenerate when?
Every on-chain interface change in CI.
kit typed clients?
Codama renders @solana/kit native functions.
gill required?
Optional sugar atop kit.
Next.js?
Import generated clients in client components for writes.
Testing?
Surfpool + devnet integration tests.
web3.js?
Do not mix with generated kit clients.
Multiple programs?
One Codama config per program or monorepo workspace.
Account fetch?
Use generated decoders with getAccountInfo.
Errors?
Map program error codes from IDL metadata.
Related
- Building Transaction Messages - compose tx
- Client-Side Signing - wallet send
- Codama - generate builders
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.