Skip to content

feat(nip77): add NEG-OPEN/NEG-MSG/NEG-CLOSE wire protocol - #818

Merged
cameri merged 5 commits into
cameri:mainfrom
Priyanshubhartistm:feat/nip77-wire-protocol
Oct 15, 2026
Merged

cameri merged 5 commits into
cameri:mainfrom
Priyanshubhartistm:feat/nip77-wire-protocol

Conversation

@Priyanshubhartistm

Copy link
Copy Markdown
Collaborator

Serves NIP-77 (Negentropy) sync over the websocket for the PostgreSQL event store, using the reconciliation core from #809.

  • NEG-OPEN, NEG-MSG and NEG-CLOSE are validated and handled; replies are NEG-MSG and NEG-ERR. NEG-OPEN for an id that is already open replaces that session, and ids are a separate namespace from REQ ids.
  • Sessions live on the connection (NegentropySessions) and are dropped on NEG-CLOSE, NEG-ERR, idle timeout, disconnect and shutdown drain. A NEG-OPEN that races a NEG-CLOSE or a replacement can't bring back a stale session.
  • Each session holds the matching (created_at, id) set in memory, so it is bounded: nip77.maxEventsPerSession (rejected with NEG-ERR blocked: and the limit as 4th element), nip77.maxSessionsPerConnection and nip77.sessionIdleTimeoutMs. For the event cap the repository query reads one row past the limit instead of loading the whole set.
  • Same NIP-42 restricted-kind and filter-size checks as COUNT.
  • New nip77 settings section, documented in CONFIGURATION.md. nip77.enabled defaults to false, so merging this changes nothing for existing relays, and it only answers when eventStore.backend is postgres.
  • Removes the temporary check:deps ignore added with the core.

NIP-11 supported_nips and the admin console settings schema are left for a follow-up.

Related Issue

Closes #817

Motivation and Context

#809 added the reconciliation core but nothing called it, so relays still could not answer NIP-77 sync requests. This exposes it with a kill-switch and resource limits, so it can be enabled safely. For reference, a session over 100,000 events measured about 25 MB steady and about 50 ms for the first reconcile step, which is the basis for the default cap.

@changeset-bot

changeset-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f2439ad

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
nostream Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coveralls

coveralls commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Coverage Status

Coverage is 74.494% — Priyanshubhartistm:feat/nip77-wire-protocol into cameri:main. No base build found for cameri:main.

@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues remain.

Summary

Adds NIP-77 sync over WebSocket for PostgreSQL, disabled by default.

  • Clients can compare event sets through NIP-77 websocket messages.
  • Each websocket connection owns short-lived negentropy sessions.
  • Restricted event sync requires matching NIP-42 authentication.
  • Operators can enable NIP-77 and set limits for sync sessions.
  • The temporary dependency-check ignore is removed.

Current code addresses all five earlier, unnumbered findings: unscoped private reads, unbounded replacement reads, stale errors, rejected replacements retaining sessions, and expired authentication on NEG-MSG. No new actionable issues were found.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[NEG-OPEN] --> B{Enabled and allowed?}
  B -->|No| E[Close ID and send NEG-ERR]
  B -->|Yes| C{Session and read slots available?}
  C -->|No| E
  C -->|Yes| D[Read capped event set]
  D --> F{Request still owns ID?}
  F -->|No| G[Discard stale result]
  F -->|Yes| H[Build session and send NEG-MSG]
  I[NEG-MSG] --> J{Session exists and access still allowed?}
  J -->|Yes| K[Reconcile and reply]
  J -->|No| E
  L[NEG-CLOSE or disconnect] --> M[Drop sessions]
Loading

Reviews (2) · Last reviewed commit: "fix(nip77): address review findings in n..." · Reviewed by Greptile

Comment thread src/handlers/neg-open-message-handler.ts Outdated
Comment thread src/utils/negentropy-sessions.ts Outdated
Comment thread src/handlers/neg-open-message-handler.ts Outdated
Comment thread src/handlers/neg-open-message-handler.ts
Comment thread src/handlers/neg-msg-message-handler.ts Outdated
greptile-apps[bot]
greptile-apps Bot previously approved these changes Oct 13, 2026
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
@greptile-apps
greptile-apps Bot dismissed their stale review October 14, 2026 18:41

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
@cameri
cameri merged commit 7409006 into cameri:main Oct 15, 2026
15 checks passed
chappie-daemon added a commit that referenced this pull request Oct 15, 2026
#818 removed src/utils/negentropy.ts from the root ignore list (its
content moved into src/utils/negentropy-sessions.ts). Keeping that row
would mask knip coverage, so the root ignore list takes main's; the
workspaces block (website/site) is ours.
chappie-daemon added a commit that referenced this pull request Oct 15, 2026
#818 removed src/utils/negentropy.ts from the root ignore list (its
content moved into src/utils/negentropy-sessions.ts). Keeping that row
would mask knip coverage, so the root ignore list takes main's; the
workspaces block (website/site) is ours.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(nip77): NEG-OPEN/NEG-MSG/NEG-CLOSE wire protocol for the PostgreSQL backend

3 participants