mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-11-13 23:39:08 -05:00
Simplify text and replace nip34 namespace with 'algo'
This commit is contained in:
parent
6fac0f53f5
commit
ad6ee17624
100
34.md
100
34.md
|
@ -6,72 +6,62 @@ 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).
|
||||
|
||||
For filters containing `limit` attribute, this NIP-34 adds `nip34` as a new filter attribute
|
||||
whose value indicates the algorithm the `client` wishes to use for sorting events.
|
||||
|
||||
For instance, if a `client` sends the message `["REQ", <sub_id>, { kinds: [1], ..., limit: 5, nip34: "a" }]`,
|
||||
it is asking the `relay` to sort five kind 1 events in **descending** order by the `nip34a` event field instead of by `created_at`.
|
||||
|
||||
In the above example, `relays` that want to support the NIP-34a algorithm must add the `nip34a` event field to each event saved to their internal databases. The new field is populated following rules described at the NIP-34a NIP extension.
|
||||
|
||||
Besides that, upon replying to such requests, the supporting `relay` MUST add `nip34: { score: "<nip34a value>" }` field to each returned event JSON.
|
||||
|
||||
It is a backward-compatible proposal because non-supporting `relays` ignore the `nip34` filter attribute and sort by `created_at`, as usual.
|
||||
|
||||
`Relays` should advertise support using both [NIP-11](11.md) `supported_nips` and `supported_nip_extensions` fields.
|
||||
|
||||
`Relays` should limit max daily user events, such as likes, reposts, zaps and comments, per IP to avoid bad actors gaming the algorithms.
|
||||
|
||||
## Motivation
|
||||
|
||||
Different algorithms are required to support diverse apps' event sorting needs.
|
||||
|
||||
However, they should be presented as optional and backward-compatible features that are easy to support.
|
||||
|
||||
Considering the request example above, we expect most `relays` to simply swap the `created_at` field
|
||||
on a regular query for the `nip34a` one. If a `relay` implementation uses a SQL DB, the above filter would turn this:
|
||||
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 nip34a DESC LIMIT 5`
|
||||
`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: "<asc value>" }` 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", <sub_id>, { 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 supported NIP-34 algorithm, the `relay` MUST allow `clients` to specify the algo as a `nip34` query param on connection URL string.
|
||||
For each algorithm, the `relay` MUST allow `clients` to specify the algo as an `algo` query param on the connection URL string.
|
||||
|
||||
For example, if supporting the NIP-34a algo, a `relay` whose regular URL is `wss://relay.url/r1` must
|
||||
also respond at `wss://relay.url/r1?nip34=a`.
|
||||
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 when `clients` connect to `wss://relay.url/r1?nip34=a` and request events using `limit`
|
||||
filter attribute, the relay will automatically sort events in **descending** order by the `nip34a` event field instead of by `created_at` when replying. Clients can still override the chosen algorithm if using the
|
||||
`nip34` filter attribute.
|
||||
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.
|
||||
|
||||
## How Clients Make Custom Requests for a Specific User
|
||||
|
||||
The algorithms are generic, meaning the "score" represented by the new event field does not differ for different users.
|
||||
|
||||
However, smart `clients` may keep track of pubkeys from whom the user is consuming content, also hashtags, for instance, and use such pubkeys/hashtags as a way to tailor the query to that specific user. For example:
|
||||
|
||||
`["REQ", <sub_id>, { kinds: [1], limit: 5, nip34: "b", authors: ["pubkey1 user follows", "pubkey2 user has read content from recently", "pubkey3 that user has liked content recently"] }, { kinds: [1], limit: 5, nip34: "b", "#t": ["cat", "bitcoin"] }]`
|
||||
|
||||
## Rules for Submitting a NIP-34 Algorithm
|
||||
|
||||
Each algorithm section describes **how** and **when** to compute the corresponding database field for each event.
|
||||
|
||||
For example, [NIP-34asc](34asc.md) extension teaches `relays` the math used to update the `nip34asc` event field.
|
||||
|
||||
The NIP extension MUST have atleast one example in any programming language, preferably with inline comments.
|
||||
|
||||
Bugfixes and small updates to embrace new event kinds may be submitted at any time by the algorithm author(s).
|
||||
|
||||
## Available Algorithms
|
||||
|
||||
| Extension | Name | Description | Modification Date |
|
||||
| ------------------- | ----------| -------------------------------------------------- | ----------------- |
|
||||
| [34asc](34asc.md) | Ascending | Events with older `created_at` are retrieved first | 18 / jul / 2023 |
|
||||
| [34seen](34seen.md) | Seen At | Events are desc sorted by first seen at timestamp | 18 / jul / 2023 |
|
||||
Clients can still override the chosen algorithm if using the `algo` filter attribute on `REQ` messages.
|
||||
|
|
34
34asc.md
34
34asc.md
|
@ -1,34 +0,0 @@
|
|||
NIP-34asc
|
||||
=========
|
||||
|
||||
Ascending
|
||||
---------
|
||||
|
||||
`draft` `optional` `author:arthurfranca`
|
||||
|
||||
Events with older `created_at` are retrieved first.
|
||||
|
||||
## Motivation
|
||||
|
||||
For thread building it may better showing first comments at top to make it easier to understand
|
||||
the context of newer comments.
|
||||
|
||||
## Implementation
|
||||
|
||||
`Relay` computes `nip34asc` field once upon receiving the event.
|
||||
|
||||
The lower the `created_at`, the higher `nip34asc` will be.
|
||||
|
||||
### Javascript
|
||||
|
||||
```js
|
||||
function getNip34asc (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.nip34asc = getNip34asc(event.created_at)
|
||||
```
|
26
34seen.md
26
34seen.md
|
@ -1,26 +0,0 @@
|
|||
NIP-34seen
|
||||
==========
|
||||
|
||||
Seen At
|
||||
-------
|
||||
|
||||
`draft` `optional` `author:arthurfranca` `author:mikedilger`
|
||||
|
||||
Events are desc sorted by first seen at timestamp.
|
||||
|
||||
## Motivation
|
||||
|
||||
Some `clients` may want to check if `relay` has recently received old events
|
||||
created before last time they checked.
|
||||
|
||||
## Implementation
|
||||
|
||||
`Relay` computes `nip34seen` field once upon receiving the event.
|
||||
|
||||
The event field is set with the timestamp of the moment the `relay` first became aware of it.
|
||||
|
||||
### Javascript
|
||||
|
||||
```js
|
||||
event.nip34seen = Math.floor(Date.now() / 1000)
|
||||
```
|
Loading…
Reference in New Issue
Block a user