Compare commits

...

8 Commits

Author SHA1 Message Date
Kayhan Alizadeh a71cfc1a1c
Merge b63beba5e2 into 7dec812f99 2025-08-12 22:27:08 +00:00
Awiteb 7dec812f99
nip22: fix example type for external URL (#2011) 2025-08-11 17:26:05 -04:00
Yoji Shidara 739f3c5263
NIP-24: Fix heading levels (#2009) 2025-08-11 19:37:53 +09:00
Yoji Shidara 8830525250
NIP-21: Fix markup issue by closing backtick (#2008) 2025-08-11 19:35:36 +09:00
Kay b63beba5e2 d tag update. 2025-02-08 16:25:22 +00:00
Kay 4a980e0284 bloom filter specs. 2025-02-08 13:49:43 +00:00
Kay e146de7bbd add kind 30010. 2025-02-07 21:38:20 +00:00
Kay f45d82acbe nip-17: support seen events. 2025-02-07 21:36:55 +00:00
5 changed files with 106 additions and 14 deletions

96
17.md
View File

@ -131,7 +131,7 @@ Clients CAN offer disappearing messages by setting an `expiration` tag in the gi
## Publishing
Kind `10050` indicates the user's preferred relays to receive DMs. The event MUST include a list of `relay` tags with relay URIs.
Kind `10050` indicates the user's preferred relays to receive DMs based on [NIP-51](51.md). The event MUST include a list of `relay` tags with relay URIs.
```jsonc
{
@ -147,6 +147,100 @@ Kind `10050` indicates the user's preferred relays to receive DMs. The event MUS
Clients SHOULD publish kind `14` events to the `10050`-listed relays. If that is not found that indicates the user is not ready to receive messages under this NIP and clients shouldn't try.
## Seen status
A client MAY publish a kind `30010` which means saw messages with a `"d"` tag set to receivers pubkey.
The `.content` field has 4 sections separated by `:`:
1. The number of bits in the bit array,
2. The number of hash rounds applied.
3. The Base64 encoded string of a bloom filter containing message ids (gift wrapped) saw by receiver.
4. The salt encoded in the Base64.
The sender pubkey's client MAY query that specific event to check which messaged in this chat is seen by receiver to enhance user experience.
Bloom filters MUST use `SHA256` functions applied to the concatenation of the key, salt, and index, as demonstrated in the pseudocode below:
```js
class BloomFilter(size: Int, rounds: Int, buffer: ByteArray, salt: ByteArray) {
val bits = BitArray(buffer)
fun bitIndex(value: ByteArray, index: Byte) {
return BigInt(sha256(value || salt || index)) % size
}
fun add(id: HexID) {
val value = id.hexToByteArray()
for (index in 0 until rounds) {
bits[bitIndex(value, index)] = true
}
}
fun mightContains(id: HexID): Boolean {
val value = id.hexToByteArray()
for (index in 0 until rounds) {
if (!bits[bitIndex(value, index)]) {
return false
}
}
return true
}
fun encode() {
return size + ":" + rounds + ":" + base64Encode(bits.toByteArray()) + ":" + base64Encode(salt)
}
fun decode(str: String): BloomFilter {
val [sizeStr, roundsStr, bufferB64, saltB64] = str.split(":")
return BloomFilter(sizeStr.toInt(), roundsStr.toInt(), base64Decode(bufferB64), base64Decode(saltB64))
}
}
```
Example event for direct chats:
```js
{
"pubkey" : sha256(hkdf(private_key, salt: 'nip17') || "<badbdda507572b397852048ea74f2ef3ad92b1aac07c3d4e1dec174e8cdc962a>"),
"kind": 30010,
"created_at": 1738964056,
"tags": [
[
"d",
"bd4ae3e67e29964d494172261dc45395c89f6bd2e774642e366127171dfb81f5"
]
],
"content": "100:10:AAAkAQANcYQFCQoB:hZkZYqqdxcE",
}
```
In this example the pubkey `badbdda507572b397852048ea74f2ef3ad92b1aac07c3d4e1dec174e8cdc962a`, has confirmed that they saw the messages with ids of `ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b` and `460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c` from pubkey `bd4ae3e67e29964d494172261dc45395c89f6bd2e774642e366127171dfb81f5`.
> d tag uses the hkdf defined in [NIP-44](44.md).
Example event for group messages:
```js
{
"pubkey" : sha256(hkdf(private_key, salt: 'nip17') || "<badbdda507572b397852048ea74f2ef3ad92b1aac07c3d4e1dec174e8cdc962a>"),
"kind": 30010,
"created_at": 1738964056,
"tags": [
[
"d",
"bd4ae3e67e29964d494172261dc45395c89f6bd2e774642e366127171dfb81f5"
]
],
"content": "100:10:AAAkAQANcYQFCQoB:hZkZYqqdxcE",
}
```
A client MAY encrypt the `.content` based on [NIP-44](44.md) for more privacy.
## Relays
It's advisable that relays do not serve `kind:1059` to clients other than the ones tagged in them.

2
21.md
View File

@ -21,7 +21,7 @@ The identifiers that come after are expected to be the same as those defined in
### Linking HTML pages to Nostr entities
`<link>` tags with `rel="alternate"` can be used to associate webpages to Nostr events, in cases where the same content is served via the two mediums (for example, a web server that exposes Markdown articles both as HTML pages and as `kind:30023' events served under itself as a relay or through some other relay). For example:
`<link>` tags with `rel="alternate"` can be used to associate webpages to Nostr events, in cases where the same content is served via the two mediums (for example, a web server that exposes Markdown articles both as HTML pages and as `kind:30023` events served under itself as a relay or through some other relay). For example:
```
<head>

8
22.md
View File

@ -143,13 +143,13 @@ A comment on a website's url looks like this:
"tags": [
// referencing the root url
["I", "https://abc.com/articles/1"],
// the root "kind": for an url, the kind is its domain
["K", "https://abc.com"],
// the root "kind": for an url
["K", "web"],
// the parent reference (same as root for top-level comments)
["i", "https://abc.com/articles/1"],
// the parent "kind": for an url, the kind is its domain
["k", "https://abc.com"]
// the parent "kind": for an url
["k", "web"]
]
// other fields
}

13
24.md
View File

@ -8,8 +8,7 @@ Extra metadata fields and tags
This NIP keeps track of extra optional fields that can added to events which are not defined anywhere else but have become _de facto_ standards and other minor implementation possibilities that do not deserve their own NIP and do not have a place in other NIPs.
kind 0
======
### kind 0
These are extra fields not specified in NIP-01 that may be present in the stringified JSON of metadata events:
@ -19,24 +18,22 @@ These are extra fields not specified in NIP-01 that may be present in the string
- `bot`: a boolean to clarify that the content is entirely or partially the result of automation, such as with chatbots or newsfeeds.
- `birthday`: an object representing the author's birth date. The format is { "year": number, "month": number, "day": number }. Each field MAY be omitted.
### Deprecated fields
#### Deprecated fields
These are fields that should be ignored or removed when found in the wild:
- `displayName`: use `display_name` instead.
- `username`: use `name` instead.
kind 3
======
### kind 3
These are extra fields not specified in NIP-02 that may be present in the stringified JSON of follow events:
### Deprecated fields
#### Deprecated fields
- `{<relay-url>: {"read": <true|false>, "write": <true|false>}, ...}`: an object of relays used by a user to read/write. [NIP-65](65.md) should be used instead.
tags
====
### tags
These tags may be present in multiple event kinds. Whenever a different meaning is not specified by some more specific NIP, they have the following meanings:

View File

@ -222,6 +222,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `30007` | Kind mute sets | [51](51.md) |
| `30008` | Profile Badges | [58](58.md) |
| `30009` | Badge Definition | [58](58.md) |
| `30010` | Seen Messages | [17](17.md) |
| `30015` | Interest sets | [51](51.md) |
| `30017` | Create or update a stall | [15](15.md) |
| `30018` | Create or update a product | [15](15.md) |