From 804ec4506fb502d980a6a5fb2f78ead0ee88bc6a Mon Sep 17 00:00:00 2001 From: 8144225309 Date: Fri, 29 May 2026 23:08:10 -0400 Subject: [PATCH] docs: JSDoc on remaining connect components (R5.27) Extends R5.x JSDoc to four remaining connect-layer components: - ManualConnectModal: task #119 pubkey@host:port form filling the rendezvous vs invite-URL gap - MyJoinAttemptsCard: task #152 outgoing-join audit; "did my join go through?" without grepping CLN logs - GossipPill: status pill explaining why discovery may seem thin when the local CLN gossip view is small - RendezvousSettings: Nostr relay + coordinator config; documents the per-network coordinator + per-tier caps flow Connect layer now fully documented. Round 17 complete (8 PRs: R5.20-R5.27). --- .../connect/GossipPill/GossipPill.tsx | 22 +++++++++++++ .../ManualConnectModal/ManualConnectModal.tsx | 31 +++++++++++++------ .../MyJoinAttemptsCard/MyJoinAttemptsCard.tsx | 27 +++++++++++++--- .../RendezvousSettings/RendezvousSettings.tsx | 29 +++++++++++++++++ 4 files changed, 96 insertions(+), 13 deletions(-) diff --git a/apps/frontend/src/components/connect/GossipPill/GossipPill.tsx b/apps/frontend/src/components/connect/GossipPill/GossipPill.tsx index 2ef03787..7f21e01a 100644 --- a/apps/frontend/src/components/connect/GossipPill/GossipPill.tsx +++ b/apps/frontend/src/components/connect/GossipPill/GossipPill.tsx @@ -4,6 +4,28 @@ import { useSelector } from 'react-redux'; import { HttpService } from '../../../services/http.service'; import { selectActiveProfileId } from '../../../store/nodesSelectors'; +/** + * Gossip Pill — live status pill on /connect. + * + * What it renders + * A small pill that tells the user how big their gossip view is: + * N nodes / M channels. Formatted as compact "1.2k" / "1M" using + * the local formatCount helper. + * + * Why it's there: when discovery seems "thin" (few LSPs in the + * discovered list), the user wants to know whether the wallet's + * own node sees enough of the network to find them. A pill saying + * "12k nodes / 50k channels" reassures them the discovery is + * real; "5 nodes / 0 channels" tells them their CLN is still + * syncing. + * + * Side effects + * - HttpService.fetchGossipCounts() every 30s (GOSSIP_REFRESH_MS) + * + * Props contract + * None — reads activeProfileId from Redux and the gossip counts + * from the backend on a poll. + */ const GOSSIP_REFRESH_MS = 30_000; const formatCount = (n: number): string => { diff --git a/apps/frontend/src/components/connect/ManualConnectModal/ManualConnectModal.tsx b/apps/frontend/src/components/connect/ManualConnectModal/ManualConnectModal.tsx index f27ddf0b..68d30b43 100644 --- a/apps/frontend/src/components/connect/ManualConnectModal/ManualConnectModal.tsx +++ b/apps/frontend/src/components/connect/ManualConnectModal/ManualConnectModal.tsx @@ -1,17 +1,30 @@ import { useState } from 'react'; import { Modal, Button, Form, Alert } from 'react-bootstrap'; -/* Task #119: manual-connect modal. +/** + * Manual Connect Modal — pubkey@host:port direct-target form (Task #119). * - * The "Open Factories" Card on the Connect page only lists LSPs that a - * rendezvous coordinator has advertised. "Join via invite link" requires - * a full superscalar:// URL with iid baked in. This modal fills the - * remaining gap: someone DMs you "my LSP is @, come - * browse my factories" and you want to talk to that LSP directly. + * What it renders + * The form that fills the gap between rendezvous-discovered LSPs + * (in ConnectList's discovered tab) and full invite URLs (which + * bake in a specific iid). The user pastes a "pubkey@host:port" + * string and the parent pops JoinFactoryModal pointed at that LSP. * - * On submit we validate format and pass the entered pubkey + address back - * to the parent, which pops the existing JoinFactoryModal with those - * values. The plugin's auto-connect helper (#118) handles the BOLT-8 hop. + * Trigger scenario: someone DMs you "my LSP is X, browse my + * factories" without sending a full invite link. + * + * Validation + * - Pubkey must be 66 hex chars + * - Host:port required and parses successfully + * + * Side effects + * None — the parent owns the BOLT-8 connect via the plugin's + * auto-connect helper (#118). + * + * Props contract + * - `show: boolean` + * - `onHide: () => void` + * - `onSubmit: (pubkey, address) => void` — fires on valid submit * * No plugin RPC of our own: factory-browse-host (called by * JoinFactoryModal) takes a peer + optional address hint, and the plugin diff --git a/apps/frontend/src/components/connect/MyJoinAttemptsCard/MyJoinAttemptsCard.tsx b/apps/frontend/src/components/connect/MyJoinAttemptsCard/MyJoinAttemptsCard.tsx index 92b054d2..3a1cb772 100644 --- a/apps/frontend/src/components/connect/MyJoinAttemptsCard/MyJoinAttemptsCard.tsx +++ b/apps/frontend/src/components/connect/MyJoinAttemptsCard/MyJoinAttemptsCard.tsx @@ -4,10 +4,29 @@ import { FactoriesService } from '../../../services/http.service'; import logger from '../../../services/logger.service'; /** - * Task #152: surface the client's outgoing factory-join-request attempts - * + current status. Powered by the plugin's client-list-outgoing-joins RPC - * (added in PR #77). Renders on the Connect page so users can see what - * happened to invites they sent without having to grep CLN logs. + * My Join Attempts Card — outgoing factory-join-request audit (Task #152). + * + * What it renders + * A Card on /connect listing every factory-join-request this client + * has sent, with the LSP target + factory iid + status (queued / + * approved / refused / expired). Powered by the plugin's + * client-list-outgoing-joins RPC. + * + * Closes the "did my join go through?" question without making + * users grep CLN logs — important for first-time SuperScalar users + * whose first attempt may fail for any number of reasons (LSP + * offline, request rejected by auto-accept-threshold, expired). + * + * Key state + * - `attempts`: the list from client-list-outgoing-joins + * - `loading` / `error` per fetch + * - 10s refresh interval while modal open + * + * Side effects + * - Plugin RPC: client-list-outgoing-joins (poll every 10s) + * + * Props contract + * None — fully self-contained card on /connect. */ type OutgoingJoin = { diff --git a/apps/frontend/src/components/connect/RendezvousSettings/RendezvousSettings.tsx b/apps/frontend/src/components/connect/RendezvousSettings/RendezvousSettings.tsx index c356a270..b348920b 100644 --- a/apps/frontend/src/components/connect/RendezvousSettings/RendezvousSettings.tsx +++ b/apps/frontend/src/components/connect/RendezvousSettings/RendezvousSettings.tsx @@ -2,6 +2,35 @@ import './RendezvousSettings.scss'; import { useEffect, useState } from 'react'; import { Accordion, Card, Form, Button, Row, Col, Spinner, Badge } from 'react-bootstrap'; import { useDispatch, useSelector } from 'react-redux'; + +/** + * Rendezvous Settings — Nostr relay + coordinator config. + * + * What it renders + * The /connect page's RendezvousSettings accordion. Lets the + * operator edit: + * - Relay list (which Nostr relays to query for vouches) + * - Coordinator npubs (which voucher identities to trust, per + * network: mainnet / signet / testnet4 / regtest) + * - Per-tier caps (channel / utxo / peer max vouches kept) + * - includePeer toggle (peer-tier is weaker; off by default) + * + * These settings flow through to the nostr.service.fetchVouches + * call inside ConnectList for discovery. + * + * Key state + * - `draft`: in-progress edits (separate from Redux until Save) + * - `saving` / `error` for the persist round-trip + * + * Side effects + * - On mount: RendezvousService.fetchSettings → dispatch into + * rendezvousSlice (lazy-injected here) + * - On Save: RendezvousService.saveSettings → re-dispatch + * + * Props contract + * None — fully self-contained accordion on /connect. + */ + import { CoordinatorEntry, CoordinatorNetwork,