Skip to content

docs(cardano): make exact scheme vendor-neutral, add masumi extension - #1

Draft
adacapo21 wants to merge 20 commits into
mainfrom
QBTLabs/cardano-open-standard-update
Draft

docs(cardano): make exact scheme vendor-neutral, add masumi extension#1
adacapo21 wants to merge 20 commits into
mainfrom
QBTLabs/cardano-open-standard-update

Conversation

@adacapo21

@adacapo21 adacapo21 commented Apr 23, 2026

Copy link
Copy Markdown
Collaborator

Status

Draft. Opened for review by the Cardano Foundation before any upstream proposal to x402-foundation/x402.

Review feedback addressed (2026-04-24):

  • Supplementary docs in docs/ have been removed from the PR tree (commit d8f1d6d4). Their content is preserved in this PR description below.
  • A full end-to-end example of the cardano-masumi extension has been added to specs/extensions/cardano_masumi.md (commit adab35d6).

Summary

Revise the Cardano exact payment scheme so that its core compliance surface is facilitator-neutral, vendor-neutral, and implementation-agnostic. Move Masumi-specific semantics out of the core scheme and into a new cardano-masumi extension that follows the existing x402 v2 extensions architecture.

Masumi support is preserved in full — only its placement in the specification changes.

Motivation

The Cardano scheme merged upstream in x402-foundation/x402#1093 embeds Masumi-specific semantics directly into the core scheme:

  • assetTransferMethod: "default" | "masumi" | "script" — a core enum that names a specific third-party protocol as a peer of generic Cardano primitives.
  • Masumi-specific fields inlined into PaymentRequirements.extra (sellerVkey, paymentType: "Web3CardanoV1", blockchainIdentifier, payByTime, submitResultTime, unlockTime, externalDisputeUnlockTime, agentIdentifier, inputHash, identifierFromPurchaser).

This couples the Cardano x402 core to one ecosystem implementation. Every Cardano facilitator has to reason about Masumi-specific fields even when it does not support Masumi; additional Cardano agent-payment or escrow protocols would need either their own enum value or second-class status; future Masumi evolution forces revisions of a core scheme document.

The x402 v2 spec already defines the canonical mechanism for this: the extensions object in PaymentRequired, PaymentPayload, and SettlementResponse. Every other chain in the repo (eip155, svm, sui, aptos, algorand, stellar, hedera) keeps its core scheme focused on ledger primitives and uses extensions for cross-cutting or ecosystem-specific behaviour. Cardano should follow the same pattern.

Rationale — why this is a standards-boundary correction, not a rejection of Masumi

Core schemes should describe MUST-support behaviour only

An x402 scheme document defines the minimum surface every conformant implementation must understand to interoperate. When vendor-specific semantics leak into that surface:

  • Every implementation pays the cost. A facilitator that never intends to handle Masumi still has to parse, schema-validate, and ignore Masumi-specific fields because they live in the core extra object. This inflates the conformance surface.
  • Naming a vendor in an enum privileges it. assetTransferMethod: "masumi" is qualitatively different from "default" or "script": it treats one ecosystem project as a peer of generic Cardano primitives. Future ecosystem projects would either negotiate their own enum value (turning the standard into a vendor registry) or accept second-class status.
  • Standards boundaries calcify. Once a vendor field is in core, removing it is a breaking change. Moving it to an extension while the scheme is young and adoption is still small is much cheaper than doing so later.

Script-parameterized payments belong in core; off-chain semantics do not

Plutus scripts with applied parameters are a generic Cardano primitive, not a vendor feature. Any Cardano-native payment flow — Masumi's escrow, an alternative agent-payment protocol, a milestone-release protocol, a subscription escrow, a vault — ultimately expresses itself as a payment to a script address with some datum and redeemer. The core scheme needs to describe "pay to a script address, with the client able to reconstruct that address from the declared script and parameters." It does not need to describe the off-chain semantics attached to any particular script.

Interoperability payoffs

  • Multi-facilitator. A facilitator can claim conformance with the Cardano exact scheme without committing to any specific agent-payment protocol.
  • Multi-ecosystem. Other Cardano agent-payment or escrow protocols can publish extensions alongside cardano-masumi without a spec change.
  • Cleaner client contracts. A client library targeting the Cardano exact scheme has a small, stable contract: address-to-address and script-parameterized payments. Ecosystem-specific stacks are opt-in via extension libraries.
  • Predictable evolution. When Masumi evolves (a Web3CardanoV2, new windows, new identifiers), the core Cardano scheme does not need to version. The extension versions independently.

This is not anti-Masumi

Masumi is one of the earliest substantial Cardano agent-payment deployments. The proposal preserves Masumi on Cardano x402 in full — via a named, versioned extension — and gives Masumi a cleaner place to evolve on its own cadence, decoupled from the core scheme's cadence.

What changed

Modified

  • specs/schemes/exact/scheme_exact_cardano.md — rewritten so the core describes only generic Cardano primitives:
    • Address-to-address payments (ADA via reserved "lovelace" asset, or Cardano native tokens).
    • Script-parameterized payments (generic Plutus scripts with applied parameters).
    • Facilitator verification rules (network, recipient, amount, asset, nonce/replay, TTL).
    • Explicit statement that ecosystem-specific semantics MUST travel via the x402 v2 extensions model.
    • assetTransferMethod enum removed; "default" and "script" are now described via field-shape rather than vendor-adjacent enum values.
    • Corrected the mermaid submission notes and step 6 wording: the node accepts a submitted tx into its mempool synchronously; block inclusion is asynchronous and probabilistic. The prior wording ("included in mempool or block") contradicted the spec's own finality warning.

Added

  • specs/extensions/cardano_masumi.md — new extension carrying Masumi-specific fields under extensions["cardano-masumi"].info, with schema, field semantics, client/server/facilitator responsibilities, explicit core-compatibility rules so a non-Masumi stack can still verify the underlying script-parameterized payment, and a full end-to-end worked example of the flow.

What moved from core to extension

Element Was (core extra) Now (extension)
assetTransferMethod: "masumi" core enum value removed; replaced by extension presence
sellerVkey core extra extensions["cardano-masumi"].info.sellerVkey
paymentType: "Web3CardanoV1" core extra extensions["cardano-masumi"].info.paymentType
blockchainIdentifier core extra extensions["cardano-masumi"].info.blockchainIdentifier
agentIdentifier core extra extensions["cardano-masumi"].info.agentIdentifier
identifierFromPurchaser core extra extensions["cardano-masumi"].info.identifierFromPurchaser
inputHash core extra extensions["cardano-masumi"].info.inputHash
payByTime / submitResultTime / unlockTime / externalDisputeUnlockTime core extra extensions["cardano-masumi"].info.*

What stays in core

  • Network identifiers cardano:mainnet / cardano:preprod / cardano:preview.
  • asset format ${policyId}.${assetNameHex}, plus reserved "lovelace" for native ADA.
  • payTo (regular or script address).
  • maxTimeoutSeconds, TTL checks.
  • payload.transaction (Base64 CBOR) and payload.nonce (UTXO reference for replay prevention).
  • Facilitator verification rules.
  • Script-parameterized payments (extra.scriptHash, extra.script, extra.parameters) as a generic Cardano primitive.

Commits

Four commits on top of cardano-foundation/x402:main, two files changed:

  • 84353d56docs(cardano): make exact scheme vendor-neutral, add masumi extension
  • caf790b8fix(cardano): correct mempool-vs-block-inclusion wording in exact scheme
  • d8f1d6d4docs(cardano): drop supplementary rationale docs from PR tree (per review)
  • adab35d6docs(cardano): add end-to-end masumi extension example (per review)

An earlier iteration of this branch also contained a merge of x402-foundation/x402:main, which inflated the diff with 44 unrelated upstream commits; that merge was dropped from the proposal so the diff isolates the Cardano-neutrality changes. Bringing cardano-foundation/x402:main up to date with upstream is tracked separately and can be handled as a plain sync PR.

Review path

  1. Cardano Foundation review (Fabian) + community discussion in the open office hours.
  2. Any required revisions on this branch.
  3. Upstream proposal to x402-foundation/x402.

Backward compatibility

  • On-chain transaction shape is unchanged.
  • Masumi integrators move fields from extra to extensions["cardano-masumi"].info; this is a mechanical client/server adjustment.
  • Facilitators that only implement the core scheme continue to verify payments correctly (they just don't enforce Masumi-specific off-chain invariants, which they were never in a position to enforce anyway).

Non-goals

  • No change to Masumi's on-chain protocol or off-chain rules.
  • No change to any chain, scheme, or facilitator implementation outside the spec.
  • No position on which Cardano agent-payment protocol implementations should be preferred.

Open questions (non-blocking)

  • Extension naming: cardano-masumi vs. masumi vs. cardano.masumi. Worth aligning with any emerging convention.
  • "lovelace" reserved value for native ADA: should be sanity-checked against existing Cardano SDK idioms in the repo.
  • Whether a Cardano-flavoured analog of the offer-receipt extension would be useful later (CIP-8 / CIP-30 signing formats are not in that extension's current format set).

rewrite specs/schemes/exact/scheme_exact_cardano.md so the core
compliance surface describes only generic cardano primitives
(address-to-address payments, script-parameterized payments,
ttl/nonce/amount/asset verification). remove the masumi-named
enum value and masumi-specific fields from the core scheme.

add specs/extensions/cardano_masumi.md carrying the masumi-specific
fields under the x402 v2 extensions model, preserving full masumi
support without coupling it to the core cardano compliance path.

add docs/cardano-open-standard-rationale.md and
docs/cardano-open-standard-pr-summary.md explaining the
standards-boundary correction.
the prior wording said cardano "includes the transaction in the mempool
or a block" at submission time, and the mermaid notes said the same.
submission only returns a synchronous mempool-acceptance ack; block
inclusion is a separate, later, probabilistic event. this contradicted
the spec's own warning that mempool status SHOULD NOT be treated as
final. clarify both mermaid notes, the return-arrow label, and step 6.

@fabianbormann fabianbormann left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate the more exact wording. Removing the docs folder and getting consensus about the extensions in the open office hour would be required to proceed with this as is, otherwise if we come to the conclusion to keep masumi as part of the core, let's keep the wording changes in any case as they really make a lot of sense.

@@ -0,0 +1,98 @@
# PR Draft — Cardano `exact` scheme: open-standard boundary correction

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding the context here. I would suggest to remove the docs folder from the PR as it would otherwise end up in the x402 foundation once merged and this is probably not the intention. If the text stays as part of the PR description in GitHub I guess that's fine.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — both files removed in commit d8f1d6d4. The rationale and summary content has been moved into the PR description so it stays with the PR but does not flow upstream as files.

@@ -0,0 +1,216 @@
# Extension: `cardano-masumi`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, but let's discuss this with the community in the open office hours session

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged — happy to walk the community through the extension shape and the rationale in the open office hours, and to adjust the proposal based on the discussion. A full end-to-end example (PaymentRequired → PAYMENT-SIGNATURE → SettlementResponse) has also been added to this file in adab35d6 so the conversation has concrete JSON to point at.

Cardano-specific ecosystem semantics that go beyond the rules above MUST be carried through the x402 v2 extensions model, following the pattern:

```
extensions[extensionId].info // extension-specific data

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you provide here also an example of a full request using the masumi extension as an example?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added — see commit adab35d6. The cardano-masumi extension spec now includes an End-to-End Example section that walks through a complete Masumi-routed flow: the 402 Payment Required body with the extension populated, the decoded PAYMENT-SIGNATURE header payload showing the client echoing the extension, and the PAYMENT-RESPONSE/SettlementResponse. There is also a short note on what a non-Masumi-aware stack sees of the same flow (generic script-parameterized payment).

per PR review feedback: these docs were meant as scaffolding for review,
not as files to flow upstream into x402-foundation. remove them from the
repo; the rationale and summary content already lives in the PR
description on github.
per PR review feedback: add a full worked example showing a complete
masumi-routed flow — PaymentRequired, PAYMENT-SIGNATURE header, and
PAYMENT-RESPONSE/SettlementResponse — so reviewers can see concrete
json for each step of the extension in use, plus a note on what a
non-masumi-aware stack sees of the same flow.
@github-actions github-actions Bot removed the docs label Apr 24, 2026
Kammerlo pushed a commit that referenced this pull request Aug 24, 2026
…dation#2698)

* docs(svm): add `batch-settlement` SVM scheme specification

SVM profile of the network-agnostic `batch-settlement` scheme: high-throughput
channel payments where a client deposits once, signs cumulative Ed25519 vouchers
verified off-chain, and the operator redeems the latest voucher per channel
on-chain in batches. The multi-voucher generalization of `upto`.

* docs(svm/batch): cascade upto role-model + cleanups to batch-settlement

Mirrors the upto spec revision, adapted for batch's client-signed cumulative
vouchers:

- Role model: the operator is the channel `payee` (the program requires the
  `settle_and_finalize` merchant == `channel.payee`), as well as fee payer and
  `rentPayer`; `authorizedSigner` stays the payer (client signs vouchers). `payTo`
  is realized as the payee (self-facilitating, `operator == payTo`) or a
  `distributionSplits` entry (separate facilitator). Added the self-facilitating
  reference-status note and set `payee = operator` / `rentPayer = operator` at open.
- Cleanups (match upto): dropped the `pay-kit`-controlled / `CHNLxY` program-id /
  "program we control" references.
- Clarified that `expiresAt` is a genuine *client* commitment here (the client
  signs each voucher), unlike upto's operator-attested field.

Deliberately NOT cascaded: `deposit == maxAmount` — batch's deposit is a
multi-request escrow, so the ceiling is `cumulativeAmount ≤ deposit`, not equality.

* docs(svm/batch): address review feedback (security, conformance, clarity)

Resolves @notorious-d-e-v's review on PR x402-foundation#2698 (verified against the
payment-channels program where relevant):

- Voucher replay (#8): the cumulativeAmount is the per-request nonce — a new
  request needs a strict increment (watermark + amount); an equal voucher is only
  an idempotent retry that replays the response cached at that cumulative, never a
  fresh serve.
- Async expiry (#9): expires_at is re-checked on-chain at settle (not just
  settleAndFinalize), so vouchers must use expiresAt == 0 or a TTL outlasting the
  redemption window (grace + buffer).
- Fee-payer guard (#7): validate the full compiled open tx (ALT resolution,
  allowed-instruction-set only, fee payer never an authority/source/writable
  except fees), per the exact SVM scheme.
- State ownership (#3): the watermark/ChannelStore is the resource server's state;
  a separate facilitator stays stateless.
- Response shape (#6): nest chargedAmount/channelState under extra, amount
  optional (core SettleResponse + EVM batch companion).
- asset is the concrete mint, not a symbol (#5); dropped SDK function names (#1);
  added a grace buffer SHOULD (#2); genericized the per-tx settle cap (#10).

* docs(svm): align batch-settlement spec with channels

* docs(svm): align batch settlement wire contract

* docs(svm): refine batch settlement lifecycle

* docs(svm): add batch refund authorization

* docs(svm): define batch refund fallback

Make payer-signed request_close the portable refund path, with facilitator-funded initiation and asynchronous finalization after a bounded grace period. Keep authenticated cooperative close as an optional fast path and align setup validation with the current SVM upto profile.

Co-authored-by: Ludo Galabru <ludo.galabru@solana.org>
Signed-off-by: Ludo Galabru <ludo.galabru@solana.org>

* docs(svm): drop block height hint

Co-authored-by: Ludo Galabru <ludo.galabru@solana.org>
Signed-off-by: Ludo Galabru <ludo.galabru@solana.org>

* docs(svm): batch-settlement review follow-ups

- switch the scheme to the protocol-default authorization payment flow:
  read-only verify before the handler, voucher commit and deposit
  broadcast in the post-handler settle
- clarify that the 900-2592000 withdrawDelay range is an x402
  conformance bound enforced by facilitators, not a program constraint
- quantify the voucher-expiry settlement buffer via an advertised
  extra.settlementBufferSeconds (default 60) so clients can compute a
  passing expiresAt from the 402 alone
- require clients to verify the corrective 402 voucherState signature
  before adopting chargedCumulativeAmount

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(svm): add settlement-buffer error code

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(svm): make non-expiring vouchers normative

Voucher expiry added a second clock the server had to beat on top of the
forced-close grace period, and a nonzero expiresAt could make an accepted
voucher unredeemable while the channel was still open. The client MUST now
sign expiresAt = 0, the server and facilitator MUST reject nonzero values,
and extra.settlementBufferSeconds is dropped along with the expiry-window
bound.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Signed-off-by: Ludo Galabru <ludo.galabru@solana.org>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants