Skip to main content
ClaudeWave
Slash Command65 repo starsupdated yesterday

generate-idl-client

Generate TypeScript client from Solana program IDL using Codama or Anchor

Install in Claude Code
Copy
mkdir -p ~/.claude/commands && curl -fsSL https://raw.githubusercontent.com/solanabr/solana-ai-kit/HEAD/.claude/commands/generate-idl-client.md -o ~/.claude/commands/generate-idl-client.md
Then start a new Claude Code session; the slash command loads automatically.

generate-idl-client.md

You are generating a TypeScript client from a Solana program's IDL. Detect the IDL source and generator, run the appropriate pipeline, and verify the output compiles.

## Related Skills

- [ext/solana-dev/skill/references/idl-codegen.md](../skills/ext/solana-dev/skill/references/idl-codegen.md) - Codama/Shank client generation patterns
- [ext/solana-dev/skill/references/programs/anchor.md](../skills/ext/solana-dev/skill/references/programs/anchor.md) - Anchor IDL format

## Step 1: Detect IDL Source

```bash
echo "Detecting IDL source..."
echo ""

# Check for Anchor IDL
if ls target/idl/*.json 2>/dev/null; then
    echo "Found Anchor IDL(s) in target/idl/"
    IDL_SOURCE="anchor"
    ls -la target/idl/*.json
fi

# Check Anchor.toml for program names
if [ -f "Anchor.toml" ]; then
    echo ""
    echo "Anchor.toml programs:"
    grep -A 10 '\[programs' Anchor.toml
fi

# Check for Shank-annotated programs
if grep -r "ShankInstruction\|ShankAccount\|shank" --include="*.rs" programs/ src/ 2>/dev/null | head -5; then
    echo ""
    echo "Shank annotations detected"
    IDL_SOURCE="${IDL_SOURCE:-shank}"
fi

# Check for Codama config
if [ -f "codama.json" ] || [ -f "codama.config.ts" ] || [ -f "codama.config.js" ]; then
    echo ""
    echo "Codama config found"
    IDL_SOURCE="${IDL_SOURCE:-codama}"
fi

# Check for existing IDL files in other locations
if ls idl/*.json 2>/dev/null || ls *.idl.json 2>/dev/null; then
    echo ""
    echo "Found IDL files in project root or idl/ directory"
fi

echo ""
echo "IDL source: ${IDL_SOURCE:-unknown}"
```

## Step 2: Generate IDL (if needed)

### Anchor IDL Generation

```bash
if [ "$IDL_SOURCE" = "anchor" ] || [ -f "Anchor.toml" ]; then
    echo "Generating Anchor IDL..."

    # Build IDL
    anchor build

    if [ $? -ne 0 ]; then
        echo "Anchor build failed. Fix errors before generating client."
        exit 1
    fi

    echo ""
    echo "Generated IDL files:"
    ls -la target/idl/*.json

    # Show IDL summary
    for idl in target/idl/*.json; do
        PROGRAM=$(basename "$idl" .json)
        INSTRUCTIONS=$(grep -c '"name"' "$idl" | head -1)
        echo "  $PROGRAM: $(cat "$idl" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'{len(d.get(\"instructions\",[]))} instructions, {len(d.get(\"accounts\",[]))} accounts')" 2>/dev/null || echo "parsed")"
    done
fi
```

### Shank IDL Generation

```bash
if [ "$IDL_SOURCE" = "shank" ]; then
    echo "Generating IDL with Shank..."

    # Install shank-cli if needed
    if ! command -v shank >/dev/null 2>&1; then
        echo "Installing shank-cli..."
        cargo install shank-cli
    fi

    # Find program crate
    PROGRAM_DIR=$(find programs/ src/ -name "Cargo.toml" -maxdepth 2 | head -1 | xargs dirname)

    if [ -n "$PROGRAM_DIR" ]; then
        shank idl -r "$PROGRAM_DIR" -o target/idl/
        echo "Shank IDL generated in target/idl/"
    else
        echo "Could not find program crate for Shank"
    fi
fi
```

## Step 3: Determine Client Generator

```bash
echo ""
echo "Detecting client generator..."

# Check for Codama pipeline
if [ -f "codama.json" ] || [ -f "codama.config.ts" ]; then
    GENERATOR="codama"
    echo "Using Codama pipeline"
elif [ -f "Anchor.toml" ]; then
    GENERATOR="anchor"
    echo "Using Anchor client generation"
else
    GENERATOR="codama"
    echo "Defaulting to Codama (recommended)"
fi

echo "Generator: $GENERATOR"
```

## Step 4: Generate Client - Codama

```bash
if [ "$GENERATOR" = "codama" ]; then
    echo "Generating client with Codama..."

    # Install Codama if needed
    if ! npm ls @codama/renderers-js 2>/dev/null | grep -q "@codama"; then
        echo "Installing Codama dependencies..."
        npm install --save-dev @codama/renderers-js @codama/nodes-from-anchor
    fi

    # Determine output directory
    CLIENT_DIR="src/generated"
    if [ -d "app" ]; then
        CLIENT_DIR="app/src/generated"
    elif [ -d "web" ]; then
        CLIENT_DIR="web/src/generated"
    fi

    mkdir -p "$CLIENT_DIR"

    # If codama config exists, use it
    if [ -f "codama.config.ts" ]; then
        npx tsx codama.config.ts
    elif [ -f "codama.config.js" ]; then
        node codama.config.js
    else
        # Generate using Codama API directly
        # The agent should create a codama generation script based on the IDL
        echo "No codama config found. Create codama.config.ts or use Anchor generation."
        echo ""
        echo "Example codama.config.ts:"
        echo '
import { createFromRoot } from "@codama/nodes";
import { rootNodeFromAnchor } from "@codama/nodes-from-anchor";
import { renderJavaScriptVisitor } from "@codama/renderers-js";
import anchorIdl from "./target/idl/program_name.json";

const node = rootNodeFromAnchor(anchorIdl);
const codama = createFromRoot(node);
codama.accept(renderJavaScriptVisitor("./src/generated"));
'
    fi

    echo "Client generated in $CLIENT_DIR"
fi
```

## Step 5: Generate Client - Anchor

```bash
if [ "$GENERATOR" = "anchor" ]; then
    echo "Generating Anchor TypeScript client..."

    # Anchor generates types automatically during build
    # Check for generated types
    if [ -d "target/types" ]; then
        echo "Anchor types found in target/types/"
        ls target/types/
    fi

    # For standalone client generation from IDL
    CLIENT_DIR="src/generated"
    if [ -d "app" ]; then
        CLIENT_DIR="app/src/generated"
    fi
    mkdir -p "$CLIENT_DIR"

    # Copy IDL for frontend consumption
    for idl in target/idl/*.json; do
        PROGRAM=$(basename "$idl" .json)
        cp "$idl" "$CLIENT_DIR/${PROGRAM}_idl.json"
        echo "Copied IDL: $CLIENT_DIR/${PROGRAM}_idl.json"
    done

    echo ""
    echo "For Anchor projects, import the IDL and use Program class:"
    echo '  import idl from "./generated/program_name_idl.json";'
    echo '  const program = new Program(idl, provider);'
fi
```

## Step 6: Verify Generated Types Compile

```bash
echo ""
echo "Verifying generated client compiles.
anchor-engineerSubagent

Anchor framework specialist for rapid Solana program development. Use for building programs with Anchor macros, IDL generation, account validation, and standardized patterns. Prioritizes developer experience while maintaining security.\\n\\nUse when: Building new programs quickly, team projects needing standardization, projects requiring IDL for client generation, or when developer experience is prioritized over maximum CU optimization.

defi-engineerSubagent

DeFi integration specialist for composing with Solana protocols including Jupiter, Drift, Kamino, Raydium, Orca, Meteora, Marginfi, and Sanctum. Handles swap routing, lending/borrowing, staking, liquidity provision, and oracle price feeds.\n\nUse when: Integrating DeFi protocols, building swap interfaces, implementing lending/borrowing, setting up yield strategies, working with Pyth/Switchboard oracles, or composing multi-protocol transactions.

devops-engineerSubagent

CI/CD, infrastructure, and deployment specialist for Solana projects. Handles GitHub Actions, Docker, monitoring, RPC management, and Cloudflare Workers edge deployment.\n\nUse when: Setting up CI/CD pipelines, containerizing Solana validators or programs, configuring monitoring and alerting, managing RPC infrastructure, deploying edge workers, or automating build and deploy workflows.

game-architectSubagent

Senior Solana game architect for game system design, Unity/C# architecture, on-chain game state, player progression, NFT integration, and PlaySolana ecosystem. Use for high-level game design decisions, architecture reviews, and planning complex game systems.\n\nUse when: Designing new Solana games from scratch, planning game state on-chain, Unity project architecture, integrating with PlaySolana/PSG1, or deciding between implementation approaches.

mobile-engineerSubagent

React Native and Expo specialist for building Solana mobile dApps. Handles mobile wallet adapter integration, transaction signing UX, deep linking, and mobile-specific performance optimization.\n\nUse when: Building React Native or Expo mobile apps with Solana integration, implementing mobile wallet adapter flows, setting up deep links for transaction signing, or optimizing mobile dApp performance.

pinocchio-engineerSubagent

CU optimization specialist using Pinocchio framework. Use for performance-critical programs requiring 80-95% CU reduction vs Anchor. Specializes in zero-copy access, manual validation, and minimal binary size.\\n\\nUse when: CU limits are being hit, transaction costs are significant at scale, binary size must be minimized, or maximum throughput is required.

rust-backend-engineerSubagent

Rust backend specialist for building async services that interact with Solana blockchain. Builds APIs, indexing services, and off-chain processing using Axum, Tokio, and modern async patterns.\n\nUse when: Building REST/WebSocket APIs for Solana dApps, implementing transaction indexers, creating webhook services, or any Rust backend that interacts with Solana.

solana-architectSubagent

Senior Solana program architect for system design, account structures, PDA schemes, token economics, and cross-program composability. Use for high-level design decisions, architecture reviews, and planning complex multi-program systems.\n\nUse when: Designing new programs from scratch, planning account structures, optimizing PDA schemes, reviewing architecture for security, or deciding between implementation approaches.