Files
proxmox/docs/04-configuration/X402_ALLTRA_ENDPOINT_SPEC.md
defiQUG e4c9dda0fd
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
chore: update submodule references and documentation
- Marked submodules ai-mcp-pmm-controller, explorer-monorepo, and smom-dbis-138 as dirty to reflect recent changes.
- Updated documentation to clarify operator script usage, including dotenv loading and task execution instructions.
- Enhanced the README and various index files to provide clearer navigation and task completion guidance.

Made-with: Cursor
2026-03-04 02:03:08 -08:00

117 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# x402 Endpoint Contract — Alltra (651940) + USDC
**Purpose:** Spec for Alltra-native x402 paid endpoints: 402 challenge, retry with PAYMENT-SIGNATURE, and local verification on chain 651940 with USDC. Settlement is on Alltra; no dependency on Base or external facilitator.
**References:** [coinbase/x402](https://github.com/coinbase/x402), [HTTP 402 — x402](https://docs.x402.org/core-concepts/http-402), [ADDRESS_MATRIX_AND_STATUS.md](../11-references/ADDRESS_MATRIX_AND_STATUS.md) §2.3 (Alltra USDC).
---
## 1. Overview
- **Chain:** `eip155:651940` (ALL Mainnet / Alltra)
- **Payment token:** USDC at `0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881`
- **Recipient:** Server treasury (e.g. `SERVER_WALLET_ADDRESS`)
- **Verification:** Local (recommended): server verifies signature, intent, and on-chain settlement; optional facilitator-like `/verify` later.
---
## 2. Step 1 — Client calls paid endpoint (unpaid)
**Request:** `GET /api/resource` (or any paid route)
**Response when unpaid:** `402 Payment Required`
**Headers:**
- `PAYMENT-REQUIRED: <base64 PaymentRequired>`
**PaymentRequired (JSON, then base64-encoded):**
| Field | Type | Description |
|-------|------|-------------|
| `network` | string | `eip155:651940` |
| `asset` | string | USDC contract address (0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881) |
| `amount` | string | Price in base units (e.g. "10000" for 0.01 USDC if 6 decimals) |
| `recipient` | string | Treasury address |
| `nonce` | string | Unique per request (e.g. UUID) |
| `expiresAt` | string | ISO 8601 (e.g. now + 5 minutes) |
| `resourceId` | string | Identifies the resource (e.g. URL or hash) so payment is bound to the request |
**Example (decoded):**
```json
{
"network": "eip155:651940",
"asset": "0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881",
"amount": "10000",
"recipient": "0x...",
"nonce": "550e8400-e29b-41d4-a716-446655440000",
"expiresAt": "2026-03-04T12:05:00.000Z",
"resourceId": "GET /api/premium"
}
```
---
## 3. Step 2 — Client pays and retries
Client performs USDC transfer (or authorization) on chain 651940 to `recipient` for `amount`, then retries the same request with:
**Headers:**
- `PAYMENT-SIGNATURE: <base64 PaymentPayload>`
**PaymentPayload (JSON, then base64-encoded):**
| Field | Type | Description |
|-------|------|-------------|
| `payer` | string | Payer wallet address |
| `signature` | string | Signature over the payment intent (e.g. EIP-191 or EIP-712 of PaymentRequired or its hash) |
| `paymentRequired` | object | Copy of PaymentRequired so server can verify match |
| `txHash` | string (optional) | Transaction hash on 651940 proving transfer (for on-chain verification) |
Server uses `txHash` to verify settlement via `eth_getTransactionReceipt` on 651940 when doing local verification.
---
## 4. Step 3 — Server verification (Alltra-native local)
1. **Decode** PaymentPayload from base64.
2. **Verify signature** — signature belongs to `payer` (recover signer from signature over payment intent).
3. **Verify intent** — PaymentPayload.paymentRequired matches the server-issued PaymentRequired (same amount, asset, chain, recipient, resourceId); `expiresAt` is in the future.
4. **Verify settlement:**
- If `txHash` present: call 651940 RPC `eth_getTransactionReceipt(txHash)`; confirm success and that transfer is to `recipient` for `amount` (USDC) from `payer`.
- If authorization-based: verify authorization and that a transfer occurred (per your scheme).
5. **Replay:** Mark `(payer, resourceId, nonce)` as consumed (store in DB or cache with TTL); reject if already consumed.
6. **Respond:** Return 200 with resource body; optionally set `PAYMENT-RESPONSE` header (per x402) with settlement response.
---
## 5. Replay protection
- Key: `(payer, resourceId, nonce)`.
- Store consumed keys with expiry ≥ `expiresAt` so the same nonce cannot be reused.
- Production: use Redis or DB; development: in-memory Map with TTL is acceptable.
---
## 6. PAYMENT-RESPONSE (optional)
Per [docs.x402.org](https://docs.x402.org/core-concepts/http-402), server may return `PAYMENT-RESPONSE` header with settlement confirmation (e.g. txHash, status). Optional for minimal implementation.
---
## 7. Separation from sponsorship
- **Sponsorship (paymaster):** Covers gas for app actions (e.g. CoreApp writes) on 651940.
- **x402:** User-paid USDC for API/service access; validated by this flow.
The two are independent: x402 payment tx is user-funded; sponsored txs are paymaster-funded.
---
## 8. Implementation
- **x402-api:** When `X402_USE_ALLTRA=true`, the server can use this local verification path: return 402 + PAYMENT-REQUIRED when unpaid; on PAYMENT-SIGNATURE, run steps 16 and serve the resource on success.
- **USDC decimals:** 6 for Alltra USDC; `amount` in PaymentRequired is in base units (e.g. 10000 = 0.01 USDC).