A2A Extension: Substrate Receipts (Maya v1)
Status: Draft v1 — 2026-05-18
Extension URI: https://projectmaya.deoscomputing.io/a2a/ext/substrate-receipts/v1
Maintainer: DEOS Computing (did:web:deos.computing)
Depends on: A2A v1.0 (a2a-protocol.org); a Maya-style trust substrate (Ed25519-signed, MMR-anchored append log)
1. Motivation
A2A v1.0's Task carries a history array and a status.timestamp. Neither survives a dispute: history lives on the server and can be rewritten, and there's no external timestamp anchor.
A Maya-style trust substrate (Ed25519-signed receipts in a Merkle Mountain Range, with optional OpenTimestamps → Bitcoin anchoring) is the missing primitive: signed, append-only, externally verifiable. This extension carries that receipt through A2A responses so clients can verify durably — months later, against a Bitcoin block, with no callback to the original server.
2. Wire format
2.1 Agent Card declaration
A server advertises receipt-extension support in its Agent Card:
{
"extensions": [
"https://projectmaya.deoscomputing.io/a2a/ext/substrate-receipts/v1"
],
"substrate_receipts": {
"substrate_url": "https://substrate.amazon.com",
"issuer_did": "did:web:substrate.amazon.com",
"tree_id": "amazon-prod",
"trust_root_url": "https://substrate.amazon.com/attestation/v1/trust-root",
"anchor_targets": ["opentimestamps-bitcoin"]
}
}
Fields under substrate_receipts:
substrate_url— HTTPS root for the issuer's substrate (where/attestation/v1/...endpoints live). Required.issuer_did— DID of the substrate's signing key. Required. Clients use this to verify receipt signatures.tree_id— namespace identifier within the substrate. Required.trust_root_url— full URL where the trust-root JSON is fetched. Required.anchor_targets— optional array of external anchor systems the substrate writes to. Recognized values:opentimestamps-bitcoin,ethereum-l1,ethereum-l2. Servers MAY include their own URIs for proprietary anchors.
2.2 Receipt envelope on responses
When a Task reaches COMPLETED (or FAILED with a partial outcome), the server MUST attach the substrate receipt to the response Message or Artifact via the extensions map:
{
"messageId": "msg-9c7a…",
"role": "ROLE_AGENT",
"parts": [{ "type": "text", "text": "Order placed: $87.99 charged to card ending 4242." }],
"extensions": {
"https://projectmaya.deoscomputing.io/a2a/ext/substrate-receipts/v1#receipt": {
"receipt_id": "eee9348b43c82413e9159dbd4bd5bfb1dfdfe23db9edc6685ad41bd322bf4687",
"leaf_index": 411,
"log_root": "17117667799da2ced88ae7cda3baa109a0525f7f411ef0b68db4c1e759a348b7",
"issuer_did": "did:web:substrate.amazon.com",
"tree_id": "amazon-prod",
"action_can": "commerce.purchase",
"issued_at_ns": 1747576123000000000,
"inclusion_proof_url": "https://substrate.amazon.com/attestation/v1/proof/eee9348b…",
"anchor": {
"kind": "opentimestamps-bitcoin",
"status": "pending",
"ots_proof_url": "https://substrate.amazon.com/attestation/v1/anchor/17117667…"
}
}
}
}
Fields:
receipt_id— substrate's unique receipt identifier (hex). Required.leaf_index— position in the MMR. Required.log_root— MMR root at the time of inclusion. Required.issuer_did— substrate signer DID. Required; MUST match the Agent Card's declaration.tree_id— namespace; MUST match Agent Card. Required.action_can— the capability that authorized this action (mirrors the UCAN'swith). Required.issued_at_ns— nanosecond Unix timestamp. Required.inclusion_proof_url— URL where the client can fetch the Merkle inclusion proof. Required.anchor— optional. Anchor state:kind— one of the declaredanchor_targets.status—pending|confirmed|failed.ots_proof_url(for OTS-style anchors) — URL where the OTS proof bytes can be fetched.block_height,tx_hash,confirmations— populated oncestatus == "confirmed".
2.3 Receipt envelope on streaming updates
For streaming tasks (SendStreamingMessage / SubscribeToTask), each TaskArtifactUpdateEvent that emits a finalized artifact MUST include the receipt in artifact.extensions under the same key. Intermediate TaskStatusUpdateEvents SHOULD NOT include receipts unless the status itself is a signed action.
2.4 Push notifications
If push notification configs are in use, the webhook payload MUST include the receipt extension in the embedded Task / Artifact per §2.2.
3. Client verification
A v1 client receiving a receipted response MUST be able to:
- Fetch the substrate's trust-root via
trust_root_url. Verify the response's signature chains to the declaredissuer_did. - Verify the receipt signature against the trust-root public key.
- Fetch the inclusion proof via
inclusion_proof_url. Verify the leaf hash is included inlog_root. - If
anchor.status == "confirmed", fetch the anchor proof and verify thelog_rootis committed in the named external system (Bitcoin block, Ethereum tx, etc).
A v1 client MUST NOT trust the receipt without at least steps 1–3. Step 4 is required for "Bitcoin-Confirmed" presentation; until then the receipt is "Substrate-Signed" only.
4. Anchor lifecycle
Anchors are asynchronous by design. The order of operations:
- Server appends the action to its substrate. Returns a receipt with
anchor.status == "pending"(or omitsanchor). - The server's anchor worker submits the current MMR root to OTS or another anchor target.
- OTS aggregates and commits to Bitcoin. Block confirmation: ~10 minutes.
- The worker polls until the OTS upgrade is available, then writes the proof back to the substrate.
- A client refetching the receipt (or polling
inclusion_proof_url) seesanchor.status == "confirmed".
Clients SHOULD NOT block on confirmation. Receipts typically reach Bitcoin within an hour; until then, the substrate-signed receipt is sufficient for every use case except the strongest dispute resolution.
5. Privacy
Receipts include action_can and timestamps in cleartext. The substrate seals the rich metadata field (X25519 encrypt-at-rest, per Maya substrate spec) so the receipt body is only legible to holders of the principal's decryption key. Servers using this extension SHOULD NOT include user-identifying content in the cleartext receipt fields.
6. Conformance
A v1 server MUST:
- Declare the extension URI in its Agent Card.
- Attach the receipt envelope to every
COMPLETEDTask response and every finalized Artifact streaming event. - Provide working
trust_root_urlandinclusion_proof_urlendpoints.
A v1 server SHOULD:
- Run a deferred-anchor worker that progresses pending receipts to
confirmedwithin 1 hour. - Honor
If-None-Match/ETagontrust_root_urlso clients can cache.
A v1 client MUST:
- Verify steps 1–3 (signature, trust-root chain, inclusion proof) before treating a receipt as authoritative.
- Surface anchor status to the user transparently — never claim "Bitcoin-Confirmed" while
status != "confirmed".
7. Composing with UCAN extension
When a server advertises BOTH this extension and …/ucan/v1, the receipt SHOULD include a UCAN reference for full audit:
"extensions": {
"https://projectmaya.deoscomputing.io/a2a/ext/substrate-receipts/v1#receipt": {
"receipt_id": "…",
"ucan_chain_cids": [
"bafyreig…", // leaf (the UCAN this action invoked)
"bafyreih…", // proof
"bafyreij…" // root (user's principal)
],
"..."
}
}
ucan_chain_cids is one CID per UCAN in the verified chain. Clients fetch each by CID (IPFS, local cache, or the substrate's CAS) to reconstruct the authorization chain. The combination is a full audit trail: who authorized what, what action ran at time T, here is the Bitcoin block proving T.
8. Reference implementations
maya-runtime— builds receipts and embeds them in A2A responses.- Maya substrate — serves trust-root, inclusion proofs, anchor status.
- Anchor worker — drives
pending → confirmedonce OTS commits to Bitcoin.
All three live in DEOS Computing's working repo, access-controlled during v1 alpha.
9. Versioning
…/substrate-receipts/v1 is immutable. Breaking changes land at …/v2; v1 stays alive per A2A's backward-compatibility rules.