nips/34.md

88 lines
3.1 KiB
Markdown
Raw Normal View History

2023-06-02 13:40:46 -04:00
NIP-34
======
Algorithmic Filter
------------------
`draft` `optional` `author:arthurfranca`
This NIP introduces a set of simple algorithms meant to support diverse apps' event sorting needs.
2023-06-02 13:40:46 -04:00
2023-09-22 14:51:33 -04:00
`Relays` MUST store an extra event field for each algo. There are two algo event fields: `asc` and `seen_at`.
2023-06-12 14:22:20 -04:00
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).
2023-06-02 13:40:46 -04:00
2023-09-22 14:51:33 -04:00
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:
2023-06-02 13:40:46 -04:00
`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`
2023-06-02 13:40:46 -04:00
## Querying
2023-06-28 10:06:54 -04:00
An extra `algo` filter key holds the selected algorithm as value. For example, the above
query is ran in response to the following request:
2023-06-28 10:06:54 -04:00
`["REQ", <sub_id>, { kinds: [1], limit: 5, algo: "asc" }]`
2023-06-28 10:06:54 -04:00
2023-09-22 14:51:33 -04:00
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](#algorithms) section below.
For example, considering above request, one of the events replied should be as follows:
```js
{
id: "...",
// ... (other regular event fields)
kind: 1,
algo: {
score: 1695408196 // the stored event.asc field value
}
}
```
## Algorithms
2023-06-28 10:06:54 -04:00
2023-09-22 14:51:33 -04:00
This section describes how the extra event field is calculated for each algo before saving it to the database.
### Ascending (asc)
2023-06-02 13:40:46 -04:00
`Relay` computes `asc` field once upon receiving the event. The lower the `created_at`, the higher `asc` will be.
2023-06-02 13:40:46 -04:00
```js
function getAsc (createdAt) {
const maxDateNowSeconds = 8640000000000 // 8.64e15 ms / 1000
2023-06-02 13:40:46 -04:00
// 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)
```
2023-06-02 13:40:46 -04:00
2023-09-22 14:51:33 -04:00
### Seen At (seen_at)
2023-06-02 13:40:46 -04:00
`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.
2023-06-02 13:40:46 -04:00
```js
event.seen_at = Math.floor(Date.now() / 1000)
```
## Relay Connection URL Query Parameter
2023-06-02 13:40:46 -04:00
For each algorithm, the `relay` MUST allow `clients` to specify the algo as an `algo` query param on the connection URL string.
2023-06-02 13:40:46 -04:00
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`.
2023-06-02 13:40:46 -04:00
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.
2023-06-02 13:40:46 -04:00
Clients can still override the chosen algorithm if using the `algo` filter attribute on `REQ` messages.