Skip to content

Commit f611466

Browse files
authored
Merge pull request #5 from RECTOR-LABS/dev
chore: revamp README, fix CI, add CLAUDE.md
2 parents ef6d2d1 + 32d8a27 commit f611466

File tree

5 files changed

+448
-175
lines changed

5 files changed

+448
-175
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ jobs:
8585
path: ~/.cargo/bin/anchor
8686
key: anchor-cli-${{ env.ANCHOR_VERSION }}-${{ runner.os }}
8787

88+
- name: Install system dependencies
89+
run: sudo apt-get update && sudo apt-get install -y libudev-dev pkg-config
90+
8891
- name: Install Anchor CLI
8992
if: steps.cache-anchor.outputs.cache-hit != 'true'
9093
run: cargo install --git https://github.com/coral-xyz/anchor --tag v${{ env.ANCHOR_VERSION }} anchor-cli

CLAUDE.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# CLAUDE.md — sol-auction
2+
3+
Project-specific instructions for Claude Code sessions.
4+
5+
## Project Overview
6+
7+
Multi-type auction engine on Solana. Three auction mechanisms (English, Dutch, Sealed-Bid Vickrey) unified under one Anchor program with shared account model and enum-based dispatch.
8+
9+
**Program ID**: `HQvAj4GGwhw4cGkxNXX22vz2NnXe5rok4n5Yyqq3WtMC` (devnet)
10+
11+
## Tech Stack
12+
13+
- **Program**: Rust + Anchor 0.32.1 (`programs/sol-auction/src/`)
14+
- **Tests**: Anchor integration tests (TypeScript, `tests/`) + Rust unit tests (`cargo test --lib`)
15+
- **CLI**: TypeScript + Commander.js (`cli/`)
16+
- **Toolchain**: Rust 1.89.0 (pinned `rust-toolchain.toml`), Solana CLI 2.2.12, Node 22, Yarn
17+
- **CI**: GitHub Actions (`.github/workflows/ci.yml`) — 3 parallel jobs
18+
19+
## Project Structure
20+
21+
```
22+
programs/sol-auction/src/
23+
├── lib.rs # Program entrypoint, 11 instructions
24+
├── errors.rs # 20 custom error variants
25+
├── helpers.rs # Pure functions (fee calc, hash, Vickrey ranking, anti-snipe)
26+
├── state/
27+
│ ├── mod.rs
28+
│ ├── auction.rs # AuctionConfig, AuctionType enum, AuctionStatus
29+
│ ├── auction_house.rs # AuctionHouse (global config)
30+
│ └── bid.rs # BidEscrow
31+
└── instructions/
32+
├── mod.rs
33+
├── initialize_house.rs
34+
├── create_auction.rs
35+
├── place_bid.rs # English: escrow + anti-snipe
36+
├── buy_now.rs # Dutch: atomic purchase
37+
├── submit_sealed_bid.rs # Sealed: Keccak256 commitment
38+
├── reveal_bid.rs # Sealed: verify hash + Vickrey ranking
39+
├── close_bidding.rs # Sealed: permissionless crank
40+
├── settle_auction.rs # English/Sealed: item + payment + fee
41+
├── cancel_auction.rs
42+
├── claim_refund.rs
43+
└── forfeit_unrevealed.rs
44+
tests/ # 33 integration tests (6 suites)
45+
cli/ # TypeScript CLI client
46+
scripts/devnet-demo.ts # End-to-end devnet demo (all 3 types)
47+
```
48+
49+
## Build & Test Commands
50+
51+
```bash
52+
anchor build # Build program
53+
anchor test # Integration tests (local validator)
54+
cargo test --lib # Unit tests (30 tests, no validator)
55+
cargo fmt --all -- --check # Format check
56+
cargo clippy --lib -- -D warnings # Lint (--lib only, not --all-targets)
57+
yarn lint # Prettier check
58+
```
59+
60+
## Critical Notes
61+
62+
### Clippy: Use `--lib` Only
63+
64+
`cargo clippy --all-targets` fails because Anchor's `#[derive(Accounts)]` macro expands to code referencing `solana_program` which isn't resolvable outside the BPF target. Always use `cargo clippy --lib`.
65+
66+
### Anchor Constraints
67+
68+
- `init-if-needed` feature is intentionally omitted — it enables account re-initialization attacks
69+
- All instructions use explicit status checks (no implicit state transitions)
70+
- PDA seeds are deterministic: `[b"auction", seller.key(), &id.to_le_bytes()]`
71+
72+
### Pure Helpers Pattern
73+
74+
`helpers.rs` contains extracted pure functions that have zero Anchor/runtime dependencies. All auction math lives here with comprehensive unit tests. When adding new logic, prefer extracting pure functions into `helpers.rs` over embedding logic in instruction handlers.
75+
76+
### Account Model
77+
78+
- `AuctionHouse`: Global config (fee rate, treasury)
79+
- `AuctionConfig`: Per-auction state with `AuctionType` enum dispatch
80+
- `ItemVault`: SPL Token PDA holding auctioned asset
81+
- `BidEscrow`: Per-bidder PDA (one per bidder per auction, not a vector)
82+
83+
### State Machine
84+
85+
```
86+
Created → Active → {English: Settled, Dutch: Settled, Sealed: BiddingClosed → RevealPhase → Settled}
87+
Created → Cancelled (only if no bids)
88+
```
89+
90+
Status transitions are one-way. No reversal from `Settled` or `Cancelled`.
91+
92+
## Code Conventions
93+
94+
- 4-space indentation (Rust, enforced by `cargo fmt`)
95+
- 2-space indentation (TypeScript, enforced by Prettier)
96+
- All arithmetic uses checked operations (`checked_add`, `checked_sub`, etc.)
97+
- Fee calculations use `u128` intermediate to prevent overflow
98+
- Custom errors are specific and actionable (20 variants in `errors.rs`)
99+
- `#[allow(ambiguous_glob_reexports)]` in `instructions/mod.rs` (all modules export `handler`)
100+
101+
## Devnet
102+
103+
- Shared devnet wallet: `~/Documents/secret/solana-devnet.json`
104+
- Demo script: `npx tsx scripts/devnet-demo.ts`
105+
- Requires `ANCHOR_PROVIDER_URL` and `ANCHOR_WALLET` env vars

0 commit comments

Comments
 (0)