Skip to content

Routing Contracts

The routing contract is the central contribution of Directory. Rather than returning a static wallet address, the DRS returns a signed document describing how value should be delivered. This document is intentionally short-lived.

Structure

{
"address": "alice@gmail.com",
"routes": [
{
"value_type": "USDC",
"transfer_type": "ethereum",
"destination": "0xABC123...",
"ttl_seconds": 300
},
{
"value_type": "ETH",
"transfer_type": "ethereum",
"destination": "0xABC123...",
"ttl_seconds": 300
}
],
"issued_at": "2026-03-08T12:00:00Z",
"expires_at": "2026-03-08T12:05:00Z",
"signature": "base64-encoded-ed25519-signature"
}

Fields

FieldTypeDescription
addressstringThe Directory address that was resolved (normalized)
routesarrayOne or more delivery routes
routes[].value_typestringWhat is being transferred
routes[].transfer_typestringHow it moves
routes[].destinationstringWhere to send it (transfer-type-specific)
routes[].ttl_secondsintegerRoute validity, 30–3600
issued_atstring (RFC 3339)Contract creation timestamp
expires_atstring (RFC 3339)Contract expiry timestamp
signaturestringBase64-encoded Ed25519 signature

Unknown top-level fields MUST be signed alongside the known fields and MUST be preserved by clients (forward compatibility).

Limits

  • routes MUST contain between 1 and 32 entries.
  • ttl_seconds MUST be 30–3600.
  • Contract body MUST be <= 64 KiB.
  • issued_at MUST NOT be more than 60 s in the future relative to the verifier’s clock.
  • expires_at MUST NOT be more than 60 s in the past relative to the verifier’s clock.

Canonicalization and Signing

Contracts are signed using Ed25519 over a canonical JSON serialization produced by RFC 8785 JSON Canonicalization Scheme (JCS):

  1. Remove the signature field.
  2. Canonicalize the remaining object with JCS (lexicographic key ordering, number canonicalization, no whitespace).
  3. Sign the resulting UTF-8 bytes with the domain’s Ed25519 private key.
  4. Base64-encode the signature and return the complete contract.

Non-finite numbers (NaN, ±Infinity) are forbidden. undefined values are stripped before canonicalization.

Verification Rules

Clients MUST:

  1. Canonicalize the received contract with JCS, excluding signature.
  2. Verify the Ed25519 signature against each Ed25519 key published at _drskey.<domain> until one succeeds.
  3. Reject the contract if no key verifies.
  4. Reject the contract if issued_at is too far in the future or expires_at is too far in the past (±60 s tolerance).
  5. On verification failure, re-fetch DNS records once and retry — this handles key-rotation overlap without breaking senders in flight.

TTL

Short TTLs prevent replay and ensure stale instructions cannot misdirect value after the recipient changes their routing. Typical values are 60–300 seconds. The protocol requires 30–3600.

Destination Patterns

The destination in a routing contract may be:

  • Direct wallet address — the recipient’s own wallet or a proxy managed by the operator.
  • Temporary deposit address — generated per transaction, expires with the TTL.
  • Payment endpoint — an HTTPS endpoint for initiating the transfer.

What the destination is — that’s the operator’s decision. The sender follows the contract.