102 lines
5.3 KiB
Markdown
102 lines
5.3 KiB
Markdown
Status: ready-for-agent
|
||
|
||
# US-049 — Mainnet USDT cutover: two-wallet pilot checklist
|
||
|
||
Priority: High (first real-money friends test)
|
||
Stage: Operator runbook + config verification
|
||
|
||
## Goal
|
||
|
||
Move from **Solana devnet + mock-USDT** to **Solana mainnet + real USDT** for a minimal pilot: **one client wallet** (inference payer) and **one node-operator wallet** (payout recipient). Treasury holds USDT and pays SOL fees. TAI stays phase B/C per [ADR-0025](../adr/0025-tai-off-chain-accrual-and-reserved-mint.md).
|
||
|
||
## Wallet roles
|
||
|
||
| Role | Keypair | On-chain use |
|
||
|---|---|---|
|
||
| **Treasury** | Operator `treasury-keypair.json` (multisig when ready) | Holds USDT float + SOL for fees; sends batched node payouts |
|
||
| **Client** | Your inference-user wallet | SPL USDT → treasury; bound to API key for ledger credit |
|
||
| **Node** | Your node-operator wallet | Receives USDT payout batches from treasury |
|
||
|
||
The node process already creates/loads a Solana wallet at startup; the client wallet is bound via accounts/dashboard (`POST /v1/wallet/register` or US-041 flows).
|
||
|
||
## Pre-flight (devnet smoke — do not skip)
|
||
|
||
- [ ] Tracker with `--solana-rpc-url https://api.devnet.solana.com`, mock mint, treasury keypair
|
||
- [ ] `--settle-period 60 --payout-threshold 0` — confirm payout appears on dashboard **Settlement history** with explorer link
|
||
- [ ] Run `python -m pytest tests/test_settlement_loop.py -q` — includes prod 24h/5 USDT gate tests
|
||
- [ ] One inference request → node pending → settlement tx → node wallet balance increases
|
||
|
||
## Mainnet config change (config-only cutover)
|
||
|
||
Replace devnet values; **no code deploy required** beyond what is already on the branch.
|
||
|
||
```bash
|
||
# Example — use your mainnet RPC provider
|
||
meshnet-tracker start \
|
||
--solana-rpc-url https://api.mainnet-beta.solana.com \
|
||
--usdt-mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
|
||
--treasury-keypair ~/.config/solana/meshnet-treasury-mainnet.json \
|
||
--settle-period 86400 \
|
||
--payout-threshold 5.0 \
|
||
--payout-dust-floor 0.01 \
|
||
--starting-credit 0 \
|
||
--devnet-topup 0
|
||
```
|
||
|
||
| Flag | Devnet (test) | Mainnet (pilot) |
|
||
|---|---|---|
|
||
| RPC | `api.devnet.solana.com` | Mainnet RPC (Helius/QuickNode/etc.) |
|
||
| `--usdt-mint` | mock mint from `devnet_setup.py` | Real USDT mint (`EPjF…` on Solana) |
|
||
| `--settle-period` | `60` (fast verify) | `86400` (24 h) |
|
||
| `--payout-threshold` | `0` | `5.0` USDT |
|
||
| `--starting-credit` | `1.0` (optional) | `0` |
|
||
| `--devnet-topup` | `1.0` | `0` |
|
||
|
||
## Treasury funding
|
||
|
||
- [ ] Fund treasury wallet with **SOL** for fees (~0.1–0.5 SOL to start; ~$0.001 per daily batch + ~$0.30 once per new node ATA)
|
||
- [ ] Fund treasury with **USDT** for node payouts (your float — e.g. first week of expected node earnings)
|
||
- [ ] Client wallet holds USDT; send a test SPL transfer to treasury ATA; confirm deposit watcher credits API key within one poll interval
|
||
|
||
## Two-wallet pilot steps
|
||
|
||
1. **Start tracker** on mainnet config above (single settlement tracker per ADR-0016).
|
||
2. **Client path:** register account → create API key → bind **client wallet** → deposit USDT to treasury → verify ledger balance on dashboard.
|
||
3. **Node path:** start `meshnet-node` with **node wallet** keypair → register → serve inference.
|
||
4. **Inference:** client sends `POST /v1/chat/completions` with API key; verify 402 before deposit, success after.
|
||
5. **Accrual:** confirm node **pending USDT** on dashboard rises; client balance debits.
|
||
6. **Payout (24 h):** wait for `--settle-period` **or** temporarily lower to `300` for first pilot verification, then restore `86400`.
|
||
7. **Threshold path:** alternatively, accumulate ≥ `5` USDT pending in one session to trigger immediate batch without waiting 24 h.
|
||
8. **Verify on-chain:** settlement history shows mainnet tx signature; node wallet USDT ATA balance increased; pending zeroed.
|
||
|
||
## Safety checks
|
||
|
||
- [ ] `--devnet-topup 0` — no faucet on mainnet
|
||
- [ ] `--starting-credit 0` — no free inference credit
|
||
- [ ] Treasury keypair not committed to git; file mode 600
|
||
- [ ] Plan multisig migration before large float ([alpha runbook](../../.scratch/alpha-hardening/runbooks/02-treasury-key-rotation.md) intent)
|
||
- [ ] Issue **21** (TOPLOC calibration) before production audit thresholds on untrusted nodes — runbook: [04-toploc-calibration-run](../../.scratch/alpha-hardening/runbooks/04-toploc-calibration-run.md)
|
||
|
||
## Cost estimate (this pilot)
|
||
|
||
- **SOL fees:** pennies per day at 1 batch × 1 node
|
||
- **USDT:** whatever clients deposit and nodes earn (treasury is passthrough for payouts)
|
||
- **TAI mint (optional, ADR-0025 phase B):** ~0.002 SOL one-time — defer if not needed for pilot
|
||
|
||
## Acceptance criteria
|
||
|
||
- [ ] Devnet checklist completed once
|
||
- [ ] Mainnet tracker serves dashboard; billing enabled
|
||
- [ ] Client wallet deposit → ledger credit → inference → debit
|
||
- [ ] Node wallet receives ≥1 confirmed USDT payout batch on mainnet
|
||
- [ ] 24 h period enforced: sub-threshold pending not paid before period (covered by `tests/test_settlement_loop.py`)
|
||
- [ ] ≥5 USDT pending triggers payout without waiting full period (covered by tests)
|
||
- [ ] Rollback documented: switch RPC + mint back to devnet if needed
|
||
|
||
## Related
|
||
|
||
- ADR-0015 (USDT custodial settlement)
|
||
- ADR-0025 (TAI reserved mint / off-chain accrual — not blocking this pilot)
|
||
- US-033 / US-032 (settlement + deposits)
|
||
- `scripts/devnet_setup.py` (devnet only)
|