Generic single-letter tag filters (NIP-12 / NIP-01 §filters) #2

Open
opened 2026-05-03 13:41:26 +00:00 by padreug · 0 comments
Owner

Problem

The NostrFilter struct hardcodes only three tag fields:

# relay/filter.py
e: list[str] = Field(default=[], alias="#e")
p: list[str] = Field(default=[], alias="#p")
d: list[str] = Field(default=[], alias="#d")

Any other single-letter tag query (#a, #t, #r, #k, #l, …) is
silently dropped. NIP-01 §filters mandates support for arbitrary
single-letter tag filters; this is the historical NIP-12 behaviour now
folded into NIP-01.

Impact

  • #a filters cannot select addressable events by their kind:pubkey:d
    coordinate — affects clients that follow NIP-33 addressable replaceable
    flows
  • #t (hashtag), #r (reference), #k (kind reference) and other
    ecosystem conventions don't work on this relay
  • README already lists this as a TODO under NIP-12

Suggested approach

Replace the three fixed fields with a dict[str, list[str]] keyed by the
single-letter tag name (matching ^#[a-zA-Z]$). Update both
NostrFilter.matches() and NostrFilter.to_sql_components() accordingly.

Reference designs:

  • nostream: .catchall(z.array(z.string().max(1024))) + isGenericTagQuery regex
  • strfry: flat_hash_map<char, FilterSetBytes>
  • khatru: go-nostr nostr.TagMap

Out of scope

This was deferred from #PR-feat-nip17-gift-wrap-support because NIP-17
only needs #p, which already works.

## Problem The `NostrFilter` struct hardcodes only three tag fields: ```python # relay/filter.py e: list[str] = Field(default=[], alias="#e") p: list[str] = Field(default=[], alias="#p") d: list[str] = Field(default=[], alias="#d") ``` Any other single-letter tag query (`#a`, `#t`, `#r`, `#k`, `#l`, …) is silently dropped. NIP-01 §filters mandates support for arbitrary single-letter tag filters; this is the historical NIP-12 behaviour now folded into NIP-01. ## Impact - `#a` filters cannot select addressable events by their `kind:pubkey:d` coordinate — affects clients that follow NIP-33 addressable replaceable flows - `#t` (hashtag), `#r` (reference), `#k` (kind reference) and other ecosystem conventions don't work on this relay - README already lists this as a TODO under NIP-12 ## Suggested approach Replace the three fixed fields with a `dict[str, list[str]]` keyed by the single-letter tag name (matching `^#[a-zA-Z]$`). Update both `NostrFilter.matches()` and `NostrFilter.to_sql_components()` accordingly. Reference designs: - nostream: `.catchall(z.array(z.string().max(1024)))` + `isGenericTagQuery` regex - strfry: `flat_hash_map<char, FilterSetBytes>` - khatru: go-nostr `nostr.TagMap` ## Out of scope This was deferred from #PR-feat-nip17-gift-wrap-support because NIP-17 only needs `#p`, which already works.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/nostrrelay#2
No description provided.