The rail refused two of the wire's four schemes. Both are implemented. **`auth-capture`.** Under `escrow` the client's settle places a hold before the work, and the server finalizes afterwards with a payload it authors itself, naming the operation as `payload.type`: a capture of what the work cost, or a void when it cost nothing. `accept` walks that, and refuses a capture over the hold before it is relayed. Later operations go through the same `/settle`, so `lifecycle_payload` builds them around the network binding's own fields — the facilitator is handed the payment rather than left to reconstruct it. `AuthCapturePayment` is the server's book of one payment: held, captured, refunded, and the two deadlines. The escrow enforces these on chain, so the book is not where safety comes from. It is where a doomed operation is refused *before* it costs a failed settle and, for an asynchronous server, a payment its own records misdescribe: a capture over the hold or past the capture deadline, a void with nothing left to release, a refund over what was captured and not yet refunded or past the refund deadline, a fee outside the bounds the client authorized. A requirement with no capture deadline is refused rather than booked — a hold that can never be reclaimed is not one to place. **`batch-settlement`.** The commitment is verified, the work runs, and the charge is stored rather than moved, so the result carries an empty `transaction` and reports the request's price in `extra.chargedAmount`. That is success, not a missing hash. The charge is bounded where it is reported, since under this scheme there is no transfer to fail instead. The settle-time amount rule is now one type, `MeteredCharge`, for every scheme whose settled figure may differ from the authorized one; `UptoCharge` stays as its name for the `upto` case. And the capability document is corrected. It claimed partial settlement as ground the wire did not cover. The wire's reservation lifecycle is as complete as ours, and the document now says so and maps all three metered schemes onto it. What that narrows our contribution there to is exactly two things, stated without decoration: nothing on that wire bounds the energy the paid work burns, and none of the three schemes carries a measurement — the figure the buyer pays is a number the seller produced, bounded above and otherwise unexplained. Co-Authored-By: Claude <[email protected]>
13 lines
950 B
TOML
13 lines
950 B
TOML
[package]
|
|
name = "op-rails-x402"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
description = "OpenPay x402 rail — the HTTP 402 'Payment Required' agentic-payment protocol. Speaks both wire versions: v1 (X-PAYMENT, maxAmountRequired) and v2 (PAYMENT-REQUIRED / PAYMENT-SIGNATURE / PAYMENT-RESPONSE, CAIP-2 networks, all four schemes — exact, upto, auth-capture and batch-settlement — declared payment flows, the facilitator split into verify + settle, and resource discovery). Emits the challenge from an OpenPay Money, enforces every metered scheme's settled <= authorized bound locally, and keeps an auth-capture payment's book of what is held, captured and refunded against its deadlines; the on-chain edge stays behind a pluggable seam."
|
|
|
|
[dependencies]
|
|
op-core = { path = "../op-core" }
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
thiserror = { workspace = true }
|