Skip to content

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 When consensus should be globally verifiable on the open Nostr network.

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 sha256 of the NIP-01 event serialization, computed over secp256k1.
  • content carries 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:

pip install claudeway[nostr]

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:

  1. Get the canonical payload via receipt.payload (already canonicalized for signing — don't re-serialize from scratch or you'll break signature verification).
  2. Render it into your wire format.
  3. Carry receipt.signature and receipt.public_key alongside so a downstream verifier can call Ed25519Backend().verify_receipt(receipt).

The signing layer never has to change.

NEWELL