<?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.35 (Ruby 3.2.11) -->


<!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="April" day="17"/>

    
    
    

    <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 the metered services.</t>



    </abstract>



  </front>

  <middle>


<?line 81?>

<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="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">42431</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>Channel State</name>

<t>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="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.feePayer</spanx></c>
      <c>boolean</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>If <spanx style="verb">true</spanx>, server pays transaction fees (default: <spanx style="verb">false</spanx>)</c>
      <c><spanx style="verb">methodDetails.chainId</spanx></c>
      <c>number</c>
      <c><bcp14>OPTIONAL</bcp14></c>
      <c>Tempo chain ID (default: 42431)</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><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": 42431
  }
}
]]></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": 42431
  }
}
]]></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 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">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>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>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",
    "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">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",
    "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">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",
    "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">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 call <spanx style="verb">close(channelId, cumulativeAmount, signature)</spanx> on-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": "close",
    "channelId": "0x6d0f4fdf1f2f6a1f6c1b0fbd6a7d5c2c0a8d3d7b1f6a9c1b3e2d4a5b6c7d8e9f",
    "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>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></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">42431</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>
  </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.</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.</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 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><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">highestAmount</spanx></t>
  <t>Submitting a voucher with lower <spanx style="verb">cumulativeAmount</spanx> than highest accepted
<bcp14>MUST</bcp14> return 200 OK with the current <spanx style="verb">highestAmount</spanx> (not an error)</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>
</texttable>

<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 calls <spanx style="verb">close(channelId, cumulativeAmount, signature)</spanx> on-chain</t>
  <t>Contract settles any delta and refunds remainder to 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>

</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">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">txHash</spanx> field serves as the core spec's <spanx style="verb">reference</spanx> field in
<xref target="I-D.httpauth-payment"/>. It 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",
  "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",
  "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>SHOULD</bcp14> skip expensive signature verification for vouchers that
do not advance state (return 200 OK with current <spanx style="verb">highestAmount</spanx> per
<xref target="idempotency"/>)</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 1636?>

<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": 42431
  }
}
]]></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="reference-implementation"><name>Reference Implementation</name>

<t>This appendix provides 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" }
      }
    }
  }
}
]]></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"
    },
    "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"
    }
  }
}
]]></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", "challengeId", "channelId", "acceptedCumulative", "spent"],
  "properties": {
    "method": { "const": "tempo" },
    "intent": { "const": "session" },
    "status": { "const": "success" },
    "timestamp": {
      "type": "string",
      "format": "date-time"
    },
    "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:
H4sIAAAAAAAAA+19S3Mb2ZXmPn9FNssRBmgABMGHJMpyN0VSJdp6sEWqqt1u
dyGBTJBpAUg4M0GRJanDMYtZzaJjwtHTy/kBs5zlrGb+iX/JnOd9ZCYoUqWq
stutcLhAIPM+zz33PL/T7XaDMi2nyV54lswWWXiaFEWazcPjeZnMy3CS5eHT
s7OT8CS6nuEX+8vyAv6bjqMSHgui0ShPLisvB3E2nkczaDPOo0nZLfHHbsE/
dvv94DLJ8eNeCJ+hoeQ8y6/3wnQ+yYJ0ke+F8+x5FqcT6eQsXxbloN9/0B8E
xXI0S6md8noBHRwfnT0Jxtm8SObFstgLy3yZBEEEg8zyvSAMuyEP5FkazcKn
WT5P4MsQuoJnn/Wcb5JZlE73wik893c03t7V9bf0S5af6/yeRaPCafTLBH5L
syL8FQygjOZltsiW06ywXXzZa/xNOjuX92/d4WE0D19lI2gaFtl0ctjzv5TW
42h+64Yf58k8xsavI6fhxz37hTQ64gdv3fAvozdJ+Dy7Sq5ts7/sOd9Iu7+D
5z7SaDDP8hkQxGWCG/vqycFgc/OBfNza2tKP27vb9+Xj/c172/pxsKMPPNjc
7NuPm/pxe+cefjzuHvYuynKBJNRdMNHv0XjkmKydXSThT+U4/JQPh38owtPx
RTJL1vitKD9Pyr0Q2yz2NjbiqIzKPBq/SfJempSTHkxzA87LBh+VHNa7W+1/
g1qyRI3/ViwwNA9fDvqD3W5/MwjwSPmLdn+XZ390fNK9tzmoTA3OVBwWcIjG
5TKHjzja8CIqLtL5eRjN4bf0fA6fm+eWpIuil8BS5MlyRhODXk7xa+zqhkm8
SmbjLHw8zWDZ5t48Nu91+w/gm9PTI3+op0kOXKR7ijzp6BL+v2ge00U5m/aK
RTLuvb2IyrfnNKzZclqmi+g82Si4GWAfZTehZnr4RuNYiSC/frp/9vWX8N3Z
0fOTl92zf+ienhwdVJaRiPYsj+ZFNGaKgAEYfraCMLJx0TMnYGORZ2U2zqYb
pW2m2MCJCDt1vl89Wu9MnsGWD/qVodJ34Vn2JoFRAp+Kozy+4wDTxaBPI7vV
OLpw4+D/hfAHHoQyCM4u0iKE5pd0w8TJJJ0nRQh0FK7JpbEGnMPcR/QDDWQt
lBMSzoDsshjonX7Vy2r14eyFx2VY8K5AX8t5Gqd5QqsZTQMYWBLNkOa1/fFF
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
uUkj2ckmAQA=

-->

</rfc>

