diff --git a/bindings/nostr-ffi/src/event/tag.rs b/bindings/nostr-ffi/src/event/tag.rs index 755c81dfd..1eaa0fc05 100644 --- a/bindings/nostr-ffi/src/event/tag.rs +++ b/bindings/nostr-ffi/src/event/tag.rs @@ -114,6 +114,7 @@ pub enum TagKindKnown { Payload, Anon, Proxy, + Emoji, } impl From<tag::TagKind> for TagKind { @@ -260,6 +261,9 @@ impl From<tag::TagKind> for TagKind { tag::TagKind::Proxy => Self::Known { known: TagKindKnown::Proxy, }, + tag::TagKind::Emoji => Self::Known { + known: TagKindKnown::Emoji, + }, tag::TagKind::Custom(unknown) => Self::Unknown { unknown }, } } @@ -316,6 +320,7 @@ impl From<TagKind> for tag::TagKind { TagKindKnown::Payload => Self::Payload, TagKindKnown::Anon => Self::Anon, TagKindKnown::Proxy => Self::Proxy, + TagKindKnown::Emoji => Self::Emoji, }, TagKind::Unknown { unknown } => Self::Custom(unknown), } @@ -505,6 +510,10 @@ pub enum TagEnum { id: String, protocol: String, }, + Emoji { + shortcode: String, + url: String, + }, } impl From<tag::Tag> for TagEnum { @@ -663,6 +672,10 @@ impl From<tag::Tag> for TagEnum { id, protocol: protocol.to_string(), }, + tag::Tag::Emoji { shortcode, url } => Self::Emoji { + shortcode, + url: url.to_string(), + }, } } } @@ -811,6 +824,10 @@ impl TryFrom<TagEnum> for tag::Tag { id, protocol: Protocol::from(protocol), }), + TagEnum::Emoji { shortcode, url } => Ok(Self::Emoji { + shortcode, + url: UncheckedUrl::from(url), + }), } } } diff --git a/bindings/nostr-ffi/src/nostr.udl b/bindings/nostr-ffi/src/nostr.udl index b949b8b96..760ac9699 100644 --- a/bindings/nostr-ffi/src/nostr.udl +++ b/bindings/nostr-ffi/src/nostr.udl @@ -435,6 +435,7 @@ enum TagKindKnown { "Payload", "Anon", "Proxy", + "Emoji", }; [Enum] @@ -492,6 +493,7 @@ interface TagEnum { Payload(string hash); Anon(string? msg); Proxy(string id, string protocol); + Emoji(string shortcode, string url); }; interface Tag { diff --git a/bindings/nostr-sdk-ffi/src/nostr_sdk.udl b/bindings/nostr-sdk-ffi/src/nostr_sdk.udl index d94459260..78d1844be 100644 --- a/bindings/nostr-sdk-ffi/src/nostr_sdk.udl +++ b/bindings/nostr-sdk-ffi/src/nostr_sdk.udl @@ -455,6 +455,7 @@ enum TagKindKnown { "Payload", "Anon", "Proxy", + "Emoji", }; [Enum] @@ -512,6 +513,7 @@ interface TagEnum { Payload(string hash); Anon(string? msg); Proxy(string id, string protocol); + Emoji(string shortcode, string url); }; interface Tag { diff --git a/crates/nostr/README.md b/crates/nostr/README.md index 1b6096391..3bde500dd 100644 --- a/crates/nostr/README.md +++ b/crates/nostr/README.md @@ -131,7 +131,7 @@ The following crate feature flags are available: | ✅ | [26 - Delegated Event Signing](https://github.com/nostr-protocol/nips/blob/master/26.md) | | ❌ | [27 - Text Note References](https://github.com/nostr-protocol/nips/blob/master/27.md) | | ✅ | [28 - Public Chat](https://github.com/nostr-protocol/nips/blob/master/28.md) | -| ❌ | [30 - Custom Emoji](https://github.com/nostr-protocol/nips/blob/master/30.md) | +| ✅ | [30 - Custom Emoji](https://github.com/nostr-protocol/nips/blob/master/30.md) | | ❌ | [31 - Dealing with Unknown Events](https://github.com/nostr-protocol/nips/blob/master/31.md) | | ❌ | [32 - Labeling](https://github.com/nostr-protocol/nips/blob/master/32.md) | | ✅ | [33 - Parameterized Replaceable Events](https://github.com/nostr-protocol/nips/blob/master/33.md) | diff --git a/crates/nostr/src/event/tag.rs b/crates/nostr/src/event/tag.rs index 40c8a57cf..8ba9c58f4 100644 --- a/crates/nostr/src/event/tag.rs +++ b/crates/nostr/src/event/tag.rs @@ -478,6 +478,8 @@ pub enum TagKind { Anon, /// Proxy Proxy, + /// Emoji + Emoji, /// Custom tag kind Custom(String), } @@ -532,6 +534,7 @@ impl fmt::Display for TagKind { Self::Payload => write!(f, "payload"), Self::Anon => write!(f, "anon"), Self::Proxy => write!(f, "proxy"), + Self::Emoji => write!(f, "emoji"), Self::Custom(tag) => write!(f, "{tag}"), } } @@ -591,6 +594,7 @@ where "payload" => Self::Payload, "anon" => Self::Anon, "proxy" => Self::Proxy, + "emoji" => Self::Emoji, tag => Self::Custom(tag.to_string()), } } @@ -683,6 +687,12 @@ pub enum Tag { id: String, protocol: Protocol, }, + Emoji { + /// Name given for the emoji, which MUST be comprised of only alphanumeric characters and underscores + shortcode: String, + /// URL to the corresponding image file of the emoji + url: UncheckedUrl, + }, } impl Tag { @@ -755,6 +765,7 @@ impl Tag { Self::Payload(..) => TagKind::Payload, Self::Anon { .. } => TagKind::Anon, Self::Proxy { .. } => TagKind::Proxy, + Self::Emoji { .. } => TagKind::Emoji, } } } @@ -926,6 +937,10 @@ where id: tag[1].to_string(), protocol: Protocol::from(&tag[2]), }), + TagKind::Emoji => Ok(Self::Emoji { + shortcode: tag[1].to_string(), + url: UncheckedUrl::from(&tag[2]), + }), _ => Ok(Self::Generic(tag_kind, tag[1..].to_vec())), } } else if tag_len == 4 { @@ -1172,6 +1187,9 @@ impl From<Tag> for Vec<String> { Tag::Proxy { id, protocol } => { vec![TagKind::Proxy.to_string(), id, protocol.to_string()] } + Tag::Emoji { shortcode, url } => { + vec![TagKind::Emoji.to_string(), shortcode, url.to_string()] + } } } }