- @pyre/solana: buildCloseEmptyAccountsTx (UNSIGNED v0 tx; re-validates each account on-chain — owner==wallet, balance==0, correct program, not frozen/delegated, Token-2022 EMPTY_CLOSE_ONLY via §7.1; rejects whole build on any ineligible account), simulateTransaction, decodeTransaction. Rent destination + close authority + fee payer all pinned to the wallet. - @pyre/api: POST /api/build/close-empty (server re-validates, 400 on ineligible) and POST /api/receipt (on-chain verified: meta.err==null, signer==wallet, rent from balance delta; lists only closes whose destination==wallet). - @pyre/web: select empty accounts → build → CLIENT-SIDE decode+match (7 checks: feePayer/all-closeAccount/dest==wallet/closed-set==selected==preview) gates signing → sign in wallet → send → confirm → on-chain receipt w/ explorer link. Built by 3 agents, reviewed by 2 audits (security: SOUND — no critical/high; integration: SHIP). Applied audit fixes: receipt destination check, doc/lint cleanup. typecheck 8/8, core 85, solana 19, web build green. Live-verified: the API refuses to build a close tx for a non-empty account (400). buildBurnTx remains a Phase-3 stub. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pyre/web
User-facing PYRE web app. Skeleton only — no wallet or business logic is
implemented yet (see CLAUDE.md and §13 of the design doc).
Stack: Next.js (App Router) + TypeScript + Tailwind + Solana Wallet Adapter + React Query.
Responsibilities (§13)
- Landing page
- Wallet connect (Solana Wallet Adapter)
- Scanner UI — display token accounts and classification grouping
- Cleanup preview — accounts to close, tokens to burn, rent returned, fees, warnings, rent destination (decode tx and match against preview before signing)
- Receipt page — tx signature, accounts closed, tokens burned, rent returned, skipped accounts
- Prometheus generation preview — Spawn name/ticker/lore/image-prompt review
- Admin review page — approve/reject generated Spawn packages
Trust rules (do not weaken)
- PYRE never holds private keys; all signing is client-side in the user's wallet.
- Always show a preview and match the decoded transaction against it before requesting a signature.
- Recovered ATA rent returns to the user by default.
TODO
- Tailwind + PostCSS config and global styles
- WalletAdapter / React Query providers
- Scanner page wired to
POST /api/scan - Cleanup preview + transaction decode/match UI
- Sign flow via wallet adapter
- Receipt page wired to
POST /api/receipt - Prometheus generation preview + admin review pages
Scripts
dev—next devbuild—next buildtypecheck—tsc --noEmitlint/test— placeholders for now