feat: add NIP-45 Event Count support#522
Conversation
3a1de5f to
b5a76b4
Compare
b5a76b4 to
8faa3f7
Compare
There was a problem hiding this comment.
Pull request overview
Adds NIP-45 COUNT support to nostream so clients can request event counts by filter without fetching full event streams.
Changes:
- Introduces
COUNT/CLOSEDmessage types, validation schema, and outgoing message helpers. - Adds
CountMessageHandler+ message handler factory routing to execute counts and respond withCOUNT(orCLOSEDon rejection/failure). - Implements
EventRepository.countByFilters()with unit tests, and documents NIP-45 support (README + package metadata + changeset).
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/unit/schemas/message-schema.spec.ts | Adds unit coverage for COUNT message validation rules (required query id, filter presence, max elements). |
| test/unit/repositories/event-repository.spec.ts | Adds unit coverage for countByFilters query construction and return parsing. |
| test/unit/handlers/count-message-handler.spec.ts | New unit tests for COUNT handler behavior (success, dedupe, limits, error -> CLOSED). |
| test/unit/factories/message-handler-factory.spec.ts | Ensures COUNT messages are routed to CountMessageHandler. |
| src/utils/messages.ts | Adds helpers to create NIP-45 COUNT and CLOSED outgoing messages. |
| src/schemas/message-schema.ts | Extends incoming message validation to include COUNT messages (min/max elements + filter schema). |
| src/repositories/event-repository.ts | Implements countByFilters using existing filter-query patterns plus deleted/expired filtering. |
| src/handlers/count-message-handler.ts | New handler to validate COUNT requests against limits and emit COUNT/CLOSED responses. |
| src/factories/message-handler-factory.ts | Routes MessageType.COUNT to the new handler. |
| src/@types/repositories.ts | Extends IEventRepository with countByFilters. |
| src/@types/messages.ts | Adds COUNT/CLOSED message types and payload typings for NIP-45. |
| package.json | Adds NIP-45 to supported NIPs list. |
| README.md | Documents NIP-45 support in the supported NIPs section. |
| .changeset/full-donuts-allow.md | Declares a minor release for adding NIP-45 COUNT support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8faa3f7 to
90e4778
Compare
|
Could you please test the performance of your implementation with the events I shared here: https://t.me/nostream_sob_2026/1/194 Are indexes properly being used? |
| } | ||
|
|
||
| private canCount(queryId: SubscriptionId, filters: SubscriptionFilter[]): string | undefined { | ||
| const subscriptionLimits = this.settings().limits?.client?.subscription |
There was a problem hiding this comment.
Let's add a setting to enable or disable COUNT. We can have it enabled by default.
@cameri I've tested with the events you shared, and yes the indexes are being used here
|
7d0a3f1 to
1de0a5b
Compare
|
CI checks are failing, we are using pino now for logging, not debug |
a4dce5d to
e77a599
Compare
…ting, and handler routing
e77a599 to
3677472
Compare



This PR adds NIP-45 COUNT support to nostream, including message validation, handler flow, and database counting by filters. It also adds tests for COUNT behavior and updates supported NIPs docs to include NIP-45.
Description
This PR adds NIP-45 COUNT support, so clients can ask the relay for a count directly instead of downloading many events to count on their side. It adds COUNT validation, COUNT/CLOSED handling, database counting by filters, and tests for the new behavior
Related Issue
nostream#341
Motivation and Context
This adds NIP-45 COUNT so clients can ask for a count directly from the relay. It saves bandwidth and is faster than downloading many events just to count them.
How Has This Been Tested?
by running automated test for the new COUNT feature, unit tests for message schema, message handler factory, count message handler, and repository count logic, also ran
npm run lintandnpm run build:checkmanual testing done on Postman by connecting to ws://127.0.0.1:8008
Screenshots (if appropriate):
Types of changes
Checklist: