x402 on Gonka
проверка…

Git: Git-хостинг gonkalabs временно недоступен. Скачайте исходный код с этого сайта — Исходный код.

Агенты и покупатели

Относитесь к платному URL Gonka как к любому HTTP-ресурсу. При 402 подпишите перевод локально и повторите запрос. Никогда не отправляйте приватный ключ фасилитатору или продавцу.

Цикл запроса

  1. Вызовите платный URL методом, который указал продавец (пример — GET /demo).
  2. Если статус не 402, готово — ресурс бесплатный или уже оплачен.
  3. Прочитайте PAYMENT-REQUIRED. Это стандартный base64 JSON. Тело — тот же объект, удобно для curl.
  4. Выберите одну запись из accepts (GNK или USDC, если продавец не указал только одну).
  5. Соберите и подпишите Gonka TxRaw, которая платит payTo не меньше amount актива asset.
  6. Повторите исходный запрос с PAYMENT-SIGNATURE, равным base64 payload платежа.
  7. При 200 прочитайте PAYMENT-RESPONSE ради хеша транзакции. Найдите её на gonka.gg.

Выбор accept

Каждый элемент accepts[] — котировка. Нужно выполнить ровно одну из них, как объявлено:

schemeДолжно быть exact.
networkДолжно быть cosmos:gonka-mainnet.
amountАтомарные единицы. Платить больше можно; меньше — отказ.
assetngonka или адрес CW-20 USDC.
payToАдрес продавца gonka1…. Получатель в транзакции должен совпасть.
maxTimeoutSecondsПоставьте authorization.timeoutAt на сейчас плюс значение меньше этого (CLI использует 55 с).
extra.paymentFlowupfront — продавец проводит settle до выдачи ресурса.

Подпись платежа

GNK

Одно /cosmos.bank.v1beta1.MsgSend: с вашего адреса, на payTo, сумма amount, denom ngonka. Комиссия 0ngonka. Лимит газа 120000 — то, что ожидает фасилитатор.

USDC

Одно /cosmwasm.wasm.v1.MsgExecuteContract к контракту USDC, сообщение:

{
  "transfer": {
    "recipient": "<payTo>",
    "amount": "<atomic amount>"
  }
}

Правила подписи

CLI в этом репозитории уже собирает такую транзакцию. Свой подписант можно сделать на CosmJS или inferenced.

Повтор с заголовком

PAYMENT-SIGNATURE — это base64 объекта:

{
  "x402Version": 2,
  "accepted": { "...the PaymentRequirements you chose" },
  "payload": {
    "signature": "<base64 64-byte secp256k1 signature>",
    "authorization": {
      "from": "gonka1…",
      "to": "gonka1…",
      "amount": "1000",
      "denom": "ngonka",
      "timeoutAt": 1710000000
    },
    "signedTx": "<base64 protobuf TxRaw>"
  }
}

Для USDC accepted.asset и authorization.denom — адрес контракта CW-20. Смысл полей — в Протоколе.

Обёртка fetch

Набросок для рантайма агента. Подпишите buildAndSign(accepted) своим кошельком Gonka.

async function paidFetch(url, key, opts = {}) {
  const first = await fetch(url, opts);
  if (first.status !== 402) return first;
  const required = JSON.parse(atob(first.headers.get("PAYMENT-REQUIRED")));
  const accepted = required.accepts[0];
  const payload = await buildAndSign(accepted, key);
  return fetch(url, {
    ...opts,
    headers: {
      ...(opts.headers || {}),
      "PAYMENT-SIGNATURE": btoa(JSON.stringify(payload)),
    },
  });
}

Повторы и ошибки

Все коды — на странице Ошибки.