Skip to content

Support 'upto' scheme #71

Description

@jeesunikim

Summary

x402's upto scheme lets a client authorize a maximum spend and the server settle only actual usage. It's the scheme for metered APIs where cost isn't known until after execution — LLM inference, search, per-byte transfer. Stellar cannot express it today. @x402/stellar currently supports exact which sends the exact amount via SAC's transfer(from, to, amount).

Proposed mechanism

Stellar has the equivalent primitive natively in the SEP-41 token interface:

fn approve(env: Env, from: Address, spender: Address, amount: i128, live_until_ledger: u32);
fn transfer_from(env: Env, spender: Address, from: Address, to: Address, amount: i128);

approve(max)transfer_from(actual). live_until_ledger gives native authorization expiry. EVM's Permit2 encodes deadlines manually.

scheme_upto.md requires each network binding to define four things; proposed Stellar answers:

Requirement Proposed Stellar mechanism
Replay protection (Permit2-nonce equivalent) Soroban auth entry nonce
Time-bound (validAfter / deadline) live_until_ledger + auth entry signatureExpirationLedger
Recipient binding to bound in the authorized invocation args
Settlement ≤ authorized max Enforced by allowance semantics; belt-and-braces check in a settle proxy

Open design questions

  1. Who submits approve, and does it cost an extra transaction? This is the crux. If approve needs its own submitted tx, upto costs 2 on-chain ops vs exact's 1, which may erase the benefit for small payments. Options: (a) facilitator submits both in sequence, (b) a Soroban settle-proxy the client authorizes once that internally does transfer_from with an enforced ceiling, (c) batch both into one transaction with multiple auth entries.
  2. Does fee sponsorship still hold? exact on Stellar advertises areFeesSponsored: true. Need to confirm the allowance flow preserves zero-XLM-for-payer.
  3. Allowance hygiene. Does a partial transfer_from leave a dangling allowance? live_until_ledger bounds it, but zeroing on settle may be cleaner.
  4. Proxy or no proxy? Raw SAC approve/transfer_from may suffice, avoiding a deployed contract entirely — a meaningful simplification over EVM if it holds.

Acceptance criteria (this repo)

  • examples/facilitator verifies an upto payload and settles actualAmount ≤ authorizedMax
  • /supported advertises {scheme: "upto", network: "stellar:testnet"}
  • Settle response populates amount with the actual settled value
  • Rejects actualAmount > authorizedMax with a spec-conformant error
  • Testnet demo: authorize $0.10, settle $0.007, verify on-chain

Written with Claude

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions