x402 `upto` vs MPP Sessions: Две философии usage-based платежей

Автор: philpher0x

Подробное сравнение x402 `upto` и MPP Tempo Sessions: как они обрабатывают платежи с переменной стоимостью, стриминговые микроплатежи, модели escrow vs allowance и когда стоит выбирать каждую архитектуру для machine-to-machine платежей.

Теги: MPP, Payments, Machine Payments, x402

TL;DR

x402 upto и MPP Sessions решают одну и ту же практическую задачу: как списывать с клиента ровно столько, сколько он фактически потребил, когда финальная стоимость заранее неизвестна, при этом уменьшая количество транзакций. Но решают они это на разных уровнях абстракции и с разными архитектурами расчётов.

  • x402 upto — это «открытый чек» с максимальной суммой. Клиент подписывает одноразовое разрешение списать до X. Сервер предоставляет услугу, вычисляет фактическую стоимость и выполняет одну on-chain транзакцию на реальную сумму. Эта модель полностью живёт внутри одного HTTP request-response цикла, использует Permit2 и не требует escrow.

  • MPP Tempo Sessions — это payment channel (state channel). Клиент депозитит средства в on-chain escrow-контракт, после чего обменивается с сервером off-chain EIP-712 «voucher»-ами, каждый из которых представляет накопительную сумму. Канал живёт долго, может содержать неограниченное количество микроплатежей и требует ровно две on-chain транзакции для всех них: открытие и закрытие.

Упрощённо:

x402 upto = один HTTP-запрос с неизвестной финальной ценой.

MPP Sessions = долгоживущее стриминговое соединение, где платежи идут синхронно с данными.


Lifecycle сессии

x402 upto

Схема upto существует внутри обычного HTTP request-response цикла:

  1. Challenge. Клиент делает запрос, а сервер отвечает 402 Payment Required, содержащим PaymentRequirements, где указаны scheme: "upto", адрес получателя, токен, сеть, максимальный timeout и, что наиболее важно, amount — верхний лимит, на который сервер хочет получить разрешение.
  2. Подпись. Клиент создаёт Permit2 permitWitnessTransferFrom сообщение, где permitted.amount равен максимальной запрошенной сумме, witness.to — адрес получателя, witness.facilitator — адрес facilitator-а (опубликован сервером через /supported), а также устанавливает deadline и validAfter. Затем подписывает его через EIP-712.
  3. Подписанная транзакция. Клиент повторяет HTTP-запрос, прикрепляя PAYMENT-SIGNATURE с payload-ом (подпись + параметры Permit2 authorization).
  4. Проверка. Facilitator проверяет подпись, Permit2 allowance, баланс клиента, окно валидности подписи и соответствие токена/сети. На этом этапе средства не двигаются.
  5. Выполнение сервиса. Сервер обрабатывает запрос (генерирует токены, возвращает файл, запускает вычисления) и рассчитывает фактическую итоговую стоимость.
  6. Settlement. Сервер снова отправляет PaymentRequirements facilitator-у, но уже с фактическим amount (это ключевая особенность схемы: одно и то же поле имеет разный смысл на разных фазах — максимум при проверке и реальное списание при settlement). Facilitator вызывает x402UptoPermit2Proxy.settle(...) с реальной суммой, которая должна быть подписанного максимума. Если фактическая сумма равна нулю, on-chain транзакция вообще не происходит — разрешение просто истекает без использования.

Одна подпись = один settlement.
upto явно запрещает multi-settlement и streaming: одна и та же подпись не может быть переиспользована из-за semantics Permit2 nonce. Если нужен ещё один charge — требуется новая подпись, а значит и новый HTTP-запрос.

Диаграмма x402 upto

MPP Tempo Sessions

Tempo session — это полноценный протокол с выделенным on-chain контрактом TempoStreamChannel и множеством состояний.

Lifecycle:

  1. Challenge. Сервер возвращает 402 с WWW-Authenticate: Payment method="tempo" intent="session". В нём указывается цена за единицу потребления (amount + unitType, например 25 base units за llm_token), рекомендуемый депозит (suggestedDeposit), адрес escrow-контракта и опционально channelId, если сервер предлагает переиспользовать уже существующий канал.
  2. Open. Клиент отправляет on-chain транзакцию open(payee, token, deposit, salt, authorizedSigner). Контракт создаёт канал с детерминированным channelId = keccak256(payer, payee, token, salt, authorizedSigner, contract, chainId) и блокирует депозит. Клиент отправляет подписанную транзакцию серверу вместе с action="open" и initial voucher-ом с cumulativeAmount = 0.
  3. Streaming + vouchers. Сервер начинает стримить контент (обычно SSE или chunked). По мере роста потребления клиент подписывает EIP-712 voucher-ы с монотонно возрастающими cumulative amount: 100 → 250 → 400 → .... Voucher-ы отправляются через тот же HTTP URI (часто через HEAD requests). Каждый voucher занимает всего несколько сотен байт и проверяется за микросекунды.
  4. Top-up (опционально). Если сессия длится дольше ожидаемого и депозит заканчивается, клиент может вызвать on-chain topUp() и продолжить без закрытия канала. Tempo даже определяет SSE event payment-need-voucher, чтобы уведомить клиента об исчерпании баланса.
  5. Settle (опционально, много раз). Сервер может вызвать settle(channelId, cumulativeAmount, signature) в любой момент, чтобы вывести уже заработанные средства без закрытия канала. Это ключевое отличие от upto: частичные on-chain settlement-ы во время живой сессии разрешены.
  6. Cooperative close. Клиент отправляет action="close" с финальным voucher-ом. Сервер вызывает close(), а контракт переводит delta (cumulativeAmount - already_settled) получателю, возвращает остаток плательщику и финализирует канал.
  7. Forced close (защита клиента). Если сервер замолкает и не закрывает канал, клиент вызывает requestClose(), ждёт grace period (15 минут в стандартной реализации), после чего вызывает withdraw(), чтобы вернуть оставшиеся средства. У сервера есть окно, чтобы отправить финальный voucher.

Ключевая деталь: voucher-ы являются накопительными. Это означает, что клиенту не нужно хранить историю — он просто подписывает «всего должно быть уплачено X». Как только сервер получает более новый voucher, все предыдущие можно выбросить. Во время settlement контракт вычисляет delta как cumulativeAmount - channel.settled, что естественным образом предотвращает replay и double-spending.

Диаграмма MPP Tempo Sessions (Cooperative Flow)

Forced Close (если сервер замолчал)


Таблица ключевых различий

Параметр x402 upto MPP Tempo Sessions
Модель settlement Allowance (Permit2) — средства остаются у клиента до settlement Escrow — средства заблокированы в контракте
Единица протокола Один HTTP-запрос Долгоживущий канал через множество запросов
On-chain tx на сессию 0 или 1 (только финальный transfer) Минимум 2 (open + close), плюс опциональный settle()
Гранулярность платежей Одна финальная сумма на запрос Неограниченные voucher-ы (per-token, per-byte, per-ms)
Скорость подтверждения платежа ~Время on-chain подтверждения Микросекунды (проверка подписи voucher-а)
Тип подписи клиента EIP-712 Permit2 Witness Transfer EIP-712 Voucher (channelId + cumulativeAmount)
Ограничения по времени Жёсткие: validAfter + deadline Нет expiry — канал живёт до явного закрытия
Переиспользование authorization Запрещено (single-use nonce) Встроено: каждый новый voucher заменяет предыдущий
Частичные settlement-ы Не поддерживаются Да, через settle()
Защита клиента, если сервер молчит Подпись истекает после deadline requestClose + grace period + withdraw
Защита сервера Подпись + allowance/balance check; клиент может вывести средства до settlement Средства уже в escrow
Требования к состоянию сервера Минимальные, почти stateless Требуется persistent accounting
Идеальный use case REST endpoint с переменной ценой Streaming, agents, high-frequency API

Архитектурные различия, которые действительно важны

Escrow vs Allowance — это не стиль, а распределение рисков

В x402 upto средства физически остаются в кошельке клиента до settlement. Сервер полагается на:

  • валидную подпись,
  • достаточный баланс на момент settlement,
  • то, что Permit2 allowance не был отозван.

Между проверкой и settlement существует окно, в котором клиент технически может вывести средства. На практике это окно короткое (секунды), но для high-stakes сценариев это всё равно риск.

В MPP Sessions средства уже находятся в escrow. Как только сервер получает подписанный voucher, он гарантированно может провести settlement — никто другой не сможет вывести эти средства. Это фундаментально другая модель гарантий, за которую приходится платить депозитами и как минимум двумя on-chain транзакциями.

Почему Sessions могут обрабатывать миллион платежей в секунду, а upto — нет

Проверка одного voucher-а в Sessions — это просто ECDSA signature верификация плюс сравнение cumulativeAmount > highestVoucherAmount. Это занимает микросекунды. Сервер может обрабатывать тысячи voucher-ов в секунду на одном канале без обращения к блокчейну. Тяжёлое взаимодействие с chain происходит только на open/close.

В upto каждый платёж требует нового Permit2 nonce и новой подписи. upto предназначен для случаев, когда ни клиент, ни сервер заранее не знают, сколько в итоге будет списано. Он позволяет выполнить сложный процесс, а затем провести settlement постфактум. MPP Sessions, напротив, позволяет непрерывный контроль процесса.

Можно реализовать более сложную channel-like логику и поверх x402 — но зачем, если MPP Sessions уже предоставляет её?

Cumulative semantics — маленькая, но элегантная деталь

В MPP Sessions voucher указывает общую сумму, уплаченную на текущий момент, а не инкрементальный платёж. Это даёт три свойства:

  • Idempotency. Повторная отправка того же voucher-а ничего не меняет.
  • Replay protection без nonce. Любой старый voucher отклоняется, потому что уже был принят или заменён более новым.
  • Устойчивость к проблемам сети. Потерянные voucher-ы не важны — следующий покрывает всё.

В upto эта проблема решается иначе: single-use signatures и semantics Permit2 nonce. Но и сам сценарий намного проще — одна подпись живёт только для одного запроса.

Состояние сервера

upto почти stateless — сервер может вообще ничего не хранить между verification и settlement, кроме самой подписи.

Sessions требуют отказоустойчивости (draft-tempo-session прямо требует записывать spent в durable storage до предоставления сервиса, иначе crash может привести к доставке неоплаченного контента). Это добавляет сложности, если ваша архитектура раньше была stateless.

Защита клиента: deadline vs Grace Period

В upto клиент защищён истечением подписи: после deadline facilitator больше не может ничего списать. Но пока подпись валидна, клиент не может её отозвать иначе как потратив средства или вызвав Permit2.invalidateNonces.

В MPP Sessions даже без содействия со стороны сервера клиент всегда может вернуть средства: requestClose → wait 15 min → withdraw. Это стоит 2–3 on-chain вызова и некоторого ожидания, но гарантирует выход.


Плюсы и минусы

x402 upto

Плюсы:

  • Самая простая интеграция поверх любого REST API.
  • stateless сервер, отсутствие фоновых settlement задач.
  • Нет депозита — средства клиента не блокируются.
  • Естественно вписывается в существующую HTTP семантику и HTTP 402.
  • Использует канонический Permit2, которому доверяет вся EVM экосистема.
  • Минимальный setup: клиенту нужно approve Permit2 только один раз.

Минусы:

  • Не подходит для стриминга: невозможно платить per-token в реальном времени.
  • Строго single-use authorization — multi-settlement не предусмотрен.
  • Сервер платит gas за каждый settlement отдельно.
  • Клиент должен доверять расчёту стоимости сервером в пределах подписанного максимума.
  • Между подписью и settlement клиент теоретически может вывести средства.
  • Требует, чтобы средства клиента оставались в кошельке, а не в escrow.

MPP Tempo Sessions

Плюсы:

  • Настоящий стриминг: платежи синхронизированы с потоком данных.
  • Амортизация gas: тысячи микроплатежей помещаются в две on-chain tx.
  • Сильные гарантии для сервера (средства уже в escrow).
  • Встроенный forced close защищает клиентов.
  • Поддерживает delegated authorizedSigner: hot wallet может подписывать, пока cold wallet держит депозит.
  • Чистая модель top-up без закрытия канала.
  • Использует IETF-compatible Payment Auth scheme — а не просто Web3 hack.

Минусы:

  • Два обязательных on-chain шага: open и close. Дорого для коротких сессий.
  • Депозит блокирует капитал клиента.
  • Требует отдельного контракта и инфраструктуры (indexing, workers, crash-safe accounting).
  • Сервер обязан хранить persistent per-channel state.
  • Сложнее дебажить: больше состояний, больше failure scenarios.
  • Привязан к конкретной сети (в данном случае Tempo chain); cross-chain сложнее.

Когда выбирать что

Выбирайте upto, если:

  • У вас классический REST/RPC API, где один запрос = один ответ.
  • Цена запроса переменная, но определяется в рамках одной атомарной операции.
  • Вы не хотите инфраструктуру escrow/state-channel.
  • Ваши клиенты не хотят блокировать депозиты.
  • Частота платежей низкая.
  • Вы хотите быстро монетизировать существующий API с минимальными изменениями.

Выбирайте Sessions, если:

  • Вы стримите контент (SSE, WebSocket, chunked) и хотите синхронизировать оплату с байтами данных.
  • Агенты/боты взаимодействуют сотни раз в минуту.
  • Стоимость gas для on-chain settlement становится сопоставимой с ценой сервиса.
  • Вам нужны сильные гарантии того, что платёж клиента обеспечен.
  • Вы строите AI inference marketplaces с billing latency в миллисекундах.
  • Ваша архитектура поддерживает stateful серверы.

Hybrid тоже возможен. Ничто не мешает одному сервису поддерживать и upto для one-shot API requests, и Sessions для streaming endpoints. На уровне 402 challenge вы просто предлагаете несколько схем и позволяете клиенту выбрать.

 

upto и Sessions — не конкуренты, а взаимодополняющие инструменты на разных точках спектра «частота vs сложность».

  • upto — это эволюция HTTP request. Вы добавляете возможность списать сумму, известную только после обработки, при этом всё остальное остаётся привычным.
  • Sessions — это эволюция платёжной инфраструктуры. Вы создаёте выделенный платежный канал, где перемещение денег становится почти бесплатным, но наследуете всю сложность state channels.

Для большинства AI API сегодня — где «один prompt = один response» — upto выигрывает за счёт простоты. Но как только вы всерьёз входите в machine-to-machine economy, где агенты живут внутри API часами и непрерывно потребляют потоки данных, MPP Sessions становится единственным жизнеспособным вариантом.

upto = «Сними с меня столько, сколько это стоит, в пределах лимита чека».

MPP Sessions = «Я положил деньги в хранилище — забирай voucher-ы по мере необходимости, пока я не скажу стоп».