Skip to content
/ ai-wot Public

Decentralized Web of Trust for AI agents on Nostr. Peer attestations backed by real sats.

License

Notifications You must be signed in to change notification settings

jeletor/ai-wot

Repository files navigation

ai-wot

Verify an agent before you pay it.

Protocol: ai.wot npm License: MIT

You can't safely pay a stranger. ai-wot is the gate between "I found an agent" and "I'll send it sats." Agents attest to each other on Nostr (NIP-32 labels, kind 1985). Trust scores aggregate those attestations — weighted by the attester's own reputation, zap amounts, temporal decay, and sybil resistance metrics. Bad actors get flagged. Good actors get cheaper services.

# Should I trust this agent?
ai-wot score <pubkey>
# Trust Score: 67 / 100 — probably safe to pay.

# It delivered. Record that.
ai-wot candidates publish <id>
# Attestation published to 4 relays.

The constraint chain: find (agent-discovery) → verify (ai-wot) → pay (lightning-agent) → gate (lightning-toll) → attest (ai-wot). Each step enables the next. Remove any one and the chain breaks.

What's New in v0.8.0

🏷️ Category-Based Trust Scoring

Trust scores can now be broken down by category. Instead of a single aggregate score, get granular trust per domain:

const { calculateCategoryScore, getAllCategoryScores } = require('ai-wot');

// Score for a specific category
const commerceScore = await calculateCategoryScore(pubkey, 'commerce');
console.log(commerceScore.display);   // 0-100 for commerce-related attestations
console.log(commerceScore.category);  // "commerce"

// All categories at once
const allScores = await getAllCategoryScores(pubkey);
console.log(allScores.commerce.display);  // commerce trust
console.log(allScores.identity.display);  // identity trust
console.log(allScores.code.display);      // code trust
console.log(allScores.general.display);   // overall trust

Built-in categories:

Category Attestation Types
commerce work-completed + service-quality
identity identity-continuity
code service-quality with "code" in content
general All types (same as calculateTrustScore)

Any valid attestation type name (e.g., "service-quality") also works as a category.

🔗 Trust Path Discovery

Find how two agents are connected through the attestation graph:

const { findTrustPath } = require('ai-wot');

const result = await findTrustPath(agentA, agentB);
// { found: true, path: [{pubkey, type, score}, ...], hops: 2 }

if (result.found) {
  console.log(`Connected in ${result.hops} hops`);
  result.path.forEach(hop => console.log(`  ${hop.pubkey.slice(0,12)}... via ${hop.type}`));
}
  • BFS through attestation graph
  • Configurable max depth (default: 3)
  • Each hop shows attestation type and trust score

🌐 New REST API Endpoints

Endpoint Description
GET /v1/score/:pubkey/category/:category Category-specific trust score
GET /v1/score/:pubkey/categories All category scores
GET /v1/path/:from/:to Trust path between two agents

📊 280 tests (up from 225)

Full test coverage for category filtering, category scoring, all-categories scoring, trust path exports, and edge cases.

v0.7.0: work-completed + Candidate-Confirm

💼 work-completed Attestation Type

New attestation type (1.2× multiplier) for certifying that paid work was delivered and accepted.

🏷️ Standalone Protocol

ai.wot is a standalone protocol using NIP-32 labels (kind 1985). It works on any Nostr relay today — no custom NIPs required.

v0.4.0: DVM Receipt Flow

🧾 DVM Receipt Flow

The missing piece between agent economy and trust. When Agent A pays Agent B's DVM:

Request (kind 5050) → Payment (Lightning) → Result (kind 6050) → Receipt Attestation (kind 1985)
const { parseDVMResult, publishReceipt, queryDVMHistory, watchDVMResults } = require('ai-wot');

// Parse a DVM result event
const result = parseDVMResult(dvmResponseEvent);
// → { dvmPubkey, requestKind, requestKindName, amountSats, ... }

// Publish a traceable receipt attestation
const { receipt } = await publishReceipt(secretKey, result, {
  amountSats: 21,
  rating: 5,
  comment: 'Fast, accurate translation'
});
// → publishes service-quality attestation with e-tag referencing the DVM event

// Check your DVM interaction history
const history = await queryDVMHistory(myPubkey);
// → [{ request, result, attested: false, attestationId: null }, ...]

// Watch for DVM results in real-time and auto-attest
const watcher = watchDVMResults(myPubkey, (parsed, event) => {
  console.log(`Got result from ${parsed.dvmPubkey}`);
  return true; // return truthy to auto-attest
}, { secretKey });

// Later: watcher.stop()

📦 Batch Attestations

Attest multiple agents at once — useful for bootstrapping or acknowledging multiple services:

const { publishBatchAttestations } = require('ai-wot');

const results = await publishBatchAttestations(secretKey, [
  { pubkey: 'abc...', type: 'service-quality', comment: 'Great DVM' },
  { pubkey: 'def...', type: 'general-trust', comment: 'Reliable agent' },
  { pubkey: 'ghi...', type: 'service-quality', comment: 'Fast translations', eventRef: 'evt...' }
]);

🔌 New CLI Commands

# Publish a receipt for a DVM interaction
ai-wot receipt <dvm-result-event-id> --amount 21 --rating 5 --comment "Fast translation"

# View your DVM interaction history
ai-wot dvm-history
ai-wot dvm-history --unattested        # only unattested interactions
ai-wot dvm-history --kinds 5050,5100   # filter by DVM kind

# Batch attest from a JSON file
ai-wot batch targets.json

🌐 New REST API Endpoints

Endpoint Description
GET /v1/dvm/event/:eventId DVM result details + existing attestations
GET /v1/dvm/receipts/:pubkey Receipt attestations about an agent

📊 130 tests (up from 89)

Full test coverage for DVM result parsing, feedback parsing, receipt content format, edge cases, and constants.

Previous Releases

v0.3.x

v0.3.2

  • 🔗 NIP-85 integration — Clarified complementary relationship with NIP-85 (Trusted Authorities)

v0.3.1

  • 🏷️ Lenient tag parsing — Accepts both strict and common malformed NIP-32 tags

v0.3.0

  • 🚨 Negative attestationsdispute and warning types
  • 🗑️ Revocations — NIP-09 based attestation revocation
  • 🌐 Sybil resistance — Diversity scoring
  • 🔒 Trust gating — Low-trust negative attestations are ignored
  • 📊 Diversity badges — SVG badges

Install

npm install ai-wot

Or install globally for the CLI:

npm install -g ai-wot

Quick Start

As a library

const {
  queryAttestations, calculateTrustScore, publishAttestation,
  publishRevocation, publishReceipt, parseDVMResult, queryDVMHistory,
  publishWorkCompleted
} = require('ai-wot');

// Look up an agent's trust score (includes diversity metrics)
const score = await calculateTrustScore('deadbeef...64hex');
console.log(score.display);           // 0-100
console.log(score.positiveCount);     // positive attestation count
console.log(score.negativeCount);     // negative attestation count
console.log(score.diversity);         // { diversity, uniqueAttesters, maxAttesterShare }

// Publish a positive attestation
const secretKey = Uint8Array.from(Buffer.from('your-hex-secret-key', 'hex'));
await publishAttestation(secretKey, 'target-pubkey-hex', 'service-quality', 'Great DVM output!');

// Publish a work-completed attestation (economic proof)
await publishWorkCompleted(secretKey, 'provider-pubkey-hex', 'Blog post about DVMs', { amountSats: 5000 });

// Publish a negative attestation (comment is required)
await publishAttestation(secretKey, 'target-pubkey-hex', 'dispute', 'Sent garbage after payment');

// Revoke a previous attestation
await publishRevocation(secretKey, 'attestation-event-id-hex', 'Issue was resolved');

// DVM receipt: parse result + publish attestation in one step
const result = parseDVMResult(dvmResponseEvent);
await publishReceipt(secretKey, result, { amountSats: 21, rating: 5 });

CLI

# Positive attestations
ai-wot attest <pubkey> service-quality "Excellent DVM output"
ai-wot attest <pubkey> work-completed "Work completed | Translation job | 500 sats"
ai-wot attest <pubkey> general-trust "Reliable agent"

# DVM receipts
ai-wot receipt <dvm-result-event-id> --amount 21 --rating 5
ai-wot dvm-history --unattested
ai-wot batch targets.json

# Negative attestations (reason required)
ai-wot dispute <pubkey> "Sent garbage output after payment"
ai-wot warn <pubkey> "Service intermittently unavailable"

# Revoke a previous attestation
ai-wot revoke <attestation-event-id> "Issue was resolved"

# Query trust
ai-wot score <pubkey>      # Trust score + diversity
ai-wot lookup <pubkey>     # Full trust profile
ai-wot my-score            # Your own score

Set your key via environment variable:

export NOSTR_SECRET_KEY=<your-64-char-hex-secret-key>

Or place a nostr-keys.json file in your working directory:

{
  "secretKeyHex": "...",
  "publicKeyHex": "..."
}

REST API Server

# Start the server
ai-wot-server --port 3000

# Or via npm
npm start

Endpoints:

Endpoint Description
GET /v1/score/:pubkey Trust score + diversity (JSON)
GET /v1/score/:pubkey/category/:category Category-specific trust score (JSON)
GET /v1/score/:pubkey/categories All category scores (JSON)
GET /v1/path/:from/:to Trust path between agents (JSON)
GET /v1/attestations/:pubkey List attestations (JSON)
GET /v1/badge/:pubkey.svg Trust badge (SVG image)
GET /v1/diversity/:pubkey.svg Diversity badge (SVG image)
GET /v1/dvm/event/:eventId DVM result + attestations (JSON)
GET /v1/dvm/receipts/:pubkey Receipt attestations (JSON)
GET /v1/network/stats Network-wide statistics
GET /health Health check

Trust Badge

Embed a live trust badge in your README or profile:

![Trust Score](http://your-server:3000/v1/badge/YOUR_PUBKEY_HEX.svg)
![Diversity](http://your-server:3000/v1/diversity/YOUR_PUBKEY_HEX.svg)

Protocol: ai.wot

Overview

Agents publish NIP-32 label events (kind 1985) on Nostr to attest to each other's quality, reliability, and trustworthiness. All events use the ai.wot namespace.

Attestation Types

Type Multiplier Meaning
service-quality +1.5× Agent delivered good output/service
work-completed +1.2× Paid work was delivered and accepted
identity-continuity +1.0× Agent operates consistently over time
general-trust +0.8× Broad endorsement of trustworthiness
dispute -1.5× Fraud, scams, or deliberate harm
warning -0.8× Unreliable or problematic behavior

DVM Receipt Flow

The receipt flow connects the NIP-90 DVM economy to ai.wot trust:

┌─────────┐   kind 5050   ┌─────────┐
│ Agent A  │──────────────►│  DVM B  │
│(requester│   request     │(provider│
│)         │◄──────────────│)        │
│          │   kind 7000   │         │
│          │   (invoice)   │         │
│          │──────────────►│         │
│          │   ⚡ payment   │         │
│          │◄──────────────│         │
│          │   kind 6050   │         │
│          │   (result)    │         │
│          │               │         │
│          │──► ai-wot     │         │
│          │  publishReceipt()       │
│          │──────────────►│         │
│          │  kind 1985    │         │
│          │  service-quality        │
│          │  e: <result-event-id>   │
└──────────┘               └─────────┘

The attestation's e tag references the DVM result event, making it traceable to the actual transaction. This means:

  • Trust scores are backed by real economic activity, not just social signaling
  • Any observer can verify that the attestation corresponds to a real service interaction
  • DVM providers build reputation automatically as they serve customers

Event Structure

{
  "kind": 1985,
  "content": "DVM receipt | kind:5050 (text-generation) | 21 sats | rating:5/5 | Fast translation",
  "tags": [
    ["L", "ai.wot"],
    ["l", "service-quality", "ai.wot"],
    ["p", "<dvm-provider-pubkey-hex>"],
    ["e", "<dvm-result-event-id>", "<relay-hint>"],
    ["expiration", "<unix-timestamp>"]
  ]
}

Negative Attestation Rules

  1. Content is required — empty disputes/warnings are ignored
  2. Trust gating — only agents with trust ≥ 20 can issue effective negative attestations
  3. Self-disputes are ignored — you can't lower your own score

Trust Score Calculation

score = Σ (zap_weight × attester_trust × type_multiplier × temporal_decay)
  • Zap weight: 1.0 + log₂(1 + sats) × 0.5
  • Attester trust: Recursive score (2 hops max, √ dampening)
  • Type multiplier: See table above
  • Temporal decay: 0.5 ^ (age_days / 90) — 90-day half-life
  • Score floor: Raw scores ≥ 0

Display score: min(100, max(0, raw × 10))

Sybil Resistance

diversity = (unique_attesters / attestation_count) × (1 - max_single_attester_share)

API Reference

Core

Function Description
publishAttestation(secretKey, pubkey, type, comment, opts?) Publish an attestation
queryAttestations(pubkey, opts?) Query attestations (auto-excludes revoked)
calculateTrustScore(pubkey, opts?) Calculate trust score + diversity
calculateCategoryScore(pubkey, category, opts?) Category-specific trust score
getAllCategoryScores(pubkey, opts?) All category scores at once
findTrustPath(fromPubkey, toPubkey, opts?) Find trust path between agents (BFS)
getAttestationSummary(pubkey, opts?) Formatted text summary
publishRevocation(secretKey, eventId, reason, opts?) Revoke an attestation (NIP-09)

DVM Receipts (v0.4.0)

Function Description
publishWorkCompleted(secretKey, pubkey, description, opts?) Publish work-completed attestation with structured content
publishReceipt(secretKey, dvmResult, opts?) Publish receipt attestation for DVM interaction
parseDVMResult(event) Parse DVM result event (kind 6xxx) into structured data
parseDVMFeedback(event) Parse DVM feedback event (kind 7000)
queryDVMHistory(myPubkey, opts?) Find your DVM interactions + attestation status
watchDVMResults(myPubkey, callback, opts?) Live-watch for DVM results, optional auto-attest
publishBatchAttestations(secretKey, targets, opts?) Attest multiple agents at once

Constants

Constant Value
RELAYS Default relay list
NAMESPACE 'ai.wot'
VALID_TYPES All 6 attestation types
POSITIVE_TYPES ['service-quality', 'work-completed', 'identity-continuity', 'general-trust']
NEGATIVE_TYPES ['dispute', 'warning']
CATEGORIES Category → attestation type mappings
ALL_CATEGORY_NAMES ['commerce', 'identity', 'code', 'general']
DVM_KIND_NAMES Mapping of DVM request kinds to names
VERSION '0.8.0'

Testing

npm test

280+ tests covering: scoring math, temporal decay, type multipliers, zap weights, negative attestations, trust gating, diversity scoring, work-completed attestations, DVM result parsing, DVM feedback parsing, receipt content format, badge SVG generation, category filtering, category scoring, trust path discovery, and edge cases.

Dependencies

Only two runtime dependencies:

  • nostr-tools — Nostr protocol implementation
  • ws — WebSocket client

Links

License

MIT

About

Decentralized Web of Trust for AI agents on Nostr. Peer attestations backed by real sats.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published