From e943ab847ae25341eff688ef47812f8003c3043e Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Fri, 2 Jan 2026 01:37:06 +0900 Subject: [PATCH] add NIP-50 query extension --- 50.md | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/50.md b/50.md index 08ce4fd2..b702d5dd 100644 --- a/50.md +++ b/50.md @@ -26,11 +26,50 @@ Relays SHOULD interpret the query to the best of their ability and return events Relays SHOULD perform matching against `content` event field, and MAY perform matching against other fields if that makes sense in the context of a specific kind. -Results SHOULD be returned in descending order by quality of search result (as defined by the implementation), -not by the usual `.created_at`. The `limit` filter SHOULD be applied after sorting by matching score. A query string may contain `key:value` pairs (two words separated by colon), these are extensions, relays SHOULD ignore extensions they don't support. +### Query Expression Extensions + +Relays MAY support query expressions with boolean operators and filter attributes. When supported, this MUST be advertised in NIP-11: + +```json +{ + "supported_nips": [50], + "nip50_search": { + "boolean_operators": true, + "filter_attributes": ["limit", "since", "until"] + } +} +``` + +When `boolean_operators` is `true`, relays SHOULD support: + +- Terms split by whitespace (implicit AND) +- Double quotes for phrase matching: `"hello world"` +- Boolean operators: `AND`, `OR` (uppercase, case-sensitive) +- Parentheses for grouping: `(cat AND dog) OR bird` +- Operator precedence: `AND` binds tighter than `OR` + +Examples: +- `hello world` → both terms required (implicit AND) +- `hello OR world` → either term matches +- `cat AND (dog OR bird)` → "cat" plus either "dog" or "bird" + +When `filter_attributes` is present, relays SHOULD support filter attributes in the query string: + +- `limit:` - limit number of results (e.g., `limit:50`) +- `since:` - filter events after timestamp (e.g., `since:1609459200`) +- `until:` - filter events before timestamp (e.g., `until:1640995200`) + +Examples: +- `nostr limit:50` → search "nostr" and return up to 50 results +- `bitcoin since:1609459200` → search "bitcoin" for events after the specified time +- `cats OR dogs limit:100 since:1640995200` → combined query with filters + +Results SHOULD be returned in descending order by quality of search result (as defined by the implementation), +not by the usual `.created_at`. The `limit` filter SHOULD be applied after sorting by matching score. + Clients may specify several search filters, i.e. `["REQ", "", { "search": "orange" }, { "kinds": [1, 2], "search": "purple" }]`. Clients may include `kinds`, `ids` and other filter field to restrict the search results to particular event kinds.