Nostr WoT

Документация

Всё, что нужно для интеграции Web of Trust в ваше приложение.

Справочник SDK

Создавайте приложения Nostr с функциями получения данных, инструментами для реле, интерфейсом входа и необязательными запросами расстояния в графе подписок.

Опубликованные пакеты

Версии проверены в npm 20 сентября 2026 года. Метапакет экспортирует WoT из корневой точки входа, а другие модули через подпути. Пакеты с областью имён можно установить напрямую; @nostr-wot/pq является отдельным пакетом.

Установка

терминал
$npm install [email protected]

Настройка провайдера

NostrSdkProvider объединяет настройки данных, состояние сеанса и необязательный контекст WoT. Явно укажите myPubkey для запросов к Oracle; вход в систему не задаёт автоматически исходный ключ запросов 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>
  );
}

Совместимость с Oracle

Опубликованная версия @nostr-wot/wot 1.0.0 использует старый контракт /api/distance/FROM/TO?maxHops= и ожидает поле distance. Oracle 0.3.0 использует /distance?from=&to=&max_hops= и возвращает hops. Одной смены базового URL недостаточно для совместимости. Используйте fetch напрямую для Oracle 0.3.0 или показанный ниже источник локального графа.

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

Справочник API Oracle

Слой данных

Независимые функции получают профили, заметки, обсуждения, подписки и реакции. Хуки React добавляют кеш, который возвращает сохранённые данные во время их обновления. Функции данных используют собственный общий пул соединений.

терминал
$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>;
}

Управление реле

RelayPool оборачивает совместимый транспорт PoolLike, предоставленный приложением. Настройте urls, используйте subscribe с onEvent/onEose и закрывайте подписки после работы. Отдельно созданная обёртка реле не подключается к провайдеру данных автоматически.

терминал
$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();
  };
}

Интерфейс входа

LoginButton и useSession используют общий сеанс NostrSdkProvider. Поддерживаются NIP-07, NIP-46, создание и импорт ключей. Установите пакет UI напрямую для импорта его компонентов и стилей.

терминал
$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>;
}

Расстояния в сети доверия

По умолчанию WoT обращается к Oracle. getDistance возвращает число или null; isInMyWoT возвращает логическое значение. getDetails предоставляет число переходов, количество путей и необязательные сведения о промежуточных связях и взаимных подписках. Используйте корректные открытые ключи из 64 шестнадцатеричных символов.

Переход на @nostr-wot/wot 1.0.0

В версии 1.0.0 удалены обнаружение расширения, методы оценки доверия и useTrustScore. Используйте useWoT или useIsInWoT и читайте поля возвращаемых объектов. Для локальных запросов передайте WoTLocalSource, например WotGraph.asWoTSource() из @nostr-wot/graph. Только getDistance, isInMyWoT и filterByWoT используют этот источник; остальные методы по-прежнему обращаются к Oracle.

Пример локального графа

Загрузите и соберите локальный граф перед передачей его источника в WoT. Пример React получает подготовленный граф и использует useIsInWoT; useWoT также запрашивает getDetails у Oracle. У @nostr-wot/graph есть собственный API getScore, отдельный от удалённого API оценки WoT.

терминал
$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>
  );
}