<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.39 (Ruby 4.0.6) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

<!ENTITY RFC2119 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC3339 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3339.xml">
<!ENTITY RFC4648 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4648.xml">
<!ENTITY RFC8174 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
<!ENTITY RFC8259 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml">
<!ENTITY RFC9110 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml">
<!ENTITY RFC9111 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9111.xml">
<!ENTITY RFC9457 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9457.xml">
<!ENTITY RFC8610 SYSTEM "https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8610.xml">
]>


<rfc ipr="noModificationTrust200902" docName="draft-tempo-session-00" category="info" consensus="true" submissionType="IETF">
  <front>
    <title abbrev="Tempo Session">Tempo Session Intent for HTTP Payment Authentication</title>

    <author initials="L." surname="Horne" fullname="Liam Horne">
      <organization>Tempo Labs</organization>
      <address>
        <email>liam@tempo.xyz</email>
      </address>
    </author>
    <author initials="G." surname="Konstantopoulos" fullname="Georgios Konstantopoulos">
      <organization>Tempo Labs</organization>
      <address>
        <email>georgios@tempo.xyz</email>
      </address>
    </author>
    <author initials="D." surname="Robinson" fullname="Dan Robinson">
      <organization>Tempo Labs</organization>
      <address>
        <email>dan@tempo.xyz</email>
      </address>
    </author>
    <author initials="B." surname="Ryan" fullname="Brendan Ryan">
      <organization>Tempo Labs</organization>
      <address>
        <email>brendan@tempo.xyz</email>
      </address>
    </author>
    <author initials="J." surname="Moxey" fullname="Jake Moxey">
      <organization>Tempo Labs</organization>
      <address>
        <email>jake@tempo.xyz</email>
      </address>
    </author>

    <date year="2026" month="August" day="07"/>

    
    
    

    <abstract>


<?line 74?>

<t>This document defines the "session" intent for the "tempo" payment method
in the Payment HTTP Authentication Scheme. It specifies unidirectional
streaming payment channels for incremental, voucher-based payments
suitable for low-cost metered services, including both legacy
contract-backed channels and TIP-20 channel precompile-backed channels.</t>



    </abstract>



  </front>

  <middle>


<?line 82?>

<section anchor="introduction"><name>Introduction</name>

<t>This document is published as Informational but contains normative requirements using BCP 14 keywords <xref target="RFC2119"/> <xref target="RFC8174"/> to ensure interoperability between implementations. Payment method specifications that reference this document inherit these requirements.</t>

<t>The <spanx style="verb">session</spanx> intent establishes a unidirectional streaming payment channel
using on-chain escrow and off-chain <xref target="EIP-712"/> vouchers. This enables high-
frequency, low-cost payments by batching many off-chain voucher signatures
into periodic on-chain settlements.</t>

<t>Unlike the <spanx style="verb">charge</spanx> intent which requires the full payment amount upfront, the
<spanx style="verb">session</spanx> intent allows clients to pay incrementally as they consume
services, paying exactly for resources received.</t>

<section anchor="use-case-llm-token-streaming"><name>Use Case: LLM Token Streaming</name>

<t>Consider an LLM inference API that charges per output token:</t>

<t><list style="numbers" type="1">
  <t>Client requests a streaming completion (SSE response)</t>
  <t>Server returns 402 with a <spanx style="verb">session</spanx> challenge</t>
  <t>Client opens a payment channel on-chain, depositing funds</t>
  <t>Server begins streaming response</t>
  <t>As response streams, or over incremental requests, client signs vouchers with increasing amounts</t>
  <t>Server settles periodically or at stream completion</t>
</list></t>

<t>The client pays exactly for tokens received, with no worst-case reservation.</t>

</section>
<section anchor="session-flow"><name>Session Flow</name>

<t>The following diagram illustrates the Tempo session flow:</t>

<figure><artwork><![CDATA[
   Client                        Server                     Tempo Network
      |                             |                             |
      |  (1) GET /api/resource      |                             |
      |-------------------------->  |                             |
      |                             |                             |
      |  (2) 402 Payment Required   |                             |
      |      intent="session"        |                             |
      |      (includes challengeId) |                             |
      |<--------------------------  |                             |
      |                             |                             |
      |  (3) GET /api/resource      |                             |
      |      Authorization: Payment |                             |
      |      action="open"          |                             |
      |      (includes signed tx)   |                             |
      |-------------------------->  |                             |
      |                             |                             |
      |                             |  (4) open(...)               |
      |                             |-------------------------->  |
      |                             |                             |
      |  (5) 200 OK + Receipt       |                             |
      |      (streaming response)   |                             |
      |<--------------------------  |                             |
      |                             |                             |
      |  (6) HEAD /api/resource     |                             |
      |      action="voucher"       |                             |
      |      (top-up, same URI)     |                             |
      |-------------------------->  |                             |
      |                             |                             |
      |  (7) 200 OK + Receipt       |                             |
      |<--------------------------  |                             |
      |                             |                             |
      |  (8) GET /api/resource      |                             |
      |      action="voucher"       |                             |
      |      (incremental request)  |                             |
      |-------------------------->  |                             |
      |                             |                             |
      |  (9) 200 OK + Receipt       |                             |
      |      (additional response)  |                             |
      |<--------------------------  |                             |
      |                             |                             |
      |  (10) GET /api/resource     |                             |
      |       action="close"        |                             |
      |-------------------------->  |                             |
      |                             |  (11) close(voucher)        |
      |                             |-------------------------->  |
      |                             |                             |
      |  (12) 200 OK + Receipt      |                             |
      |       (includes txHash)     |                             |
      |<--------------------------  |                             |
      |                             |                             |
]]></artwork></figure>

<t>Voucher updates and close requests are submitted to the <strong>same resource
URI</strong> that requires payment. This allows sessions to work on any endpoint
without dedicated payment control plane routes. Servers <bcp14>SHOULD</bcp14> support
voucher updates via any HTTP method; clients <bcp14>MAY</bcp14> use <spanx style="verb">HEAD</spanx> for pure
voucher top-ups when no response body is needed.</t>

</section>
<section anchor="concurrency"><name>Concurrency Model</name>

<t>A channel supports one active session at a time. The cumulative voucher
semantics ensure correctness—each voucher advances a single monotonic
counter. The channel is the unit of concurrency; no additional session
locking is required.</t>

<t>When a client sends a new streaming request on a channel that already
has an active session, servers <bcp14>SHOULD</bcp14> terminate the previous session and
start a new one. Voucher updates <bcp14>MAY</bcp14> arrive on separate HTTP connections
(including HTTP/2 streams) and <bcp14>MUST</bcp14> be processed atomically with respect
to balance updates.</t>

<t>Servers <bcp14>MUST</bcp14> ensure that voucher acceptance and balance deduction are
serialized per channel to prevent race conditions.</t>

</section>
</section>
<section anchor="requirements-language"><name>Requirements Language</name>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<?line -18?>

</section>
<section anchor="terminology"><name>Terminology</name>

<dl>
  <dt>Streaming Payment Channel</dt>
  <dd>
    <t>A unidirectional off-chain payment mechanism where the payer deposits
funds into an escrow contract and signs cumulative vouchers authorizing
increasing payment amounts.</t>
  </dd>
  <dt>Voucher</dt>
  <dd>
    <t>An <xref target="EIP-712"/> signed message authorizing a cumulative payment amount for
a specific channel. Vouchers are monotonically increasing in amount.</t>
  </dd>
  <dt>Channel</dt>
  <dd>
    <t>A payment relationship between a payer and payee, identified by a
unique <spanx style="verb">channelId</spanx>. The channel holds deposited funds and tracks
cumulative settlements.</t>
  </dd>
  <dt>Settlement</dt>
  <dd>
    <t>The on-chain <xref target="TIP-20"/> transfer that converts off-chain voucher
authorizations into actual token movement.</t>
  </dd>
  <dt>Authorized Signer</dt>
  <dd>
    <t>An address delegated to sign vouchers on behalf of the payer.
Defaults to the payer if not specified.</t>
  </dd>
  <dt>Base Units</dt>
  <dd>
    <t>The smallest indivisible unit of a TIP-20 token. TIP-20 tokens use
6 decimal places; one million base units equals 1.00 tokens.</t>
  </dd>
</dl>

</section>
<section anchor="protocol-versions"><name>Protocol Versions</name>

<t>Tempo session challenges can identify the channel backend through
<spanx style="verb">methodDetails.sessionProtocol</spanx>:</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>Channel backend</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">v1</spanx></c>
      <c>Contract-backed escrow</c>
      <c>The legacy <spanx style="verb">TempoStreamChannel</spanx> contract interface described in <xref target="channel-state"/>.</c>
      <c><spanx style="verb">v2</spanx></c>
      <c>TIP-20 channel precompile</c>
      <c>The TIP-20 channel escrow precompile described in <xref target="precompile-channel-state"/>.</c>
</texttable>

<t>If <spanx style="verb">methodDetails.sessionProtocol</spanx> is absent, clients <bcp14>MAY</bcp14> treat the
challenge as <spanx style="verb">v1</spanx> for backwards compatibility. New servers <bcp14>SHOULD</bcp14> emit
<spanx style="verb">"sessionProtocol": "v2"</spanx> when using the TIP-20 channel precompile. A
client <bcp14>MUST NOT</bcp14> answer a challenge using a different session protocol than
the one indicated by the challenge.</t>

</section>
<section anchor="encoding"><name>Encoding Conventions</name>

<t>This section defines normative encoding rules for interoperability.</t>

<section anchor="hexadecimal-values"><name>Hexadecimal Values</name>

<t>All byte arrays (addresses, hashes, signatures, channelId) use:</t>

<t><list style="symbols">
  <t>Lowercase hexadecimal encoding</t>
  <t><spanx style="verb">0x</spanx> prefix</t>
  <t>No padding or truncation</t>
</list></t>

<texttable>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Length</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c>address</c>
      <c>42 chars (0x + 40 hex)</c>
      <c><spanx style="verb">0x742d35cc6634c0532925a3b844bc9e7595f8fe00</spanx></c>
      <c>bytes32</c>
      <c>66 chars (0x + 64 hex)</c>
      <c><spanx style="verb">0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f</spanx></c>
      <c>signature</c>
      <c>130-132 chars (0x + 128-130 hex)</c>
      <c>65-byte (r‖s‖v) or 64-byte EIP-2098 compact</c>
</texttable>

<t>Implementations <bcp14>MUST</bcp14> use lowercase hex. Implementations <bcp14>SHOULD</bcp14> accept
mixed-case input but normalize to lowercase before comparison.</t>

</section>
<section anchor="numeric-values"><name>Numeric Values</name>

<t>Integer values (amounts, timestamps) are encoded as decimal strings in
JSON to avoid precision loss with large numbers:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Encoding</ttcol>
      <ttcol align='left'>Example</ttcol>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>Decimal string</c>
      <c><spanx style="verb">"250000"</spanx></c>
      <c><spanx style="verb">requestedAt</spanx></c>
      <c>Decimal string (Unix seconds)</c>
      <c><spanx style="verb">"1736165100"</spanx></c>
      <c><spanx style="verb">chainId</spanx></c>
      <c>JSON number</c>
      <c><spanx style="verb">4217</spanx></c>
</texttable>

<t>The <spanx style="verb">chainId</spanx> uses JSON number encoding as values are small enough to
avoid precision issues.</t>

</section>
<section anchor="timestamp-format"><name>Timestamp Format</name>

<t>HTTP headers and receipt fields use <xref target="RFC3339"/> formatted timestamps:
<spanx style="verb">2025-01-06T12:05:00Z</spanx>. Timestamps in EIP-712 signed data use Unix
seconds as decimal strings.</t>

</section>
</section>
<section anchor="channel-escrow-contract"><name>Channel Escrow Contract</name>

<t>Streaming payment channels require an on-chain escrow contract that holds
user deposits and enforces voucher-based withdrawals.</t>

<section anchor="channel-state"><name>Contract-Backed Channel State</name>

<t>For <spanx style="verb">sessionProtocol: "v1"</spanx>, each channel is identified by a unique
<spanx style="verb">channelId</spanx> and stores:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">payer</spanx></c>
      <c>address</c>
      <c>User who deposited funds</c>
      <c><spanx style="verb">payee</spanx></c>
      <c>address</c>
      <c>Server authorized to withdraw</c>
      <c><spanx style="verb">token</spanx></c>
      <c>address</c>
      <c><xref target="TIP-20"/> token address</c>
      <c><spanx style="verb">authorizedSigner</spanx></c>
      <c>address</c>
      <c>Authorized signer (0 = payer)</c>
      <c><spanx style="verb">deposit</spanx></c>
      <c>uint128</c>
      <c>Total amount deposited</c>
      <c><spanx style="verb">settled</spanx></c>
      <c>uint128</c>
      <c>Cumulative amount already withdrawn by payee</c>
      <c><spanx style="verb">closeRequestedAt</spanx></c>
      <c>uint64</c>
      <c>Timestamp when close was requested (0 if not)</c>
      <c><spanx style="verb">finalized</spanx></c>
      <c>bool</c>
      <c>Whether channel is closed</c>
</texttable>

<t>The <spanx style="verb">channelId</spanx> <bcp14>MUST</bcp14> be computed deterministically using the escrow
contract's <spanx style="verb">computeChannelId()</spanx> function:</t>

<figure><artwork><![CDATA[
channelId = keccak256(abi.encode(
    payer,
    payee,
    token,
    salt,
    authorizedSigner,
    address(this),
    block.chainid
))
]]></artwork></figure>

<t>Note: The <spanx style="verb">channelId</spanx> includes <spanx style="verb">address(this)</spanx> (the escrow contract
address) and <spanx style="verb">block.chainid</spanx>, explicitly binding the channel to a
specific contract deployment and chain. Clients <bcp14>MUST</bcp14> use the contract's
<spanx style="verb">computeChannelId()</spanx> function or equivalent logic to ensure
interoperability.</t>

</section>
<section anchor="precompile-channel-state"><name>Precompile-Backed Channel State</name>

<t>For <spanx style="verb">sessionProtocol: "v2"</spanx>, the channel is identified by a descriptor
and the TIP-20 channel escrow precompile.</t>

<section anchor="channel-descriptor"><name>Channel Descriptor</name>

<t>The descriptor is carried in each v2 credential payload and contains:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">payer</spanx></c>
      <c>address</c>
      <c>Wallet that funds the channel and authorizes voucher spend</c>
      <c><spanx style="verb">payee</spanx></c>
      <c>address</c>
      <c>Wallet that receives settlement from the channel</c>
      <c><spanx style="verb">operator</spanx></c>
      <c>address</c>
      <c>Optional payee-side operator authorized for channel operations; zero address if unset</c>
      <c><spanx style="verb">token</spanx></c>
      <c>address</c>
      <c>TIP-20 token escrowed by the channel</c>
      <c><spanx style="verb">salt</spanx></c>
      <c>bytes32</c>
      <c>Payer-selected entropy</c>
      <c><spanx style="verb">authorizedSigner</spanx></c>
      <c>address</c>
      <c>Voucher signer; zero address delegates to <spanx style="verb">payer</spanx></c>
      <c><spanx style="verb">expiringNonceHash</spanx></c>
      <c>bytes32</c>
      <c>Hash of the sender-signed expiring-nonce open transaction</c>
</texttable>

<t>The v2 <spanx style="verb">channelId</spanx> <bcp14>MUST</bcp14> be computed as:</t>

<figure><artwork><![CDATA[
channelId = keccak256(abi.encode(
    payer,
    payee,
    operator,
    token,
    salt,
    authorizedSigner,
    expiringNonceHash,
    escrow,
    chainId
))
]]></artwork></figure>

<t>The <spanx style="verb">escrow</spanx> value is the precompile or escrow address from
<spanx style="verb">methodDetails.escrowContract</spanx>, and <spanx style="verb">chainId</spanx> is
<spanx style="verb">methodDetails.chainId</spanx>. Servers <bcp14>MUST</bcp14> recompute this value from the
descriptor and reject credentials whose <spanx style="verb">channelId</spanx> does not match.</t>

<t>For v2, servers <bcp14>MUST</bcp14> verify that:</t>

<t><list style="symbols">
  <t><spanx style="verb">descriptor.payee</spanx> matches the challenge <spanx style="verb">recipient</spanx></t>
  <t><spanx style="verb">descriptor.token</spanx> matches the challenge <spanx style="verb">currency</spanx></t>
  <t><spanx style="verb">descriptor.operator</spanx> matches <spanx style="verb">methodDetails.operator</spanx> when present,
or is the zero address when no operator is advertised</t>
  <t><spanx style="verb">descriptor.expiringNonceHash</spanx> matches the open transaction being
broadcast</t>
</list></t>

<t>V2 channel amounts use unsigned 96-bit integer semantics. Clients and
servers <bcp14>MUST</bcp14> reject deposits, voucher amounts, settlement amounts, and
close capture amounts that exceed <spanx style="verb">2^96 - 1</spanx>.</t>

</section>
</section>
<section anchor="channel-lifecycle"><name>Channel Lifecycle</name>

<t>Channels have no expiry—they remain open until explicitly closed.</t>

<figure><artwork><![CDATA[
┌─────────────────────────────────────────────────────────────────┐
│                          CHANNEL OPEN                           │
│       Client deposits tokens, channel created with unique ID    │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                       SESSION PAYMENTS                           │
│          Client signs vouchers, server provides service         │
│          Server may periodically settle() to claim funds        │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
┌─────────────────────────┐     ┌─────────────────────────────────┐
│   COOPERATIVE CLOSE     │     │          FORCED CLOSE           │
│  Server calls close()   │     │  1. Client calls requestClose() │
│   with final voucher    │     │  2. Wait 15 min grace period    │
│                         │     │  3. Client calls withdraw()     │
└─────────────────────────┘     └─────────────────────────────────┘
              │                               │
              └───────────────┬───────────────┘
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                        CHANNEL CLOSED                           │
│           Funds distributed, channel finalized                  │
└─────────────────────────────────────────────────────────────────┘
]]></artwork></figure>

</section>
<section anchor="contract-functions"><name>Contract Functions</name>

<t>Compliant escrow contracts <bcp14>MUST</bcp14> implement the following functions. The
signatures shown are a reference implementation; alternative implementations
<bcp14>MAY</bcp14> use different parameter types (e.g., <spanx style="verb">uint256</spanx> instead of <spanx style="verb">uint128</spanx>)
as long as the semantics are preserved.</t>

<section anchor="open"><name>open</name>

<t>Opens a new channel with escrowed funds.</t>

<texttable>
      <ttcol align='left'>Parameter</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">payee</spanx></c>
      <c>address</c>
      <c>Server's address authorized to withdraw funds</c>
      <c><spanx style="verb">token</spanx></c>
      <c>address</c>
      <c><xref target="TIP-20"/> token contract address</c>
      <c><spanx style="verb">deposit</spanx></c>
      <c>uint128</c>
      <c>Amount to deposit in base units (6 decimals)</c>
      <c><spanx style="verb">salt</spanx></c>
      <c>bytes32</c>
      <c>Random value for deterministic channelId computation</c>
      <c><spanx style="verb">authorizedSigner</spanx></c>
      <c>address</c>
      <c>Delegated signer; use <spanx style="verb">0x0</spanx> to default to payer</c>
</texttable>

<t>Returns the computed <spanx style="verb">channelId</spanx>.</t>

<figure><sourcecode type="solidity"><![CDATA[
function open(
    address payee,
    address token,
    uint128 deposit,
    bytes32 salt,
    address authorizedSigner
) external returns (bytes32 channelId);
]]></sourcecode></figure>

</section>
<section anchor="settle"><name>settle</name>

<t>Server withdraws funds using a signed voucher without closing the channel.</t>

<texttable>
      <ttcol align='left'>Parameter</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>bytes32</c>
      <c>Unique channel identifier</c>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>uint128</c>
      <c>Cumulative total authorized (not delta)</c>
      <c><spanx style="verb">signature</spanx></c>
      <c>bytes</c>
      <c>EIP-712 signature from authorized signer</c>
</texttable>

<t>The contract computes <spanx style="verb">delta = cumulativeAmount - channel.settled</spanx> and
transfers <spanx style="verb">delta</spanx> tokens to the payee.</t>

<figure><sourcecode type="solidity"><![CDATA[
function settle(
    bytes32 channelId,
    uint128 cumulativeAmount,
    bytes calldata signature
) external;
]]></sourcecode></figure>

</section>
<section anchor="topup"><name>topUp</name>

<t>User adds more funds to an existing channel. If a close request is
pending (<spanx style="verb">closeRequestedAt != 0</spanx>), calling <spanx style="verb">topUp()</spanx> <bcp14>MUST</bcp14> cancel it by
resetting <spanx style="verb">closeRequestedAt</spanx> to zero and emitting a
<spanx style="verb">CloseRequestCancelled</spanx> event.</t>

<texttable>
      <ttcol align='left'>Parameter</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>bytes32</c>
      <c>Existing channel identifier</c>
      <c><spanx style="verb">additionalDeposit</spanx></c>
      <c>uint128</c>
      <c>Additional amount to deposit in base units</c>
</texttable>

<figure><sourcecode type="solidity"><![CDATA[
function topUp(
    bytes32 channelId,
    uint128 additionalDeposit
) external;
]]></sourcecode></figure>

</section>
<section anchor="close"><name>close</name>

<t>Server closes the channel, settling any outstanding voucher and refunding
the remainder to the payer. Only callable by the payee.</t>

<texttable>
      <ttcol align='left'>Parameter</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>bytes32</c>
      <c>Channel to close</c>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>uint128</c>
      <c>Final cumulative amount for settlement</c>
      <c><spanx style="verb">signature</spanx></c>
      <c>bytes</c>
      <c>EIP-712 signature from authorized signer</c>
</texttable>

<t>Transfers <spanx style="verb">cumulativeAmount - channel.settled</spanx> to payee, refunds
<spanx style="verb">channel.deposit - cumulativeAmount</spanx> to payer, and marks channel finalized.</t>

<figure><sourcecode type="solidity"><![CDATA[
function close(
    bytes32 channelId,
    uint128 cumulativeAmount,
    bytes calldata signature
) external;
]]></sourcecode></figure>

</section>
<section anchor="requestclose"><name>requestClose</name>

<t>User requests channel closure, starting a grace period of at least 15 minutes.</t>

<texttable>
      <ttcol align='left'>Parameter</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>bytes32</c>
      <c>Channel for which to request closure</c>
</texttable>

<t>Sets <spanx style="verb">channel.closeRequestedAt</spanx> to current block timestamp. The grace period
allows the payee time to submit any outstanding vouchers before forced closure.</t>

<figure><sourcecode type="solidity"><![CDATA[
function requestClose(bytes32 channelId) external;
]]></sourcecode></figure>

</section>
<section anchor="withdraw"><name>withdraw</name>

<t>User withdraws remaining funds after the grace period expires.</t>

<texttable>
      <ttcol align='left'>Parameter</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>bytes32</c>
      <c>Channel to withdraw from</c>
</texttable>

<t>Requires <spanx style="verb">block.timestamp &gt;= channel.closeRequestedAt + CLOSE_GRACE_PERIOD</spanx>.
Refunds all remaining deposit to payer and marks channel finalized.</t>

<figure><sourcecode type="solidity"><![CDATA[
function withdraw(bytes32 channelId) external;
]]></sourcecode></figure>

</section>
</section>
<section anchor="access-control"><name>Access Control</name>

<t>The escrow contract <bcp14>MUST</bcp14> enforce the following access control:</t>

<texttable>
      <ttcol align='left'>Function</ttcol>
      <ttcol align='left'>Caller</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">open</spanx></c>
      <c>Anyone</c>
      <c>Creates channel; caller becomes payer</c>
      <c><spanx style="verb">settle</spanx></c>
      <c>Payee only</c>
      <c>Withdraws funds using voucher</c>
      <c><spanx style="verb">topUp</spanx></c>
      <c>Payer only</c>
      <c>Adds funds to existing channel</c>
      <c><spanx style="verb">close</spanx></c>
      <c>Payee only</c>
      <c>Closes channel with final voucher</c>
      <c><spanx style="verb">requestClose</spanx></c>
      <c>Payer only</c>
      <c>Initiates forced close</c>
      <c><spanx style="verb">withdraw</spanx></c>
      <c>Payer only</c>
      <c>Withdraws after grace period</c>
</texttable>

</section>
<section anchor="signature-verification"><name>Signature Verification</name>

<t>The escrow contract <bcp14>MUST</bcp14> perform the following signature verification for
all functions that accept voucher signatures (<spanx style="verb">settle</spanx>, <spanx style="verb">close</spanx>):</t>

<t><list style="numbers" type="1">
  <t><strong>Canonical signatures</strong>: The contract <bcp14>MUST</bcp14> reject ECDSA signatures
with non-canonical (high-s) values. Signatures <bcp14>MUST</bcp14> have
<spanx style="verb">s &lt;= secp256k1_order / 2</spanx> where the half-order is
<spanx style="verb">0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0</spanx>.
See <xref target="signature-malleability"/> for rationale.</t>
  <t><strong>Authorized signer verification</strong>: The contract <bcp14>MUST</bcp14> recover the
signer address from the EIP-712 signature and verify it matches the
expected signer for the channel:
  <list style="symbols">
      <t>If <spanx style="verb">channel.authorizedSigner</spanx> is non-zero, the recovered signer
<bcp14>MUST</bcp14> equal <spanx style="verb">channel.authorizedSigner</spanx></t>
      <t>Otherwise, the recovered signer <bcp14>MUST</bcp14> equal <spanx style="verb">channel.payer</spanx></t>
    </list></t>
  <t><strong>Domain binding</strong>: The contract <bcp14>MUST</bcp14> use its own address as the
<spanx style="verb">verifyingContract</spanx> in the EIP-712 domain separator, ensuring
vouchers cannot be replayed across different escrow deployments.</t>
</list></t>

<t>Failure to enforce these requirements on-chain would allow attackers to
bypass server-side validation by submitting transactions directly to
the contract.</t>

</section>
</section>
<section anchor="request-schema"><name>Request Schema</name>

<t>The <spanx style="verb">request</spanx> parameter in the <spanx style="verb">WWW-Authenticate</spanx> challenge contains a
base64url-encoded JSON object.</t>

<section anchor="fields"><name>Fields</name>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">amount</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Price per unit in base units (see note below)</c>
      <c><spanx style="verb">unitType</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Unit being priced (e.g., <spanx style="verb">"llm_token"</spanx>, <spanx style="verb">"byte"</spanx>, <spanx style="verb">"request"</spanx>)</c>
      <c><spanx style="verb">suggestedDeposit</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Suggested channel deposit amount in base units</c>
      <c><spanx style="verb">currency</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c><xref target="TIP-20"/> token address (e.g., <spanx style="verb">"0x20c0..."</spanx>)</c>
      <c><spanx style="verb">recipient</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Payee address (server's withdrawal address)—equivalent to the on-chain <spanx style="verb">payee</spanx></c>
</texttable>

<t>For the <spanx style="verb">session</spanx> intent, <spanx style="verb">amount</spanx> specifies the price per unit of service
in base units (6 decimals), not a total charge. When <spanx style="verb">unitType</spanx> is present,
clients can use it together with <spanx style="verb">amount</spanx> to estimate costs before streaming
begins. The total cost depends on consumption:
<spanx style="verb">total = amount × units_consumed</spanx>.</t>

<t>The optional <spanx style="verb">suggestedDeposit</spanx> indicates the server's recommended
channel deposit for typical usage. Clients <bcp14>MAY</bcp14> deposit less (if they
expect limited usage) or more (for extended sessions). The minimum
viable deposit is implementation-defined but <bcp14>SHOULD</bcp14> be at least
<spanx style="verb">amount</spanx> to cover one unit of service.</t>

<t>Challenge expiry is specified via the <spanx style="verb">expires</spanx> auth-param in the
<spanx style="verb">WWW-Authenticate</spanx> header per <xref target="I-D.httpauth-payment"/>, using <xref target="RFC3339"/>
timestamp format. Unlike the <spanx style="verb">charge</spanx> intent, the session request JSON
does not include an <spanx style="verb">expires</spanx> field—expiry is conveyed solely via the
HTTP header.</t>

</section>
<section anchor="method-details"><name>Method Details</name>

<t>As of version 00, session-specific request fields are placed in
<spanx style="verb">methodDetails</spanx>. A future high-level "session" intent definition may
promote common fields to the core schema.</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">methodDetails.escrowContract</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Address of the channel escrow contract</c>
      <c><spanx style="verb">methodDetails.channelId</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Channel ID if resuming an existing channel</c>
      <c><spanx style="verb">methodDetails.minVoucherDelta</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Minimum amount increase between vouchers (server policy hint)</c>
      <c><spanx style="verb">methodDetails.chainId</spanx></c>
      <c>number</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Tempo chain ID (default: 4217)</c>
      <c><spanx style="verb">methodDetails.operator</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>V2 payee-side operator address clients encode in new channel descriptors</c>
      <c><spanx style="verb">methodDetails.sessionProtocol</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Session protocol version, either <spanx style="verb">"v1"</spanx> or <spanx style="verb">"v2"</spanx></c>
      <c><spanx style="verb">methodDetails.sessionSnapshot</spanx></c>
      <c>object</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>V2 reusable channel snapshot; see <xref target="session-snapshot"/></c>
</texttable>

<t>Channel reuse is <bcp14>OPTIONAL</bcp14>. Servers <bcp14>MAY</bcp14> include <spanx style="verb">channelId</spanx> to suggest
resuming an existing channel:</t>

<t><list style="symbols">
  <t><strong>New channel</strong> (no <spanx style="verb">channelId</spanx>): Client generates a random salt locally,
computes <spanx style="verb">channelId</spanx> using the formula in <xref target="channel-state"/>, opens the channel
on-chain, and returns the <spanx style="verb">channelId</spanx> in the credential.</t>
  <t><strong>Existing channel</strong> (<spanx style="verb">channelId</spanx> provided): Client <bcp14>MUST</bcp14> verify
<spanx style="verb">channel.deposit - channel.settled &gt;= amount</spanx> before resuming. If
insufficient, client <bcp14>SHOULD</bcp14> either call <spanx style="verb">topUp()</spanx> with the difference
or open a new channel.</t>
</list></t>

<t>Servers <bcp14>MAY</bcp14> cache <spanx style="verb">(payer address, payee address, token) → channelId</spanx>
mappings to suggest channel reuse, reducing on-chain transactions.</t>

<t>When <spanx style="verb">methodDetails.sessionProtocol</spanx> is <spanx style="verb">"v2"</spanx>, servers <bcp14>MUST</bcp14> include
<spanx style="verb">methodDetails.chainId</spanx> and <spanx style="verb">methodDetails.escrowContract</spanx> in the
challenge after applying defaults. The <spanx style="verb">escrowContract</spanx> value identifies
the TIP-20 channel escrow precompile or compatible deployment. Servers
<bcp14>MAY</bcp14> include <spanx style="verb">methodDetails.operator</spanx>; if omitted, clients <bcp14>MUST</bcp14> use the
zero address for the descriptor <spanx style="verb">operator</spanx>.</t>

</section>
<section anchor="session-snapshot"><name>Session Snapshot</name>

<t>For v2 reusable channels, servers <bcp14>MAY</bcp14> include a snapshot of channel state
in <spanx style="verb">methodDetails.sessionSnapshot</spanx> and <bcp14>MAY</bcp14> also send it in the
<spanx style="verb">Payment-Session-Snapshot</spanx> response header. The header value is a
base64url-encoded JSON object without padding. Servers <bcp14>MAY</bcp14> also send a
<spanx style="verb">Payment-Session</spanx> header containing the reusable <spanx style="verb">channelId</spanx>.</t>

<t>A session snapshot contains:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">acceptedCumulative</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Highest cumulative voucher amount accepted by the server</c>
      <c><spanx style="verb">chainId</spanx></c>
      <c>number</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Tempo chain ID</c>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>V2 channel identifier</c>
      <c><spanx style="verb">closeRequestedAt</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Close-request timestamp if the channel is closing</c>
      <c><spanx style="verb">deposit</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Current on-chain deposit</c>
      <c><spanx style="verb">descriptor</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel descriptor from <xref target="precompile-channel-state"/></c>
      <c><spanx style="verb">escrow</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Escrow precompile or contract address</c>
      <c><spanx style="verb">requiredCumulative</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Minimum cumulative amount required for the challenged request</c>
      <c><spanx style="verb">settled</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Amount already settled on-chain</c>
      <c><spanx style="verb">spent</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Amount consumed according to server accounting</c>
      <c><spanx style="verb">units</spanx></c>
      <c>number</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Units delivered according to server accounting</c>
</texttable>

<t>Clients <bcp14>MAY</bcp14> use a valid snapshot to avoid local channel lookup. Clients
<bcp14>MUST</bcp14> verify that the snapshot <spanx style="verb">channelId</spanx>, descriptor, <spanx style="verb">escrow</spanx>, and
<spanx style="verb">chainId</spanx> are consistent with the v2 channel ID derivation before using
it to construct a credential.</t>

<section anchor="bootstrap-preflight"><name>Bootstrap Preflight</name>

<t>Servers <bcp14>MAY</bcp14> support same-resource bootstrap for reusable v2 channels. A
client sends a <spanx style="verb">HEAD</spanx> request to the protected resource. If the server
needs payer identity before it can resolve a channel, it <bcp14>MAY</bcp14> challenge
with a zero-amount <spanx style="verb">tempo</spanx> <spanx style="verb">charge</spanx> request. After the client proves the
zero-amount challenge, the server returns <spanx style="verb">204 No Content</spanx> and <bcp14>MAY</bcp14> include
<spanx style="verb">Payment-Session</spanx> and <spanx style="verb">Payment-Session-Snapshot</spanx> headers.</t>

<t><strong>Example (new channel):</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "amount": "25",
  "unitType": "llm_token",
  "suggestedDeposit": "10000000",
  "currency": "0x20c0000000000000000000000000000000000000",
  "recipient": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
  "methodDetails": {
    "escrowContract": "0x1234567890abcdef1234567890abcdef12345678",
    "chainId": 4217,
    "sessionProtocol": "v2"
  }
}
]]></sourcecode></figure>

<t>This requests a price of 0.000025 tokens per LLM token, with a suggested
deposit of 10.00 tokens. The client generates a random salt locally.</t>

<t><strong>Example (existing channel):</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "amount": "25",
  "unitType": "llm_token",
  "currency": "0x20c0000000000000000000000000000000000000",
  "recipient": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
  "methodDetails": {
    "escrowContract": "0x1234567890abcdef1234567890abcdef12345678",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "chainId": 4217,
    "sessionProtocol": "v2"
  }
}
]]></sourcecode></figure>

<t>For existing channels, <spanx style="verb">suggestedDeposit</spanx> is omitted since the channel
already has funds. The <spanx style="verb">channelId</spanx> tells the client to resume this channel.</t>

</section>
</section>
</section>
<section anchor="fee-payment"><name>Fee Payment</name>

<t>When a challenge includes <spanx style="verb">methodDetails.feePayer: true</spanx>, the server
commits to paying transaction fees on behalf of the client. In the
<spanx style="verb">session</spanx> intent, <spanx style="verb">feePayer</spanx> affects only the client-originated channel
funding transactions (<spanx style="verb">open</spanx> and <spanx style="verb">topUp</spanx>).</t>

<section anchor="server-paid-fees"><name>Server-Paid Fees</name>

<t>When <spanx style="verb">feePayer: true</spanx> for <spanx style="verb">open</spanx> or <spanx style="verb">topUp</spanx>:</t>

<t><list style="numbers" type="1">
  <t><strong>Client signs with placeholder</strong>: The client signs the Tempo Transaction
<xref target="TEMPO-TX-SPEC"/> with <spanx style="verb">fee_payer_signature</spanx> set to a placeholder value
(<spanx style="verb">0x00</spanx>) and <spanx style="verb">fee_token</spanx> left empty. The client uses signature domain
<spanx style="verb">0x76</spanx>.</t>
  <t><strong>Server receives credential</strong>: The server extracts the client-signed
transaction from the credential payload.</t>
  <t><strong>Server adds fee payment signature</strong>: The server selects a <spanx style="verb">fee_token</spanx>
(any USD-denominated TIP-20 stablecoin) and signs the transaction using
signature domain <spanx style="verb">0x78</spanx>. This signature commits to the transaction
including the <spanx style="verb">fee_token</spanx> and client's address.</t>
  <t><strong>Server broadcasts</strong>: The final transaction contains both signatures:  <list style="symbols">
      <t>Client's signature (authorizing the channel operation)</t>
      <t>Server's <spanx style="verb">fee_payer_signature</spanx> (committing to pay fees)</t>
    </list></t>
</list></t>

</section>
<section anchor="client-paid-fees"><name>Client-Paid Fees</name>

<t>When <spanx style="verb">feePayer: false</spanx> or omitted, the client <bcp14>MUST</bcp14> set <spanx style="verb">fee_token</spanx> to a valid
USD TIP-20 token address and include valid fee payment fields so the
transaction is executable without server fee sponsorship. The server
broadcasts the transaction as-is.</t>

</section>
<section anchor="server-initiated-operations"><name>Server-Initiated Operations</name>

<t>The <spanx style="verb">settle</spanx> and <spanx style="verb">close</spanx> contract functions are server-originated on-chain
transactions. The server pays transaction fees for these operations
regardless of the <spanx style="verb">feePayer</spanx> setting:</t>

<t><list style="symbols">
  <t><strong>Voucher updates</strong> (<spanx style="verb">action="voucher"</spanx>) are off-chain and incur no
transaction fees.</t>
  <t><strong>Settlement</strong> (<spanx style="verb">settle()</spanx>) and channel <strong>close</strong> (<spanx style="verb">close</spanx> invocation) are initiated by
the server using the highest valid voucher. The server covers the fees for
these transactions.</t>
  <t>Servers <bcp14>MAY</bcp14> recover settlement costs through pricing or other business
logic.</t>
</list></t>

<t>The <spanx style="verb">feePayer</spanx> field applies only to <spanx style="verb">open</spanx> and <spanx style="verb">topUp</spanx> operations where
the client provides a signed transaction.</t>

</section>
<section anchor="server-requirements"><name>Server Requirements</name>

<t>When acting as fee payer for <spanx style="verb">open</spanx> or <spanx style="verb">topUp</spanx>:</t>

<t><list style="symbols">
  <t>Servers <bcp14>MUST</bcp14> maintain sufficient balance of a USD TIP-20 token to pay
transaction fees</t>
  <t>Servers <bcp14>MAY</bcp14> use any USD-denominated TIP-20 token with sufficient AMM
liquidity as the fee token</t>
  <t>Servers <bcp14>MUST</bcp14> validate the transaction matches challenge and channel
parameters before adding fee payer signature</t>
  <t>Servers <bcp14>MUST</bcp14> reject credentials with unknown <spanx style="verb">action</spanx> values</t>
</list></t>

</section>
<section anchor="client-requirements"><name>Client Requirements</name>

<t><list style="symbols">
  <t>When <spanx style="verb">feePayer: true</spanx>: Clients <bcp14>MUST</bcp14> sign with <spanx style="verb">fee_payer_signature</spanx>
set to <spanx style="verb">0x00</spanx> and <spanx style="verb">fee_token</spanx> empty or <spanx style="verb">0x80</spanx> (RLP null)</t>
  <t>When <spanx style="verb">feePayer: false</spanx> or omitted: Clients <bcp14>MUST</bcp14> set <spanx style="verb">fee_token</spanx> to a
valid USD TIP-20 token and have sufficient balance to pay fees</t>
</list></t>

</section>
</section>
<section anchor="credential-schema"><name>Credential Schema</name>

<t>The credential in the <spanx style="verb">Authorization</spanx> header contains a base64url-encoded
JSON object per <xref target="I-D.httpauth-payment"/>.</t>

<section anchor="credential-structure"><name>Credential Structure</name>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">challenge</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Echo of the challenge parameters from the server's WWW-Authenticate header</c>
      <c><spanx style="verb">payload</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Session-specific payload object</c>
</texttable>

<t>Implementations <bcp14>MUST</bcp14> ignore unknown fields in credential payloads, request
objects, and receipts to allow forward-compatible extensions.</t>

</section>
<section anchor="credential-lifecycle"><name>Credential Lifecycle</name>

<t>A streaming payment session progresses through distinct phases, each
corresponding to a payload action:</t>

<t><list style="numbers" type="1">
  <t><strong>Open</strong>: Client deposits funds on-chain and presents the <spanx style="verb">open</spanx> action
to begin the session. The server verifies the on-chain deposit and
validates the initial zero-amount voucher.</t>
  <t><strong>Streaming</strong>: Client submits <spanx style="verb">voucher</spanx> actions with increasing
cumulative amounts as service is consumed. The server may periodically
settle vouchers on-chain.</t>
  <t><strong>Close</strong>: Client sends the <spanx style="verb">close</spanx> action with the final voucher. The
server settles on-chain and returns a receipt.</t>
</list></t>

<t>Each action carries action-specific fields directly in the <spanx style="verb">payload</spanx> object,
with the <spanx style="verb">action</spanx> field discriminating between phases.</t>

</section>
<section anchor="payload-actions"><name>Payload Actions</name>

<t>The <spanx style="verb">payload</spanx> object uses an <spanx style="verb">action</spanx> discriminator with action-specific
fields at the same level:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">action</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>One of <spanx style="verb">"open"</spanx>, <spanx style="verb">"topUp"</spanx>, <spanx style="verb">"voucher"</spanx>, <spanx style="verb">"close"</spanx></c>
</texttable>

<t>Action-specific fields are placed directly in the <spanx style="verb">payload</spanx> object alongside
<spanx style="verb">action</spanx>. See each action's definition for required fields.</t>

<texttable>
      <ttcol align='left'>Action</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">open</spanx></c>
      <c>Confirms channel is open on-chain; begins streaming</c>
      <c><spanx style="verb">topUp</spanx></c>
      <c>Adds funds to an existing channel</c>
      <c><spanx style="verb">voucher</spanx></c>
      <c>Submits an updated cumulative voucher</c>
      <c><spanx style="verb">close</spanx></c>
      <c>Requests server to close the channel</c>
</texttable>

<section anchor="open-payload"><name>Open Payload</name>

<t>The <spanx style="verb">open</spanx> action confirms an on-chain channel opening and begins the
streaming session. The client provides a signed transaction for the server
to broadcast.</t>

<t><strong>Payload fields (in addition to <spanx style="verb">action</spanx>):</strong></t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">type</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c><spanx style="verb">"transaction"</spanx></c>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel identifier (hex-encoded bytes32)</c>
      <c><spanx style="verb">transaction</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Signed transaction bytes</c>
      <c><spanx style="verb">authorizedSigner</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Address delegated to sign vouchers</c>
      <c><spanx style="verb">descriptor</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14> for v2</c>
      <c>Channel descriptor from <xref target="precompile-channel-state"/></c>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Initial cumulative amount (typically <spanx style="verb">"0"</spanx>)</c>
      <c><spanx style="verb">signature</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>EIP-712 voucher signature for the initial amount</c>
</texttable>

<t>The <spanx style="verb">transaction</spanx> field contains the complete signed Tempo Transaction
(type 0x76) <xref target="TEMPO-TX-SPEC"/> serialized as RLP and hex-encoded. The server
broadcasts the transaction, optionally adding a fee payer signature if
<spanx style="verb">feePayer: true</spanx> was specified in the challenge (see <xref target="fee-payment"/>).</t>

<t>For v1, the server recovers the <spanx style="verb">payer</spanx> address from the signed transaction
and uses it to compute the <spanx style="verb">channelId</spanx> deterministically (see
<xref target="channel-state"/>). The <spanx style="verb">authorizedSigner</spanx> is inferred from the calldata
inside <spanx style="verb">transaction</spanx> and verified when the transaction is signed.</t>

<t>For v2, the client <bcp14>MUST</bcp14> include <spanx style="verb">descriptor</spanx>. The server <bcp14>MUST</bcp14> verify that
the descriptor matches the signed open transaction, the challenge payment
fields, and the <spanx style="verb">channelId</spanx> derivation in <xref target="precompile-channel-state"/>. If
<spanx style="verb">authorizedSigner</spanx> is present in the payload, it <bcp14>MUST</bcp14> match
<spanx style="verb">descriptor.authorizedSigner</spanx>.</t>

<t>The initial voucher (<spanx style="verb">cumulativeAmount</spanx> and <spanx style="verb">signature</spanx>) proves the client
controls the signing key and establishes the voucher chain.</t>

<t><strong>Example:</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "open",
    "type": "transaction",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "descriptor": {
      "payer": "0x1111111111111111111111111111111111111111",
      "payee": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
      "operator": "0x0000000000000000000000000000000000000000",
      "token": "0x20c0000000000000000000000000000000000000",
      "salt": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "authorizedSigner": "0x0000000000000000000000000000000000000000",
      "expiringNonceHash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    },
    "transaction": "0x76f901...signed transaction bytes...",
    "cumulativeAmount": "0",
    "signature": "0xabcdef1234567890..."
  }
}
]]></sourcecode></figure>

<t>Note: The <spanx style="verb">transaction</spanx> field contains RLP-encoded transaction bytes.
When provided, the <spanx style="verb">signature</spanx> field is the EIP-712 voucher signature
(65 bytes r‖s‖v or 64 bytes EIP-2098 compact).</t>

<t>The <spanx style="verb">challenge</spanx> object <bcp14>MUST</bcp14> echo the challenge parameters from the server's
<spanx style="verb">WWW-Authenticate</spanx> header per <xref target="I-D.httpauth-payment"/>.</t>

</section>
<section anchor="topup-payload"><name>TopUp Payload</name>

<t>The <spanx style="verb">topUp</spanx> action adds funds to an existing channel during a streaming
session. Like <spanx style="verb">open</spanx>, the client provides a signed transaction for the
server to broadcast.</t>

<t>Clients <bcp14>MUST</bcp14> include a <spanx style="verb">challenge</spanx> object in the Payment credential for <spanx style="verb">topUp</spanx>
actions. To obtain a challenge for a top-up outside an active streaming
response, clients <bcp14>MAY</bcp14> send a <spanx style="verb">HEAD</spanx> request to the protected resource;
the server returns 402 with a <spanx style="verb">WWW-Authenticate</spanx> challenge (no body).
Servers <bcp14>MUST</bcp14> reject <spanx style="verb">topUp</spanx> actions referencing an unknown or expired
challenge <spanx style="verb">id</spanx> with problem type <spanx style="verb">challenge-not-found</spanx>.</t>

<t><strong>Payload fields (in addition to <spanx style="verb">action</spanx>):</strong></t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">type</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c><spanx style="verb">"transaction"</spanx></c>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel ID</c>
      <c><spanx style="verb">transaction</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Signed transaction bytes</c>
      <c><spanx style="verb">descriptor</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14> for v2</c>
      <c>Channel descriptor from <xref target="precompile-channel-state"/></c>
      <c><spanx style="verb">additionalDeposit</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Additional amount to deposit in base units</c>
</texttable>

<t><strong>Example:</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "topUp",
    "type": "transaction",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "descriptor": {
      "payer": "0x1111111111111111111111111111111111111111",
      "payee": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
      "operator": "0x0000000000000000000000000000000000000000",
      "token": "0x20c0000000000000000000000000000000000000",
      "salt": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "authorizedSigner": "0x0000000000000000000000000000000000000000",
      "expiringNonceHash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    },
    "transaction": "0x76f901...signed topUp transaction bytes...",
    "additionalDeposit": "5000000"
  }
}
]]></sourcecode></figure>

<t>Upon successful verification, the server updates the channel's available
balance. The new deposit is immediately available for voucher authorization.</t>

</section>
<section anchor="voucher-payload"><name>Voucher Payload</name>

<t>The <spanx style="verb">voucher</spanx> action submits an updated cumulative voucher during streaming.</t>

<t><strong>Payload fields (in addition to <spanx style="verb">action</spanx>):</strong></t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel identifier</c>
      <c><spanx style="verb">descriptor</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14> for v2</c>
      <c>Channel descriptor from <xref target="precompile-channel-state"/></c>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Cumulative amount authorized</c>
      <c><spanx style="verb">signature</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>EIP-712 voucher signature</c>
</texttable>

<t><strong>Example:</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "voucher",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "descriptor": {
      "payer": "0x1111111111111111111111111111111111111111",
      "payee": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
      "operator": "0x0000000000000000000000000000000000000000",
      "token": "0x20c0000000000000000000000000000000000000",
      "salt": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "authorizedSigner": "0x0000000000000000000000000000000000000000",
      "expiringNonceHash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    },
    "cumulativeAmount": "250000",
    "signature": "0xabcdef1234567890..."
  }
}
]]></sourcecode></figure>

</section>
<section anchor="close-payload"><name>Close Payload</name>

<t>The <spanx style="verb">close</spanx> action requests the server to close the channel and settle
on-chain.</t>

<t><strong>Payload fields (in addition to <spanx style="verb">action</spanx>):</strong></t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel identifier</c>
      <c><spanx style="verb">descriptor</spanx></c>
      <c>object</c>
      <c><bcp14>REQUIRED</bcp14> for v2</c>
      <c>Channel descriptor from <xref target="precompile-channel-state"/></c>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Final cumulative amount for settlement</c>
      <c><spanx style="verb">signature</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>EIP-712 voucher signature</c>
</texttable>

<t>The server uses the voucher fields (channelId, cumulativeAmount, signature)
to close the channel on-chain. For v2, the server <bcp14>MUST</bcp14> use the descriptor
to identify the channel and <bcp14>MUST</bcp14> reject a close credential whose descriptor
does not match the stored channel.</t>

<t><strong>Example:</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "close",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "descriptor": {
      "payer": "0x1111111111111111111111111111111111111111",
      "payee": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
      "operator": "0x0000000000000000000000000000000000000000",
      "token": "0x20c0000000000000000000000000000000000000",
      "salt": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "authorizedSigner": "0x0000000000000000000000000000000000000000",
      "expiringNonceHash": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    },
    "cumulativeAmount": "500000",
    "signature": "0xabcdef1234567890..."
  }
}
]]></sourcecode></figure>

</section>
</section>
</section>
<section anchor="voucher-format"><name>Voucher Signing Format</name>

<t>Vouchers use typed structured data signing compatible with <xref target="EIP-712"/>.
This section normatively defines the signing procedure; <xref target="EIP-712"/> is
referenced for background only.</t>

<section anchor="wire-format"><name>Wire Format</name>

<t>Voucher fields are placed directly in the credential <spanx style="verb">payload</spanx> object
(alongside <spanx style="verb">action</spanx>) rather than in a nested structure:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel identifier (hex-encoded bytes32)</c>
      <c><spanx style="verb">cumulativeAmount</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Cumulative amount authorized (decimal string)</c>
      <c><spanx style="verb">signature</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>EIP-712 signature (hex-encoded)</c>
</texttable>

<t>The EIP-712 domain and type definitions are fixed by this specification.
Implementations <bcp14>MUST</bcp14> reconstruct the full typed data structure using the
domain parameters from the challenge (<spanx style="verb">chainId</spanx>, <spanx style="verb">escrowContract</spanx>) before
signature verification.</t>

</section>
<section anchor="type-definitions"><name>Type Definitions</name>

<t>The <spanx style="verb">types</spanx> object <bcp14>MUST</bcp14> contain exactly:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "Voucher": [
    { "name": "channelId", "type": "bytes32" },
    { "name": "cumulativeAmount", "type": "uint128" }
  ]
}
]]></sourcecode></figure>

<t>For <spanx style="verb">sessionProtocol: "v2"</spanx>, <spanx style="verb">cumulativeAmount</spanx> is encoded as <spanx style="verb">uint96</spanx>
instead of <spanx style="verb">uint128</spanx>.</t>

<t>Note: The <spanx style="verb">EIP712Domain</spanx> type is implicit per EIP-712 and <bcp14>SHOULD NOT</bcp14> be
included in the <spanx style="verb">types</spanx> object. The domain separator is computed from
the <spanx style="verb">domain</spanx> object using the canonical type string
<spanx style="verb">EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)</spanx>.</t>

</section>
<section anchor="domain-separator"><name>Domain Separator</name>

<t>The <spanx style="verb">domain</spanx> object <bcp14>MUST</bcp14> contain:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Value</ttcol>
      <c><spanx style="verb">name</spanx></c>
      <c>string</c>
      <c><spanx style="verb">"Tempo Stream Channel"</spanx> for v1; <spanx style="verb">"TIP20 Channel Reserve"</spanx> for v2</c>
      <c><spanx style="verb">version</spanx></c>
      <c>string</c>
      <c><spanx style="verb">"1"</spanx></c>
      <c><spanx style="verb">chainId</spanx></c>
      <c>number</c>
      <c>Tempo chain ID (e.g., <spanx style="verb">4217</spanx>)</c>
      <c><spanx style="verb">verifyingContract</spanx></c>
      <c>string</c>
      <c>Escrow contract address from challenge</c>
</texttable>

</section>
<section anchor="signing-procedure"><name>Signing Procedure</name>

<t>To sign a voucher, implementations <bcp14>MUST</bcp14>:</t>

<t><list style="numbers" type="1">
  <t>Construct the domain separator hash:  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
domainSeparator = keccak256(
  abi.encode(
    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
    keccak256(bytes(name)),
    keccak256(bytes(version)),
    chainId,
    verifyingContract
  )
)
]]></artwork></figure>
  </t>
  <t>Construct the struct hash:  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
structHash = keccak256(
  abi.encode(
    keccak256("Voucher(bytes32 channelId,uint128 cumulativeAmount)"),
    channelId,
    cumulativeAmount
  )
)
]]></artwork></figure>
  <vspace blankLines='1'/>
For v2, the struct type string is
<spanx style="verb">Voucher(bytes32 channelId,uint96 cumulativeAmount)</spanx>.</t>
  <t>Compute the signing hash:  <vspace blankLines='1'/>
    <figure><artwork><![CDATA[
signingHash = keccak256("\x19\x01" || domainSeparator || structHash)
]]></artwork></figure>
  </t>
  <t>Sign with ECDSA using secp256k1 curve</t>
  <t>Encode signature as 65-byte <spanx style="verb">r || s || v</spanx> where <spanx style="verb">v</spanx> is 27 or 28</t>
</list></t>

</section>
<section anchor="cumulative-semantics"><name>Cumulative Semantics</name>

<t>Vouchers specify cumulative totals, not incremental deltas:</t>

<t><list style="symbols">
  <t>Voucher #1: <spanx style="verb">cumulativeAmount = 100</spanx> (authorizes 100 total)</t>
  <t>Voucher #2: <spanx style="verb">cumulativeAmount = 250</spanx> (authorizes 250 total)</t>
  <t>Voucher #3: <spanx style="verb">cumulativeAmount = 400</spanx> (authorizes 400 total)</t>
</list></t>

<t>When settling, the contract computes: <spanx style="verb">delta = cumulativeAmount - settled</spanx></t>

</section>
</section>
<section anchor="verification-procedure"><name>Verification Procedure</name>

<section anchor="open-verification"><name>Open Verification</name>

<t>On <spanx style="verb">action="open"</spanx>, servers <bcp14>MUST</bcp14>:</t>

<t><list style="numbers" type="1">
  <t><strong>Transaction verification</strong>: Decode the signed transaction from
<spanx style="verb">transaction</spanx>, verify it calls <spanx style="verb">open()</spanx> on the expected escrow contract
with correct parameters. Recover the <spanx style="verb">payer</spanx> address from the
transaction, infer <spanx style="verb">authorizedSigner</spanx> from the calldata, and compute
<spanx style="verb">channelId</spanx> deterministically (see <xref target="channel-state"/>). If <spanx style="verb">feePayer: true</spanx>,
add fee payer signature using domain <spanx style="verb">0x78</spanx> (see <xref target="fee-payment"/>) and
broadcast. Otherwise, broadcast as-is.
For v2, servers <bcp14>MUST</bcp14> also verify the payload <spanx style="verb">descriptor</spanx>, the computed
<spanx style="verb">channelId</spanx>, the descriptor <spanx style="verb">expiringNonceHash</spanx>, and the emitted channel
open receipt before accepting the credential.</t>
  <t>Query the escrow contract to verify channel state:
  <list style="symbols">
      <t>Channel exists with the computed <spanx style="verb">channelId</spanx></t>
      <t><spanx style="verb">channel.payee</spanx> matches server's address</t>
      <t><spanx style="verb">channel.token</spanx> matches <spanx style="verb">request.currency</spanx></t>
      <t><spanx style="verb">channel.deposit - channel.settled &gt;= amount</spanx> (sufficient available balance)</t>
      <t>Channel is not finalized</t>
      <t><spanx style="verb">channel.closeRequestedAt == 0</spanx> (no pending close request)</t>
    </list></t>
  <t>If <spanx style="verb">cumulativeAmount</spanx> and <spanx style="verb">signature</spanx> are provided, verify the initial
voucher:
  <list style="symbols">
      <t>Recover signer from EIP-712 signature</t>
      <t>Verify signature uses canonical low-s values (see <xref target="signature-malleability"/>)</t>
      <t>Signer matches <spanx style="verb">channel.payer</spanx> or <spanx style="verb">channel.authorizedSigner</spanx></t>
      <t><spanx style="verb">voucher.channelId</spanx> matches</t>
      <t><spanx style="verb">voucher.cumulativeAmount &gt;= channel.settled</spanx> (at or above current settlement)</t>
    </list></t>
  <t>Initialize server-side channel state</t>
</list></t>

</section>
<section anchor="topup-verification"><name>TopUp Verification</name>

<t>On <spanx style="verb">action="topUp"</spanx>, servers <bcp14>MUST</bcp14>:</t>

<t><list style="numbers" type="1">
  <t><strong>Transaction verification</strong>: Decode the signed transaction from
<spanx style="verb">transaction</spanx>, verify it calls <spanx style="verb">topUp()</spanx> on the expected escrow contract
with the specified <spanx style="verb">additionalDeposit</spanx> amount. If
<spanx style="verb">feePayer: true</spanx>, add fee payer signature using domain <spanx style="verb">0x78</spanx> (see
<xref target="fee-payment"/>) and broadcast. Otherwise, broadcast as-is.
For v2, servers <bcp14>MUST</bcp14> verify that the payload <spanx style="verb">descriptor</spanx> matches the
stored channel and that the top-up receipt references the credential
<spanx style="verb">channelId</spanx>.</t>
  <t>Query the escrow contract to verify updated channel state:
  <list style="symbols">
      <t><spanx style="verb">channel.deposit</spanx> increased by <spanx style="verb">additionalDeposit</spanx></t>
      <t>Channel is not finalized</t>
    </list></t>
  <t>Update server-side accounting:
  <list style="symbols">
      <t>Increase available balance by <spanx style="verb">additionalDeposit</spanx></t>
    </list></t>
</list></t>

</section>
<section anchor="voucher-verification"><name>Voucher Verification</name>

<t>On <spanx style="verb">action="voucher"</spanx>, servers <bcp14>MUST</bcp14>:</t>

<t><list style="numbers" type="1">
  <t>Verify the credential descriptor for v2, including channel ID, payee,
token, operator, escrow address, and chain ID binding.</t>
  <t>Verify voucher signature using EIP-712 recovery</t>
  <t>Verify signature uses canonical low-s values (see <xref target="signature-malleability"/>)</t>
  <t>Recover signer and <bcp14>MUST</bcp14> verify it matches expected signer from on-chain state</t>
  <t>Verify <spanx style="verb">channel.closeRequestedAt == 0</spanx> (no pending close request).
Servers <bcp14>MUST</bcp14> reject vouchers on channels with a pending forced close
to prevent service delivery that cannot be settled.</t>
  <t>Verify monotonicity:
  <list style="symbols">
      <t><spanx style="verb">cumulativeAmount &gt;= highestVoucherAmount</spanx></t>
      <t>if <spanx style="verb">cumulativeAmount == highestVoucherAmount</spanx>, treat the request as
an idempotent retry and do not change voucher state</t>
      <t>if <spanx style="verb">cumulativeAmount &gt; highestVoucherAmount</spanx>,
<spanx style="verb">(cumulativeAmount - highestVoucherAmount) &gt;= minVoucherDelta</spanx></t>
    </list></t>
  <t>Verify <spanx style="verb">cumulativeAmount &lt;= channel.deposit</spanx></t>
  <t>Persist voucher to durable storage before providing service</t>
  <t>Update <spanx style="verb">highestVoucherAmount = cumulativeAmount</spanx></t>
</list></t>

<t>Servers <bcp14>MUST</bcp14> derive the expected signer from on-chain channel state by
querying the escrow contract. The expected signer is <spanx style="verb">channel.authorizedSigner</spanx>
if non-zero, otherwise <spanx style="verb">channel.payer</spanx>. Servers <bcp14>MUST NOT</bcp14> trust signer
claims in HTTP payloads.</t>

<t>Servers <bcp14>MUST</bcp14> persist the highest voucher to durable storage before
providing the corresponding service. Failure to do so may result in
unrecoverable fund loss if the server crashes after service delivery.</t>

</section>
<section anchor="idempotency"><name>Idempotency</name>

<t>Servers <bcp14>MUST</bcp14> treat voucher submissions idempotently:</t>

<t><list style="symbols">
  <t>Resubmitting a voucher with the same <spanx style="verb">cumulativeAmount</spanx> as the highest
accepted <bcp14>MUST</bcp14> return 200 OK with the current <spanx style="verb">acceptedCumulative</spanx></t>
  <t>Submitting a voucher with lower <spanx style="verb">cumulativeAmount</spanx> than highest accepted
<bcp14>MUST</bcp14> be rejected</t>
  <t>Clients <bcp14>MAY</bcp14> safely retry voucher submissions after network failures</t>
</list></t>

</section>
<section anchor="error-responses"><name>Rejection and Error Responses</name>

<t>If verification fails, servers <bcp14>MUST</bcp14> return an appropriate HTTP status
code with a Problem Details <xref target="RFC9457"/> response body:</t>

<texttable>
      <ttcol align='left'>Status</ttcol>
      <ttcol align='left'>When</ttcol>
      <c>400 Bad Request</c>
      <c>Malformed payload or missing fields</c>
      <c>402 Payment Required</c>
      <c>Invalid signature or signer mismatch</c>
      <c>410 Gone</c>
      <c>Channel finalized or not found</c>
</texttable>

<t>Error responses use Problem Details format:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "type": "https://paymentauth.org/problems/session/invalid-signature",
  "title": "Invalid Signature",
  "status": 402,
  "detail": "Voucher signature could not be verified",
  "channelId": "0x6d0f4fdf..."
}
]]></sourcecode></figure>

<t>Problem type URIs:</t>

<texttable>
      <ttcol align='left'>Type URI</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">https://paymentauth.org/problems/session/invalid-signature</spanx></c>
      <c>Voucher or close request signature invalid</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/signer-mismatch</spanx></c>
      <c>Signer is not authorized for this channel</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/amount-exceeds-deposit</spanx></c>
      <c>Voucher amount exceeds channel deposit</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/delta-too-small</spanx></c>
      <c>Amount increase below <spanx style="verb">minVoucherDelta</spanx></c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/channel-not-found</spanx></c>
      <c>No channel with this ID exists</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/channel-finalized</spanx></c>
      <c>Channel has been closed</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/challenge-not-found</spanx></c>
      <c>Challenge ID unknown or expired</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/insufficient-balance</spanx></c>
      <c>Insufficient authorized balance for request</c>
</texttable>

<t>For errors on the Payment Auth protected resource (the initial request
carrying <spanx style="verb">Authorization: Payment</spanx>), servers <bcp14>MUST</bcp14> return 402 with a fresh
<spanx style="verb">WWW-Authenticate: Payment</spanx> challenge per <xref target="I-D.httpauth-payment"/>.</t>

</section>
</section>
<section anchor="server-accounting"><name>Server-Side Accounting</name>

<t>Servers <bcp14>MUST</bcp14> maintain per-session accounting state to track authorized
funds versus consumed service. This section defines the normative
requirements for balance tracking, crash safety, and idempotency.</t>

<section anchor="accounting-state"><name>Accounting State</name>

<t>For each active session identified by <spanx style="verb">(challengeId, channelId)</spanx>, servers
<bcp14>MUST</bcp14> maintain:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">acceptedCumulative</spanx></c>
      <c>uint128</c>
      <c>Highest valid voucher amount accepted (monotonically increasing)</c>
      <c><spanx style="verb">spent</spanx></c>
      <c>uint128</c>
      <c>Cumulative amount charged for delivered service (monotonically increasing)</c>
      <c><spanx style="verb">settledOnChain</spanx></c>
      <c>uint128</c>
      <c>Last cumulative amount settled on-chain (informational)</c>
      <c><spanx style="verb">deposit</spanx></c>
      <c>uint128 or uint96</c>
      <c>Latest verified on-chain deposit</c>
      <c><spanx style="verb">closeRequestedAt</spanx></c>
      <c>uint64</c>
      <c>Latest verified close-request timestamp, or zero</c>
</texttable>

<t>For v2 channels, <spanx style="verb">acceptedCumulative</spanx>, <spanx style="verb">spent</spanx>, <spanx style="verb">settledOnChain</spanx>, and
<spanx style="verb">deposit</spanx> are uint96 values. Servers <bcp14>MUST</bcp14> key channel state by normalized
lowercase <spanx style="verb">channelId</spanx>. Channel state updates <bcp14>MUST</bcp14> be linearizable per
channel across concurrent requests.</t>

<t>The <spanx style="verb">available</spanx> balance is computed as:</t>

<figure><artwork><![CDATA[
available = acceptedCumulative - spent
]]></artwork></figure>

</section>
<section anchor="per-request-processing"><name>Per-Request Processing</name>

<t>For each request carrying a Payment credential with <spanx style="verb">intent="session"</spanx>,
servers <bcp14>MUST</bcp14> follow this procedure:</t>

<t><list style="numbers" type="1">
  <t><strong>Voucher acceptance</strong> (if a voucher is provided in the credential):
  <list style="symbols">
      <t>Verify signature and monotonicity per <xref target="voucher-verification"/></t>
      <t>If valid, persist the new <spanx style="verb">acceptedCumulative</spanx> value to durable storage</t>
      <t>If invalid, return 402 with a fresh challenge</t>
    </list></t>
  <t><strong>Balance check</strong>:
  <list style="symbols">
      <t>Compute <spanx style="verb">available = acceptedCumulative - spent</spanx></t>
      <t>Compute <spanx style="verb">cost</spanx> for this request (see <xref target="cost-calculation"/>)</t>
      <t>If <spanx style="verb">available &lt; cost</spanx>: return 402 with Problem Details including
<spanx style="verb">requiredTopUp = cost - available</spanx></t>
    </list></t>
  <t><strong>Charge and deliver</strong> (if <spanx style="verb">available &gt;= cost</spanx>):
  <list style="symbols">
      <t><strong><bcp14>MUST</bcp14> persist</strong> <spanx style="verb">spent := spent + cost</spanx> to durable storage BEFORE
or atomically with delivering the metered service</t>
      <t>Deliver the response (or next chunk/token window for streaming)</t>
      <t>Return <spanx style="verb">Payment-Receipt</spanx> header with current balance state</t>
    </list></t>
  <t><strong>Receipt generation</strong>:
  <list style="symbols">
      <t>Include balance state in receipt (see <xref target="receipt-generation"/>)</t>
    </list></t>
</list></t>

</section>
<section anchor="crash-safety"><name>Crash Safety</name>

<t>To prevent fund loss from server crashes:</t>

<t><list style="symbols">
  <t>Servers <bcp14>MUST</bcp14> persist <spanx style="verb">spent</spanx> increments BEFORE delivering corresponding
service. If the server crashes after persisting but before delivery,
the client may retry and be charged again (see Idempotency below).</t>
  <t>Servers <bcp14>MUST</bcp14> persist <spanx style="verb">acceptedCumulative</spanx> BEFORE relying on the new
balance for service authorization.</t>
  <t>Implementations <bcp14>SHOULD</bcp14> use transactional storage or write-ahead logging
to ensure atomicity between state updates and service delivery.</t>
</list></t>

</section>
<section anchor="request-idempotency"><name>Request Idempotency</name>

<t>To prevent double-charging on retries and network failures:</t>

<t><list style="symbols">
  <t>Clients <bcp14>SHOULD</bcp14> include an <spanx style="verb">Idempotency-Key</spanx> header on paid requests</t>
  <t>Servers <bcp14>SHOULD</bcp14> track <spanx style="verb">(challengeId, idempotencyKey)</spanx> pairs and return
the cached response (including receipt) for duplicate requests</t>
  <t>Servers <bcp14>MUST NOT</bcp14> increment <spanx style="verb">spent</spanx> for duplicate idempotent requests</t>
</list></t>

<t>If idempotency is not implemented, servers <bcp14>MUST</bcp14> document this limitation
and warn clients that retries may incur additional charges.</t>

<t><strong>Example idempotent request:</strong></t>

<figure><sourcecode type="http"><![CDATA[
GET /api/chat HTTP/1.1
Host: api.example.com
Idempotency-Key: req_a1b2c3d4e5f6
Authorization: Payment eyJ...
]]></sourcecode></figure>

</section>
<section anchor="cost-calculation"><name>Cost Calculation</name>

<t>The <spanx style="verb">cost</spanx> for a request depends on the pricing model declared in the
challenge. Servers <bcp14>MUST</bcp14> support at least one of:</t>

<t><list style="symbols">
  <t><strong>Fixed cost</strong>: A predetermined amount per request</t>
  <t><strong>Usage-based fees</strong>: Pricing proportional to resource consumption (e.g.,
tokens generated, bytes transferred, compute time)</t>
</list></t>

<t>For metered resources, servers compute cost during or after service
delivery. For streaming responses (SSE, chunked), servers <bcp14>SHOULD</bcp14>:</t>

<t><list style="numbers" type="1">
  <t>Reserve an estimated cost before starting delivery</t>
  <t>Adjust <spanx style="verb">spent</spanx> as actual consumption is measured</t>
  <t>Pause delivery if <spanx style="verb">available</spanx> is exhausted (client must top-up)</t>
</list></t>

</section>
<section anchor="insufficient-balance-during-streaming"><name>Insufficient Balance During Streaming</name>

<t>When a streaming response exhausts <spanx style="verb">available</spanx> balance:</t>

<t><list style="numbers" type="1">
  <t>Server <bcp14>MUST</bcp14> stop delivering additional metered content</t>
  <t>Server <bcp14>MAY</bcp14> hold the connection open awaiting a voucher top-up</t>
  <t>Server <bcp14>MAY</bcp14> close the response; client then retries with higher voucher</t>
  <t>If client submits a voucher update (request to same URI or any
endpoint protected by the same payment handler), server <bcp14>SHOULD</bcp14>
resume delivery on the original connection if still open</t>
</list></t>

<t>For SSE responses, servers <bcp14>MUST</bcp14> emit an <spanx style="verb">payment-need-voucher</spanx> event when
available balance is exhausted:</t>

<figure><artwork><![CDATA[
event: payment-need-voucher
data: {"channelId":"0x6d0f4fdf...","requiredCumulative":"250025","acceptedCumulative":"250000","deposit":"500000"}
]]></artwork></figure>

<t>The <spanx style="verb">payment-need-voucher</spanx> event data <bcp14>MUST</bcp14> be a JSON object containing:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Required</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">acceptedCumulative</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Current highest accepted voucher amount (base units)</c>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Channel identifier (hex-encoded bytes32)</c>
      <c><spanx style="verb">deposit</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Current on-chain deposit in the escrow contract (base units)</c>
      <c><spanx style="verb">requiredCumulative</spanx></c>
      <c>string</c>
      <c><bcp14>REQUIRED</bcp14></c>
      <c>Minimum cumulative amount the next voucher must authorize (base units)</c>
</texttable>

<t>The <spanx style="verb">deposit</spanx> field allows the client to determine the correct recovery
action. When <spanx style="verb">requiredCumulative</spanx> exceeds <spanx style="verb">deposit</spanx>, the client <bcp14>MUST</bcp14>
submit <spanx style="verb">action="topUp"</spanx> to increase the on-chain deposit before sending
a new voucher. When <spanx style="verb">requiredCumulative</spanx> is within <spanx style="verb">deposit</spanx>, the client
can submit <spanx style="verb">action="voucher"</spanx> directly.</t>

<t>After emitting <spanx style="verb">payment-need-voucher</spanx>, the server <bcp14>MUST</bcp14> pause delivery
until a valid voucher advancing <spanx style="verb">acceptedCumulative</spanx> is accepted.
Servers <bcp14>SHOULD</bcp14> close the stream if no voucher is received within a
reasonable timeout (for example, 60 seconds). Clients <bcp14>SHOULD</bcp14> respond
by sending a voucher credential to any endpoint protected by the same
payment handler.</t>

<t>Servers <bcp14>SHOULD NOT</bcp14> deliver service beyond the authorized balance under
any circumstances. See <xref target="dos-mitigation"/> for rate limiting requirements.</t>

</section>
</section>
<section anchor="settlement-procedure"><name>Settlement Procedure</name>

<section anchor="settlement-timing"><name>Settlement Timing</name>

<t>Servers <bcp14>MAY</bcp14> settle at any time using their own criteria:</t>

<t><list style="symbols">
  <t>Periodically (e.g., every N seconds or M base units accrued)</t>
  <t>When <spanx style="verb">action="close"</spanx> is received</t>
  <t>When accumulated unsettled amount exceeds a threshold</t>
  <t>Based on gas cost optimization</t>
</list></t>

<t>Settlement frequency is an implementation detail left to servers.</t>

<t>The <spanx style="verb">close()</spanx> function settles any delta between the provided
<spanx style="verb">cumulativeAmount</spanx> and <spanx style="verb">channel.settled</spanx>. If the server has already
settled the highest voucher via <spanx style="verb">settle()</spanx>, calling <spanx style="verb">close()</spanx> with the
same amount will only refund the payer the remaining deposit.</t>

</section>
<section anchor="cooperative-close"><name>Cooperative Close</name>

<t>When the client sends <spanx style="verb">action="close"</spanx>:</t>

<t><list style="numbers" type="1">
  <t>Server receives the signed close request</t>
  <t>Server verifies the close voucher covers at least the greater of
server-recorded <spanx style="verb">spent</spanx> and current on-chain <spanx style="verb">settled</spanx></t>
  <t>Server closes on-chain, capturing only the amount actually owed to the
payee and refunding the remainder to the payer</t>
  <t>Server returns receipt with transaction hash</t>
</list></t>

<t>Servers <bcp14>SHOULD</bcp14> close promptly when clients request—the economic
incentive is to claim earned funds immediately.</t>

<t>Servers <bcp14>MUST NOT</bcp14> capture more than the amount actually consumed by
delivered service. A client can pre-authorize more funds than were spent;
the server <bcp14>MUST</bcp14> use its accounting state to determine the close capture
amount and <bcp14>MUST NOT</bcp14> treat <spanx style="verb">cumulativeAmount</spanx> alone as the amount to
capture. For v2, the close capture amount is:</t>

<figure><artwork><![CDATA[
captureAmount = max(spent, settledOnChain)
]]></artwork></figure>

<t>and <spanx style="verb">captureAmount</spanx> <bcp14>MUST</bcp14> be less than or equal to both the close voucher
<spanx style="verb">cumulativeAmount</spanx> and the on-chain <spanx style="verb">deposit</spanx>.</t>

</section>
<section anchor="forced-close"><name>Forced Close</name>

<t>If the server does not respond to close requests:</t>

<t><list style="numbers" type="1">
  <t>Client calls <spanx style="verb">requestClose(channelId)</spanx> on-chain</t>
  <t>15-minute grace period begins (wall-clock time via <spanx style="verb">block.timestamp</spanx>)</t>
  <t>Server can still <spanx style="verb">settle()</spanx> or <spanx style="verb">close()</spanx> during grace period</t>
  <t>After grace period, client calls <spanx style="verb">withdraw(channelId)</spanx></t>
  <t>Client receives all remaining (unsettled) funds</t>
</list></t>

<t>Clients <bcp14>SHOULD</bcp14> wait at least 16 minutes after <spanx style="verb">requestClose()</spanx> before
calling <spanx style="verb">withdraw()</spanx> to account for block time variance.</t>

</section>
<section anchor="sequential-sessions"><name>Sequential Sessions</name>

<t>A single channel supports sequential sessions. Each session uses the same
cumulative voucher counter. When a new session begins on a channel, the
previous session's spending state is irrelevant—the channel's
<spanx style="verb">highestVoucherAmount</spanx> is the source of truth for the next voucher's
minimum value.</t>

</section>
<section anchor="voucher-submission-transport"><name>Voucher Submission Transport</name>

<t>Vouchers are submitted via HTTP requests to the <strong>same resource URI</strong> that
requires payment. There is no separate session endpoint. Clients <bcp14>SHOULD</bcp14> use
HTTP/2 multiplexing or maintain separate connections for voucher updates
and content streaming when topping up during a long-lived response.</t>

<t>For voucher-only updates (no response body needed), clients <bcp14>MAY</bcp14> use <spanx style="verb">HEAD</spanx>
requests. Servers <bcp14>SHOULD</bcp14> support voucher credentials on <spanx style="verb">HEAD</spanx> requests
for resources that require session payment.</t>

</section>
<section anchor="receipt-generation"><name>Receipt Generation</name>

<t>Servers <bcp14>MUST</bcp14> return a <spanx style="verb">Payment-Receipt</spanx> header on <strong>every successful
paid request</strong>. For streaming responses (SSE, chunked transfer), servers
<bcp14>MUST</bcp14> include the receipt in the initial response headers AND in the final
message of the stream. This ensures clients receive at least one receipt
even if the stream is interrupted, while also providing accurate final
state when the stream completes normally.</t>

<t>For SSE responses, the final receipt <bcp14>SHOULD</bcp14> be delivered as an event:</t>

<figure><artwork><![CDATA[
event: payment-receipt
data: {"method":"tempo","intent":"session","status":"success",...}
]]></artwork></figure>

<t>For chunked responses, the final receipt <bcp14>MAY</bcp14> be delivered as an HTTP
trailer if the client advertises trailer support via <spanx style="verb">TE: trailers</spanx>.</t>

<t>The base Payment Auth spec defines core receipt fields. The session intent
extends the receipt with balance tracking:</t>

<texttable>
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">method</spanx></c>
      <c>string</c>
      <c><spanx style="verb">"tempo"</spanx></c>
      <c><spanx style="verb">intent</spanx></c>
      <c>string</c>
      <c><spanx style="verb">"session"</spanx></c>
      <c><spanx style="verb">status</spanx></c>
      <c>string</c>
      <c><spanx style="verb">"success"</spanx></c>
      <c><spanx style="verb">timestamp</spanx></c>
      <c>string</c>
      <c><xref target="RFC3339"/> response time</c>
      <c><spanx style="verb">reference</spanx></c>
      <c>string</c>
      <c>Payment reference; for session receipts, the <spanx style="verb">channelId</spanx></c>
      <c><spanx style="verb">challengeId</spanx></c>
      <c>string</c>
      <c>Challenge identifier for audit correlation</c>
      <c><spanx style="verb">channelId</spanx></c>
      <c>string</c>
      <c>The channel identifier</c>
      <c><spanx style="verb">acceptedCumulative</spanx></c>
      <c>string</c>
      <c>Highest voucher amount accepted</c>
      <c><spanx style="verb">spent</spanx></c>
      <c>string</c>
      <c>Total amount charged so far</c>
      <c><spanx style="verb">units</spanx></c>
      <c>number</c>
      <c><bcp14>OPTIONAL</bcp14>: Units consumed this request (e.g., tokens, bytes)</c>
      <c><spanx style="verb">txHash</spanx></c>
      <c>string</c>
      <c><bcp14>OPTIONAL</bcp14>: On-chain transaction hash (present on settlement/close)</c>
</texttable>

<t>The <spanx style="verb">reference</spanx> field serves as the core spec's payment reference and is
the channel ID. The <spanx style="verb">txHash</spanx> field is <bcp14>OPTIONAL</bcp14> because not every response
involves an on-chain settlement; voucher updates are off-chain.</t>

<t>The <spanx style="verb">units</spanx> field indicates what was consumed for <strong>this specific request</strong>.
When the challenge includes <spanx style="verb">unitType</spanx>, clients can use it to interpret the
unit of measure. Clients can compute cost as <spanx style="verb">units × amount</spanx> from the
challenge.</t>

<t><strong>Example receipt (per-request with metering):</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "method": "tempo",
  "intent": "session",
  "status": "success",
  "timestamp": "2025-01-06T12:08:30Z",
  "reference": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
  "challengeId": "c_8d0e3b5a9f2c1d4e",
  "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
  "acceptedCumulative": "250000",
  "spent": "237500",
  "units": 500
}
]]></sourcecode></figure>

<t><strong>Example receipt (on close with settlement):</strong></t>

<figure><sourcecode type="json"><![CDATA[
{
  "method": "tempo",
  "intent": "session",
  "status": "success",
  "timestamp": "2025-01-06T12:10:00Z",
  "reference": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
  "challengeId": "c_8d0e3b5a9f2c1d4e",
  "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
  "acceptedCumulative": "250000",
  "spent": "250000",
  "txHash": "0x1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890"
}
]]></sourcecode></figure>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<section anchor="replay-prevention"><name>Replay Prevention</name>

<t>Vouchers are bound to a specific channel and contract via:</t>

<t><list style="symbols">
  <t><spanx style="verb">channelId</spanx> in the voucher message</t>
  <t><spanx style="verb">verifyingContract</spanx> in EIP-712 domain</t>
  <t><spanx style="verb">chainId</spanx> in EIP-712 domain</t>
  <t>Cumulative amount semantics (can only increase)</t>
</list></t>

<t>The escrow contract enforces:</t>

<t><list style="symbols">
  <t><spanx style="verb">cumulativeAmount &gt; channel.settled</spanx> (monotonicity)</t>
  <t><spanx style="verb">cumulativeAmount &lt;= channel.deposit</spanx> (cap)</t>
</list></t>

</section>
<section anchor="no-voucher-expiry"><name>No Voucher Expiry</name>

<t>Vouchers have no <spanx style="verb">validUntil</spanx> field. This simplifies the protocol:</t>

<t><list style="symbols">
  <t>Channels have no expiry—they are closed explicitly</t>
  <t>Vouchers remain valid until the channel closes</t>
  <t>The close grace period protects against clients disappearing</t>
</list></t>

<t><strong>Operational guidance:</strong> Servers <bcp14>SHOULD</bcp14> settle and close channels that
have been inactive for extended periods (e.g., 30+ days) to reduce
storage requirements and operational liability. Servers <bcp14>MAY</bcp14> refuse to
accept vouchers for channels with no activity exceeding a configured
threshold.</t>

</section>
<section anchor="dos-mitigation"><name>Denial of Service</name>

<t>To mitigate voucher flooding, servers <bcp14>MUST</bcp14> implement rate limiting:</t>

<t><list style="symbols">
  <t>Servers <bcp14>SHOULD</bcp14> limit voucher submissions to 10 per second per session</t>
  <t>Servers <bcp14>MAY</bcp14> implement additional IP-based rate limiting for
unauthenticated requests</t>
  <t>Servers <bcp14>MUST</bcp14> enforce <spanx style="verb">minVoucherDelta</spanx> when present to prevent tiny increments</t>
  <t>Servers <bcp14>MAY</bcp14> skip expensive signature verification for vouchers whose
<spanx style="verb">cumulativeAmount</spanx> is below the accepted cumulative amount, because such
vouchers are rejected before they can advance state</t>
</list></t>

<t>Servers <bcp14>SHOULD</bcp14> perform format validation (field presence, hex encoding,
length checks) before expensive ECDSA signature recovery to minimize
computational cost of malformed requests.</t>

<t>To mitigate channel griefing via dust deposits:</t>

<t><list style="symbols">
  <t>Servers <bcp14>SHOULD</bcp14> enforce a minimum deposit (e.g., 1 USD equivalent)</t>
  <t>Servers <bcp14>MAY</bcp14> reject channels below this threshold</t>
</list></t>

</section>
<section anchor="front-running-protection"><name>Front-Running Protection</name>

<t>Cumulative voucher semantics prevent front-running attacks. If a client
submits a higher voucher while a server's <spanx style="verb">settle()</spanx> transaction is
pending, the settlement will still succeed—it merely leaves additional
unsettled funds that the server can claim later.</t>

</section>
<section anchor="cross-contract-replay-prevention"><name>Cross-Contract Replay Prevention</name>

<t>The EIP-712 domain includes <spanx style="verb">verifyingContract</spanx>, binding vouchers to a
specific escrow contract address. This prevents replay of vouchers
across different escrow contract deployments.</t>

</section>
<section anchor="escrow-guarantees"><name>Escrow Guarantees</name>

<t>The escrow contract provides:</t>

<t><list style="symbols">
  <t><strong>Payer protection</strong>: Funds only withdrawn with valid voucher signature</t>
  <t><strong>Payee protection</strong>: Deposited funds guaranteed (cannot be drained)</t>
  <t><strong>Forced close</strong>: 15-minute grace period protects both parties</t>
</list></t>

</section>
<section anchor="authorized-signer"><name>Authorized Signer</name>

<t>The <spanx style="verb">authorizedSigner</spanx> field allows delegation of signing authority
to a hot wallet while the main wallet only deposits funds. This reduces
exposure of the primary key during streaming sessions.</t>

<t><strong>Security considerations for delegated signing:</strong></t>

<t><list style="symbols">
  <t>Clients using <spanx style="verb">authorizedSigner</spanx> delegation <bcp14>SHOULD</bcp14> limit channel
deposits to acceptable loss amounts</t>
  <t>Clients <bcp14>SHOULD</bcp14> rotate authorized signers periodically</t>
  <t>Clients <bcp14>SHOULD NOT</bcp14> reuse signers across multiple high-value channels</t>
  <t>If the authorized signer key is compromised, an attacker can drain
the entire channel deposit</t>
</list></t>

</section>
<section anchor="signature-malleability"><name>Signature Malleability</name>

<t>ECDSA signatures are malleable: for any valid signature <spanx style="verb">(r, s)</spanx>, the
signature <spanx style="verb">(r, -s mod n)</spanx> is also valid for the same message. To prevent
signature substitution attacks, implementations <bcp14>MUST</bcp14> enforce canonical
signatures:</t>

<t><list style="symbols">
  <t>Signatures <bcp14>MUST</bcp14> use "low-s" values with <spanx style="verb">s &lt;= secp256k1_order / 2</spanx></t>
  <t>The secp256k1 half-order is:
<spanx style="verb">0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0</spanx></t>
  <t>Servers <bcp14>MUST</bcp14> reject signatures with <spanx style="verb">s</spanx> values exceeding this threshold</t>
</list></t>

<t>Accepted signature formats:</t>

<t><list style="symbols">
  <t>65-byte <spanx style="verb">(r, s, v)</spanx> format where <spanx style="verb">v</spanx> is 27 or 28</t>
  <t>64-byte EIP-2098 compact format</t>
</list></t>

<t>Implementations <bcp14>SHOULD</bcp14> use established libraries (e.g., OpenZeppelin ECDSA)
that enforce these requirements.</t>

</section>
<section anchor="voucher-context-and-user-experience"><name>Voucher Context and User Experience</name>

<t>The voucher message contains only <spanx style="verb">channelId</spanx> and <spanx style="verb">cumulativeAmount</spanx>. The
<spanx style="verb">channelId</spanx> is derived from channel parameters including payer, payee,
token, salt, and authorized signer, cryptographically binding these values.</t>

<t>However, wallet signing interfaces may only display the raw <spanx style="verb">channelId</spanx>
bytes, making it difficult for users to verify payment details. Wallet
implementations are encouraged to:</t>

<t><list style="symbols">
  <t>Decode <spanx style="verb">channelId</spanx> components when the derivation formula is known</t>
  <t>Display the payee address and token in human-readable form</t>
  <t>Show cumulative vs. incremental amounts clearly</t>
</list></t>

</section>
<section anchor="session-attribution"><name>Session Attribution</name>

<t>Vouchers are bound to channels but not to specific HTTP sessions or API
requests. When a payee operates multiple services using the same channel,
voucher-to-service attribution is an implementation concern.</t>

<t>The <spanx style="verb">challengeId</spanx> in the challenge provides correlation across requests.
Servers <bcp14>MUST</bcp14> implement challenge-to-voucher mapping for:</t>

<t><list style="symbols">
  <t>Dispute resolution</t>
  <t>Usage accounting</t>
  <t>Audit trails</t>
</list></t>

</section>
<section anchor="session-binding"><name>Cross-Session Replay Prevention</name>

<t>Vouchers use cumulative amount semantics: each voucher authorizes a total
payment up to <spanx style="verb">cumulativeAmount</spanx>, and the on-chain contract enforces strict
monotonicity (<spanx style="verb">cumulativeAmount &gt; channel.settled</spanx>). This means a voucher
can only ever advance the channel state forward -- it cannot be "replayed"
to extract additional funds because the settlement watermark only moves in
one direction.</t>

<t>A separate <spanx style="verb">sessionHash</spanx> binding is therefore unnecessary:</t>

<t><list style="symbols">
  <t><strong>Cross-session replay is harmless</strong>: If a voucher from session A is
presented in session B, it can only authorize funds up to the amount
already committed. The server tracks <spanx style="verb">highestVoucherAmount</spanx> per session
and rejects vouchers that do not advance state.</t>
  <t><strong>Cross-resource replay</strong>: Vouchers authorize cumulative payment on a
channel, not access to specific resources. Resource authorization is
handled at the application layer via <spanx style="verb">challengeId</spanx> correlation.</t>
</list></t>

<t>This simplification aligns the spec with the deployed <spanx style="verb">TempoStreamChannel</spanx>
contract and the <spanx style="verb">@tempo/stream-channels</spanx> package, neither of which
include a session hash in the voucher type.</t>

</section>
<section anchor="chain-reorg"><name>Chain Reorganization</name>

<t>On Tempo networks, finality is achieved within approximately 500ms.
However, for high-value channels, servers <bcp14>SHOULD</bcp14>:</t>

<t><list style="numbers" type="1">
  <t>Re-verify channel state periodically during long-lived sessions</t>
  <t>Monitor for <spanx style="verb">ChannelClosed</spanx> or <spanx style="verb">CloseRequested</spanx> events</t>
  <t>Cease service delivery if the channel becomes invalid</t>
</list></t>

<t>If a chain reorganization invalidates an accepted transaction, the
server <bcp14>SHOULD</bcp14>:</t>

<t><list style="numbers" type="1">
  <t>Stop accepting vouchers for that channel</t>
  <t>Return 410 Gone with problem type <spanx style="verb">channel-not-found</spanx></t>
  <t>Log the incident for investigation</t>
</list></t>

</section>
<section anchor="grace-period-rationale"><name>Grace Period Rationale</name>

<t>The 15-minute forced close grace period balances competing concerns:</t>

<t><list style="symbols">
  <t><strong>Payer protection</strong>: Ensures timely fund recovery if the server becomes
unresponsive</t>
  <t><strong>Payee protection</strong>: Provides time to detect close requests and submit
final settlements, even during network congestion or maintenance windows</t>
  <t><strong>Block time variance</strong>: Allows margin for timestamp variations in
on-chain enforcement</t>
</list></t>

<t>Implementations <bcp14>MAY</bcp14> use different grace periods in their escrow contracts,
but <bcp14>MUST</bcp14> clearly document the value and ensure clients are aware.</t>

</section>
</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="payment-intent-registration"><name>Payment Intent Registration</name>

<t>This document registers the following payment intent in the "HTTP Payment
Intents" registry established by <xref target="I-D.httpauth-payment"/>:</t>

<texttable>
      <ttcol align='left'>Intent</ttcol>
      <ttcol align='left'>Applicable Methods</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c><spanx style="verb">session</spanx></c>
      <c><spanx style="verb">tempo</spanx></c>
      <c>Streaming payment channel</c>
      <c>This document</c>
</texttable>

<t>Contact: Tempo Labs (<eref target="mailto:contact@tempo.xyz">contact@tempo.xyz</eref>)</t>

</section>
<section anchor="problem-type-registration"><name>Problem Type Registration</name>

<t>This document registers the following problem types in the "HTTP
Problem Types" registry established by <xref target="RFC9457"/>:</t>

<texttable>
      <ttcol align='left'>Type URI</ttcol>
      <ttcol align='left'>Title</ttcol>
      <ttcol align='left'>Status</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c><spanx style="verb">https://paymentauth.org/problems/session/invalid-signature</spanx></c>
      <c>Invalid Signature</c>
      <c>402</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/signer-mismatch</spanx></c>
      <c>Signer Mismatch</c>
      <c>402</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/amount-exceeds-deposit</spanx></c>
      <c>Amount Exceeds Deposit</c>
      <c>402</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/delta-too-small</spanx></c>
      <c>Delta Too Small</c>
      <c>402</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/channel-not-found</spanx></c>
      <c>Channel Not Found</c>
      <c>410</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/channel-finalized</spanx></c>
      <c>Channel Finalized</c>
      <c>410</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/challenge-not-found</spanx></c>
      <c>Challenge Not Found</c>
      <c>402</c>
      <c>This document</c>
      <c><spanx style="verb">https://paymentauth.org/problems/session/insufficient-balance</spanx></c>
      <c>Insufficient Balance</c>
      <c>402</c>
      <c>This document</c>
</texttable>

<t>Each problem type is defined in <xref target="error-responses"/>.</t>

</section>
</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">

&RFC2119;
&RFC3339;
&RFC4648;
&RFC8174;
&RFC8259;
&RFC9110;
&RFC9111;
&RFC9457;
<reference anchor="I-D.httpauth-payment" target="https://datatracker.ietf.org/doc/draft-ryan-httpauth-payment/">
  <front>
    <title>The 'Payment' HTTP Authentication Scheme</title>
    <author initials="J." surname="Moxey" fullname="Jake Moxey">
      <organization></organization>
    </author>
    <date year="2026" month="January"/>
  </front>
</reference>


    </references>

    <references title='Informative References' anchor="sec-informative-references">

&RFC8610;
<reference anchor="EIP-712" target="https://eips.ethereum.org/EIPS/eip-712">
  <front>
    <title>Typed structured data hashing and signing</title>
    <author initials="R." surname="Bloemen" fullname="Remco Bloemen">
      <organization></organization>
    </author>
    <date year="2017" month="September"/>
  </front>
</reference>
<reference anchor="SSE" target="https://html.spec.whatwg.org/multipage/server-sent-events.html">
  <front>
    <title>Server-Sent Events</title>
    <author >
      <organization>WHATWG</organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="TEMPO-TX-SPEC" target="https://docs.tempo.xyz/protocol/transactions/spec-tempo-transaction">
  <front>
    <title>Tempo Transaction Specification</title>
    <author >
      <organization>Tempo Labs</organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="TIP-20" target="https://docs.tempo.xyz/protocol/tip20/spec">
  <front>
    <title>TIP-20 Token Standard</title>
    <author >
      <organization>Tempo Labs</organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>


    </references>

</references>


<?line 1846?>

<section anchor="example"><name>Example</name>

<t>Note: In examples throughout this appendix, hex values shown with <spanx style="verb">...</spanx>
(e.g., <spanx style="verb">"0x6d0f4fdf..."</spanx>) are abbreviated for readability. Actual values
<bcp14>MUST</bcp14> be full-length as specified in <xref target="encoding"/>.</t>

<section anchor="challenge"><name>Challenge</name>

<figure><sourcecode type="http"><![CDATA[
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment id="kM9xPqWvT2nJrHsY4aDfEb",
  realm="api.llm-service.com",
  method="tempo",
  intent="session",
  expires="2025-01-06T12:05:00Z",
  request="<base64url-encoded JSON below>"
]]></sourcecode></figure>

<t>The <spanx style="verb">request</spanx> decodes to:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "amount": "25",
  "unitType": "llm_token",
  "suggestedDeposit": "10000000",
  "currency": "0x20c0000000000000000000000000000000000000",
  "recipient": "0x742d35cc6634c0532925a3b844bc9e7595f8fe00",
  "methodDetails": {
    "escrowContract": "0x9d136eEa063eDE5418A6BC7bEafF009bBb6CFa70",
    "chainId": 4217,
    "sessionProtocol": "v2"
  }
}
]]></sourcecode></figure>

<t>Note: Challenge expiry is in the header <spanx style="verb">expires</spanx> auth-param, not in the
request JSON. The client generates a random salt locally for new channels.</t>

<t>This requests a price of 0.000025 tokens per LLM token, with a suggested
deposit of 10.00 pathUSD (10000000 base units).</t>

</section>
<section anchor="open-credential"><name>Open Credential</name>

<t>The client retries the <strong>same resource URI</strong> with the open credential:</t>

<figure><sourcecode type="http"><![CDATA[
GET /api/chat HTTP/1.1
Host: api.llm-service.com
Authorization: Payment <base64url-encoded credential>
]]></sourcecode></figure>

<t>The credential payload for an open action:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "open",
    "type": "transaction",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "transaction": "0x76f901...signed transaction bytes...",
    "cumulativeAmount": "0",
    "signature": "0xabcdef1234567890..."
  }
}
]]></sourcecode></figure>

</section>
<section anchor="voucher-top-up-same-resource-uri"><name>Voucher Top-Up (Same Resource URI)</name>

<t>During streaming, clients submit updated vouchers to the <strong>same resource
URI</strong>. This can use any HTTP method; <spanx style="verb">HEAD</spanx> is recommended for pure
top-ups when no response body is needed:</t>

<figure><sourcecode type="http"><![CDATA[
HEAD /api/chat HTTP/1.1
Host: api.llm-service.com
Authorization: Payment <base64url-encoded credential with action="voucher">
]]></sourcecode></figure>

<t>Or with a regular request that also retrieves content:</t>

<figure><sourcecode type="http"><![CDATA[
GET /api/chat HTTP/1.1
Host: api.llm-service.com
Authorization: Payment <base64url-encoded credential with action="voucher">
]]></sourcecode></figure>

<t>The credential payload for a voucher update:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "voucher",
    "channelId": "0x6d0f4fdf...",
    "cumulativeAmount": "250000",
    "signature": "0x1234567890abcdef..."
  }
}
]]></sourcecode></figure>

</section>
<section anchor="close-request-same-resource-uri"><name>Close Request (Same Resource URI)</name>

<t>Close requests are also sent to the same resource URI:</t>

<figure><sourcecode type="http"><![CDATA[
GET /api/chat HTTP/1.1
Host: api.llm-service.com
Authorization: Payment <base64url-encoded credential with action="close">
]]></sourcecode></figure>

<t>The credential payload for a close request:</t>

<figure><sourcecode type="json"><![CDATA[
{
  "challenge": {
    "id": "kM9xPqWvT2nJrHsY4aDfEb",
    "realm": "api.llm-service.com",
    "method": "tempo",
    "intent": "session",
    "request": "eyJ...",
    "expires": "2025-01-06T12:05:00Z"
  },
  "payload": {
    "action": "close",
    "channelId": "0x6d0f4fdf...",
    "cumulativeAmount": "500000",
    "signature": "0xabcdef1234567890..."
  }
}
]]></sourcecode></figure>

<t>The voucher fields contain the final cumulative amount for on-chain settlement.</t>

</section>
</section>
<section anchor="legacy-contract-reference-implementation"><name>Legacy Contract Reference Implementation</name>

<t>This appendix provides legacy v1 contract reference implementation details.
These are informative and not normative.</t>

<section anchor="solidity-interface"><name>Solidity Interface</name>

<figure><sourcecode type="solidity"><![CDATA[
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface ITempoStreamChannel {
    struct Channel {
        address payer;
        address payee;
        address token;
        address authorizedSigner;
        uint128 deposit;
        uint128 settled;
        uint64 closeRequestedAt;
        bool finalized;
    }

    function CLOSE_GRACE_PERIOD() external view returns (uint64);
    function VOUCHER_TYPEHASH() external view returns (bytes32);
    function CLOSE_REQUEST_TYPEHASH() external view returns (bytes32);

    function open(
        address payee,
        address token,
        uint128 deposit,
        bytes32 salt,
        address authorizedSigner
    ) external returns (bytes32 channelId);

    function settle(
        bytes32 channelId,
        uint128 cumulativeAmount,
        bytes calldata signature
    ) external;

    function topUp(
        bytes32 channelId,
        uint128 additionalDeposit
    ) external;

    function close(
        bytes32 channelId,
        uint128 cumulativeAmount,
        bytes calldata signature
    ) external;

    function requestClose(bytes32 channelId) external;

    function withdraw(bytes32 channelId) external;

    function getChannel(bytes32 channelId)
        external view returns (Channel memory);

    function getChannelsBatch(bytes32[] calldata channelIds)
        external view returns (Channel[] memory);

    function computeChannelId(
        address payer,
        address payee,
        address token,
        bytes32 salt,
        address authorizedSigner
    ) external view returns (bytes32);

    function getVoucherDigest(
        bytes32 channelId,
        uint128 cumulativeAmount
    ) external view returns (bytes32);

    function getCloseRequestDigest(
        bytes32 channelId,
        uint64 requestedAt
    ) external view returns (bytes32);

    function domainSeparator() external view returns (bytes32);

    event ChannelOpened(
        bytes32 indexed channelId,
        address indexed payer,
        address indexed payee,
        address token,
        address authorizedSigner,
        uint256 deposit
    );

    event Settled(
        bytes32 indexed channelId,
        address indexed payer,
        address indexed payee,
        uint256 cumulativeAmount,
        uint256 deltaPaid,
        uint256 newSettled
    );

    event CloseRequested(
        bytes32 indexed channelId,
        address indexed payer,
        address indexed payee,
        uint256 closeGraceEnd
    );

    event CloseRequestCancelled(
        bytes32 indexed channelId,
        address indexed payer,
        address indexed payee
    );

    event TopUp(
        bytes32 indexed channelId,
        address indexed payer,
        address indexed payee,
        uint256 additionalDeposit,
        uint256 newDeposit
    );

    event ChannelClosed(
        bytes32 indexed channelId,
        address indexed payer,
        address indexed payee,
        uint256 settledToPayee,
        uint256 refundedToPayer
    );

    error ChannelAlreadyExists();
    error ChannelNotFound();
    error ChannelFinalized();
    error InvalidSignature();
    error AmountExceedsDeposit();
    error AmountNotIncreasing();
    error NotPayer();
    error NotPayee();
    error TransferFailed();
    error CloseNotReady();
}
]]></sourcecode></figure>

</section>
<section anchor="deployed-contracts"><name>Deployed Contracts</name>

<texttable>
      <ttcol align='left'>Network</ttcol>
      <ttcol align='left'>Chain ID</ttcol>
      <ttcol align='left'>Contract Address</ttcol>
      <c>Moderato (Testnet)</c>
      <c>42431</c>
      <c><spanx style="verb">0x9d136eEa063eDE5418A6BC7bEafF009bBb6CFa70</spanx></c>
</texttable>

</section>
<section anchor="contract-source"><name>Contract Source</name>

<t>The reference implementation is available at:
https://github.com/tempoxyz/tempo/tree/main/tips/ref-impls/src/TempoStreamChannel.sol</t>

</section>
</section>
<section anchor="schema-definitions-json-schema"><name>Schema Definitions (JSON Schema)</name>

<t>This appendix provides JSON Schema definitions for implementations that
prefer JSON Schema over CDDL.</t>

<section anchor="session-request-schema"><name>Session Request Schema</name>

<figure><sourcecode type="json"><![CDATA[
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://paymentauth.org/schemas/session-request.json",
  "title": "Session Request",
  "type": "object",
  "required": ["amount", "currency", "recipient", "methodDetails"],
  "properties": {
    "amount": {
      "type": "string",
      "pattern": "^[0-9]+$",
      "description": "Price per unit in base units (decimal string)"
    },
    "unitType": {
      "type": "string",
      "description": "Unit type being priced (e.g., llm_token, byte)"
    },
    "suggestedDeposit": {
      "type": "string",
      "pattern": "^[0-9]+$",
      "description": "Suggested channel deposit in base units"
    },
    "currency": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{40}$",
      "description": "TIP-20 token address (mixed-case accepted, normalized to lowercase)"
    },
    "recipient": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{40}$",
      "description": "Payee address (mixed-case accepted, normalized to lowercase)"
    },
    "methodDetails": { "$ref": "#/$defs/methodDetails" }
  },
  "$defs": {
    "methodDetails": {
      "type": "object",
      "required": ["escrowContract"],
      "properties": {
        "escrowContract": {
          "type": "string",
          "pattern": "^0x[0-9a-fA-F]{40}$"
        },
        "channelId": {
          "type": "string",
          "pattern": "^0x[0-9a-fA-F]{64}$",
          "description": "OPTIONAL: for channel reuse"
        },
        "minVoucherDelta": {
          "type": "string",
          "pattern": "^[0-9]+$",
          "description": "OPTIONAL: server policy hint"
        },
        "feePayer": {
          "type": "boolean",
          "default": false,
          "description": "If true, server pays transaction fees"
        },
        "chainId": { "type": "integer" },
        "operator": {
          "type": "string",
          "pattern": "^0x[0-9a-fA-F]{40}$",
          "description": "OPTIONAL: v2 channel operator"
        },
        "sessionProtocol": {
          "enum": ["v1", "v2"],
          "description": "OPTIONAL: session protocol version"
        },
        "sessionSnapshot": { "$ref": "#/$defs/sessionSnapshot" }
      }
    },
    "descriptor": {
      "type": "object",
      "required": ["payer", "payee", "operator", "token", "salt", "authorizedSigner", "expiringNonceHash"],
      "properties": {
        "payer": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "payee": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "operator": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "token": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "salt": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" },
        "authorizedSigner": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "expiringNonceHash": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" }
      }
    },
    "sessionSnapshot": {
      "type": "object",
      "required": ["acceptedCumulative", "chainId", "channelId", "deposit", "descriptor", "escrow", "requiredCumulative", "settled", "spent"],
      "properties": {
        "acceptedCumulative": { "type": "string", "pattern": "^[0-9]+$" },
        "chainId": { "type": "integer" },
        "channelId": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" },
        "closeRequestedAt": { "type": "string", "pattern": "^[0-9]+$" },
        "deposit": { "type": "string", "pattern": "^[0-9]+$" },
        "descriptor": { "$ref": "#/$defs/descriptor" },
        "escrow": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "requiredCumulative": { "type": "string", "pattern": "^[0-9]+$" },
        "settled": { "type": "string", "pattern": "^[0-9]+$" },
        "spent": { "type": "string", "pattern": "^[0-9]+$" },
        "units": { "type": "integer" }
      }
    }
  }
}
]]></sourcecode></figure>

</section>
<section anchor="session-payload-schema"><name>Session Payload Schema</name>

<figure><sourcecode type="json"><![CDATA[
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://paymentauth.org/schemas/session-payload.json",
  "title": "Session Payload",
  "type": "object",
  "required": ["action"],
  "properties": {
    "action": { "enum": ["open", "topUp", "voucher", "close"] },
    "transaction": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]+$",
      "description": "Signed transaction bytes"
    },
    "channelId": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{64}$",
      "description": "Channel identifier"
    },
    "descriptor": {
      "$ref": "#/$defs/descriptor",
      "description": "REQUIRED for v2"
    },
    "cumulativeAmount": {
      "type": "string",
      "pattern": "^[0-9]+$",
      "description": "Cumulative amount authorized (decimal string)"
    },
    "signature": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{128,130}$",
      "description": "EIP-712 voucher signature"
    }
  },
  "$defs": {
    "descriptor": {
      "type": "object",
      "required": ["payer", "payee", "operator", "token", "salt", "authorizedSigner", "expiringNonceHash"],
      "properties": {
        "payer": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "payee": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "operator": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "token": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "salt": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" },
        "authorizedSigner": { "type": "string", "pattern": "^0x[0-9a-fA-F]{40}$" },
        "expiringNonceHash": { "type": "string", "pattern": "^0x[0-9a-fA-F]{64}$" }
      }
    }
  }
}
]]></sourcecode></figure>

</section>
<section anchor="session-receipt-schema"><name>Session Receipt Schema</name>

<t>Servers <bcp14>MUST</bcp14> include <spanx style="verb">Payment-Receipt</spanx> only on successful processing of a
session action (2xx responses). On error responses (4xx/5xx), servers <bcp14>MUST</bcp14>
return Problem Details and <bcp14>MUST NOT</bcp14> include a <spanx style="verb">Payment-Receipt</spanx> header.
The <spanx style="verb">status</spanx> field is always <spanx style="verb">"success"</spanx> because receipts represent
successful acceptance; failures are communicated via HTTP status codes
and Problem Details.</t>

<figure><sourcecode type="json"><![CDATA[
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://paymentauth.org/schemas/session-receipt.json",
  "title": "Session Receipt",
  "type": "object",
  "required": ["method", "intent", "status", "timestamp", "reference", "challengeId", "channelId", "acceptedCumulative", "spent"],
  "properties": {
    "method": { "const": "tempo" },
    "intent": { "const": "session" },
    "status": { "const": "success" },
    "timestamp": {
      "type": "string",
      "format": "date-time"
    },
    "reference": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{64}$"
    },
    "challengeId": { "type": "string" },
    "channelId": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{64}$"
    },
    "acceptedCumulative": {
      "type": "string",
      "pattern": "^[0-9]+$",
      "description": "Highest voucher amount accepted"
    },
    "spent": {
      "type": "string",
      "pattern": "^[0-9]+$",
      "description": "Total amount charged so far"
    },
    "units": {
      "type": "integer",
      "description": "OPTIONAL: Units consumed this request"
    },
    "txHash": {
      "type": "string",
      "pattern": "^0x[0-9a-fA-F]{64}$",
      "description": "OPTIONAL: On-chain transaction hash (present on settlement/close)"
    }
  }
}
]]></sourcecode></figure>

</section>
</section>
<section anchor="acknowledgements"><name>Acknowledgements</name>

<t>The authors thank the Tempo community for their feedback on session
payment design.</t>

</section>


  </back>

<!-- ##markdown-source:
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
7ysr7Y9377fe37ruzpe/+k9pAqyrO3j4n34dIPGc0hHM0uzsCqjYnHC1VuyL
0X433Kta+K0x3fqYkGKTYo7rn8uhjq6AksX0ik42Mr2GZGyPjPVf3TnGhVo0
8M9CXGfJn9BEHbqWVN/GjsdC2AQO3HcniBFkDoccjonbJPIy22nFbA93DHQZ
GZeKHk7DkPjiNUya+IYzQqQ/agnG5i6qdpPHKXtpzpOl8e9Esny4Kvgp7oTJ
FF11swSmML4KIxgTbAtwY3JHYKtH05F/MZxnKSy47AC8xhuATZKbHffEmbbv
7jgxf8FgsVHjFnn/nr1s6KhCR+sMr11yC2QL4IR4RVadLUFoVlscUkwFk3IV
pWywhvW7oO6gb7WfwZBPcM9kL+EiA06ME0JXoIg4uKmWTICbjuPzKJ3hRWiI
sAf9H8SzaJWyY8VSZzKDG9J6O/EWfIr28TcLJFmeeDFHm2aBfrJpcpEUCbou
9bKN1OVIk+h5f6HbDxE0OzDiSQKtoDwEV8xjkiHmSZoi90fnKDUHssEfYTmK
cNDrawvE5Y/FnRx+y9igAsQUdTF3BS9UgLDi2+ONKRYOFBw3oZ4rmrwSCDlF
kRzOQUY7Ow9GLG4dxGWUpEVPmtL+R7tB8CH8NkqB5j4ofzBtfIAlRsa9pDvt
Q6CKQl1h8L+BJ8PRxWCETVZcu8IiPtA2sPs3HNEsmV3JEEaWidBVMovoenVu
kffvZcZdECrK+OPHXsjdDrHbtU5j6bnyu4zKeazSl+N1bug2OJqFN6wzymXR
GIEXHU/wxUmTmzYwm4uXGa0eSsK4bO8ivPOxfzhp7DTuhS9RhvMFsBi0hGC0
Uel6YzfcuBhujFh+Zn9tWV8CO8NeuBeIwKh3JjCY4h2yLkuC0lIUTpMZeRNL
Q6ZKyMhCFkFJjCamo8YqxdhQLDdFJ+JwMclInttHlrMo5VDE8vVHceAXfGMZ
2IR1zuuTYb5CpxsjF3xXO6sI38SXkZ5eovwC2BNIE+MrkDRB+ETnW0sYE/ph
ERCE/7Xe5U5o2HMbGQIcom74PIMVIk/cudOBjgoeGPUvR7jMs+QS/nqJzuAp
DRgdfPlqIRhDIGIEJgGhPofFAVH1Q3h4GaGf0J7AD/Vzh8Sv3PRDuDUkjy5M
pH8JavZWHweF7hsYxIOt4fT+9mSys3N/a9Lfvj98NNyO7o8fbm2NJ4/iB9uP
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
tVjZaO3GCk7jvR0PmnXPYLjekxxHla2dxCeQ2u1W2RYpDc0YGudSh5d4A40X
qzmdtYsB3pAXQ3vKbtpmSUYqDVOFYHzqulGcLKJlcZ6VzUyl+hCxFWrJY086
JG/Vb8dQSPnAeZKagR/M4sFnwSfBaKOU5IWqno/fkccH9vQlIt8pGdTNbGmp
dF4njBvJwVtGHvYXaMil289ti5ftCzREy37ndohteu3Utu0LjK2+7Z860Eaa
bjgfdyLshnRmHcvHOu5d1QlNYaWOd5g6en+y3Fyr24QHg9Vw+kjp0W6m/cZE
azeunF45n8iWvZv5c8mp6vL65PFPrRT9ie+7jK/OP53ffdrlXf0Cp6Cpmtcn
TkZJ6ZPfl/R8n/a2pmJsJCT/hAY+ZEOV02MBMvzkirQgC65TpGWst1WkGZlw
jXqs0IX3jvzAIL1Q6lp1HICNIhx+b7idD6n7dIXoOtVyDTavoks2SPCfoJd5
knt1JOpYsxmK/TE0izPXnO11HZkaapQJbVjVmmuokS+qytczPTrZJ643brhw
lc/YhMHwYWdw/zoNWdNb1ZI4bdiT3qTE/ixw/ixw/ocRONdcZ1pGQq8zP82G
RKfXa0VQ6gLEk5gKEagQ4kcq7DHDjHDSg3Dh1vDy0lYQaPfCVwvxTTjFI7Yu
Lze3Ly/bforMQIpWaECimJX8iko2kn5dZYseh7RoIn2ToTxK36GJwM2mr8kn
NM09Zj3gXA6BM2NJDcbJ8aWuOKdyzebz1UKyZZrKK9xxSHE0VMakMp/eT2qV
p4leb5WnR24pTAjSsmPAlR2TirrjZp/uuDmmO35u6Kr60qzsOApJo9RiMJ9w
ijCNHAEnGf5priIDAHWfUSyovbA0lbb3lBCNFXKczNo3XmsMV8RfEJPdxXer
FmSbgPtzJZWqCOQk4a5zmB9EVvJG0Kwhfknh5IZqDxVxZPkJdvqbRnBN4Yi6
p6fRUK7qyboeblVnwu/LJDP/oUTfz65T4QhmNln63gRTdYHueCbZgomf8x3M
1eneEnCZA+eFB5dXmiQwydHyO8VoVe6Tk+LYzGMoFvaC/x/lIizOTFwBAA==

-->

</rfc>

