Nostr WoT

Documentation

Tout ce dont vous avez besoin pour intégrer le Web of Trust dans votre application.

Référence du SDK

Créez des applications Nostr avec des fonctions de récupération de données, des outils de relais, une interface de connexion et des requêtes optionnelles de distance dans le graphe des abonnements.

Paquets publiés

Versions vérifiées sur npm le 20 septembre 2026. Le métapaquet exporte WoT à sa racine et les autres modules via des sous-chemins. Vous pouvez aussi installer directement les paquets avec portée ; @nostr-wot/pq est un paquet distinct.

Installation

terminal
$npm install [email protected]

Configuration du fournisseur

NostrSdkProvider combine la configuration des données, la session et le contexte WoT optionnel. Fournissez explicitement myPubkey pour les requêtes Oracle ; la connexion ne définit pas automatiquement la racine des requêtes WoT.

tsx
"use client";
import type { ReactNode } from "react";
import { NostrSdkProvider } from "nostr-wot-sdk/react";

export function Providers({ children }: { children: ReactNode }) {
  return (
    <NostrSdkProvider
      relays={["wss://relay.damus.io", "wss://nos.lol"]}
      profileAggregators={["wss://purplepag.es"]}
    >
      {children}
    </NostrSdkProvider>
  );
}

Compatibilité avec Oracle

La version publiée @nostr-wot/wot 1.0.0 utilise l’ancien contrat /api/distance/FROM/TO?maxHops= et attend un champ distance. Oracle 0.3.0 utilise /distance?from=&to=&max_hops= et renvoie hops. Changer uniquement l’URL de base ne les rend pas compatibles. Utilisez fetch directement avec Oracle 0.3.0 ou la source du graphe local ci-dessous.

typescript
async function oracleDistance(from: string, to: string) {
  const query = new URLSearchParams({ from, to, max_hops: "2" });
  const response = await fetch(
    "https://wot-oracle.mappingbitcoin.com/distance?" + query,
  );
  if (!response.ok) throw new Error("Oracle HTTP " + response.status);
  const result = await response.json();
  return result.hops as number | null;
}

Référence de l’API Oracle

Couche de données

Les fonctions autonomes récupèrent profils, notes, fils, abonnements et interactions. Les hooks React ajoutent un cache qui renvoie les données stockées tout en les revalidant. Les fonctions de données partagent leur propre pool de connexions.

terminal
$npm install @nostr-wot/[email protected]
typescript
import {
  fetchProfile, fetchNotesByAuthor, fetchEngagement, setDefaultRelays,
} from "@nostr-wot/data";

setDefaultRelays(["wss://relay.damus.io", "wss://nos.lol"]);

async function loadAuthor(pubkey: string) {
  const profile = await fetchProfile(pubkey);
  const notes = await fetchNotesByAuthor(pubkey, { limit: 50 });
  const engagement = await fetchEngagement(notes.map(note => note.id));
  return { profile, notes, engagement };
}
tsx
"use client";
import { useProfile } from "@nostr-wot/data/react";

function ProfileCard({ pubkey }: { pubkey: string }) {
  const profile = useProfile(pubkey);
  if (!profile) return null;
  return <h1>{profile.displayName ?? profile.name ?? pubkey}</h1>;
}

Gestion des relais

RelayPool encapsule un transport PoolLike compatible fourni par votre application. Configurez urls, utilisez subscribe avec onEvent/onEose et fermez les abonnements une fois terminé. Un adaptateur de relais créé séparément ne se connecte pas automatiquement au fournisseur de données.

terminal
$npm install @nostr-wot/[email protected]
typescript
import { RelayPool, type PoolLike, type NostrEvent } from "@nostr-wot/relay";

function watchNotes(transport: PoolLike, onEvent: (event: NostrEvent) => void) {
  const pool = new RelayPool({
    urls: ["wss://relay.damus.io", "wss://nos.lol"],
    pool: transport,
  });
  const sub = pool.subscribe({ kinds: [1], limit: 50 }, { onEvent });
  return () => {
    sub.close();
    pool.destroy();
  };
}

Interface de connexion

LoginButton et useSession partagent la session de NostrSdkProvider. Les méthodes incluent NIP-07, NIP-46, la génération et l’importation de clés. Installez directement le paquet UI pour importer ses composants et ses styles.

terminal
$npm install @nostr-wot/[email protected]
tsx
"use client";
import { LoginButton, useSession } from "@nostr-wot/ui";
import { NostrSdkProvider } from "nostr-wot-sdk/react";
import "@nostr-wot/ui/styles.css";

function Account() {
  const { pubkey } = useSession();
  return <><LoginButton /><output>{pubkey}</output></>;
}

function App() {
  return <NostrSdkProvider><Account /></NostrSdkProvider>;
}

Distances du réseau de confiance

WoT interroge l’Oracle par défaut. getDistance renvoie un nombre ou null ; isInMyWoT renvoie un booléen. getDetails fournit les sauts, un nombre de chemins et des informations optionnelles sur les intermédiaires et les abonnements mutuels. Utilisez des clés publiques hexadécimales valides de 64 caractères.

Migration vers @nostr-wot/wot 1.0.0

La version 1.0.0 a supprimé la détection d’extension, les méthodes de score de confiance et useTrustScore. Utilisez useWoT ou useIsInWoT et lisez leurs objets de résultat. Pour les requêtes locales, fournissez un WoTLocalSource, par exemple WotGraph.asWoTSource() de @nostr-wot/graph. Seuls getDistance, isInMyWoT et filterByWoT utilisent cette source ; les autres méthodes interrogent toujours l’Oracle.

Exemple de graphe local

Chargez et parcourez un graphe local avant de transmettre sa source à WoT. L’exemple React reçoit ce graphe préparé et utilise useIsInWoT ; useWoT demande aussi getDetails à l’Oracle. @nostr-wot/graph possède sa propre API getScore, distincte de l’API de score supprimée de WoT.

terminal
$npm install @nostr-wot/[email protected] @nostr-wot/[email protected]
typescript
import { WotGraph } from "@nostr-wot/graph";
import { WoT } from "@nostr-wot/wot";

async function prepareGraph(myPubkey: string, targetPubkey: string) {
  const graph = new WotGraph({
    namespace: "my-app",
    relays: ["wss://relay.damus.io", "wss://nos.lol"],
  });
  await graph.load();
  await graph.crawl(myPubkey, { maxDepth: 2 });
  const wot = new WoT({ source: graph.asWoTSource(), maxHops: 2 });
  const distance = await wot.getDistance(targetPubkey);
  const inWoT = await wot.isInMyWoT(targetPubkey);
  return { graph, distance, inWoT };
}
tsx
"use client";
import type { WotGraph } from "@nostr-wot/graph";
import { NostrSdkProvider, useIsInWoT } from "nostr-wot-sdk/react";

function FollowBadge({ pubkey }: { pubkey: string }) {
  const { inWoT, loading, error } = useIsInWoT(pubkey, { maxHops: 2 });
  if (loading || error || !inWoT) return null;
  return <span>{pubkey}</span>;
}

function LocalTrust({ graph, pubkey }: { graph: WotGraph; pubkey: string }) {
  return (
    <NostrSdkProvider wot={{ enabled: true, options: { source: graph.asWoTSource() } }}>
      <FollowBadge pubkey={pubkey} />
    </NostrSdkProvider>
  );
}