NIP-34 ====== Algorithmic Filter ------------------ `draft` `optional` `author:arthurfranca` This NIP introduces a set of simple algorithms meant to support diverse apps' event sorting needs. `Relays` MUST store an extra event field for each algo. Today there are two: `asc` and `seen_at`. According to [NIP-01](01.md), filters with `limit` attribute are replied with events sorted in **descending** order by the `created_at` event field (newest events first). But now when a `client` requests events while filtering by an algo field, the `relay` MUST replace the `created_at` field in the query with the algo field. For example, a SQL relay should turn this: `SELECT * FROM events WHERE kind in (1) ORDER BY created_at DESC LIMIT 5` Into this: `SELECT * FROM events WHERE kind in (1) ORDER BY asc DESC LIMIT 5` Upon replying to such requests, the supporting `relay` MUST add `algo: { score: "" }` field to each returned event JSON. ## Querying An extra `algo` filter key holds the selected algorithm as value. For example, the above query is ran in response to the following request: `["REQ", , { kinds: [1], limit: 5, algo: "asc" }]` ## Algorithms ### Asc `Relay` computes `asc` field once upon receiving the event. The lower the `created_at`, the higher `asc` will be. ```js function getAsc (createdAt) { const maxDateNowSeconds = 8640000000000 // 8.64e15 ms / 1000 // Make it lower the greater the ts is (the newer the createdAt is) // maxDateNowSeconds - -maxDateNowSeconds equals 17280000000000 and is lower than Number.MAX_SAFE_INTEGER return maxDateNowSeconds - createdAt } event.asc = getAsc(event.created_at) ``` ### Seen At `Relay` computes `seen_at` field once upon receiving the event. The event field is set with the timestamp of the moment the `relay` first became aware of it, in seconds. ```js event.seen_at = Math.floor(Date.now() / 1000) ``` ## Relay Connection URL Query Parameter For each algorithm, the `relay` MUST allow `clients` to specify the algo as an `algo` query param on the connection URL string. In other words, a `relay` whose regular URL is `wss://relay.url/r1` MUST also respond at `wss://relay.url/r1?algo=asc` and `wss://relay.url/r1?algo=seen_at`. Then, for example, when `clients` connect to `wss://relay.url/r1?algo=asc` and request events using the `limit` filter attribute, the relay will automatically sort events using the `asc` event field instead of the `created_at` one when replying. Clients can still override the chosen algorithm if using the `algo` filter attribute on `REQ` messages.