3.8 KiB
EasyNostr
A simple and functional Rust crate for building Nostr applications. This library handles the complexity of keys, relays, and protocol details (NIPs), giving you easy-to-use functions for a social media app.
Features
- Identity: Easy management of keys (nsec/npub).
- Social Feed: View timeline of friends or global random posts.
- Posting: Publish text notes (Kind 1).
- Contacts: Follow users and retrieve your contact list.
- Direct Messages: Send and receive encrypted private messages (NIP-17 & NIP-04).
Getting Started
1. Initialize the Client
First, you need to create an instance of EasyNostr using your secret key (nsec).
use easy_nostr::EasyNostr;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Your secret key (nsec)
let my_secret_key = "nsec1...";
// Initialize client
let client = EasyNostr::new(my_secret_key).await?;
// Connect to Relays
client.add_relays(vec![
"wss://relay.damus.io",
"wss://nos.lol",
"wss://relay.primal.net"
]).await?;
println!("Connected and ready!");
Ok(())
}
Capabilities & Usage
📝 Publishing Posts
Post a simple text message to the network.
let event_id = client.post_text("Hello Nostr world!").await?;
println!("Posted! ID: {}", event_id.to_bech32()?);
📰 Reading Feeds
You can read posts from people you follow (Timeline) or random posts from the network.
Get Timeline (Followed Users):
// List of public keys (npubs) you want to see posts from
let following = vec!["npub1...", "npub1..."];
let posts = client.get_timeline(following).await?;
for post in posts {
println!("@{} wrote: {}", post.author.to_bech32()?, post.content);
}
Get Global Feed (Random/Recent):
let random_posts = client.get_random_posts().await?;
for post in random_posts {
println!("New Post: {}", post.content);
}
The Post Structure:
When you get posts, you receive a Post struct:
post.id: The unique Event ID.post.author: The PublicKey of the author.post.content: The text content.post.created_at: The timestamp.
👥 Managing Contacts (Followers)
Manage who you follow.
Follow a User:
let jack_dorsey = "npub1sg6plzptd64u62a878hep2kd8856nmmhd0x479jp6bir725uqqks698teq";
// Context: (NPub, Optional Nickname)
client.create_contact(jack_dorsey, Some("Jack".to_string())).await?;
Get Your Contact List:
let my_contacts = client.get_contacts().await?;
for contact in my_contacts {
println!("Following: {:?}", contact.public_key.to_bech32()?);
if let Some(alias) = &contact.alias {
println!(" - Alias: {}", alias);
}
}
🔒 Direct Messages (DMs)
Send and receive encrypted private chats. Supports modern GiftWraps (NIP-17).
Send a DM:
let friend_npub = "npub1...";
client.send_private_message(friend_npub, "Hey, this is secret!").await?;
Read DMs:
let friend_npub = "npub1...";
let messages = client.get_private_messages(friend_npub).await?;
for msg in messages {
let direction = if msg.is_incoming { "Received" } else { "Sent" };
println!("[{}] {}", direction, msg.content);
}
The Message Structure:
msg.sender: PublicKey of the sender.msg.content: Decrypted text.msg.is_incoming:trueif you received it,falseif you sent it.msg.created_at: Usemsg.created_at.as_secs()to get the unix timestamp.
Dependencies
Ensure you have the following in your Cargo.toml. easy-nostr re-exports most things you need, but you might need anyhow and tokio.
[dependencies]
nostr-sdk = { version = "0.44.1", features = ["all-nips", "nip44"] }
tokio = { version = "1.48.0", features = ["full"] }
anyhow = "1.0.100"