Status: ready-for-agent # 32 — Devnet custodial treasury: mock-USDT mint + deposit watcher ## What to build The real Solana adapter behind the `packages/contracts` boundary, custodial model per ADR-0015. All on-chain surface is plain SPL transfers — no Anchor programs. **Setup script** (`scripts/devnet_setup.py`): creates the mock-USDT SPL mint (6 decimals, matching real USDT) and the treasury token account on devnet, airdropping SOL for fees, and prints the `.env.devnet` values (mint address, RPC URL, treasury keypair path). **Wallet binding**: `POST /v1/wallet/register` binds a client wallet pubkey to an API key. **Deposit watcher**: polls the treasury token account for confirmed incoming USDT transfers and credits the sending wallet's bound API-key ledger balance. Transaction signatures are deduplicated so replayed/re-observed transfers credit exactly once. Note: this supersedes the "testnet, never devnet" note in issue 06 (see ADR-0015) — devnet is the ecosystem standard for app development and real USDT exists on neither cluster. ## Acceptance criteria - [ ] `scripts/devnet_setup.py` creates mint + treasury ATA and prints `.env.devnet` values - [ ] `POST /v1/wallet/register` binds client wallet pubkey to API key - [ ] Deposit watcher credits ledger within one poll interval of a confirmed transfer - [ ] Duplicate/replayed transactions credit exactly once (signature dedupe) - [ ] Local `solana-test-validator` integration test covers mint → deposit → credit - [ ] Deterministic local adapter still works for CI without any validator ## Blocked by - `31-billing-ledger.md`