All basic functions plus guide README to use

This commit is contained in:
Malte Schröder
2025-12-19 20:25:39 +01:00
parent db48f07b78
commit 397635d43e
12 changed files with 486 additions and 22 deletions

75
src/functions/feed.rs Normal file
View File

@@ -0,0 +1,75 @@
use crate::nips::nip01::Post;
use anyhow::{Context, Result};
use nostr_sdk::prelude::*;
use std::time::Duration;
/// Fetches a timeline/feed of posts from specific users (Followed users).
///
/// # Arguments
/// * `client` - The Nostr client.
/// * `followed_pubkeys` - A list of hex strings (bech32 also works if parsed correctly, but we assume hex or wait for parsing) representing the users to follow.
///
/// The function parses the keys, creates a filter, and returns a list of sorted Posts.
pub async fn get_followed_feed(
client: &Client,
followed_pubkeys: Vec<String>,
) -> Result<Vec<Post>> {
let mut keys = Vec::new();
for key in followed_pubkeys {
// We try to parse each key. If one fails, we just ignore it or log it (here we context it).
let pk = PublicKey::parse(&key).context(format!("Invalid public key: {}", key))?;
keys.push(pk);
}
if keys.is_empty() {
return Ok(Vec::new());
}
// Create a filter for Text Notes (Kind 1) from these authors
let filter = Filter::new().kind(Kind::TextNote).authors(keys).limit(50); // Limit to 50 posts for now
let timeout = Duration::from_secs(10);
let events = client.fetch_events(filter, timeout).await?;
// Convert Events to our Post struct
let mut posts: Vec<Post> = events
.into_iter()
.map(|e| Post {
id: e.id,
author: e.pubkey,
content: e.content.clone(),
created_at: e.created_at,
})
.collect();
// Sort by created_at descending (newest first)
posts.sort_by(|a, b| b.created_at.cmp(&a.created_at));
Ok(posts)
}
/// Fetches random (recent) posts from the connected Relays (Global Feed).
///
/// This is useful for discovery.
pub async fn get_random_posts(client: &Client) -> Result<Vec<Post>> {
// Filter for any Text Note, limit 20
let filter = Filter::new().kind(Kind::TextNote).limit(20);
let timeout = Duration::from_secs(10);
let events = client.fetch_events(filter, timeout).await?;
let mut posts: Vec<Post> = events
.into_iter()
.map(|e| Post {
id: e.id,
author: e.pubkey,
content: e.content.clone(),
created_at: e.created_at,
})
.collect();
// Sort by newest first
posts.sort_by(|a, b| b.created_at.cmp(&a.created_at));
Ok(posts)
}

View File

@@ -1,5 +1,7 @@
pub mod new;
pub mod messages;
pub mod relays;
pub mod create_contact;
pub mod feed;
pub mod get_contacts;
pub mod create_contact;
pub mod messages;
pub mod new;
pub mod publish;
pub mod relays;

13
src/functions/publish.rs Normal file
View File

@@ -0,0 +1,13 @@
use crate::nips::nip01;
use anyhow::Result;
use nostr_sdk::prelude::*;
/// Publishes a text post to the network.
///
/// # Arguments
/// * `client` - The Nostr client.
/// * `content` - The text content of the post.
pub async fn post_text_note(client: &Client, content: &str) -> Result<EventId> {
// We delegate the actual protocol work to the nip01 module
nip01::publish_text(client, content).await
}