mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-03-25 17:21:52 +01:00
Merge b63beba5e26c559fe806e4a7eade6df84ed9355a into 0619f370bca3485bb9c5870bc2defa03c7c3d10e
This commit is contained in:
commit
7f2e89c1cc
96
17.md
96
17.md
@ -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.
|
||||
|
@ -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) |
|
||||
|
Loading…
x
Reference in New Issue
Block a user