# Obsidio × x402

**Status:** Phase 2 live — `https://obsidio.network/x402/demo/ping` (also `/rpc/x402/demo/ping`) 402→pay→200; `validatePayment` checks amount/pay_to/asset + tx reuse; C1 travel-rule gate (≥1000 OBS). Remaining: wallet auto-retry client, live sanctions feed, C3–C4 ops.  
**Dev guide:** [https://obsidio.network/developers/#x402](https://obsidio.network/developers/#x402)  
**Spec reference:** [x402 v2](https://github.com/x402-foundation/x402/blob/main/specs/x402-specification-v2.md) · [HTTP transport](https://github.com/coinbase/x402/blob/main/specs/transports-v2/http.md)

## Why

x402 unlocks **HTTP 402 Payment Required** for agents and APIs. Obsidio bots should sell both:

- to humans in chat (`sendInvoice`)  
- to machines over HTTP (x402)

**One settlement layer:** invoice / memo / L1 transfer.

## Standard headers (do not invent a parallel protocol)

| Header | Direction | Content |
|--------|-----------|---------|
| `PAYMENT-REQUIRED` | Server → Client | Base64 JSON `PaymentRequired` |
| `PAYMENT-SIGNATURE` | Client → Server | Base64 JSON payment payload / proof |
| `PAYMENT-RESPONSE` | Server → Client | Base64 JSON settlement result |

Legacy `X-Obsidio-*` headers may appear only as a **compat shim** in early wallet builds.

## Obsidio network binding

```json
{
  "x402Version": 2,
  "error": "Payment required",
  "resource": {
    "url": "/x402/demo/ping",
    "description": "Demo paid ping"
  },
  "accepts": [
    {
      "scheme": "exact",
      "network": "obsidio:mainnet-v2",
      "amount": "1000000000000000000",
      "asset": "OBS",
      "payTo": "ons1…",
      "maxTimeoutSeconds": 3600,
      "extra": {
        "memo": "inv_abc",
        "invoice_id": "inv_abc",
        "decimals": 18
      }
    }
  ]
}
```

### Settlement flow (Obsidio `exact`)

1. Resource returns **402** + `PAYMENT-REQUIRED`.  
2. Client creates invoice-linked transfer (or uses returned `invoice_id`) and pays on L1.  
3. Client retries with `PAYMENT-SIGNATURE` carrying at least:
   ```json
   {
     "x402Version": 2,
     "scheme": "exact",
     "network": "obsidio:mainnet-v2",
     "payload": {
       "tx_hash": "…",
       "invoice_id": "inv_abc",
       "payer": "ons1…"
     }
   }
   ```
4. Server / facilitator calls `obsidio_validatePayment` (amount, `pay_to`, memo/invoice, confirmation).  
5. On success: **200** + body + `PAYMENT-RESPONSE`.

Facilitator MVP = **Obsidio node RPC** (no external Coinbase facilitator required for OBS-native scheme).

## RPC

| Method | Role |
|--------|------|
| `obsidio_createInvoice` | Build pay intent (also used by bots) |
| `obsidio_confirmInvoicePayment` | Attach `tx_hash` after L1 send |
| `obsidio_validatePayment` | Facilitator check for x402 / bots |
| `obsidio_x402Quote` | Build `PaymentRequired` object for a resource |

HTTP demo: `GET /x402/demo/ping` → 402; retry with signature → 200.

## Shared with bots

```
sendInvoice  ──┐
x402 402     ──┼──► InvoiceStore(memo, amount, pay_to)
               │
L1 Transfer  ──┘──► confirm / validate ──► webhook payment | HTTP 200
```

## Compliance roadmap (must reach “full”)

Aligned with [JURISDICTION.md](./JURISDICTION.md) and `compliance_svc`:

| Stage | Feature |
|-------|---------|
| **C0** | Sanctions name/address check on `pay_to` & payer before confirming invoice |
| **C1** | Amount threshold (e.g. ≥ 1000 OBS equiv): require travel-rule envelope (existing Kyber demo path) |
| **C2** | Persist travel-rule check id on invoice; refuse settle if missing/invalid |
| **C3** | Operator policy hooks (geo / deny lists) without breaking open RPC reads |
| **C4** | Audit export of paid invoices for VASP-style ops (if Operator becomes regulated) |

Until C1+, large-value x402 is **testnet/demo posture** — not a compliance certification.

## Non-goals (for now)

- EIP-3009 / Permit2 (EVM schemes) — separate if we bridge USDC rails into x402 later  
- Batch settlement schemes  
- Replacing chat pay-to-read (different product)

## Acceptance criteria (“done”)

1. Demo bot sells an item in chat via invoice.  
2. Same payee serves `GET /x402/...` with real 402 → pay → 200.  
3. `validatePayment` rejects wrong amount / wrong `pay_to` / expired invoice.  
4. C0 sanctions block + C1 travel-rule gate wired for large invoices.  
5. Public docs + `demos/bots` runnable against mainnet RPC.
