use nostr_sdk::nips::{nip44, nip59};
use nostr_sdk::prelude::*;
use crate::error::{MostroError, ServiceError};
pub async fn wrap_chat_message(
sender_trade_keys: &Keys,
conv: &Keys,
sign: &Keys,
message: &str,
) -> Result<Event, MostroError> {
wrap_chat_message_with_tags(sender_trade_keys, conv, sign, message, Vec::new()).await
}
pub async fn wrap_chat_message_with_tags(
sender_trade_keys: &Keys,
conv: &Keys,
sign: &Keys,
message: &str,
extra_tags: Vec<Tag>,
) -> Result<Event, MostroError> {
if extra_tags.iter().any(|t| t.kind() == TagKind::p()) {
return Err(MostroError::MostroInternalErr(
ServiceError::UnexpectedError("extra_tags must not contain a p tag".to_string()),
));
}
let now = Timestamp::now();
let inner = EventBuilder::text_note(message)
.custom_created_at(now)
.build(sender_trade_keys.public_key())
.sign(sender_trade_keys)
.await
.map_err(|e| MostroError::MostroInternalErr(ServiceError::NostrError(e.to_string())))?;
let content = nip44::encrypt(
conv.secret_key(),
&conv.public_key(),
inner.as_json(),
nip44::Version::V2,
)
.map_err(|e| MostroError::MostroInternalErr(ServiceError::EncryptionError(e.to_string())))?;
let mut tags = vec![Tag::public_key(conv.public_key())];
tags.extend(extra_tags);
EventBuilder::new(Kind::PrivateDirectMessage, content)
.tags(tags)
.custom_created_at(now)
.sign_with_keys(sign)
.map_err(|e| MostroError::MostroInternalErr(ServiceError::NostrError(e.to_string())))
}
pub async fn wrap_giftwrap_chat_message(
sender_trade_keys: &Keys,
shared_pubkey: &PublicKey,
message: &str,
) -> Result<Event, MostroError> {
let inner = EventBuilder::text_note(message)
.build(sender_trade_keys.public_key())
.sign(sender_trade_keys)
.await
.map_err(|e| MostroError::MostroInternalErr(ServiceError::NostrError(e.to_string())))?;
let ephemeral = Keys::generate();
let encrypted = nip44::encrypt(
ephemeral.secret_key(),
shared_pubkey,
inner.as_json(),
nip44::Version::V2,
)
.map_err(|e| MostroError::MostroInternalErr(ServiceError::EncryptionError(e.to_string())))?;
EventBuilder::new(Kind::GiftWrap, encrypted)
.tag(Tag::public_key(*shared_pubkey))
.custom_created_at(Timestamp::tweaked(nip59::RANGE_RANDOM_TIMESTAMP_TWEAK))
.sign_with_keys(&ephemeral)
.map_err(|e| MostroError::MostroInternalErr(ServiceError::NostrError(e.to_string())))
}