Skip to main content
Glama

x402 Image API

Платная генерация изображений с помощью ИИ на протоколе x402 — $0.001/изображение, USDC на Base, без API-ключей.

Живая конечная точка: https://x402.chaly.org · health · OpenAPI 3.1 · .well-known/x402 · llms.txt

Стандарт x402 возрождает HTTP 402 Payment Required для машинных платежей: покупатель (человек или ИИ-агент) отправляет POST с запросом, получает подписанное платёжное предложение в заголовке PAYMENT-REQUIRED, авторизует перевод USDC по EIP-3009 своим кошельком, повторяет запрос, а сторонний фасилитатор проверяет и завершает расчёт в сети. Никаких аккаунтов, API-ключей и газа для покупателя — платёж и есть аутентификация.

POST /generate {prompt}          → 402 + PAYMENT-REQUIRED (machine-readable offer)
   ↳ buyer signs EIP-3009 authorization (USDC on Base)
POST /generate {prompt} + PAYMENT-SIGNATURE
                                 → 202 {jobId, pollUrl, estimatedSeconds}
GET  /result/:id every ~5s       → processing … → done {urls: [...]}

Цены

качество

мегапиксели

за изображение

low

1K

$0.001

  • Итоговая сумма = цена за изображение × количество (count 1–8, или пакет items: [["prompt", n], …], всего ≤ 8).

  • Соотношение сторон бесплатно.

  • В внутренней таблице цен есть более крупные тарифы, но рекламируются только доступные для обслуживания.

  • Цены динамические: предложение 402 вычисляется для каждого запроса на основе тела (PRICE_TABLE в server.js), поэтому покупатель платит ровно столько, сколько генерирует обработчик.

Related MCP server: Nexus MCP

Быстрый старт для покупателя

npm i @x402/fetch @x402/evm viem
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.BUYER_PRIVATE_KEY);
const fetchWithPay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
});

// 402 → auto-pay → retry → 202 {jobId, pollUrl}
const res = await fetchWithPay("https://x402.chaly.org/generate", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ prompt: "a red cube on a blue table", count: 1 }),
});
const job = await res.json();
// poll GET job.pollUrl every 5s until status === "done"

См. client.mjs для полного рабочего клиента (включая опрос).

MCP-сервер

mcp-server.mjs предоставляет API как MCP-инструменты (image_generate, image_health, image_openapi, image_poll), чтобы кодирующие агенты могли генерировать изображения напрямую:

{
  "mcpServers": {
    "x402-image-api": {
      "command": "node",
      "args": ["mcp-server.mjs"],
      "env": {
        "X402_API_URL": "https://x402.chaly.org",
        "BUYER_PRIVATE_KEY": "0x…"
      }
    }
  }
}

Инструменты без оплаты (health/openapi/poll) работают без ключа.

Самостоятельный хостинг

npm install
cp .env.example .env      # set PAY_TO_ADDRESS (public address only!)
npm start                 # node --env-file=.env server.js → :4021

Ключевые переменные окружения: PAY_TO_ADDRESS, X402_NETWORK (eip155:8453), X402_FACILITATOR_URL (например, PayAI), PORT, OUT_DIR, PUBLIC_URL, MAX_COUNT, а также MEDIA_IO_PROJECT_DIR — путь к вашему генераторному бэкенду.

Подключаемый бэкенд: слой Express запускает одноразовый рабочий подпроцесс для каждого запроса и читает одну строку JSON из stdout. В этом репозитории поставляется сторона продавца; наш собственный мостовой воркер (gen_worker.py) остаётся закрытым. Чтобы подключить свой генератор, предоставьте исполняемый файл, который

  • читает {prompt, aspect, megapixels, quality, count, …} как JSON из stdin,

  • записывает {ok, urls: [...], …} как последнюю строку stdout,

  • завершается с ненулевым кодом при ошибке.

Публичный доступ (без VPS)

Единственный вход — Cloudflare Tunnel: TLS завершается на границе Cloudflare, а упавший источник автоматически отдаёт 503/530 (бесплатный heartbeat). Полное руководство в cloudflared/README.md; параллельные скрипты запуска в scripts/ (+ systemd-юниты для Linux).

Заметки по дизайну

  • Порядок middleware важен: express.json() выполняется до платёжного middleware, чтобы функция динамической цены могла прочитать разобранное тело — иначе пакет за $0.008 молча оценивается как одно изображение за $0.001.

  • Ограничение ёмкости до оплаты: middleware до оплаты возвращает 503 insufficient_capacity, когда сегодня нельзя занять слот генерации, срабатывая до любого 402 — покупатели никогда не подписывают то, что мы не можем доставить.

  • 202 + опрос вместо долгоживущих ответов: генерация занимает ~50–90 с/изображение; немедленный возврат дескриптора задания избегает таймаутов шлюза (лимит Cloudflare 100 с) для пакетов до 8 изображений.

  • Белая маркировка вывода: PNG попадают под GET /images/:file (хэш-имена, защита от обхода каталога), обслуживаемые с вашего домена.

  • Обнаружение в Bazaar: declareDiscoveryExtension открывает этот сервис в x402 Bazaar; агенты могут найти его без указания URL.

  • Идемпотентность: передайте "id" для дедупликации повторов — кэшированные результаты возвращаются без повторной генерации (orders.jsonl + in-memory jobs).

Безопасность

  • Сервер хранит только ваш публичный адрес получения; расчёт выполняется в сети и поступает на ваш кошелёк.

  • .env, jobs.json, orders.jsonl в .gitignore — никогда не коммитьте их.

  • Используйте отдельный кошелёк для PAY_TO_ADDRESS; держите казначейства холодными.

Лицензия

MIT

Related MCP Connectors

Related MCP Servers