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
| Field | Type | Description |
|---|---|---|
address | string | The full Directory address that was resolved |
routes | array | All delivery routes for the address |
routes[].value_type | string | What is being transferred |
routes[].transfer_type | string | How it moves |
routes[].destination | string | Where to send it (address on the transfer type) |
routes[].ttl_seconds | integer | How long this route is valid (30–3600 seconds) |
issued_at | string | ISO 8601 timestamp of contract creation |
expires_at | string | ISO 8601 timestamp of contract expiry |
signature | string | Base64-encoded Ed25519 signature |
Layer Separation
Routing contracts contain only delivery routes. They never contain:
- Sponsors
- References
- Asset metadata
Those belong in the capability manifest. This separation ensures that the routing contract is a minimal, focused delivery instruction. It is enforced in the JSON schemas and tested.
Signing
Contracts are signed using Ed25519 over a canonical JSON serialization:
- Remove the
signaturefield from the contract - Serialize to canonical JSON (sorted keys, no whitespace)
- Sign the resulting bytes with the domain’s Ed25519 private key
- Base64-encode the signature
The public key for verification is published in DNS at _drskey.{domain}.
Verification Rules
Clients must:
- Verify the Ed25519 signature against the DNS-published public key
- Check that
expires_athas not passed - Reject contracts with invalid signatures
- Reject expired contracts
- Re-fetch the DNS key once on verification failure (handles key rotation)
TTL
Every route includes a TTL, typically between 30 and 300 seconds. Short TTLs prevent replay attacks and ensure stale instructions cannot misdirect value after the recipient changes their routing.
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.