# CLAUDE.md: Solana program (Anchor)

## Commands
- `anchor build` · `anchor test` (spins up a local validator) · `cargo clippy --all-targets -- -D warnings` · `cargo fmt --check`
- Check `Anchor.toml` and `Cargo.toml` for the Anchor and Solana versions and use matching APIs; Anchor's macros changed between majors.
- Deploy only to localnet/devnet unless explicitly told otherwise. Never use or print a mainnet keypair.

## Code map
`programs/<name>/src/lib.rs` (instruction entrypoints), `instructions/` (one module per instruction with its `Accounts` struct), `state/` (account structs), `errors.rs`. Clients/tests in `tests/` (TypeScript) or `tests/*.rs`.

## Security rules
- Validate every account through Anchor constraints: `has_one`, `seeds` + `bump`, `constraint = ...`, `address = ...`, and `Signer<'info>` for authorities. Never trust an account just because it was passed in.
- Use typed `Account<'info, T>` / `Program<'info, T>` / `Interface` types; `UncheckedAccount` only with a `/// CHECK:` comment explaining why it is safe.
- PDAs: store the canonical bump in the account on init and reuse it (`bump = state.bump`); don't recompute with arbitrary bumps.
- All arithmetic uses `checked_add/sub/mul/div` and returns a custom error on overflow. No `as` casts that can truncate.
- `init` accounts get explicit `space` (`8 + T::INIT_SPACE` with `#[derive(InitSpace)]`); close accounts with `close = destination` to reclaim rent.
- CPIs: verify the target program ID (use `Program<'info, Token>` etc.), pass signer seeds only for PDAs you own, and re-load accounts after a CPI if you read them again.
- Token work via `anchor_spl` (token or token-2022 interface); check mint and owner of every token account.
- Emit events for state changes; return descriptive `#[error_code]` errors.

## Tests
Cover the happy path plus wrong signer, wrong PDA, wrong mint, and overflow cases for every instruction.

## Don't
Don't add `unsafe` code, disable overflow checks in release profile, or commit keypair JSON files.
