Skip to content

Commit c5e536f

Browse files
authored
Merge branch 'main' into copilot/revamp-contributing-workflow
2 parents 2ed271b + 3c78e61 commit c5e536f

34 files changed

Lines changed: 1704 additions & 93 deletions

.changeset/empty-nip40-tests.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
Test-only NIP-40 integration coverage; no release version bump required.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": patch
3+
---
4+
5+
Fix replaceable batch upserts to apply NIP-01 tie-breaker semantics when timestamps are equal by comparing event IDs.

.changeset/full-donuts-allow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": minor
3+
---
4+
5+
added NIP-45 COUNT support with end-to-end handling (validation, handler routing, DB counting, and tests).
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": patch
3+
---
4+
5+
Add unit tests for InvoiceRepository and UserRepository with sinon-stubbed DB client
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": patch
3+
---
4+
5+
Add integration tests for NIP-02 contact lists (Kind 3)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": patch
3+
---
4+
5+
Support uppercase tag filters (#A-Z) in filter schema validation

CONFIGURATION.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ The schema ships with a small, query-driven set of indexes. The most important o
8787
| `events_active_pubkey_kind_created_at_idx` | `REQ` with `authors`+`kinds` ordered by `created_at DESC, event_id ASC`; `hasActiveRequestToVanish`; by-pubkey deletes. Composite key `(event_pubkey, event_kind, event_created_at DESC, event_id)` so the ORDER BY tie-breaker is satisfied from the index without a sort step. |
8888
| `events_deleted_at_partial_idx` | Retention purge over soft-deleted rows. Partial on `deleted_at IS NOT NULL`. |
8989
| `invoices_pending_created_at_idx` | `findPendingInvoices` poll (`ORDER BY created_at ASC`). Partial on `status = 'pending'`. |
90-
| `event_tags (tag_name, tag_value)` | NIP-01 generic tag filters (`#e`, `#p`, …) via the normalized `event_tags` table. |
90+
| `event_tags (tag_name, tag_value)` | NIP-01 generic tag filters (`#e`, `#p`, `#K`, `#I`, …) via the normalized `event_tags` table. Both lowercase and uppercase single-letter tag filters are supported. |
9191
| `events_event_created_at_index` | Time-range scans (`since` / `until`). |
9292
| `events_event_kind_index` | Kind-only filters and purge kind-whitelist logic. |
9393

@@ -108,6 +108,17 @@ npm run db:verify-index-impact
108108

109109
The hot-path index migration (`20260420_120000_add_hot_path_indexes.js`) uses `CREATE INDEX CONCURRENTLY`, so it can be applied to a running relay without taking `ACCESS EXCLUSIVE` locks on the `events` or `invoices` tables.
110110

111+
## Tag filter scope
112+
113+
Subscription filters support single-letter tag filters using the `#<letter>` key syntax (NIP-01). Both lowercase (`#a``#z`) and uppercase (`#A``#Z`) variants are accepted.
114+
115+
| Scope | Examples | Usage |
116+
|-------|---------|-------|
117+
| Lowercase (`#a``#z`) | `#e`, `#p`, `#a`, `#k` | Standard NIP-01 tag queries; parent-level references in NIP-22 comment threading |
118+
| Uppercase (`#A``#Z`) | `#E`, `#P`, `#A`, `#K`, `#I` | Root-level references in NIP-22 comment threading and other NIPs that use uppercase to distinguish root vs. parent scope |
119+
120+
**NIP-22 comment threading (kind 1111):** NIP-22 comment events use lowercase tags (`#e`, `#a`, `#i`, `#k`) to reference the immediate parent and uppercase tags (`#E`, `#A`, `#I`, `#K`) to reference the root item. Filters must therefore accept both cases to allow clients to query the full comment thread hierarchy. For example, to find all comments on a root event: `{"kinds":[1111],"#E":["<root-event-id>"]}`, or to find comments of a specific root kind: `{"kinds":[1111],"#K":["1"]}`.
121+
111122
# Settings
112123

113124
Running `nostream` for the first time creates the settings file in `<project_root>/.nostr/settings.yaml`. If the file is not created and an error is thrown ensure that the `<project_root>/.nostr` folder exists. The configuration directory can be changed by setting the `NOSTR_CONFIG_DIR` environment variable. `nostream` will pick up any changes to this settings file without needing to restart.
@@ -163,6 +174,7 @@ The settings below are listed in alphabetical order by name. Please keep this ta
163174
| nip05.mode | NIP-05 verification mode: `enabled` requires verification, `passive` verifies without blocking, `disabled` does nothing. Defaults to `disabled`. |
164175
| nip05.verifyExpiration | Time in milliseconds before a successful NIP-05 verification expires and needs re-checking. Defaults to 604800000 (1 week). |
165176
| nip05.verifyUpdateFrequency | Minimum interval in milliseconds between re-verification attempts for a given author. Defaults to 86400000 (24 hours). |
177+
| nip45.enabled | Enable or disable NIP-45 COUNT handling. Defaults to true. |
166178
| paymentProcessors.lnbits.baseURL | Base URL of your Lnbits instance. |
167179
| paymentProcessors.lnbits.callbackBaseURL | Public-facing Nostream's Lnbits Callback URL. (e.g. https://relay.your-domain.com/callbacks/lnbits) |
168180
| paymentProcessors.lnurl.invoiceURL | [LUD-06 Pay Request](https://github.com/lnurl/luds/blob/luds/06.md) provider URL. (e.g. https://getalby.com/lnurlp/your-username) |

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ NIPs with a relay-specific implementation are listed here.
6161
- [x] NIP-33: Parameterized Replaceable Events
6262
- [x] NIP-40: Expiration Timestamp
6363
- [x] NIP-44: Encrypted Payloads (Versioned)
64+
- [x] NIP-45: Event Counts
6465
- [x] NIP-62: Request to Vanish
6566

6667
## Requirements

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
28,
1919
33,
2020
40,
21-
44
21+
44,
22+
45
2223
],
2324
"supportedNipExtensions": [
2425
"11a"

resources/default-settings.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ nip05:
5353
domainWhitelist: []
5454
# Block authors with NIP-05 at these domains
5555
domainBlacklist: []
56+
nip45:
57+
enabled: true
5658
network:
5759
maxPayloadSize: 524288
5860
# Uncomment only when using a trusted reverse proxy and configuring trustedProxies.

0 commit comments

Comments
 (0)