114 lines
4.7 KiB
Markdown
114 lines
4.7 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Commands
|
|
|
|
### Solana Programs (Rust)
|
|
|
|
```bash
|
|
# Build (registry must be built first — descro depends on it)
|
|
cargo build-sbf --manifest-path programs/descro_ext_resolvers/Cargo.toml && \
|
|
cargo build-sbf --manifest-path programs/descro/Cargo.toml
|
|
|
|
# Test (programs must be built first — tests load .so via include_bytes!)
|
|
cargo test --manifest-path programs/descro/Cargo.toml
|
|
cargo test --manifest-path programs/descro_ext_resolvers/Cargo.toml
|
|
|
|
# Single test / specific file
|
|
cargo test --manifest-path programs/descro/Cargo.toml -- test_create_escrow
|
|
cargo test --manifest-path programs/descro/Cargo.toml --test test_resolve
|
|
|
|
# Lint / Format
|
|
cargo clippy --manifest-path programs/descro/Cargo.toml
|
|
cargo fmt --manifest-path programs/descro/Cargo.toml
|
|
```
|
|
|
|
### TypeScript SDK (`sdk/`)
|
|
|
|
No build step — consumed as raw TypeScript via `transpilePackages` in the app. Install from repo root:
|
|
|
|
```bash
|
|
yarn install
|
|
```
|
|
|
|
### App (`app/`)
|
|
|
|
```bash
|
|
# Dev server (Turbopack)
|
|
yarn workspace descro-app run dev
|
|
|
|
# Production build (generates tamagui.generated.css then runs next build)
|
|
yarn workspace descro-app run build
|
|
```
|
|
|
|
## Repository Structure
|
|
|
|
```
|
|
programs/
|
|
├── descro/ — Escrow Program
|
|
└── descro_ext_resolvers/ — Resolver Registry
|
|
sdk/ — @descro/sdk TypeScript client (workspace package)
|
|
├── src/
|
|
│ ├── idl/ — Anchor-generated IDL JSON files
|
|
│ ├── escrow.ts — EscrowClient (instruction builders + fetchers)
|
|
│ ├── registry.ts — RegistryClient
|
|
│ ├── listener.ts — WebSocket subscriptions
|
|
│ ├── pda.ts — PDA derivation helpers + program IDs
|
|
│ ├── types.ts — TypeScript types matching on-chain state
|
|
│ └── index.ts — Re-exports + DescroSdk convenience class
|
|
app/ — Next.js + Tamagui playground (workspace package)
|
|
├── src/app/ — Next.js App Router pages + providers
|
|
├── src/components/ — UI components (EscrowDetail, ResolverPanel, …)
|
|
└── src/hooks/ — useEscrows, useEscrowDetail
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Yarn Workspaces
|
|
|
|
Root `package.json` declares `workspaces: ["sdk", "app"]`. The repo uses `nodeLinker: node-modules` (in `.yarnrc.yml`) because Next.js Turbopack does not support Yarn PnP. Run `yarn install` from the repo root.
|
|
|
|
The app depends on the SDK via `"@descro/sdk": "workspace:*"` and lists it in `transpilePackages` in `next.config.ts` so Next.js compiles the TypeScript source directly (no SDK build step needed).
|
|
|
|
### Two-Program Protocol
|
|
|
|
`descro` depends on `descro_ext_resolvers` (with `features = ["cpi"]`). Communication is one-way: escrow → registry via CPI. The registry does not depend on the escrow.
|
|
|
|
### Escrow Program (`descro`)
|
|
|
|
**State:** `EscrowAccount` PDA holds trade state. SOL is held in a separate `Vault` PDA (system-owned, data-free).
|
|
|
|
**PDA seeds:**
|
|
- Escrow: `["escrow", seller_pubkey, escrow_id_le_bytes]`
|
|
- Vault: `["vault", escrow_account_pubkey]`
|
|
|
|
**Instruction flow:**
|
|
```
|
|
create_escrow (seller) → deposit (buyer) → complete (buyer)
|
|
→ dispute (buyer|seller) → resolve (resolver)
|
|
cancel (seller, only from AwaitingDeposit)
|
|
```
|
|
|
|
|
|
### Resolver Registry (`descro_ext_resolvers`)
|
|
|
|
**State:** `ResolverEntry` PDA at `["resolver", authority_pubkey]`. Tracks name, type, fee, and resolution stats.
|
|
|
|
**CPI authorization:** Only the escrow program may call `update_stats`, enforced via an `["escrow_authority"]` PDA that only the escrow program can sign for. The registry verifies `seeds::program = ESCROW_PROGRAM_ID`.
|
|
|
|
**Optional CPI:** `resolve()` checks `resolver_entry.data_is_empty()` before calling the registry — unregistered resolvers still work.
|
|
|
|
### Anchor / SDK Notes
|
|
|
|
- **Anchor 1.0.x:** use `UncheckedAccount<'info>` with `/// CHECK:` instead of `AccountInfo<'info>` in account structs; `#[derive(InitSpace)]` + `#[max_len(N)]` for strings.
|
|
- **`@coral-xyz/anchor@0.32.x`:** Use `new Program(idl, provider)` — the IDL's `address` field provides the program ID. The 3-argument form `new Program(idl, programId, provider)` is broken in 0.32.x.
|
|
- **LiteSVM tests:** each `tests/common/mod.rs` has `setup()`, PDA helpers, `send()`/`try_send()`, `ix_*` builders, and `read_*` deserializers. `test_resolve_with_registry.rs` loads both `.so` files to test the full CPI flow.
|
|
|
|
### Program IDs
|
|
|
|
| Program | ID |
|
|
|---|---|
|
|
| `descro` | `DjVR4EuYV6USMJFfsGZwhZ3y8rtWsmG8EvDY96GTqqi3` |
|
|
| `descro_ext_resolvers` | `GwUPAKs3HHzCpj8uhet4NAnxk9GWNwfrYbpihu5DyFp` |
|