mostro_core/chat/
unwrap.rs1use nostr_sdk::nips::nip44;
4use nostr_sdk::prelude::*;
5
6use crate::error::{MostroError, ServiceError};
7
8#[derive(Debug, Clone)]
10pub struct ChatMessage {
11 pub content: String,
13 pub sender: PublicKey,
16 pub created_at: Timestamp,
18}
19
20pub async fn unwrap_chat_message(
31 shared_keys: &Keys,
32 event: &Event,
33) -> Result<ChatMessage, MostroError> {
34 if event.kind != Kind::GiftWrap {
35 return Err(MostroError::MostroInternalErr(
36 ServiceError::UnexpectedError("event is not a GiftWrap".to_string()),
37 ));
38 }
39
40 let decrypted = nip44::decrypt(shared_keys.secret_key(), &event.pubkey, &event.content)
41 .map_err(|e| {
42 MostroError::MostroInternalErr(ServiceError::DecryptionError(format!(
43 "shared-key decrypt failed: {e}"
44 )))
45 })?;
46
47 let inner = Event::from_json(&decrypted).map_err(|e| {
48 MostroError::MostroInternalErr(ServiceError::NostrError(format!(
49 "malformed inner chat event: {e}"
50 )))
51 })?;
52
53 if inner.kind != Kind::TextNote {
54 return Err(MostroError::MostroInternalErr(
55 ServiceError::UnexpectedError("inner chat event is not a TextNote".to_string()),
56 ));
57 }
58
59 inner.verify().map_err(|e| {
60 MostroError::MostroInternalErr(ServiceError::NostrError(format!(
61 "invalid inner chat signature: {e}"
62 )))
63 })?;
64
65 Ok(ChatMessage {
66 content: inner.content,
67 sender: inner.pubkey,
68 created_at: inner.created_at,
69 })
70}