Skip to content
Merged
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Learn more about `rust-nostr` at <https://rust-nostr.org>.
| ❌ | [B0 - Web Bookmarks](https://github.com/nostr-protocol/nips/blob/master/B0.md) |
| ✅ | [B7 - Blossom](https://github.com/nostr-protocol/nips/blob/master/B7.md) |
| ✅ | [C0 - Code Snippets](https://github.com/nostr-protocol/nips/blob/master/C0.md) |
| | [C7 - Chats](https://github.com/nostr-protocol/nips/blob/master/C7.md) |
| | [C7 - Chats](https://github.com/nostr-protocol/nips/blob/master/C7.md) |
| ✅ | [EE - Messaging using the MLS Protocol](https://github.com/nostr-protocol/nips/blob/master/EE.md) |

## State
Expand Down
1 change: 1 addition & 0 deletions crates/nostr/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

### Added

- Add NIP-C7 support (https://github.com/rust-nostr/nostr/pull/1067)
- Implement `ToBech32` trait for `Nip21`
- Add nip47 holdinvoice methods and notification (https://github.com/rust-nostr/nostr/pull/1019)
- Add `TransactionState` to `LookupInvoiceResponse` and `PaymentNotification` (https://github.com/rust-nostr/nostr/pull/1045)
Expand Down
70 changes: 70 additions & 0 deletions crates/nostr/src/event/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub enum Error {
/// NIP04 error
#[cfg(feature = "nip04")]
NIP04(nip04::Error),
/// NIP21 error
NIP21(nip21::Error),
/// NIP44 error
#[cfg(all(feature = "std", feature = "nip44"))]
NIP44(nip44::Error),
Expand Down Expand Up @@ -80,6 +82,7 @@ impl fmt::Display for Error {
Self::NIP03(e) => e.fmt(f),
#[cfg(feature = "nip04")]
Self::NIP04(e) => e.fmt(f),
Self::NIP21(e) => e.fmt(f),
#[cfg(all(feature = "std", feature = "nip44"))]
Self::NIP44(e) => e.fmt(f),
Self::NIP58(e) => e.fmt(f),
Expand Down Expand Up @@ -125,6 +128,12 @@ impl From<nip04::Error> for Error {
}
}

impl From<nip21::Error> for Error {
fn from(e: nip21::Error) -> Self {
Self::NIP21(e)
}
}

#[cfg(all(feature = "std", feature = "nip44"))]
impl From<nip44::Error> for Error {
fn from(e: nip44::Error) -> Self {
Expand Down Expand Up @@ -1706,6 +1715,67 @@ impl EventBuilder {
pub fn poll_response(response: PollResponse) -> Self {
response.to_event_builder()
}

/// Chat message
///
/// <https://github.com/nostr-protocol/nips/blob/master/C7.md>
#[inline]
pub fn chat_message<S>(content: S) -> Self
where
S: Into<String>,
{
Self::new(Kind::ChatMessage, content)
}

/// Chat message reply
///
/// <https://github.com/nostr-protocol/nips/blob/master/C7.md>
pub fn chat_message_reply<S>(
content: S,
reply_to: &Event,
relay_url: Option<RelayUrl>,
) -> Result<Self, Error>
where
S: Into<String>,
{
let mut content = content.into();

if !has_nostr_event_uri(&content, &reply_to.id) {
let nevent = Nip19Event {
event_id: reply_to.id,
author: None,
kind: None,
relays: relay_url.clone().into_iter().collect(),
};
content = format!("{}\n{content}", nevent.to_nostr_uri()?);
}

Ok(
Self::new(Kind::ChatMessage, content).tag(Tag::from_standardized_without_cell(
TagStandard::Quote {
event_id: reply_to.id,
relay_url,
public_key: Some(reply_to.pubkey),
},
)),
)
}
}

fn has_nostr_event_uri(content: &str, event_id: &EventId) -> bool {
const OPTS: NostrParserOptions = NostrParserOptions::disable_all().nostr_uris(true);

let parser = NostrParser::new().parse(content).opts(OPTS);

for token in parser.into_iter() {
if let Token::Nostr(nip21) = token {
if nip21.event_id().as_ref() == Some(event_id) {
return true;
}
}
}

false
}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions crates/nostr/src/event/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ kind_variants! {
CodeSnippet => 1337, "Code Snippets", "<https://github.com/nostr-protocol/nips/blob/master/C0.md>",
Poll => 1068, "Poll", "<https://github.com/nostr-protocol/nips/blob/master/88.md>",
PollResponse => 1018, "Poll response", "<https://github.com/nostr-protocol/nips/blob/master/88.md>",
ChatMessage => 9, "Chat Message", "<https://github.com/nostr-protocol/nips/blob/master/C7.md>",
}

impl PartialEq for Kind {
Expand Down
Loading