Introduction
Getting Started with Shank
This guide will walk you through setting up Shank and extracting your first IDL from a Rust Solana program.
Prerequisites
Before getting started with Shank, ensure you have:
- Rust toolchain installed (1.56.0 or later)
- Cargo package manager
- A Solana program written in Rust
- Basic familiarity with Solana program development
Installation
Installing Shank CLI
Install the Shank command-line tool using Cargo:
cargo install shank-cli
Verify the installation:
shank --version
Adding Shank to Your Project
Add Shank as a dependency in your Cargo.toml
:
[dependencies]
shank = "0.4"
[build-dependencies]
shank-cli = "0.4"
Your First Shank Project
1. Annotate Your Program
Start by adding Shank derive macros to your existing Solana program:
use shank::ShankInstruction;
#[derive(ShankInstruction)]
#[rustfmt::skip]
pub enum MyProgramInstruction {
/// Creates a new account with the given name
#[account(0, writable, signer, name="user", desc="User account")]
#[account(1, writable, name="account", desc="Account to create")]
#[account(2, name="system_program", desc="System program")]
CreateAccount {
name: String,
space: u64,
},
/// Updates an existing account
#[account(0, writable, signer, name="authority", desc="Account authority")]
#[account(1, writable, name="account", desc="Account to update")]
UpdateAccount {
new_name: String,
},
}
2. Annotate Account Structures
Add ShankAccount
to your account structs:
use shank::ShankAccount;
#[derive(ShankAccount)]
pub struct UserAccount {
pub name: String,
pub created_at: i64,
pub authority: Pubkey,
}
3. Extract IDL
Run the Shank CLI to extract the IDL:
shank idl --out-dir ./target/idl --crate-root ./
This will generate an IDL file (e.g., my_program.json
) in the ./target/idl
directory.
4. Verify the Output
Check the generated IDL file:
cat ./target/idl/my_program.json
You should see a JSON structure containing your program's instructions, accounts, and types.
Project Structure
A typical Shank-enabled project structure looks like:
my-solana-program/
βββ Cargo.toml
βββ src/
β βββ lib.rs
β βββ instruction.rs # Contains ShankInstruction enums
β βββ state.rs # Contains ShankAccount structs
β βββ processor.rs # Program logic
βββ target/
β βββ idl/
β βββ my_program.json # Generated IDL
βββ sdk/ # Generated TypeScript SDK (optional)
βββ ...
Core Components
Shank consists of several interconnected crates:
- shank: Top-level crate providing macro annotations
- shank-cli: Command-line tool for IDL extraction
- shank-macro: Derive macros for code generation
- shank-idl: Processes files and converts annotations to IDL
- shank-render: Generates Rust implementation blocks
Key Features
Derive Macros
Shank provides five essential derive macros for annotating your Solana program code:
ShankAccount
: Annotates structs representing accounts with serializable data- Supports
#[idl_type()]
for type overrides - Supports
#[padding]
for padding fields - Works with Borsh serialization
- Supports
ShankBuilder
: Generates instruction builders for each annotated instruction- Creates builder pattern implementations
- Simplifies instruction construction
ShankContext
: Creates account structs for instructions- Generates context structures for program instructions
- Integrates with Anchor framework patterns
ShankInstruction
: Annotates the program's instruction enum- Uses
#[account()]
attributes to specify account requirements - Supports account mutability, signer requirements, and descriptions
- Generates comprehensive instruction metadata
- Uses
ShankType
: Marks structs or enums with serializable data- Used for custom types referenced in accounts or instructions
- Ensures proper IDL generation for complex data structures
Integration with Metaplex Ecosystem
Shank integrates seamlessly with other Metaplex tools:
- Kinobi: Uses Shank JS library for IDL generation and client creation
- Solita: Generates TypeScript SDKs from Shank-extracted IDLs
CLI Usage
Once you have Shank installed and your program annotated, extract IDL with:
# Basic IDL extraction
shank idl --out-dir ./target/idl --crate-root ./
# Extract IDL for a specific crate
shank idl --out-dir ./idl --crate-root ./my-program
# Generate IDL with custom program ID
shank idl --out-dir ./idl --crate-root ./ --program-id MyProgram111111111111111111111111111111
Next Steps
Now that you have Shank set up and generating IDL files, you can:
- Macros Reference: Complete reference for all Shank macros and attributes
- Integration with Kinobi: Generate modern TypeScript SDKs compatible with Umi (recommended)
- Solita: Generate legacy TypeScript SDKs compatible with web3.js
Troubleshooting
Common Issues
IDL generation fails with parsing errors:
- Ensure your Rust code compiles successfully
- Check that all derive macros are properly imported
- Verify account annotations are correctly formatted
Missing accounts in generated IDL:
- Make sure structs are annotated with
#[derive(ShankAccount)]
- Check that the struct is public and accessible
Build script errors:
- Ensure
shank-cli
is installed and available in PATH - Verify build script permissions and execution rights
For more help, visit our GitHub repository or join the Metaplex Discord.