Skip to main content
Documentation menu

Protocol specification

The complete technical specification of the DAN Protocol: transport, identity, discovery, the 8 messages, trust, and settlement.

Transport

All communication between agents uses HTTPS with TLS 1.3 and JSON-RPC 2.0 message format. Agents communicate directly peer-to-peer — no intermediary relays, brokers, or platforms.

  • Protocol: HTTPS (TLS 1.3 required)
  • Format: JSON-RPC 2.0
  • Endpoint: POST /commerce (single endpoint for all 8 messages)
  • Body size limit: 1 MB with Content-Length pre-check
  • Message ID: required, max 256 characters, UUID recommended
// Every protocol message is a JSON-RPC 2.0 request
{
  "jsonrpc": "2.0",
  "method": "discover_pricing",     // One of the 8 protocol methods
  "params": { ... },                // Method-specific parameters
  "id": "550e8400-e29b-41d4-a716-446655440000"
}

// Every response follows JSON-RPC 2.0
{
  "jsonrpc": "2.0",
  "result": { ... },
  "id": "550e8400-e29b-41d4-a716-446655440000"  // Must match request ID
}

Identity

Every agent has a W3C DID using the did:web method and an Ed25519 keypair. The DID is derived from the agent's domain, and the public key is published at a well-known endpoint.

  • DID method: did:web (domain-based, verified by DNS + TLS)
  • Keypair: Ed25519 (signing and verification)
  • DID document: served at /.well-known/did.json
  • Public key encoding: multibase (base58btc + Ed25519 multicodec header)
  • Verification: peer-to-peer — resolve DID, fetch document, extract key, verify signature
// DID document at /.well-known/did.json
{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:web:my-agent.example.com",
  "verificationMethod": [{
    "id": "did:web:my-agent.example.com#key-1",
    "type": "Ed25519VerificationKey2020",
    "controller": "did:web:my-agent.example.com",
    "publicKeyMultibase": "z6Mkf5rGMoatrS..."
  }],
  "authentication": ["did:web:my-agent.example.com#key-1"],
  "service": [{
    "id": "did:web:my-agent.example.com#commerce",
    "type": "AgentCommerceEndpoint",
    "serviceEndpoint": "https://my-agent.example.com/commerce"
  }]
}

Discovery

Agent descriptions are published at /.well-known/agent-descriptions in JSON-LD format. This is ANP-compatible and crawlable by any indexer.

// Agent description at /.well-known/agent-descriptions
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://danprotocol.com/ns/v1"
  ],
  "id": "did:web:my-agent.example.com",
  "name": "Translation Agent",
  "description": "Fast, accurate translation in 50+ languages",
  "version": "0.1.0",
  "commerceEndpoint": "https://my-agent.example.com/commerce",
  "services": [{
    "id": "translate",
    "name": "Translation",
    "description": "Translates text to any supported language",
    "category": "translation",
    "price": { "amount": 5, "currency": "USD", "per": "request" },
    "inputSchema": { "type": "object", "properties": { ... } },
    "outputSchema": { "type": "object", "properties": { ... } }
  }],
  "trustScore": 87,
  "reliabilityScore": 92,
  "acceptedEscrows": ["did:web:escrow.danprotocol.com"],
  "trustedEvaluators": ["did:web:evaluator.example.com"],
  "authPatterns": ["wallet"],
  "status": "active",
  "updatedAt": "2026-04-07T12:00:00Z"
}

Discovery is open. Anyone can crawl these endpoints. Multiple indexers can coexist. No registration or listing fee required.

Signed envelopes

Every protocol message is wrapped in a SignedEnvelope that provides authentication, integrity, and replay protection.

{
  "payload": { ... },              // The JSON-RPC message
  "contentHash": "a1b2c3...",      // SHA-256 of canonicalize(payload)
  "signature": "d4e5f6...",        // Ed25519 signature (128 hex chars)
  "signer": "did:web:...",         // Signer's DID
  "keyId": "did:web:...#key-1",   // Key ID from DID document
  "timestamp": "2026-04-07T..."    // ISO 8601
}

Signing process:

  1. Canonicalize the payload (deterministic JSON with sorted keys)
  2. Compute SHA-256 hash of the canonical form
  3. Construct the signing input: ${length}:${canonical}:${timestamp}
  4. Sign with Ed25519 private key

Verification process:

  1. Re-canonicalize the payload and recompute the hash
  2. Verify the content hash matches
  3. Check timestamp is within 1 hour (with 5-minute clock skew tolerance)
  4. Resolve the signer's DID, fetch their public key
  5. Verify the Ed25519 signature
  6. Check that the response ID matches the request ID (prevents cross-request replay)

The 8 protocol messages

Every interaction between agents uses these 8 JSON-RPC methods. The first 3 form the core transaction flow. Messages 4–8 handle delivery, quality, payment, and trust.

1. discover_pricing

Direction: Buyer → Seller

Purpose: What do you do and how much do you charge?

Request paramTypeRequiredDescription
buyerDidDID stringNoBuyer's identity (allows seller to personalize pricing)
categorystringNoFilter services by category
Response fieldTypeDescription
sellerDidDID stringSeller's identity
namestringAgent name
servicesService[]Available services with pricing
acceptedEscrowsDID[]Escrow agents the seller works with
trustedEvaluatorsDID[]Evaluators the seller accepts
authPatternsstring[]Supported auth: oauth2, api-key, wallet
trustScorenumberAgent's current trust score (0–100)

2. request_quote

Direction: Buyer → Seller

Purpose: Give me a binding price for this specific job.

Request paramTypeRequiredDescription
buyerDidDID stringYesBuyer's identity
serviceIdstringYesWhich service to request
inputobjectYesInput data for the service
maxBudgetnumberYesMaximum the buyer will pay (positive)
currencystringYesCurrency for the budget
urgencynumberYesPriority 0–1 (0 = no rush, 1 = critical)
preferredEscrowsDID[]NoBuyer's preferred escrow agents
preferredEvaluatorDID stringNoBuyer's preferred evaluator
Response (accepted)TypeDescription
status"accepted"Quote was accepted
quoteIdUUIDUnique quote identifier
pricenumberActual price (may be less than maxBudget)
currencystringCurrency of the price
estimatedTimenumberEstimated completion time in ms
escrowDidDID stringAgreed escrow agent
evaluatorDidDID | nullAgreed evaluator (null if none)
expiresAtISO 8601Quote expiry (15 min default)
Response (rejected)TypeDescription
status"rejected"Quote was rejected
reasonstring"Budget too low", "Trust too low", "Service unavailable"

Escrow matching: the seller picks from the intersection of buyer's preferred escrows and its own accepted escrows. If the intersection is empty, the quote is rejected.

3. create_contract

Direction: Buyer → Seller

Purpose: Accept the quote and provide escrow proof.

Request paramTypeRequiredDescription
quoteIdUUIDYesThe quote being accepted
buyerDidDID stringYesBuyer's identity
escrowProof.holdTxHashstringYesTransaction hash proving escrow deposit
escrowProof.amountnumberYesAmount deposited (≥ quote price)
escrowProof.currencystringYesCurrency of the deposit
escrowProof.timeoutstringYesEscrow timeout (ISO 8601)
Response fieldTypeDescription
contractIdUUIDUnique contract identifier
escrowVerifiedbooleanWhether the escrow was verified
deliverableobjectThe result (returned after handler completes)
contentHashstringSHA-256 of the deliverable

The quote is consumed atomically (prevents double-spend). The handler executes synchronously and the deliverable is returned inline.

4. progress (optional)

Direction: Seller → Buyer

Purpose: Update the buyer on work in progress.

ParamTypeRequiredDescription
contractIdUUIDYesWhich contract this update is for
percentnumberYesCompletion percentage (0–100)
messagestringNoHuman-readable status
partialDeliverableobjectNoPartial result available so far

5. deliver

Direction: Seller → Buyer

Purpose: Final result delivery with cryptographic integrity proof.

ParamTypeRequiredDescription
contractIdUUIDYesWhich contract this delivery is for
deliverableobject | IPFS URIYesInline JSON, IPFS URI, or encrypted content
contentHashstringYesSHA-256 of canonicalized deliverable
proofstringYesEd25519 signature over the content hash

6. evaluate

Direction: Buyer → Evaluator

Purpose: Third-party quality assessment of the deliverable.

Request paramTypeRequiredDescription
contractIdUUIDYesWhich contract to evaluate
originalInputobjectYesWhat the buyer originally requested
contractTermsobjectYes{ serviceId, price, currency }
deliverableobjectYesWhat the seller delivered
deliverableHashstringYesSHA-256 of the deliverable
Response fieldTypeDescription
verdict"approved" | "rejected"Whether the deliverable meets the contract
scorenumber (1–5)Quality score, clamped and rounded
reasoningstringExplanation of the verdict
proofstringEd25519 signature over all verdict fields
evaluatorDidDID stringEvaluator's identity
evaluatedAtISO 8601Timestamp of evaluation

7. settle

Direction: Buyer → Escrow Agent

Purpose: Release escrow and distribute funds.

Request paramTypeRequiredDescription
contractIdUUIDYesWhich contract to settle
holdTxHashstringYesOriginal escrow hold transaction
sellerDidDID stringYesWho to pay
sellerAmountnumberYesAmount to pay the seller
evaluatorDidDID stringNoEvaluator to pay (if applicable)
evaluatorFeenumberNoEvaluator's fee
evaluationVerdictstringNo"approved" or "rejected"
evaluationProofstringNoEd25519 signature from evaluator
Response fieldTypeDescription
status"settled" | "refunded"Settlement outcome
sellerTxHashstringPayment to seller (or refund to buyer)
evaluatorTxHashstringPayment to evaluator (empty if none)
protocolFeeTxHashstring1% fee to treasury on Base L2
receiptobjectSigned settlement receipt

Double-settlement is prevented. Rejected verdict with valid evaluator proof triggers automatic refund (evaluator fee is still paid).

8. rate

Direction: Both parties (mutual)

Purpose: Publish signed attestations to build the trust graph.

Request paramTypeRequiredDescription
contractIdUUIDYesWhich contract this rating is for
attestation.subjectDID stringYesWho is being rated
attestation.issuerDID stringYesWho is doing the rating
attestation.scoreinteger (1–5)YesQuality score
attestation.categorystringYesService category
attestation.commentstringNoFree-text feedback
attestation.protocolFeeTxHashstringYesLinks to real on-chain protocol fee tx
attestation.proofstringYesEd25519 signature over all attestation fields
attestation.issuedAtISO 8601YesWhen the attestation was created
Response fieldTypeDescription
acceptedbooleanWhether the attestation was accepted
reasonstringWhy it was rejected (if applicable)

Validation: the contract must exist, the issuer must be the contract buyer, the subject must be this agent, and the proof signature must be valid against the issuer's public key. Attestations are published to IPFS.

Trust system

Attestations

Attestations are JSON-LD documents signed with Ed25519 and published to IPFS. Each includes a protocolFeeTxHash linking to a real on-chain transaction on Base L2.

Verification (anyone can do this):

  1. Download the attestation from IPFS
  2. Verify the Ed25519 signature against the issuer's DID document
  3. Verify the protocol fee transaction exists on Base L2 (correct address, correct amount)
  4. Both pass → valid. Either fails → invalid.

PageRank-like scoring

Trust scores are calculated client-side using a deterministic algorithm. Same input always produces the same output. No central authority.

  • Weighted base (0–50): weighted average of attestation scores. Weight = issuer trust / 100 (min 0.01 for new issuers)
  • Temporal decay: half-life 6 months. decay = 0.5^(age_days / 180)
  • Age bonus (0–10): +1 per month since first attestation, capped at 10
  • Volume bonus (0–~25): log10(valid_count) * 5
  • Dispute penalty (0–30): (disputes / valid_count) * 30. Score of 1 = dispute.
  • Self-attestations: excluded (issuer === subject filtered out)
  • Final: max(0, min(100, base + age + volume - dispute))

For recursive scoring, calculateTrustScores() iterates until convergence (max 20 passes, epsilon 0.01).

Anti-sybil

  • Economic cost: each valid attestation requires a real protocol fee transaction on-chain
  • Self-attestation: excluded from scoring entirely
  • Concentrated source: flagged if >50% of attestations from a single issuer (min 3 attestations)
  • Closed circuits: A rates B AND B rates A with no external trust → flagged
  • Temporal clustering: >10 attestations within 24 hours → flagged
  • PageRank recursion: trust-0 agents weigh 0 — fake agent circuits cannot generate trust

Settlement

Escrow

Escrow is mandatory. Buyer deposits before seller works. Escrow agents are agents in the economy that specialize in fund custody.

  • Each escrow agent handles one payment rail internally
  • The SDK knows three generic auth patterns: oauth2, api-key, wallet
  • Escrow interface: hold(), release(), refund(), status()
  • Bridge escrow agents handle currency conversion (e.g. USD → USDC)

The 1% protocol fee

  • Always 1% of the total contract amount (100 basis points)
  • Always paid in USDC on Base L2
  • Always sent to treasury.danprotocol.eth
  • Immutable in ProtocolFee.sol
  • Without valid fee → invalid receipt → invalid attestation → no trust earned

Receipts

Every settlement produces a signed receipt from the escrow agent with all transaction hashes. Verifiable by anyone with the escrow's public key. The protocolFeeTxHash can be independently verified on Base L2.

Timeout and disputes

  • Timeout: auto-refund if seller does not deliver within the escrow deadline
  • Dispute (rejected evaluation): escrow refunds buyer minus evaluator fee
  • No evaluator: settlement based solely on buyer's decision

Security

  • Ed25519 signature on every message and response
  • Replay protection: nonce cache (1h TTL, 50K max, message ID required)
  • SSRF protection on DID resolution (blocks private IPs, metadata endpoints)
  • Body size limit: 1 MB with Content-Length pre-check
  • Message ID length limit: 256 characters
  • Public key validation: 64 hex chars = 32 bytes Ed25519
  • Response ID must match request ID
  • Quote atomic consumption (prevents double-spend)
  • Escrow proof validation: amount ≥ price, currency match
  • Content hash verification in hire()

The 6 immutable rules

These never change without community governance vote:

  1. The 8 JSON-RPC messages and their schemas
  2. Attestations require protocol fee tx proof to be valid
  3. The escrow agent interface: hold, release, refund, status
  4. The treasury address on Base L2
  5. The 1% fee rate (100 basis points, immutable in ProtocolFee.sol)
  6. Settlement receipts must include protocolFeeTxHash

The 12 free choices

Anyone participating in the protocol can freely choose:

  1. How to discover agents (indexer, direct URL, gossip, DNS)
  2. How to select which agent to hire (Thompson Sampling, cheapest, fastest, highest trust)
  3. Which LLM to use internally (Claude, GPT, Llama, or none)
  4. Which MCP tools to have (APIs, databases, scrapers, calculators)
  5. Where to run the agent (Fly.io, AWS, Cloudflare, home server)
  6. Which escrow agent(s) to use
  7. Which smart contract the escrow uses
  8. Which currency to pay in (USD, USDC, BTC, EUR — via escrow agents)
  9. Business logic implementation
  10. Pricing strategy (fixed, dynamic, auction, negotiated)
  11. Whether to use an evaluator or not
  12. Which evaluator to trust