Private Messages (NIP-17)
NIP-17 defines an encrypted direct messaging scheme using NIP-44 encryption, NIP-59 seals and gift wraps. See NIP-17 for a detailed description. This scheme is used to send messages between two parties avoiding metadata leaks as in NIP-04 (Encrypted Direct Message).
Rust
// Sender
let alice_keys =
Keys::parse("5c0c523f52a5b6fad39ed2403092df8cebc36318b39383bca6c00808626fab3a")?;
let alice_client = Client::new(alice_keys);
alice_client.add_relay(url.clone()).await?;
alice_client.connect().await;
// Receiver
let bob_keys = Keys::parse("nsec1j4c6269y9w0q2er2xjw8sv2ehyrtfxq3jwgdlxj6qfn8z4gjsq5qfvfk99")?;
let bob_client = Client::new(bob_keys.clone());
bob_client.add_relay(url.clone()).await?;
bob_client.connect().await;
// Initialize subscription on Bob's side before sending the message
// Limit is set to 0 to get only new events!
// Timestamp::now() CAN'T be used for gift wrap since the timestamps are tweaked!
let message_filter = Filter::new()
.kind(Kind::GiftWrap)
.pubkey(bob_keys.public_key())
.limit(0);
let subscription_id = bob_client.subscribe(vec![message_filter], None).await?;
// Alice sends private message to Bob
alice_client.send_private_msg(bob_keys.public_key(), "Hello Bob!".to_string(), None).await?;
println!("Sent private message to Bob");
// Bob receives private message
bob_client.handle_notifications(|notification| async {
if let RelayPoolNotification::Event { event, .. } = notification {
if event.kind == Kind::GiftWrap {
let UnwrappedGift { rumor, sender } = bob_client.unwrap_gift_wrap(&event).await?;
if rumor.kind == Kind::PrivateDirectMessage {
println!("Bob received private message from {sender}: {}", &rumor.content);
return Ok(true); // Message received, exit.
}
}
}
Ok(false)
}).await?;
bob_client.unsubscribe(subscription_id.val).await;
Python
TODO
JavaScript
TODO
Kotlin
TODO
Swift
TODO