# Manual x402 unlock — seller-agent / generational-agent

Unlock sealed packs on **Base** mainnet with USDC via HTTP 402.

## Prerequisites

| Item | Value |
|------|--------|
| Network | **Base** (chain id 8453) |
| Asset | USDC on Base |
| Pay to | `0xa00876513bAA433ce2B58A5341Fd06d2b6f9A6ED` (from `/api/health` → `payments.payTo`) |
| Price | **$24.99** USDC each (`seller-agent`, `buyer-agent`, `generational-agent`) |
| Wallet | MetaMask (or any Base wallet) with USDC + ETH for gas |

## Skills

| Skill | Pay challenge | Detail |
|-------|---------------|--------|
| Seller Agent | https://lvlltd.com/api/pay?skill=seller-agent | https://lvlltd.com/skill-details/seller-agent.md |
| Generational Agent | https://lvlltd.com/api/pay?skill=generational-agent | https://lvlltd.com/skill-details/generational-agent.md |
| Buyer Agent | https://lvlltd.com/api/pay?skill=buyer-agent | https://lvlltd.com/skill-details/buyer-agent.md |

## Path A — Marketplace UI (recommended)

1. Open https://lvlltd.com/hub/marketplace/ (or homepage skill card).  
2. Find **Seller Agent** or **Generational Agent Infrastructure**.  
3. Connect wallet on Base.  
4. Click unlock / pay — wallet prompts for **USDC transfer** matching the x402 challenge.  
5. After confirm, the site POSTs `X-PAYMENT` to `/api/pay` and downloads unlock JSON + sealed pack files.  
6. Install locally:  
   `node scripts/install-unlocked-pack.mjs unlock.json ./skills`

## Path B — Manual curl + wallet (operator debug)

### 1. Fetch 402 challenge

```bash
curl -s "https://lvlltd.com/api/pay?skill=seller-agent" | jq .
curl -s "https://lvlltd.com/api/pay?skill=generational-agent" | jq .
# Expect HTTP 402
```

Live challenge shape (verified):

| Field | Value |
|-------|--------|
| `accepts[0].network` | `base` |
| `accepts[0].maxAmountRequired` | `24990000` ($24.99 USDC, 6 decimals) |
| `accepts[0].payTo` | `0xa00876513baa433ce2b58a5341fd06d2b6f9a6ed` |
| `accepts[0].asset` | USDC |
| `accepts[0].assetContract` | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
| Also accepts | USDbC `0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA` |

### 2. Send USDC on Base

Transfer exactly **24990000** base units (\$24.99) to `payTo`.  
Record **tx hash**.

### 3. Unlock with payment proof

```bash
# Shape of X-PAYMENT depends on x402 client; marketplace UI builds this after wallet settle.
# After unlock response, save body as unlock.json
curl -s -X POST "https://lvlltd.com/api/pay?skill=seller-agent" \
  -H "Content-Type: application/json" \
  -H "X-PAYMENT: <base64-or-json-payment-payload-from-wallet-flow>" \
  -o unlock-seller.json
```

Demo / fake receipts are **rejected** when `X402_LIVE=1` (production).

### 4. Install pack

```bash
node scripts/install-unlocked-pack.mjs unlock-seller.json ./skills
# Seller runtime under skills/seller-agent or goods/seller-agent
```

### 5. Re-redeem

```bash
# Same verified txHash returns sealed_pack.files again (idempotent ledger)
curl -s -X POST "https://lvlltd.com/api/pay" \
  -H "Content-Type: application/json" \
  -H 'X-PAYMENT: {"txHash":"0xYOUR_VERIFIED_TX","skill":"seller-agent"}' \
  -o unlock-seller.json
```

### 6. Public sealed CDN (teasers only)

Public `/sealed/<id>/` serves **stubs and marketing files only**. Full `src/` implementation is **not** on the public CDN; it is returned only inside the unlock JSON after verified payment. HTTP requests to `/__locked__/*` return **403**.

Agent client: https://lvlltd.com/sdk/agent-shop.mjs  
OpenAPI: https://lvlltd.com/openapi.json  
llms.txt: https://lvlltd.com/llms.txt

### 7. Verify teaser static (paywall stub)

```bash
curl -sI "https://lvlltd.com/sealed/seller-agent/src/intake.js"
curl -sI "https://lvlltd.com/sealed/generational-agent/src/succession.js"
# Entitlement is the unlock receipt; static CDN may be public for inspection
```

## Smoke after unlock (local)

```bash
npm run seller-agent:test
npm run generational:test
node scripts/seller-agent-run.mjs intake --spec demos/seller-agent/sell-spec.rav4.json
node scripts/generational-agent-run.mjs init --role seller-agent
```

## Failures to check

| Symptom | Likely cause |
|---------|----------------|
| 503 Payments not configured | `X402_LIVE=0` on Pages |
| 402 always on POST | Missing/invalid `X-PAYMENT` or wrong amount |
| Demo receipt rejected | Live mode — use real Base tx |
| Wrong payTo | Confirm `/api/health` → `payments.payTo` |
