This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Light Token example programs demonstrating rent-free token vaults using Light Protocol on Solana. Contains Anchor programs (escrow, fundraiser, token-swap, light-token-minter, pinocchio-swap), a shared test utilities crate, TypeScript and Rust client examples, and toolkits (payments, streaming, sign-with-privy, gasless-transactions).
All Anchor programs live in programs/anchor/ as a Cargo workspace. Build and test from that directory:
# Build a single program
cd programs/anchor && cargo build-sbf --manifest-path escrow/Cargo.toml
# Test a single program (runs LiteSVM-based tests, no validator needed)
cd programs/anchor && cargo test-sbf -p escrow
cd programs/anchor && cargo test-sbf -p fundraiser
cd programs/anchor && cargo test-sbf -p light-token-minter
cd programs/anchor && cargo test-sbf -p swap_example
# Run a single test by name
cd programs/anchor && cargo test-sbf -p escrow -- test_escrow_spl
# Pinocchio swap example
cd pinocchio/swap && cargo test-sbf -p pinocchio-swap
# TypeScript client examples
cd typescript-client && npm install && npm run create-mint:actionCI runs cargo test-sbf -p <package> for each program (see .github/workflows/rust-tests.yml). Solana CLI 2.3.11, Rust 1.90.0.
All programs use #[light_program] + #[program] dual macros from Light Protocol. The #[light_program] macro generates LightAccountVariant, vault seed structs, and CPI signer boilerplate.
- escrow — Peer-to-peer token swap.
make_offercreates an Offer account + rent-free Light vault;take_offercompletes the swap and closes the vault.OfferderivesLightAccount→ generatesLightAccountVariant::Vault,VaultSeeds,OfferSeeds. - fundraiser — Crowdfunding.
initializecreates a Fundraiser + vault;contribute,check_contributions,refund.Fundraiseruses#[account]only (noLightAccountderive) → no cold/hot vault loading possible. - token-swap — AMM with
create_amm,create_pool,deposit_liquidity,withdraw_liquidity,swap_exact_tokens_for_tokens,create_pool_light_lp. - light-token-minter — Helper program to create Light mints with metadata and mint tokens.
- shared-test-utils — Reusable test helpers for SPL/T22/Light mint creation, ATA creation, SPL interface PDAs, balance verification. All programs depend on this for tests.
Each program's shared.rs contains transfer_tokens() which picks the CPI path at runtime:
- Both accounts Light →
TransferCheckedCpi(direct, no interface PDA) - One SPL/T22 + one Light →
TransferInterfaceCpi(cross-standard, requires SPL interface PDA)
Each program tests 5 token standard combinations via TokenConfig enum:
Spl— SPL mint + SPL ATAs + Light vaultToken2022— T22 mint + T22 ATAs + Light vaultLight— Light mint + Light ATAs + Light vaultLightSpl— SPL mint, but user accounts converted to Light ATAs before escrowLightT22— T22 mint, but user accounts converted to Light ATAs before escrow
Tests follow: create_test_rpc() → setup_*_test(config) → create_token_account()/create_contributor() → run_*_full_flow(). Common modules in tests/common/mod.rs.
Light accounts auto-compress after rent expires. Escrow tests exercise the full cycle: create → warp_to_compress (calls rpc.warp_epoch_forward(30)) → load_light_accounts → transact. Fundraiser skips this because Fundraiser state lacks LightAccount derive.
All light-* crates are sourced from crates.io (currently 0.23.0).
CpiSigner+derive_light_cpi_signer!at crate root for each program- Constants used in
token::owner_seedsmust bepub use-exported fromlib.rs - Per-program rent sponsor PDA:
derive_rent_sponsor_pda(&program_id)— separate from globalLIGHT_TOKEN_RENT_SPONSOR get_create_accounts_proof()fetches validity proofs for account creation (needed forinitinstructions, not reads)InitializeRentFreeConfigsets up per-program compression config before any#[light_account(init)]