Survey results
We ran a 3-layer NIP-77 support survey across 1,044 live relays (from NIP-66 monitor data):
| Layer |
Method |
NIP-77 count |
% of total |
| NIP-66 monitor |
supportedNips from kind 30166 |
268 |
25.7% |
| NIP-11 direct |
HTTP GET with Accept: application/nostr+json |
263 |
25.2% |
| Live NEG-OPEN |
WebSocket probe with actual negentropy handshake |
211 |
20.2% |
Software breakdown (live-confirmed)
| Software |
Relays |
NIP-77 |
Rate |
| strfry |
268 |
218 (191 live-confirmed) |
81% |
| nostr-rs-relay |
210 |
0 |
0% |
| haven (khatru) |
82 |
0 |
0% |
| nostream |
51 |
0 |
0% |
| khatru (direct) |
48 |
1 |
2% |
| pyramid |
19 |
18 |
95% |
Key finding: khatru has the code but it's not wired up
Khatru already has a full NIP-77 implementation in negentropy.go using go-nostr/nip77/negentropy. However, it's gated behind a Negentropy bool field that defaults to false:
// relay.go line 103-104
// set this to true to support negentropy
Negentropy bool
The WebSocket message parser only tries NIP-77 parsing when this flag is true (handlers.go:154):
if err == nostr.UnknownLabel && rl.Negentropy {
envelope = nip77.ParseNegMessage(message)
}
We confirmed this by probing fiatjaf.com (fiatjaf's own khatru relay): NOTICE: failed to parse envelope: unknown envelope label.
Why this matters for outbox
Our outbox relay benchmark measures a 77% relay-list availability → 24% event recall gap. The #1 cause is the write-side gap: when users change relay lists, old events don't migrate. NIP-77 negentropy is the only efficient solution for this — it enables set reconciliation without transferring full event payloads.
But at 20% relay support (strfry-only), negentropy-based migration is not viable as a general strategy.
Adoption path
Three changes would push NIP-77 from 20% to ~55% of relays:
| Target |
Instances |
Effort |
Notes |
| khatru (enable by default or config flag) |
48 + ~82 cascade to haven |
Low |
Code exists, needs wiring. Tradeoff: in-memory Vector per session adds memory/CPU load. Maybe config opt-in rather than default-on? |
| nostr-rs-relay |
210 |
Medium |
Rust negentropy crate v0.5.0 exists. Issue #234 open, no work started |
| nostream |
51 |
High |
Reference JS impl exists. Last commit Oct 2024 — may be abandoned |
Questions for relay devs
- khatru/haven operators: Would you enable negentropy if it were a config option? What are your concerns about memory/CPU overhead?
- nostr-rs-relay contributors: Anyone interested in implementing NIP-77? The
negentropy Rust crate handles protocol logic; main work is WebSocket routing + SQLite query adapter (~200-400 lines)
- Is the in-memory Vector approach good enough? strfry uses persistent LMDB B-trees for negentropy storage. khatru rebuilds from scratch per session. For personal relays (haven's use case) this is probably fine, but worth discussing.
- Should negentropy be opt-in or default-on in relay frameworks? fiatjaf made it explicitly opt-in in khatru. Is that the right call?
Survey script
The probe script is at bench/probe-nip77.ts — run with --live for WebSocket verification. Full results cached in bench/.cache/nip77_survey.json.
Cross-reference
Survey results
We ran a 3-layer NIP-77 support survey across 1,044 live relays (from NIP-66 monitor data):
supportedNipsfrom kind 30166Accept: application/nostr+jsonSoftware breakdown (live-confirmed)
Key finding: khatru has the code but it's not wired up
Khatru already has a full NIP-77 implementation in
negentropy.gousinggo-nostr/nip77/negentropy. However, it's gated behind aNegentropybool field that defaults to false:The WebSocket message parser only tries NIP-77 parsing when this flag is true (handlers.go:154):
We confirmed this by probing
fiatjaf.com(fiatjaf's own khatru relay):NOTICE: failed to parse envelope: unknown envelope label.Why this matters for outbox
Our outbox relay benchmark measures a 77% relay-list availability → 24% event recall gap. The #1 cause is the write-side gap: when users change relay lists, old events don't migrate. NIP-77 negentropy is the only efficient solution for this — it enables set reconciliation without transferring full event payloads.
But at 20% relay support (strfry-only), negentropy-based migration is not viable as a general strategy.
Adoption path
Three changes would push NIP-77 from 20% to ~55% of relays:
negentropycrate v0.5.0 exists. Issue #234 open, no work startedQuestions for relay devs
negentropyRust crate handles protocol logic; main work is WebSocket routing + SQLite query adapter (~200-400 lines)Survey script
The probe script is at
bench/probe-nip77.ts— run with--livefor WebSocket verification. Full results cached inbench/.cache/nip77_survey.json.Cross-reference
nbd-wtf/go-nostr/nip77/negentropy