upto when a seller needs to authorize a cap before it knows the final
metered amount. The contract settles actual atomically and refunds the
remainder. The buyer does not sign a new payment for every usage increment.
What ships in this repository
Install the temporary client
Client setup
maxTimeoutSeconds, binds the payer, payTo, token, maximum, network,
settlement contract, facilitator, settlement ID, and optional hook, signs the
payer authorization entry, and leaves only the facilitator authorization to be
completed.
Resource-server setup
The resource server registers the temporary server-side scheme alongside the facilitator. The server-side adapter parses Stellar asset prices and preserves the standardextra.areFeesSponsored requirement; it does not settle the
transaction itself.
facilitator/examples/self-facilitating-resource-server/index.ts.
Embedded facilitation still requires PostgreSQL so idempotency, channel leases,
budgets, and unknown-transaction recovery survive a process restart. For a
shared deployment, replace createEmbeddedFacilitator() with the HTTP
facilitator client described in self-hosting.
Contract algorithm
The Soroban contract performs one atomic execution:- require the payer authorization for the declared arguments;
- require the facilitator authorization for the complete call including
actual; - reject negative or over-maximum
actualvalues; - require the allowance to equal exactly
max_amount; - approve/pull the maximum from the payer;
- pay
actualto the bound recipient; - refund
max_amount - actualto the payer; - consume the allowance and host authorization nonce;
- invoke the optional hook after the payment/refund window;
- re-check allowance, payer, recipient, and event/balance invariants; and
- emit the terminal settlement event.
Ledger validity ordering
The three clocks must be ordered as:Upto configuration
Upto is enabled per network. The contract address is an operator-controlled deployment value; it is not accepted from the payment payload. The checked-in testnet profile uses the measured contract and fee ceilings below. Pubnet has no default contract and remains fail-closed.upto in /supported only when upto_contract is
configured for that network. Do not raise the fee ceiling without fresh
enforcing-simulation p99 measurements. The full network, asset, sponsorship,
search, catalog, and pubnet startup controls are in the
configuration reference.
Settlement hooks
The hook is an optional, versioned protocol boundary, not a required policy implementation. It receives aSettlementNoticeV1 containing the settlement
ID, payer, recipient, token, maximum, and actual. The facilitator and ledger
deadline are not fields in the current notice ABI; the hook can bind its own
caller check to the settlement contract.
- The hook fires for zero settlement too.
- The hook runs on the facilitator’s sponsored transaction and therefore inside the enforcing simulation fee gate.
- A payer-signed hook that is unavailable or reverts bricks that payer’s own settlement; this is the payer’s availability risk.
- The settlement contract rejects a hook equal to itself or the token contract.
- The post-hook invariant recheck is normative, not merely a test: a malicious hook cannot alter the final balance/allowance outcome undetected.
- Re-entry is bounded by authorization nonce consumption; the contract holds no payment balance at callback time because refund already completed.
OpenZeppelin smart-account composition
An OZ smart account needs two context rules for the nested authorization tree:approve invocation. Record-mode simulation does not execute __check_auth,
so it cannot prove policy behavior. The facilitator records resources, the buyer
signs, then enforcing simulation executes the real account check and hook before
fee ceilings or submission.
The effective agent ceiling is the minimum of:
- local agent/MCP budget;
- signed x402 maximum; and
- on-chain smart-account spending policy.
mock_auths() or mock_all_auths().
Failure semantics
Insufficient balance, missing trustline, expired allowance, failed token call,
failed recipient transfer, malformed auth tree, changed recipient/token/contract,
and invalid custom-account policy all revert without partial balance changes.