From 0b4f7710bc732e5a6665eae4d5be6b7694a66e85 Mon Sep 17 00:00:00 2001 From: BCR Date: Tue, 8 Sep 2026 14:37:39 -0400 Subject: [PATCH] README: document COUNT support (relay.count, countWithHLL, pool.countMany) (#553) NIP-45 has been implemented for a while but the README never mentioned it, and #369 is still open asking whether it exists. Co-authored-by: sunmoonron <16808243+sunmoonron@users.noreply.github.com> --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index dcc3fae..74c4762 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,34 @@ import WebSocket from 'ws' useWebSocketImplementation(WebSocket) ``` +### Counting events (NIP-45) + +Relays that support NIP-45 answer `COUNT` requests instead of sending the events. `relay.count()` resolves to the number; `relay.countWithHLL()` also returns the HyperLogLog registers when the relay includes them, and `pool.countMany()` merges those registers across relays, so the same event seen on several relays is not counted twice. + +```js +import { Relay } from '@nostr/tools/relay' + +const relay = await Relay.connect('wss://relay.example.com') + +// how many notes has this pubkey published, according to this relay +const notes = await relay.count([{ kinds: [1], authors: [''] }]) + +// the same with the HLL registers, if the relay sends them +const { count, hll } = await relay.countWithHLL([{ kinds: [1], authors: [''] }]) +``` + +Across a pool, `countMany` builds the filter for you from a target and a directive, one of `'reactions'`, `'reposts'`, `'quotes'`, `'replies'`, `'comments'` or `'followers'`: + +```js +// followers of a pubkey, merged across relays +const { count } = await pool.countMany(relays, '', 'followers') + +// reactions to a note +const reactions = await pool.countMany(relays, '', 'reactions', { maxWait: 3000 }) +``` + +Relays that don't support `COUNT` are skipped by `countMany`; a single `relay.count()` against one of them rejects. + ### Authenticating with relays (NIP-42) Some relays will return a `CLOSED` message with an `"auth-required:"` prefix in order to signal that such request requires authentication.