Merge b63beba5e26c559fe806e4a7eade6df84ed9355a into 0619f370bca3485bb9c5870bc2defa03c7c3d10e

This commit is contained in:
k. 2025-03-20 12:30:34 +01:00 committed by GitHub
commit 7f2e89c1cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 96 additions and 1 deletions

96
17.md
View File

@ -130,7 +130,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
{
@ -146,6 +146,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.

View File

@ -209,6 +209,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) |