# 🌌 EasyNostr [![Rust](https://img.shields.io/badge/rust-stable-brightgreen.svg)](https://www.rust-lang.org/) [![Nostr](https://img.shields.io/badge/nostr-protocol-purple.svg)](https://nostr.com/) **EasyNostr** is a high-level, developer-friendly Rust library designed to simplify the development of Nostr applications. It wraps the powerful `nostr-sdk` to provide a clean, intuitive API for common operations like identity management, social feeds, and encrypted messaging. --- ## 🚀 Key Features * **Identity Management**: Simple handling of keys (nsec/npub). * **Social Connectivity**: Follow users and manage contact lists. * **Rich Feeds**: Access follow-based timelines, global discovery, and hashtag-based searches. * **Encrypted Messaging**: Secure NIP-17 direct messages. * **Profile Management**: Update account metadata (Kind 0) with support for standard and custom fields. * **Extensible Architecture**: Clean separation between protocol logic (NIPs) and high-level functions. --- ## 📦 Installation Add `easy-nostr` and its core dependencies to your `Cargo.toml`: ```toml [dependencies] easy-nostr = { path = "." } # Use the crate path tokio = { version = "1.48.0", features = ["full"] } anyhow = "1.0.100" ``` --- ## 🛠️ Usage Guide ### 1. Initialization & Connection Create a new instance and connect to your preferred relays. ```rust use easy_nostr::EasyNostr; use anyhow::Result; #[tokio::main] async fn main() -> Result<()> { // Initialize with your private key (nsec) let secret_key = "nsec1..."; let en = EasyNostr::new(secret_key).await?; // Add relays to connect to the network en.add_relays(vec![ "wss://relay.damus.io", "wss://nos.lol", "wss://relay.primal.net" ]).await?; println!("Connected to Nostr!"); Ok(()) } ``` ### 📝 Publishing Content Post a simple text note (Kind 1) to the network. ```rust let event_id = en.post_text("Building with EasyNostr is awesome!").await?; println!("Successfully posted! Event ID: {}", event_id); ``` ### 👤 Profile & Metadata Update account information (NIP-01) including support for custom fields (e.g., bot, birthday). ```rust en.set_metadata( Some("user_name".to_string()), Some("Display Name".to_string()), Some("About me...".to_string()), Some("user@domain.com".to_string()), // NIP-05 Some("user@getalby.com".to_string()), // LUD-16 Some("https://website.com".to_string()), Some("https://banner.com/img.png".to_string()), Some(false), // bot (custom field) Some("1990-01-01".to_string()), // birthday (custom field) ).await?; ``` ### 📰 Social Feeds #### Timeline (Followed Users) Fetch posts from a specific list of public keys. ```rust let follow_list = vec!["npub1...".to_string(), "npub2...".to_string()]; match en.get_timeline(follow_list).await { Ok(posts) => { for post in posts { println!("@{} says: {}", post.author, post.content); } } Err(e) => eprintln!("Failed to load timeline: {}", e), } ``` #### Discovery (Global Feed) Get recent random posts from connected relays. ```rust let global_posts = en.get_random_posts().await?; ``` #### Hashtag Search (NIP-12) Search for posts containing specific hashtags. ```rust let tags = vec!["bitcoin".to_string(), "rust".to_string()]; let filtered_posts = en.get_posts_by_hashtags(tags).await?; ``` ### 👥 Contacts & Following #### Follow a User ```rust en.create_contact("npub1...", Some("Alice".to_string())).await?; ``` #### Retrieve Contact List ```rust let contacts = en.get_contacts().await?; ``` ### 🔒 Private Messaging (NIP-17) #### Send a Message ```rust en.send_private_message("npub1...", "Hello, this is a secret!").await?; ``` #### Retrieve Conversations ```rust let history = en.get_private_messages("npub1...").await?; ``` --- ## 📂 Project Structure | Directory | Purpose | | :--- | :--- | | `src/lib.rs` | Main entry point and public `EasyNostr` interface. | | `src/functions/` | Implementation of high-level features (feeds, messaging, etc.). | | `src/nips/` | Protocol-level logic and data structures categorized by NIP. | | `src/bin/` | Utility binaries and examples. | --- ## ⚖️ License Distributed under the MIT License. See `LICENSE` for more information.