decentrl.
Mediators

Command Protocol

The wire format, replay protection, and real-time delivery mechanisms of the mediator protocol.

Formal spec: DCTRL-0004 — Mediator Protocol defines all commands, wire formats, error codes, and the WebSocket protocol.

Command Wire Format

All commands follow a uniform structure — a signed envelope with a header, payload, and Ed25519 signature:

{
  "header": {
    "channel": "DIRECT_AUTHENTICATED | TWO_WAY_PRIVATE",
    "sender_did": "did:decentrl:...",
    "sender_signing_key_id": "did:decentrl:...#signing",
    "recipient_did": "did:decentrl:...",
    "timestamp": 1699123456000,
    "nonce": "550e8400-e29b-41d4-a716-446655440000"
  },
  "payload": { },
  "signature": "<Ed25519 over canonical JSON of { header, payload }>"
}

The signature is computed over canonical JSON — keys are deep-sorted and the string is UTF-8 encoded before signing. This ensures deterministic verification regardless of JSON serialization order.

Replay Protection

Every command carries a UUID nonce and a millisecond-precision timestamp. Mediators enforce two protections:

  1. Timestamp drift window — commands with timestamps outside a 5-minute window are rejected
  2. Nonce deduplication — seen nonces are stored and duplicates are rejected

Together, these prevent both replay attacks and nonce reuse.

Real-Time Delivery via WebSocket

Mediators support WebSocket connections for push-based event delivery:

1. Client connects via WebSocket
2. Client sends authentication:
   {
     type: AUTHENTICATE,
     did: "did:decentrl:...",
     signing_key_id: "did:decentrl:...#signing",
     timestamp: 1699123456000,
     nonce: "...",
     signature: "<Ed25519>"
   }
3. Mediator verifies: timestamp drift < 5 min, resolves DID, verifies signature, checks registration
4. Mediator responds: { type: AUTH_SUCCESS }
5. On new events: mediator pushes { type: PENDING_EVENTS, events: [...] }

This eliminates polling. The mediator pushes notifications for new pending events, contract updates, and other state changes in real time.

HTTP API

For clients that don't maintain persistent connections, mediators expose a standard HTTP API. Each command is a POST request with the signed envelope as the body. The mediator responds with the result.

Both HTTP and WebSocket use the same command format and the same authentication model — the only difference is the transport.