npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ai-wot

v0.8.0

Published

Web of Trust for AI agents on Nostr — attestations, trust scoring, and reputation via NIP-32 labels

Readme

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.

💼 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.

🧾 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.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