D1 interactive demo -- demo.pay.vauban.tech
Vauban Pay developer demo
Three interactive panels: (1) JCS canonicalisation per RFC 8785 with live SHA-256 recomputation; (2) bounded-spend authorization fixture vectors you can reproduce client-side; (3) the first live receipt emission on Starknet Sepolia.
All cryptographic operations in this demo run in your browser via the Web Crypto API and a TypeScript JCS implementation (RFC 8785). No server call is made for the canonicalisation or hashing steps.
Canonical JCS reproducer
Paste any JSON object below. The right panel shows the JCS-canonicalised bytes (RFC 8785 ; alphabetical key order, no whitespace, recursive sort) and the SHA-256 of those bytes.
This is the exact canonicalisation step used to produce
expected_delegation_grant_hash and
expected_settlement_receipt_hash in every Vauban Pay fixture.
Five independent implementations (Rust, Python, Node.js, TypeScript, Go) produce
the same bytes from the same JSON input.
RFC 8785 reference: rfc-editor.org/rfc/rfc8785. Implementation: TypeScript port of the JCS algorithm (alphabetical sort, deterministic number serialisation).
AP2 open_mandate_hash ; conformance validation
serde_jcs@0.2.0 (Rust) ; Vauban Pay implementation ; 3rd independent impl (AP2/issues/265, 2026-05-23)
The AP2 open_mandate_hash is defined as
SHA-256(JCS_RFC8785(unsigned_mandate_body)).
The same JCS canonicalisation rule that underpins x402 STARK receipts applies here ;
different protocol, same derivation.
7 conformance vectors from AP2 issue #265 were verified byte-for-byte by the Vauban Pay
Rust runner (runner-ap2-omh.rs) using serde_jcs@0.2.0.
This makes Vauban Pay the 3rd independent implementation to verify these vectors.
Conformance vectors (AP2 issue #265, v0)
| Vector ID | JCS | Hash |
|---|---|---|
ap2-omh-v0-baseline-001 | OK | OK |
ap2-omh-v0-object-key-order-002 | OK | OK |
ap2-omh-v0-array-order-003 | OK | OK |
ap2-omh-v0-optional-fields-004 | OK | OK |
ap2-omh-v0-unicode-nfc-006a | OK | OK |
ap2-omh-v0-unicode-nfd-006b | OK | OK |
ap2-omh-v0-mixed-types-005 | OK | OK |
Pair invariants (4 / 4 verified)
| Invariant | Rule | Result |
|---|---|---|
001 == 002 | Object key order ; JCS sorts, hash must match | PASS |
001 != 003 | Array order significant ; JCS preserves, hash must differ | PASS |
001 != 004 | Optional fields not collapsed ; hash must differ | PASS |
006a != 006b | No Unicode normalisation ; NFC ≠ NFD, hash must differ | PASS |
CROSS-PROTOCOL BRIDGE
One canonicalisation layer, two protocols.
AP2 ; agentic mandates
open_mandate_hash = SHA-256(JCS(unsigned_mandate_body)) x402 ; STARK receipts (IETF I-D)
open_receipt_hash = SHA-256(JCS(receipt_core))
Both derivations share the identical SHA-256(JCS(•)) construction.
A conforming implementation of either protocol can reuse the same JCS canonicalisation
library and hash function ; no protocol-specific variant is required.
The Axis 0 substrate (RFC 8785) is the shared foundation.
crates/zkpay-x402/examples/runner-ap2-omh.rs
(committed in vauban-zkpay). The runner ingests the AP2 v0 vector file,
serialises each unsigned_mandate_body through serde_jcs::to_string,
computes SHA-256 over the UTF-8 bytes, and asserts byte-for-byte equality
against the pinned expected digest. 7/7 assertions pass, 4/4 pair invariant checks pass.
Library: serde_jcs@0.2.0 (Rust). Hash: sha2@0.10.
Axis 0 ; Canonicalisation substrate
AlgoVoi (chopmob-cloud) ; 4 vector sets / 53 vectors / 37 pair invariants / 5-impl byte-for-byte
The substrate layer defines the single JCS canonicalisation rule (RFC 8785) that every coalition axis follows before hashing. Any JSON object passed into any axis is first serialised to deterministic bytes: alphabetical Unicode code-point key order at every nesting level, no whitespace, Unicode NFC normalisation on string values, float rejection (non-finite numbers are protocol errors), and deterministic number representation per RFC 8785 §3.2.2.
The four AlgoVoi-authored vector sets (53 vectors total, 37 pair invariants) serve as the normative conformance anchors. A conforming implementation must reproduce each pinned SHA-256 digest byte-for-byte. Five independent implementations across five languages and four non-overlapping author sets all pass 53/53 vectors and 37/37 pair invariants.
Regulatory retention obligations (MiCA Art. 80, AMLR Art. 56, DORA Art. 14) require
auditors to pin a specific vector revision for multi-year reference. The in-tree mirror
at fixtures/canonicalisation-substrate/v0/ provides that repo-tagged anchor
in place of mutable gist URLs.
Vector sets (in-tree mirror)
| File | Vectors | Pair invariants | Layer |
|---|---|---|---|
ap2-omh-v0.json | 7 | 4 | AP2 OMH v0 |
ctef_vectors.json | 7 | included | CTEF-APS ; trust-evidence container |
privacy_class_v0.1.json | 13 | 12 | privacy_class v0 ; attestation |
per_chain_envelope_v0.json | 19 | 9 | per_chain_envelope v0 ; chain-native-value |
Cross-implementation conformance matrix (re-verified 2026-05-21)
| Library | Lang | Maintainer | Result |
|---|---|---|---|
rfc8785@0.1.4 | Python | Trail of Bits | 53/53 + 37/37 |
canonicalize@3.0.0 | JS | Erdtman + Rundgren | 53/53 + 37/37 |
gowebpki/jcs v1.0.1 | Go | GoWebPKI | 53/53 + 37/37 |
cyberphone/json-canonicalization | Java | Rundgren (RFC 8785 reference) | 53/53 + 37/37 |
serde_jcs 0.2.0 | Rust | Vauban Pay (5th-impl runner) | 53/53 + 37/37 |
Vector provenance: each JSON file is a byte-for-byte mirror of the canonical AlgoVoi gist
at the timestamp recorded in its published_at field.
Provenance verification: gh api gists/<id> | diff - against the in-tree file.
RFC 8785 reference:
rfc-editor.org/rfc/rfc8785.
STARK receipts ; Vauban Pay
LIVE ; Sepolia 2026-05-23Vauban Pay (pay.vauban.tech) ; Rust, serde_jcs 0.2.0, Stwo Circle STARK M31
The STARK receipts layer introduces BoundReceipt<T>: a deterministic
CBOR (RFC 8949) envelope that wraps any settlement receipt type and binds it to a
action_ref work-proof computed via SHA-256(JCS(RFC 8785)) over the
canonicalized action preimage. The envelope is compact by construction: the fixture
vector encodes 197 bytes of canonical CBOR from a four-field settlement receipt plus
a 32-byte action_ref.
The IETF Internet-Draft
draft-vauban-x402-stark-receipts (submitted 2026-05-21) formalizes
the encoding rules: receipt_core is JCS-canonicalized first, SHA-256 is computed
over those bytes to produce the receipt_core_hash anchored on Starknet,
and the BoundReceipt envelope carries both the raw receipt and the action_ref in a
single CBOR-deterministic byte string that any compliant verifier can recompute offline.
Cross-axis binding is structural: the same payment_hash and
action_ref appear verbatim in Axes 2 (FeedOracle hybrid-PQC), 3
(andysalvo work-receipt), and 4 (nobulex composite). One mutation to either field
invalidates all axes simultaneously ; the Axis 1 CBOR envelope is the on-chain
settlement anchor for the entire coalition fixture set.
0x6bcbb2440007419557110871c5e46962ec33d5b0fe0afe98b4a5a0e29c4044f Verified on Voyager (Sepolia) ; block explorer canonical
0x438f7ea2b67036873bd7248481ffa9adca548a654c6330520d37526f9bb014 felt252 (masked) anchored on-chain via
PaymentDemoEmitter 50000 centimes USDC (= 500.00 USDC) 0x55534443 ASCII decode: "USDC" 1779548263147 2026-05-23 (Unix ms) 0x5f4802a628e6a5342f9487253d1447c70583cea92358d2ce5781d67baf08d9 0x044dd87a94a801cf775d4c5e4b6703102d4e97e1cd1d0a8879341219ae4f19ff PaymentDemoEmitter ; Starknet Sepolia
Verify on-chain
Fetch the live receipt from Starknet Sepolia via self-hosted RPC. Enter any tx hash or use the demo transaction pre-filled below.
stark-vauban-pay-v1 PASS 2ed186ebc66947eaac6a05a88c7bc096ee07ac11a2c44bb5580bd72b3670f580 SHA-256(utf8(
x402-payment-base-0xUSDC-50000-base-mainnet-demo)).
Shared with FeedOracle fixture verbatim ; documents a hypothetical x402 USDC-Base
settlement for fixture purposes.
10d8a38c01d8672176aa6e5209a368fde3e1831640d69e15283142b35880c2c1 SHA-256(JCS(RFC 8785)) over
{"action_type":"sanctions_screen","agent_id":"did:web:agent-7.example.com","scope":"counterparty-due-diligence","timestamp_ms":1747728000000}.
Shared with Axes 2 and 3.
550e8400-e29b-41d4-a716-446655440000
• block 9786058 (Starknet Sepolia)
• settled_at 1700000005 (2023-11-14T22:13:25Z)
omdyZWNlaXB0pGpwYXltZW50X2lkeCQ1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDBndHhfaGFzaHcweHN0YXJrX2ZpeHR1cmVfdHhfaGFzaGxibG9ja19udW1iZXIaAJVSampzZXR0bGVkX2F0GmVT8QVqYWN0aW9uX3JlZpggEBjYGKMYjAEY2BhnGCEYdhiqGG4YUgkYoxhoGP0Y4xjhGIMWGEAY1hieFRgoGDEYQhizGFgYgBjCGME 197 CBOR bytes ; canonical CBOR (RFC 8949 deterministic encoding). Computed by
crates/zkpay-x402/examples/compute-fixture.rs
using ciborium 0.2 + vauban-zkpay-x402 0.1.0.
cargo test --package vauban-zkpay-x402 bound_receipt_interop_fixture 2>&1 | tail -3
Tamper evidence model
The CBOR envelope is deterministic: a conforming encoder (ciborium 0.2, RFC 8949
deterministic) always produces the exact same byte sequence from the same input.
Flipping any byte in bound_receipt_cbor_hex either causes CBOR
decode failure or yields a different action_ref ; the on-chain
receipt_core_hash no longer matches. There is no structurally valid
mutation that preserves the digest.
Two conformance failure cases are documented inline in the fixture JSON:
case 1 mutates the action_ref_preimage_jcs (breaks the work-proof
binding across all axes) ; case 2 mutates the CBOR payload directly (breaks the
STARK on-chain anchor). Both are independently detectable without contacting
any external service.
Cross-axis binding ; coalition fixture set
This vector shares payment_hash and action_ref verbatim
with the FeedOracle hybrid-PQC receipt (Axis 2) and the andysalvo action-ref-verify
vector 0008 (Axis 3). The FeedOracle coalition gist documents the shared anchor at
gist.github.com/feedoracle/704ab891170e2b43050f6f0ae00e6923.
Axis 1 is the settlement proof layer ; Axes 2 and 3 add post-quantum signature
integrity and work-receipt accountability over the same underlying payment event.
IETF I-D draft-vauban-x402-stark-receipts (submitted 2026-05-21)
is the normative specification governing the BoundReceipt<T>
encoding. The Vauban Rust crate is the 5th independent implementation in the
coalition cross-implementation matrix, complementing the Python, JS, Go, and Java
runners that pass the Axis 0 substrate vectors (53/53 + 37/37).
Fixture file
fixtures/x402-interop/vector-stark-vauban-pay-v1.jsonIn-tree ; verifiable offline
Apache 2.0. Authored by Vauban Pay as the 5th-impl contributor to the x402-foundation coalition fixture set. The CBOR encoding uses ciborium 0.2 (Rust). The Stwo Circle STARK M31 prover is a stub reference in this fixture ; the production proof path is wired in Sprint 3+4 of the vauban-zkpay roadmap.
Zero-Trust Receipt Verifier
Starknet SepoliaVerify a Vauban Pay receipt without trusting Vauban. Every cryptographic step runs in your browser ; the on-chain check calls Starknet directly. No server involved.
- 1 Edit the receipt in panel 01 Build — watch the hash recompute on every keystroke. Then hit Toggle Tamper Test to see how changing a single digit breaks the fingerprint.
- 2 Click "Verify on-chain" in panel 02 Verify — your browser queries the Starknet node directly and checks that the hash in the receipt matches what was recorded on-chain. No login, no API key.
- 3 See the proof chain in panel 03 Understand — a six-step diagram from raw JSON to on-chain event.
Want to verify your own receipt? Replace the JSON in panel 01 and the tx hash in panel 02 with your own values.
Zero-trust means no party needs to trust Vauban's servers. The verification is deterministic and reproducible by anyone with access to the JSON and the public Starknet Sepolia node.
keys[1] from the emitted event and compare with their locally computed felt252.Bounded-spend authorization fixture vectors
Three vectors from
fixtures/bounded-spend-authorization-sample/v0/vectors/
shipped at commit 1c35845. Each vector carries a
DelegationGrant and a SettlementReceipt
with pinned JCS hashes. Click "Reproduce" to recompute the hash
client-side and compare.
The DelegationGrant authorises the agent to spend up to 1 USDC per transaction and 100 USDC per 24-hour rolling period, with a single listed merchant, in USDC on Starknet Sepolia.
Hybrid post-quantum receipt
FeedOracle (@feedoracle) ; ES256K + ML-DSA-65 dual signature, FIPS 204, NIST IR 8547 transition-compliant
Both classical (ES256K, secp256k1 ECDSA) and post-quantum (ML-DSA-65, FIPS 204 lattice-based) signatures are required for receipt acceptance ; an attacker must defeat both simultaneously to forge a valid receipt. Both signatures cover identical JCS-canonical bytes derived via SHA-256(JCS(RFC 8785)(receipt_core)), ensuring deterministic, implementation-independent verification.
The receipt core is canonicalized once and shared between both signature schemes. This avoids ambiguity: one canonical byte string, two independent cryptographic commitments. Offline verification against a public JWKS requires no facilitator callback.
Cross-axis binding is achieved via the same payment_hash and
action_ref fields present in Axes 1, 3, and 4. A single mutation to
either value invalidates all axes simultaneously, making multi-axis tamper evidence
structurally guaranteed.
Nominal receipt core. Both ES256K and ML-DSA-65 signatures cover SHA-256(JCS(core)). Canonical baseline for cross-implementation comparison.
Field name substitution:
observed_at (RFC 3339 string) vs
observed_at_ms (epoch integer). Different canonical byte string
produces a divergent digest ; both signatures reject.
One byte flipped in the signed receipt core. Both ES256K and ML-DSA-65 signatures fail independently, demonstrating that tamper evidence holds against both classical and lattice-based verification paths.
Cross-layer binding. Carries the same
payment_hash (2ed186eb...0f580) and
action_ref (10d8a38c...0c2c1) as action-ref-verify
v0 vector 0008 (Axis 3) and the zkpay STARK set (Axis 1). One payment,
three axes, shared binding.
Regulatory alignment + cross-axis binding
ML-DSA-65 (FIPS 204, August 2024) is listed in NIST IR 8547 as an approved post-quantum algorithm for the NIST PQC transition. The EU PQC Roadmap (ANSSI, BSI Joint Position 2024) explicitly names ML-DSA as a priority migration target for digital signatures ; this axis demonstrates a concrete conformance fixture against that roadmap. The hybrid construction satisfies both the NIST transition requirement (ML-DSA primary) and classical backward compatibility (ES256K) during the migration window.
Cross-axis binding is structural: payment_hash and
action_ref are shared across Axes 1, 2, 3, and 4 of the coalition
fixture set. Axis 2 vector 0008 is the interoperability proof point for this
binding.
Source PR
x402-foundation/x402#2411FeedOracle JWKS (live)
tooloracle.io/.well-known/jwks.jsonkid: feedoracle-mldsa65-1, alg: ML-DSA-65, FIPS 204
Reproduce
pip install cryptography pqcrypto
Apache 2.0. Contributed by FeedOracle to the x402-foundation coalition fixture set.
Fixture structure follows the fixtures/<suite>/<version>/
convention established in PR #2398 (Axis 3, andysalvo). No changes to protocol code
or repo CI dependencies.
Work-receipt binding
andysalvo (@andysalvo) ;
action_ref = SHA-256(JCS(preimage)),
no ZK overhead, HTTP-client verifiable
The work-receipt axis is the simplest of the four coalition axes: a pure
32-byte SHA-256 digest of the JCS-canonicalised (RFC 8785) preimage object,
producing the action_ref that binds a payment to whatever the
agent produced after the payment was settled.
Deterministic by construction: the same preimage fields in any key order canonicalise to the same bytes, and the same bytes hash to the same 32-byte digest. Any HTTP client with a JSON parser and a SHA-256 primitive can reproduce and verify the digest independently, with no prover, no trusted setup, and no external dependency.
This axis defines the canonical action_ref value that the other
axes bind to: Axis 1 (STARK) includes it in the proof statement; Axis 2
(Hybrid-PQC) signs over the pair (payment_hash, action_ref).
One mutation to action_ref breaks the binding across all axes
simultaneously.
Vectors derived from action-ref-verify v0.3.0 (Apache-2.0, andysalvo). No code changes, no added dependencies, no CI modifications ; conformance data only. Reproducible by any SHA-256 + RFC 8785 implementation.
Axis 4 ; Composite trust-query
nobulex (@arian-gogani) ; tri-party composite envelope, multi-emitter evidence rows. Preimage algorithm: AlgoVoi (@chopmob-cloud).
The composite trust-query is the multi-stakeholder evidence envelope: one query
against (payment_hash, action_ref) returns N evidence rows, each from a
distinct emitter, each independently signed and framework-declared.
This is the composition-layer axis. Axes 0, 1, 2, 3 contribute rows. Axis 4 defines the envelope that assembles and binds them under a single query surface.
COMPOSITE ANCHOR
Both fields are present in every emitter row. They are the join key that makes the composite meaningful. A supervisor re-verifying at year 5 confirms all rows bind to the same anchor.
payment_hash
2ed186ebc66947eaac6a05a88c7bc096ee07ac11a2c44bb5580bd72b3670f580 action_ref (Axis 3)
10d8a38c01d8672176aa6e5209a368fde3e1831640d69e15283142b35880c2c1 Full tri-party response (vectors 0001/0002 ; identical composite digest despite row rotation)
Emitter 1 ; AlgoVoi
Compliance screening
Frameworks: UK MLR 2017, EU FSF, OFSI, OFAC.
~20ms p50, ~45ms p99. Session-level amortisation.
evidenceType: behavioral
Emitter 2 ; Vauban Pay
STARK proof-of-payment-conditions
Settlement chain: Starknet. Stwo Circle STARK M31 prover.
evidenceType: cryptographic
Emitter 3 ; nobulex (@arian-gogani)
Bilateral receipt
Schema: verascore-evidence-schema-v0.1.
Tri-party envelope author ; composite-layer co-design.
evidenceType: observational
Emitter 4 ; risk-check (anticipated)
AlexanderLawson17 / AlgoVoi production reference. AML/sanctions screen, session-scoped amortisation. Slots in as 4th emitter row; no envelope schema change required. Spec: x402 PR #2422.
Partial bi-party response (STARK row absent ; (payment_hash, action_ref) still anchors cleanly)
A composite query may return fewer rows than the declared emitter set.
The (payment_hash, action_ref) anchor is sufficient to
bind the partial composite. A policy evaluator marks the absent row as
PENDING or UNKNOWN rather than failing the query.
Emitter 1 ; AlgoVoi ; present
compliance-screening row ; ALLOW ; jurisdiction_flags: ["UK", "EU"]
Emitter 2 ; Vauban Pay ; absent (STARK prover timeout)
row status: PENDING ; policy decision at evaluator layer
Emitter 3 ; nobulex ; present
verascore-evidence-schema-v0.1 row ; observational evidence confirmed
sig fields are excluded from the preimage before hashing.
Attribution: AlgoVoi (@chopmob-cloud), x402 issue #2322.
Step 1 ; lexicographic sort of source_ids
[
"algovoi.compliance-screening",
"nobulex.verascore-evidence-schema-v0.1",
"vauban.stark-proof-of-payment-conditions"
]
Step 2 ; composite hash
SHA-256(JCS([row_algovoi, row_nobulex, row_vauban]))
Per-row sig fields are excluded from the preimage before hashing.
A verifier strips sig from each row, builds the sorted JCS array,
then recomputes the composite digest.
Structural rule ; for evidenceType: behavioral,
anchor_chains ⊆ contributing_chains is REQUIRED. A behavioral emitter
cannot anchor receipts on a chain it has not observed.
For evidenceType: regulatory or cryptographic, the anchor chain
is an independent infrastructure choice (per x402 PR #2322).
Vauban Pay MCP server
mcp.vauban.tech/pay/mcp exposes 4 MCP tools over StreamableHTTP.
Any MCP-compatible agent (Claude Code, CC/Preste SDK) can call them to run a
complete x402 payment cycle: DelegationGrant authorization, bounded-spend payment
emission, and cryptographic audit verification on Starknet Sepolia.
JWT Bearer auth via auth.vauban.tech (OAuth 2.1 PKCE). The server
declares its resource metadata at
/.well-known/oauth-protected-resource.
Supported scopes: pay:read, pay:write, pay:admin.
Tool registry
jcs_hashrequest_delegation_grantDelegationGrant authorization object with caps,
scope, and expiry. Returns the grant hash (JCS+SHA-256,
canon_version x402-jcs-v1.0.0).
make_paymentPaymentReceiptEmitted event and returns a
SettlementReceipt with tx_hash + Voyager link.
verify_receiptSettlementReceipt. Local JCS mode (receipt + expected_hash)
or on-chain mode (tx_hash): reads the Sepolia event, reconstructs the receipt,
computes JCS hash, returns audit-ready proof bundle.
Agent flow: 402 paywall → on-chain proof
.claude/settings.json or ~/.claude.json:
{
"mcpServers": {
"pay": {
"type": "http",
"url": "https://mcp.vauban.tech/pay/mcp"
}
}
} 402 Payment Required with x402 headers:
HTTP/1.1 402 Payment Required
X-Payment-Required: version=2,
network=starknet-sepolia,
recipient=0x044dd87a94a801c...,
amount=50000,
currency=USDC,
scope=api.vauban.tech/pay/data request_delegation_grant({
delegator: "0x005f4802...",
delegatee: "claude-code-agent",
scope:
"api.vauban.tech/pay/data",
expires_at:
"2026-05-23T04:00:00Z",
cap_per_tx: 100000,
cap_per_period: 1000000
}) {
"canon_version":
"x402-jcs-v1.0.0",
"grant_hash":
"a4f7e29b1c83d5f0...",
"grant_jcs_b64":
"eyJ0eXBlIjoiRGVs..."
} PaymentDemoEmitter.
make_payment({
amount: 50000,
currency: "USDC",
recipient:
"0x044dd87a...",
scope:
"api.vauban.tech/pay/data"
}) {
"status": "submitted",
"payment_hash":
"4eacfd4049ca47af...",
"tx_hash":
"0x02919a45344660ce...",
"voyager_url":
"https://sepolia.voyager.online/tx/0x02919a..."
} verify_receipt({ tx_hash: "0x02919a45344660ce..." })
// Result:
{
"verified": true,
"tx_hash":
"0x02919a45344660ce8ca9cbd5ecf96afbc56664c67d...",
"voyager_url":
"https://sepolia.voyager.online/tx/0x02919a...",
"on_chain_event": {
"receipt_core_hash":
"0x4eacfd4049ca47afc28a3c46d4d592d2e3237ca3...",
"payment_amount": "50000",
"currency_decoded": "USDC",
"timestamp_ms": "1779527515000",
"tx_emitter": "0x005f4802..."
},
"reconstructed_receipt": {
"type": "SettlementReceipt",
"canon_version": "x402-jcs-v1.0.0",
"network": "starknet-sepolia",
"contract_address": "0x044dd87a94a801cf..."
},
"computed_jcs_hash":
"sha256:4eacfd4049ca47afc28a3c46d4d592d2e3237ca3...",
"contract_address": "0x044dd87a..."
} receipt_core_hash from the on-chain event.
pay-mcp is a stateless StreamableHTTP MCP server (Node.js 22, TypeScript).
Chain mode activates when PAY_MCP_SEPOLIA_ACCOUNT_ADDRESS
and PAY_MCP_SEPOLIA_PRIVATE_KEY are set in the pod environment.
The Starknet signer uses an OZ account on Sepolia
(0x005f4802a628e6a5...)
to invoke PaymentDemoEmitter at
0x044dd87a94a801cf775d4c5e4b6703102d4e97e1cd1d0a8879341219ae4f19ff.
Settlement receipts are JCS-hashed per x402 LF spec and stored as
receipt_core_hash in the PaymentReceiptEmitted event.
Live Sepolia receipt
The first PaymentReceiptEmitted event on Starknet Sepolia.
The on-chain receipt_core_hash is SHA-256(JCS(receipt_core)).
Any buyer can re-derive the digest off-chain and compare against Voyager.
0x4048125390be67a16ae197be1fac1e6bd1fa04c4830b5db219be2e2e1090a4f https://sepolia.rpc.vauban.tech/rpc/v0_10Cross-axis binding
The four coalition axes share the same payment_hash and action_ref.
One mutation to either value breaks all axes simultaneously.
| Axis | Implementation | Bound field | Value (truncated) |
|---|---|---|---|
| Axis 0 ; Substrate | AlgoVoi (Go + Rust 5th-impl) | payment_hash | 2ed186eb...0f580 |
| Axis 1 ; STARK | Vauban (Rust, Stwo Circle STARK M31) | payment_hash + action_ref | payment_hash: 2ed186eb...0f580action_ref: 10d8a38c...0c2c1 |
| Axis 2 ; Hybrid-PQC | FeedOracle (Python, ES256K + ML-DSA-65) | payment_hash + action_ref | payment_hash: 2ed186eb...0f580action_ref: 10d8a38c...0c2c1 |
| Axis 3 ; Work-receipt | andysalvo (Node.js, RFC 8785 JCS) | action_ref | 10d8a38c...0c2c1 |
Bounded-spend fixture vectors bind to this same payment_hash /
action_ref pair via the cross_axis_binding field.
The Axis 1 core digest is referenced in each vector's
settlement_receipt.evidence.intent_proof_ref.claim_hash.