3.1 KiB
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. There are two algo event fields: asc
and seen_at
.
According to NIP-01, 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 to be filtered by an algo field, the relay
MUST replace the created_at
field in the query with the algo field. For example, when filtering by the asc
algo, 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
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", <sub_id>, { kinds: [1], limit: 5, algo: "asc" }]
Upon replying to such requests, the supporting relay
MUST add an extra score
field,
namespaced in an algo
key, holding the selected algo's event field value. It must be
added to each returned event JSON.
The algo field is calculated as described in the Algorithms section below.
For example, considering above request, one of the events replied should be as follows:
{
id: "...",
// ... (other regular event fields)
kind: 1,
algo: {
score: 1695408196 // the stored event.asc field value
}
}
Algorithms
This section describes how the extra event field is calculated for each algo before saving it to the database.
Ascending (asc)
Relay
computes asc
field once upon receiving the event. The lower the created_at
, the higher asc
will be.
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 (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.
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.