NIP-RTC WebRTC¶
draft
optional
author:jacany
author:riccardobl
based on https://github.com/nostr-protocol/nips/blob/ead1cd6ca6b5b789d70e0d146d17266a2e8e2fba/100.md
This NIP defines how to do WebRTC communication over nostr.¶
Defining Rooms¶
Rooms are essentially the space that you will be connected to.
Rooms are created by generating a random secret key from wich the derived public key is used as the room id.
Event an one to one connection requires a room.
To comunicate with someone in the room the events must use a r
tag with the room id and a p
tag with the public key of the person you are trying to connect to.
Some events will require only the r
tag and as such are broadcasted to the entire room, others require the p
tag and are sent to a specific person in the room.
Clients MUST listen for both the r
and p
tag containing their pubkey so they know that event is intended for them, for the offer, answer and candidate events, and only to the r
tag for connect and disconnect events.
Encryption¶
The content
field is encrypted with NIP-44
, twice, first with the conversation key derives by sender priv + receiver pub and then with the conversation key derived by room priv + receiver pub.
Pseudo code:
function encrypt(localPrivKey, content, recipientPubkey, roomSecretKey){
const serialized = JSON.stringify(content);
let encrypted = nip44Encrypt(serialized, nip44ConversationKey(localPrivKey, recipientPubkey));
encrypted = nip44Encrypt(encrypted, nip44ConversationKey(roomSecretKey, recipientPubkey));
return encrypted;
}
function decrypt(localPrivKey, content, senderPubkey, roomPublicKey){
content = nip44Decrypt(content, nip44ConversationKey(localPrivKey, roomPublicKey));
content = nip44Decrypt(content, nip44ConversationKey(localPrivKey, senderPubkey));
return JSON.parse(decrypted);
}
Broadcasting that you are present¶
Announces that the client is ready to connect to others. The connection ID is inferred from the provided pubkey.
{
"kind": 25050,
"pubkey": "<sender pubkey>",
"tags": [
["t", "connect"],
["r", "room id"]
["expiration", "<expiration>"]
]
}
Closing¶
This is used when disconnecting from everybody else. Ex: when browser tab is closed.
{
"kind": 25050,
"pubkey": "<sender pubkey>",
"tags": [
["type", "disconnect"],
["r", "room id"]
]
}
Offering to connect¶
Used when responding to a type:connect
. Offering to connect to that peer.
{
"kind": 25050,
"pubkey": "<sender pubkey>",
"tags": [
["type", "offer"],
["p", "<reciever>"],
["r", "<room id>"]
],
"content": encrypt({
"offer": "<offer>",
"turn": ["protocol://turnserver:port", "protocol://turnserver2:port"],
...misc
})
}
Answering an Offer¶
{
"kind": 25050,
"pubkey": "<sender pubkey>",
"tags": [
["type", "answer"],
["p", "<reciever>"],
["r", "<room id>"]
],
"content": encrypt({
"sdp": "<sdp>",
"turn": ["protocol://turnserver:port", "protocol://turnserver2:port"],
...misc
})
}
Broadcasting ICE Candidate¶
{
"kind": 25050,
"pubkey": "<sender pubkey>",
"tags": [
["type", "candidate"],
["p", "<reciever>"],
["r", "<room id>"]
],
"content": encrypt({
"candidates": ["<sdp>"],
...misc
})
}