You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: support uppercase tag filters (#A-Z) in filter schema (#548)
* feat: support uppercase tag filters (#A-Z) in filter schema
Updates filter-schema.ts validation regex from /^#[a-z]$/ to /^#[a-zA-Z]$/
so uppercase tag filters like #I, #K, #E, #A (used by NIP-22 comment
threading) pass validation. Adds unit test covering NIP-22 uppercase
tag filter acceptance.
* refactor: reuse isGenericTagQuery in filter schema validation
* chore: add changeset for uppercase tag filter support
* docs: add tag filter scope section and NIP-22 comment threading test
---------
Co-authored-by: Ricardo Cabral <me@ricardocabral.io>
Copy file name to clipboardExpand all lines: CONFIGURATION.md
+12-1Lines changed: 12 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -87,7 +87,7 @@ The schema ships with a small, query-driven set of indexes. The most important o
87
87
|`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. |
88
88
|`events_deleted_at_partial_idx`| Retention purge over soft-deleted rows. Partial on `deleted_at IS NOT NULL`. |
89
89
|`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.|
|`events_event_kind_index`| Kind-only filters and purge kind-whitelist logic. |
93
93
@@ -108,6 +108,17 @@ npm run db:verify-index-impact
108
108
109
109
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.
110
110
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
+
111
122
# Settings
112
123
113
124
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.
0 commit comments