Skip to main content

Upto Session Contract

The upto-session contract supports capped metered payments for x402 upto workflows. It lets a buyer authorize a maximum spend for a resource while the seller or facilitator settles only the actual usage.

Exact x402 payments should remain contract-free when Stellar/Soroban authorization entries and the Stellar Asset Contract provide enough enforcement. Use this contract only when a resource needs metered settlement after execution.

Use Cases

Use upto-session for:

  • LLM inference billed by token.
  • Search APIs billed by result count.
  • Data APIs billed by bytes or rows.
  • MCP tools billed by usage.
  • Long-running agent tasks with a maximum spend cap.

Public Interface

initialize(admin: Address)

create_session(
buyer: Address,
seller: Address,
asset: Address,
max_amount: i128,
expires_at_ledger: u32,
resource_hash: BytesN<32>
) -> BytesN<32>

settle(
session_id: BytesN<32>,
actual_amount: i128,
usage_hash: BytesN<32>
)

cancel(session_id: BytesN<32>)

get_session(session_id: BytesN<32>) -> Session

extend_ttl(session_id: BytesN<32>)

Session Type

Session {
id: BytesN<32>,
buyer: Address,
seller: Address,
asset: Address,
max_amount: i128,
settled_amount: i128,
expires_at_ledger: u32,
resource_hash: BytesN<32>,
usage_hash: Option<BytesN<32>>,
status: SessionStatus,
}

initialize

Stores contract admin configuration.

Requirements:

  • Must be called once.
  • Repeated calls fail with AlreadyInitialized.
  • Admin address must be recorded for future administrative actions if any are added.

create_session

Creates a capped session.

Inputs:

  • buyer: buyer address that authorizes the cap.
  • seller: fixed recipient.
  • asset: fixed Stellar Asset Contract address.
  • max_amount: maximum spend cap.
  • expires_at_ledger: last ledger where settlement is valid.
  • resource_hash: hash binding the session to a resource.

Guarantees:

  • Buyer authorization is required.
  • Seller is fixed.
  • Asset is fixed.
  • Maximum amount is fixed.
  • Expiry is fixed.
  • Resource hash is recorded.
  • Session starts unsettled.

settle

Settles actual usage against the cap.

Inputs:

  • session_id: existing session ID.
  • actual_amount: amount to transfer.
  • usage_hash: hash of usage receipt or billing evidence.

Settlement must reject:

  • Missing sessions.
  • Expired sessions.
  • Cancelled sessions.
  • Already settled sessions.
  • Amounts above cap.
  • Invalid amounts.
  • Wrong seller or unauthorized settlement actor.
  • Wrong asset path.

After successful settlement, the contract records settled_amount, usage_hash, and settled status.

cancel

Cancels an unsettled session.

Expected behavior:

  • Buyer can cancel before settlement.
  • Settled sessions cannot be cancelled.
  • Cancelled sessions cannot be settled.
  • Missing sessions fail with SessionNotFound.

get_session

Returns current session state by ID. Backend services use this to inspect capped payment state, generate receipts, and reconcile frontend display.

extend_ttl

Extends contract storage TTL safely for active sessions. TTL behavior must be documented with resource usage expectations and tests.

Contract Guarantees

The contract must guarantee:

  • Buyer authorization is required.
  • Seller recipient is fixed.
  • Asset is fixed.
  • Maximum amount cannot be exceeded.
  • Session cannot be settled twice.
  • Expired session cannot be settled.
  • Cancelled session cannot be settled.
  • Usage receipt hash is recorded.
  • TTL is extended safely.
  • Storage layout is versioned.

Error Codes

AlreadyInitialized
Unauthorized
InvalidAmount
ExpiredSession
SessionNotFound
SessionAlreadySettled
SessionCancelled
AmountExceedsCap
InvalidAsset
InvalidSeller
TtlExtensionFailed

Events

The contract should emit stable events for:

  • Session creation.
  • Settlement.
  • Cancellation.
  • TTL extension if useful for operators.

Events should include session ID and enough indexed values for backend reconciliation.

Required Tests

Contract tests should cover:

  • Create valid session.
  • Reject unauthorized session creation.
  • Reject zero or negative cap.
  • Settle valid session.
  • Reject settlement over cap.
  • Reject double settlement.
  • Reject expired settlement.
  • Reject settlement by wrong seller.
  • Cancel session before settlement.
  • Reject cancel after settlement.
  • Extend TTL.
  • Validate storage persistence.
  • Validate emitted events.

Generated Artifacts

The contracts repo should publish:

  • Contract ABI/spec files.
  • TypeScript bindings where applicable.
  • Contract IDs for local and testnet deployments.
  • Gas/resource usage notes.
  • Security limitations.

The backend should consume generated bindings instead of hand-typing the contract interface.