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:

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:

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:

  1. Fetch the substrate's trust-root via trust_root_url. Verify the response's signature chains to the declared issuer_did.
  2. Verify the receipt signature against the trust-root public key.
  3. Fetch the inclusion proof via inclusion_proof_url. Verify the leaf hash is included in log_root.
  4. If anchor.status == "confirmed", fetch the anchor proof and verify the log_root is 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:

  1. Server appends the action to its substrate. Returns a receipt with anchor.status == "pending" (or omits anchor).
  2. The server's anchor worker submits the current MMR root to OTS or another anchor target.
  3. OTS aggregates and commits to Bitcoin. Block confirmation: ~10 minutes.
  4. The worker polls until the OTS upgrade is available, then writes the proof back to the substrate.
  5. A client refetching the receipt (or polling inclusion_proof_url) sees anchor.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:

A v1 server SHOULD:

A v1 client MUST:

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

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.