Skip to content

Commit df6755c

Browse files
committed
nostr/nips: extend NIP-58 with Badge Award event
1 parent 8c95bf2 commit df6755c

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

crates/nostr/src/nips/nip58.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,21 @@
22
//!
33
//! <https://github.com/nostr-protocol/nips/blob/master/58.md>
44
5-
use crate::{event::builder::Error, Event, EventBuilder, Keys, Kind, Tag};
5+
use crate::{event::builder::Error as BuilderError, Event, EventBuilder, Keys, Kind, Tag};
6+
7+
#[derive(Debug, thiserror::Error)]
8+
/// [`BadgeAward`] error
9+
pub enum Error {
10+
/// Invalid kind
11+
#[error("invalid kind")]
12+
InvalidKind,
13+
/// Identifier tag not found
14+
#[error("identifier tag not found")]
15+
IdentifierTagNotFound,
16+
/// Event builder Error
17+
#[error(transparent)]
18+
Event(#[from] crate::event::builder::Error),
19+
}
620

721
/// Simple struct to hold `width` x `height.
822
pub struct ImageDimensions(u64, u64);
@@ -106,3 +120,47 @@ impl BadgeDefinitionBuilder {
106120

107121
/// Badge definition event as specified in NIP-58
108122
pub struct BadgeDefinition(Event);
123+
124+
/// Badge award event as specified in NIP-58
125+
pub struct BadgeAward(Event);
126+
127+
impl BadgeAward {
128+
///
129+
pub fn new(
130+
badge_definition: &Event,
131+
awarded_pub_keys: Vec<Tag>,
132+
keys: &Keys,
133+
) -> Result<BadgeAward, Error> {
134+
let badge_id = match badge_definition.kind {
135+
Kind::BadgeDefinition => badge_definition.tags.iter().find_map(|t| match t {
136+
Tag::Identifier(id) => Some(id),
137+
_ => None,
138+
}),
139+
_ => return Err(Error::InvalidKind),
140+
}
141+
.ok_or(Error::IdentifierTagNotFound)?;
142+
143+
let awarded_pub_keys: Vec<Tag> = awarded_pub_keys
144+
.into_iter()
145+
.filter(|e| matches!(e, Tag::PubKey(..)))
146+
.collect();
147+
148+
if awarded_pub_keys.is_empty() {
149+
return Err(Error::InvalidKind);
150+
}
151+
152+
let a_tag = Tag::A {
153+
kind: Kind::BadgeDefinition,
154+
public_key: keys.public_key(),
155+
identifier: badge_id.to_owned(),
156+
relay_url: None,
157+
};
158+
let mut tags = vec![a_tag];
159+
tags.extend(awarded_pub_keys);
160+
161+
let event_builder = EventBuilder::new(Kind::BadgeAward, String::new(), &tags);
162+
let event = event_builder.to_event(keys)?;
163+
164+
Ok(BadgeAward(event))
165+
}
166+
}

0 commit comments

Comments
 (0)