# x402 adapter

The `@quitanza/x402` adapter maps the HTTP 402 payment-required handshake onto the Quitanza escrow lifecycle, so an x402-style paid request settles with recourse and ends in a quitanza instead of a bare transfer. The adapter is live today on simulated rails (scheme `quitanza-sandbox`, network `quitanza-local`); integration with external x402 facilitators is in development.

## The handshake, settled through escrow

1. The client requests a paid resource. The server answers `402 Payment Required` with an `accepts` array of payment requirements: price, asset, resource id, and the server's Ed25519 key as `payTo`.
2. The client builds a payment authorization, a signature over canonical `{amount, asset, from, payTo, resource}`, and retries with it base64-encoded in the `X-PAYMENT` header.
3. The server verifies the authorization, runs a full escrow lifecycle for the request (create → fund → deliver the resource → verify → settle), and responds with the resource plus an `X-PAYMENT-RESPONSE` header naming the escrow and the quitanza that proves the matter closed.

Every step lands on the escrow's hash-chained evidence trail, exactly as in a long-form escrow.

## Try it against the sandbox

The local API serves a live demo resource:

```
GET /v1/x402/demo
→ 402 { "x402Version": 1, "accepts": [ { "scheme": "quitanza-sandbox", "maxAmountRequired": "0.10", … } ], "error": "…" }
```

Client side, with the adapter:

```ts
import { createPaymentHeader } from "@quitanza/x402";
import { generateKeypair } from "@quitanza/core";

const payer = generateKeypair();
const offer = (await (await fetch(url)).json()).accepts[0];
const paid = await fetch(url, {
  headers: { "X-PAYMENT": createPaymentHeader(offer, payer) }
});
// paid.headers.get("X-PAYMENT-RESPONSE") names the quitanza.
```

Server side, `X402Gateway` wraps any resource:

```ts
import { X402Gateway } from "@quitanza/x402";

const gateway = new X402Gateway({ engine, payTo: serverKeys });
const requirements = gateway.requirements({
  resource: "/reports/q2",
  amount: "0.10",
  asset: "USDC",
  description: "Q2 report"
});
// no X-PAYMENT header → respond 402 with gateway.paymentRequired(requirements)
// valid header → gateway.settle(header, requirements, resource) returns
// { escrow, delivery, verdict, quitanza, responseHeader }
```

## Why escrow under 402

A bare 402 payment is fire-and-forget: the client pays, and what arrives is whatever arrives. Routed through Quitanza, the same handshake gains verification against terms, a dispute path, timeout guarantees, and a terminal proof either party can hold.

## Status

| Piece | State |
|---|---|
| 402 handshake, X-PAYMENT / X-PAYMENT-RESPONSE headers | Live |
| Escrow lifecycle per paid request, quitanza issued | Live |
| Rails | Simulated (`quitanza-local`): no chain, no real funds |
| External facilitator integration | In development |
