Transports¶
Signing (claudeway.signing) is
independent of transport. A ConsensusReceipt is a canonical, signed
payload; the transports below render that same receipt into a wire format
downstream systems consume. Change transports without re-signing.
| Transport | Wire format | Where it lands | When to use |
|---|---|---|---|
| JSON receipt | Plain JSON | Files, logs, HTTP bodies, anything | Default. Simplest verifiable artifact. |
| W3C Verifiable Credential | VC v2.0 envelope | W3C-aligned identity/attestation systems | When the consumer follows W3C VC/DID conventions (the direction the W3C AI Agent Protocol CG is standardizing on). |
| Nostr NIP-78 event | kind: 30078 addressable event, BIP-340 Schnorr signature |
Any Nostr relay — including Buzz rooms | When consensus should land in a room agents already monitor. Buzz interop. |
Why three¶
There is no single "right" wire format for an agent attestation. The W3C community is converging on Verifiable Credentials for agent identity; Nostr is the dominant open-protocol transport for real-time agent rooms; and a plain JSON receipt is the lowest-common-denominator any system can ingest.
Hardwiring any one of these would force a rewrite. Claudeway's
SignatureBackend ABC signs the canonical payload once; each transport only
decides how that signed payload is wrapped for the wire.
JSON receipt¶
The simplest verifiable artifact. to_json_receipt produces a self-contained
JSON document carrying the receipt payload, signature, and public key. Anyone
holding the document can verify integrity later.
from claudeway.transports import to_json_receipt
doc = to_json_receipt(receipt) # -> dict ready for json.dumps
Use this when:
- You're persisting receipts in a database, object store, or audit log.
- You're returning consensus over HTTP from your own service.
- You don't need to interop with W3C VC consumers or Nostr relays.
W3C Verifiable Credential¶
Renders the signed receipt as a W3C VC v2.0-compatible envelope. The receipt's payload becomes the credential subject; the signature is referenced as the proof.
This is the format the W3C AI Agent Protocol Community Group is standardizing on for agent attestation. If you're building on a W3C-aligned identity stack (DIDs, verifiable credentials, presentation exchanges), this is the transport that fits.
Nostr NIP-78 event¶
Renders the signed receipt as a NIP-78 addressable application data event:
kind: 30078— NIP-78 addressable app data.- BIP-340 Schnorr signature over
sha256of the NIP-01 event serialization, computed over secp256k1. contentcarries the signed JSON receipt — any Nostr client can decode and verify it.
from claudeway.transports import to_nostr_event
event = to_nostr_event(receipt, private_key_hex=nostr_key, d_tag="room-42")
# event.kind == 30078
# event.sig is BIP-340 Schnorr
# publish to any Nostr relay
The events Claudeway produces verify clean under nak
(the reference Nostr CLI) and round-trip through nak serve — publish,
subscribe, read back, receipt signature still verifies. See
TESTLOG.md
for the four-layer evidence trail (BIP-340 KAT, test suite, nak verify,
end-to-end demo).
Nostr requires an extra¶
The Nostr path needs secp256k1 + BIP-340 Schnorr, which requires a native library. Install the extra:
coincurve ships prebuilt wheels for
CPython 3.11–3.13 on Windows, Linux, and macOS. The import is lazy — pip
install claudeway (without the extra) stays lean and never touches
secp256k1.
Designing your own transport¶
to_json_receipt, to_verifiable_credential, and to_nostr_event are
plain functions over a ConsensusReceipt. If you need a different wire
format (CBOR, a custom envelope, an internal protobuf), the pattern is:
- Get the canonical payload via
receipt.payload(already canonicalized for signing — don't re-serialize from scratch or you'll break signature verification). - Render it into your wire format.
- Carry
receipt.signatureandreceipt.public_keyalongside so a downstream verifier can callEd25519Backend().verify_receipt(receipt).
The signing layer never has to change.