Files
bitvid/docs/relay-trust-bootstrap.md
T

4.5 KiB
Raw Blame History

Relay trust bootstrap

This document describes how js/services/trustBootstrap.js seeds trusted relays/actors for moderation, how it waits for relay availability, and how the relay list and admin lists are refreshed.

Overview

bootstrapTrustedSeeds() is a lightweight bootstrapping step that:

  1. Waits briefly for admin list hydration and relay readiness.
  2. Builds a trusted seed set from admin configuration and defaults.
  3. Hands that trusted seed set to moderationService so trusted reports, mutes, and summary stats are computed consistently.
  4. Re-runs when admin/editor lists change.

Configuration inputs

Trusted seed inputs are pulled from configuration and feature flags:

  • FEATURE_TRUST_SEEDS (flag in js/constants.js): gates whether bootstrapping runs at all.
  • ADMIN_SUPER_NPUB (from config/instance-config.js via js/config.js): always included when set.
  • accessControl.getEditors() (from js/accessControl.js): editor list sourced from admin lists or defaults.
  • DEFAULT_TRUST_SEED_NPUBS (from config/instance-config.js via js/constants.js): used only if there are no super/admin seeds.

Seed selection and trust computation

buildTrustedSeeds() composes a Set of Nostr npub identifiers in this order:

  1. Add the super admin (ADMIN_SUPER_NPUB).
  2. Add editor npubs (accessControl.getEditors()).
  3. If no seeds exist yet, fall back to DEFAULT_TRUST_SEED_NPUBS.

The resulting Set is passed to moderationService.setTrustedSeeds(seeds). moderationService uses these seeds as the baseline for trusted contacts and downstream trust calculations (trusted report counts, trusted mute lists, etc.), and recomputeAllSummaries() is called immediately after applying seeds so moderation views reflect the updated trust graph.

Relay readiness and fallback behavior

Bootstrapping is intentionally defensive so the UI can initialize quickly:

  • Access control hydration: waitForAccessControl() races accessControl.ensureReady() against a 3.5s timeout. If hydration times out, bootstrapping logs a dev warning and falls back to defaults.
  • Immediate apply: Seeds are applied immediately after the first hydration attempt, even if the admin list hydration failed, so moderation does not block on relay availability.
  • Retry when relays are ready: If hydration failed, bootstrapTrustedSeeds() checks for relay readiness via nostrService.nostrClient.relays (and pool existence). If relays become available within 3.5s, it retries admin list hydration once. If relays never become ready, it logs a dev warning and re-applies the current seeds to keep moderation functional.
  • Change listeners: accessControl.onWhitelistChange() and accessControl.onEditorsChange() are registered so any subsequent admin/editor updates re-run seed application and recompute moderation summaries.

Relay list persistence and refresh

trustBootstrap does not persist or update relay lists itself. Instead it relies on the shared Nostr client state maintained by the relay manager and access control:

  • Relay list loading: js/relayManager.js loads a profile’s relay list from NIP-65 (kind 10002) events, normalizes relay URLs, and falls back to DEFAULT_RELAY_URLS if nothing is found or the pool is unavailable. The relay manager updates the active nostrClient relay list in memory via nostrClient.applyRelayPreferences() (or by assigning to nostrClient.relays).
  • Relay list refresh: Relay list changes are published to relays via relayManager.publishRelayList() and reloaded during profile refresh flows, which updates nostrClient.relays that trustBootstrap later observes.
  • Admin list persistence: js/accessControl.js hydrates admin/editor lists from cached state in js/adminListStore.js (local storage). It then refreshes from relay-backed admin lists when ensureReady() is called. The cache ensures bootstrapTrustedSeeds() can use stored admin lists before relays are available.

Data flow summary

config/instance-config.js
  └─> js/config.js -> js/constants.js (FEATURE_TRUST_SEEDS, DEFAULT_TRUST_SEED_NPUBS)
                         └─> js/services/trustBootstrap.js
                                ├─> accessControl.ensureReady() (admin lists + cache)
                                ├─> nostrService.nostrClient.relays (relay readiness)
                                └─> moderationService.setTrustedSeeds() + recomputeAllSummaries()

When the relay list or admin lists change, accessControl refreshes from cache/relays and the trust bootstrapper re-applies seeds so moderation stays up to date.