Перейти к содержимому

x402: HTTP 402 в нативном USDC

x402 — это HTTP 402 Payment Required: ресурс отвечает на неоплаченный запрос котировкой, клиент подписывает, facilitator проводит расчёт on-chain. Без аккаунта, без API-ключа, без gas-токена.

На POA единица — нативный USDC, не ERC-20. Stock ExactEvm вызвал бы transferWithAuthorization у Ethereum mainnet USDC (0xa0b86991…) или Permit2. Здесь это неверная схема. On-chain метод — прекомпайл NativeTransferAuth по адресу 0x2D00…0006: тот же EIP-3009-образный ABI, но против state.accounts. Permit2 не используется. Facilitator не умеет минтить. Публичный GET /faucet не публикуется.

ПоверхностьURL
DemoGET https://poa.net/77/x402/demo — без оплаты HTTP 402 с PAYMENT-REQUIRED
FacilitatorGET https://poa.net/77/x402/facilitator/supported
POST https://poa.net/77/x402/facilitator/verify
POST https://poa.net/77/x402/facilitator/settle

Страница в эксплорере: https://poa.net/77/docs/x402. Это не Agent Gateway (/77/agent/v1) и не invite-кран (POST /77/agent/v1/faucet).

Окно терминала
curl -sS -D - https://poa.net/77/x402/demo -o /tmp/x402-demo.json

Требования объявляют scheme=exact, network=eip155:77, asset=0x2D00…0006 и extra: assetTransferMethod=eip3009, paymentFlow=authorization, kind=native, EIP-712 имя USDC, версия 2, 6 decimals.

Тело 402 — котировка; заголовок PAYMENT-REQUIRED — тот же JSON в Base64, берите тело. Там resource и accepts. PAYMENT-SIGNATURE — Base64 вот этого конверта, не EIP-712-дайджест и не один payload.authorization. resource копируйте из 402 как есть. Выбранный объект accepts[i] кладите в accepted. authorization.to = accepted.payTo, authorization.value = accepted.amount. validAfter / validBefore — unix-секунды; validBefore не дальше accepted.maxTimeoutSeconds от now. nonce — 32 случайных байта. Адреса в 402 в нижнем регистре, копируйте как есть. Без resource.url или accepted в поле error 402 (и в PAYMENT-RESPONSE после неудачного settle) будет invalid_payload.

{
"x402Version": 2,
"resource": { "url": "https://poa.net/77/x402/demo", "mimeType": "application/json", "description": "" },
"accepted": {
"scheme": "exact",
"network": "eip155:77",
"asset": "0x2d00000000000000000000000000000000000006",
"amount": "10000",
"payTo": "0x…",
"maxTimeoutSeconds": 60,
"extra": {
"assetTransferMethod": "eip3009",
"paymentFlow": "authorization",
"kind": "native",
"name": "USDC",
"version": "2",
"decimals": 6,
"symbol": "USDC"
}
},
"payload": {
"signature": "0x…",
"authorization": {
"from": "0x…",
"to": "0x…",
"value": "10000",
"validAfter": "0",
"validBefore": "",
"nonce": "0x…"
}
}
}

POST /77/x402/facilitator/verify и settle принимают { "x402Version": 2, "paymentPayload": <конверт>, "paymentRequirements": <accepted> }.

Сейчас работает: EOA с нативным USDC и EIP-712 подписью.

  1. Держать нативный USDC в сети 77 (мост).
  2. Подписать EIP-712 TransferWithAuthorization для NativeTransferAuth (name=USDC, version=2, verifyingContract=0x2D00…0006, chainId=77). Суммы — в 6-decimal единицах USDC.
  3. Повторить запрос с PAYMENT-SIGNATURE = Base64 конверта выше. Публичный facilitator /77/x402/facilitator/* — тот же in-process facilitator, что обслуживает demo; он рассылает transferWithAuthorization с settler-ключа. Demo отвечает 200 только после включения settler-транзакции со status 0x1. Нет receipt — settlement_pending (402), не успех. Worker 502/504 после settle не значит, что платёж провалился: сверьте tx hash / (from, nonce) до новой подписи.
  4. Один и тот же (from, nonce) второй раз не проходит. Адрес operator-pool (genesis-оператор моста, ему запрещены обычные переводы) не может быть EIP-712 from.

Assigned wallet: вызовите POST /77/agent/v1/x402/authorize с API bearer token, имеющим capability transfer. Передайте quote как payment_required и новый 32-байтовый hex nonce; подписант вернёт авторизацию платежа. Требуются включённый x402 и разрешённые оператором сумма и получатель. MCP-адаптер этот endpoint пока не оборачивает. См. Agent Gateway.

У POA нет token-контракта. Клиент, нацеленный на Ethereum mainnet USDC, списал бы не ту сеть. NativeTransferAuth — закрытый прекомпайл в наборе 0x2D00…, как HTLC и bridge mint: Elixir, его выкатывает оператор, без байт-кода. Подробности: Precompile-контракты.