# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Overview This repo contains essential programs for the **Logos Execution Zone (LEZ)** — a zkVM-based execution environment built on [RISC Zero](https://risczero.com/). Programs run inside the RISC Zero zkVM (`riscv32im-risc0-zkvm-elf` target) and interact with the LEZ runtime via the `nssa_core` library from `logos-execution-zone`. Five programs are implemented: - **token** — Fungible and non-fungible token program (create, mint, burn, transfer, print NFTs) - **amm** — Automated market maker (constant product AMM with add/remove liquidity and swaps) - **ata** — Associated Token Account program (derives and initializes deterministic token accounts for a given owner and token definition) - **stablecoin** — Collateral-backed position program (open positions, repay debt, withdraw collateral) - **twap_oracle** — TWAP oracle (provides canonical on-chain price accounts consumed by other programs) ## Build Commands ```bash # Check all workspace crates (skips expensive guest ZK builds) make clippy # Run all tests (dev mode skips ZK proof generation) make test # Run tests for a single package RISC0_DEV_MODE=1 cargo test -p token_program RISC0_DEV_MODE=1 cargo test -p amm_program RISC0_DEV_MODE=1 cargo test -p ata_program RISC0_DEV_MODE=1 cargo test -p stablecoin_program RISC0_DEV_MODE=1 cargo test -p twap_oracle_program # Format make fmt # Build the guest ZK binary (requires risc0 toolchain) cargo risczero build --manifest-path programs//methods/guest/Cargo.toml ``` Built binaries output to: `/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/.bin` ## IDL Generation Using the `idl-gen` crate (no external toolchain required — this is what CI uses): ```bash make idl ``` Or individually per program: ```bash cargo run -p idl-gen -- programs//methods/guest/src/bin/.rs > artifacts/-idl.json ``` Alternatively, using the `spel` CLI (requires the SPEL toolchain): ```bash spel generate-idl programs//methods/guest/src/bin/.rs > artifacts/-idl.json ``` Generated IDL files live in `artifacts/`. CI checks that every program under `*/methods/guest/src/bin/` has a corresponding `artifacts/-idl.json` that matches the source. ## Deployment `wallet` and `spel` are CLI tools that ship with the [SPEL](https://github.com/logos-co/spel.git) toolchain. `wallet` requires `NSSA_WALLET_HOME_DIR` to point to a directory containing the wallet config. **Note:** `spel` and `wallet` may use different versions of the wallet package. If `spel --idl ...` fails, ensure `seq_poll_timeout_millis` is set in the wallet config at `~/.nssa/wallet`. ```bash # Deploy a program binary to the sequencer wallet deploy-program # Inspect the ProgramId of a built binary spel inspect ``` ## Workspace Structure ``` Cargo.toml # Workspace root (excludes guest crates) programs/ token/ core/src/lib.rs # Data types & Instruction enum (shared with guest) src/ # Program logic: burn, mint, transfer, initialize, new_definition, print_nft methods/ # Host-side zkVM method embedding (build.rs uses risc0_build::embed_methods) methods/guest/ # Guest binary (separate workspace, riscv32im target) amm/ core/src/lib.rs # Data types, Instruction enum, PDA computation helpers src/ # Program logic: add, remove, swap, new_definition methods/ # Host-side zkVM method embedding methods/guest/ # Guest binary (separate workspace) ata/ core/src/lib.rs # Data types & Instruction enum src/ # Program logic: create, burn, transfer methods/ # Host-side zkVM method embedding methods/guest/ # Guest binary (separate workspace) stablecoin/ core/src/lib.rs # Data types & Instruction enum src/ # Program logic: open_position, repay_debt, withdraw_collateral methods/ # Host-side zkVM method embedding methods/guest/ # Guest binary (separate workspace) twap_oracle/ core/src/lib.rs # Data types & Instruction enum src/ # Program logic: noop (price account initialization) methods/ # Host-side zkVM method embedding methods/guest/ # Guest binary (separate workspace) integration_tests/ tests/ # End-to-end tests through the zkVM (token, amm, ata) apps/ amm/ # QML-based UI for the AMM program (Nix flake) ``` ## Architecture Each program follows a layered pattern: 1. **`*_core` crate** — shared types (Instructions, account data structs) serialized with Borsh for on-chain storage, serde for instruction passing. Also contains PDA seed computation (amm_core). 2. **Program crate** — pure functions that take `AccountWithMetadata` inputs and return `Vec` (and `Vec` for AMM). No I/O or state — all state transitions are deterministic and testable without the zkVM. 3. **`methods/guest`** — the guest binary wired to the LEZ framework via `spel-framework` using the `#[lez_program]` and `#[instruction]` proc macros. This is what gets compiled to RISC-V and ZK-proven. 4. **`methods`** — host crate that embeds the guest ELF for use in tests and deployment. ## Key Patterns **Account data serialization**: On-chain account data uses Borsh (`BorshSerialize`/`BorshDeserialize`). Instructions use serde JSON. Both implement `TryFrom<&Data>` and `From<&T> for Data` for conversion. **Program-Derived Addresses (PDAs)**: The AMM uses SHA-256-based PDAs (`compute_pool_pda`, `compute_vault_pda`, `compute_liquidity_token_pda` in `amm_core`) to derive deterministic account addresses for pools, vaults, and liquidity tokens. **Chained calls**: The AMM's swap and liquidity operations compose with the token program via `ChainedCall` — the AMM instructs the token program to execute transfers as part of the same atomic operation. **Testing**: Tests call program functions directly (no zkVM overhead). Set `RISC0_DEV_MODE=1` to skip ZK proof generation when running integration tests that go through the zkVM. The Rust toolchain version is pinned in `rust-toolchain.toml`.