Nostr WoT

Documentación

Todo lo que necesitas para integrar Web of Trust en tu aplicación.

Referencia del SDK

Crea aplicaciones Nostr con funciones de consulta, utilidades de relés, interfaz de inicio de sesión y consultas opcionales de distancia en el grafo de seguimientos.

Paquetes publicados

Versiones verificadas en npm el 20 de septiembre de 2026. El metapaquete exporta WoT desde su raíz y otros módulos mediante subrutas. También puedes instalar paquetes con ámbito directamente; @nostr-wot/pq es un paquete independiente.

Instalación

terminal
$npm install [email protected]

Configuración del proveedor

NostrSdkProvider combina la configuración de datos, el estado de sesión y el contexto WoT opcional. Indica myPubkey explícitamente para las consultas al Oracle; iniciar sesión no configura automáticamente la raíz de consulta 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>
  );
}

Compatibilidad con Oracle

La versión publicada @nostr-wot/wot 1.0.0 utiliza el contrato anterior /api/distance/FROM/TO?maxHops= y espera el campo distance. Oracle 0.3.0 utiliza /distance?from=&to=&max_hops= y devuelve hops. Cambiar solo la URL base no los hace compatibles. Usa fetch directamente con Oracle 0.3.0 o la fuente del grafo local mostrada abajo.

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;
}

Referencia de la API del Oracle

Capa de datos

Las funciones independientes obtienen perfiles, notas, hilos, seguimientos e interacciones. Los hooks de React añaden una caché que devuelve datos almacenados mientras los revalida. Las funciones de datos comparten su propio grupo de conexiones.

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>;
}

Gestión de relés

RelayPool envuelve un transporte PoolLike compatible proporcionado por tu aplicación. Configura urls, utiliza subscribe con onEvent/onEose y cierra las suscripciones al terminar. Un envoltorio de relés creado por separado no se conecta automáticamente al proveedor de datos.

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();
  };
}

Interfaz de inicio de sesión

LoginButton y useSession comparten la sesión de NostrSdkProvider. Los métodos incluyen NIP-07, NIP-46, generación e importación de claves. Instala el paquete UI directamente para importar sus componentes y estilos.

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>;
}

Distancias de la red de confianza

WoT consulta el Oracle de forma predeterminada. getDistance devuelve un número o null; isInMyWoT devuelve un booleano. getDetails proporciona saltos, un número de rutas e información opcional sobre conexiones intermedias y seguimiento mutuo. Usa claves públicas hexadecimales válidas de 64 caracteres.

Migración a @nostr-wot/wot 1.0.0

La versión 1.0.0 eliminó la detección de extensiones, los métodos de puntuación de confianza y useTrustScore. Usa useWoT o useIsInWoT y lee sus objetos de resultado. Para consultas locales, proporciona un WoTLocalSource, como WotGraph.asWoTSource() de @nostr-wot/graph. Solo getDistance, isInMyWoT y filterByWoT utilizan esa fuente; los demás métodos siguen consultando el Oracle.

Ejemplo de grafo local

Carga y rastrea un grafo local antes de pasar su fuente a WoT. El ejemplo React recibe este grafo preparado y usa useIsInWoT; useWoT también solicita getDetails al Oracle. @nostr-wot/graph tiene su propia API getScore, independiente de la API de puntuación eliminada 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>
  );
}