Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit 6af8528

Browse files
committed
Create recommendation events
1 parent 4e2b601 commit 6af8528

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

mutiny-core/src/nostr/mod.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ use lnurl::lnurl::LnUrl;
2626
use nostr::key::SecretKey;
2727
use nostr::nips::nip04::{decrypt, encrypt};
2828
use nostr::nips::nip47::*;
29-
use nostr::{Event, EventBuilder, EventId, Filter, JsonUtil, Keys, Kind, Metadata, Tag, Timestamp};
29+
use nostr::{
30+
Event, EventBuilder, EventId, Filter, JsonUtil, Keys, Kind, Metadata, Tag, TagKind, Timestamp,
31+
};
3032
use nostr_sdk::{Client, NostrSigner, RelayPoolNotification};
3133
use serde::{Deserialize, Serialize};
3234
use std::collections::{HashMap, HashSet};
@@ -1195,6 +1197,60 @@ impl<S: MutinyStorage> NostrManager<S> {
11951197
Ok(event_id)
11961198
}
11971199

1200+
/// Creates a recommendation event for a federation
1201+
pub async fn recommend_federation(
1202+
&self,
1203+
invite_code: &InviteCode,
1204+
) -> Result<EventId, MutinyError> {
1205+
let kind = Kind::from(18173);
1206+
// first pull down our current recommendation event, we need to do this
1207+
// to make sure we don't overwrite any other recommendations
1208+
let filter = Filter::new().kind(kind).author(self.public_key).limit(1);
1209+
// fetch events
1210+
let events = self
1211+
.client
1212+
.get_events_of(vec![filter], Some(Duration::from_secs(5)))
1213+
.await?;
1214+
1215+
let current = events
1216+
.into_iter()
1217+
.find_map(|e| if e.kind == kind { Some(e) } else { None });
1218+
1219+
// tag the federation invite code
1220+
let invite_code_tag = Tag::Generic(
1221+
TagKind::U,
1222+
vec![invite_code.to_string(), "fedimint".to_string()],
1223+
);
1224+
1225+
// todo tag the federation announcement event, to do so we need to have the pubkey of the federation
1226+
1227+
// create the new recommendation event by either creating a new one or modifying the current one
1228+
let builder = match current {
1229+
Some(e) => {
1230+
let mut tags = e.tags.clone();
1231+
1232+
let mut modified = false;
1233+
1234+
if !tags.iter().any(|t| t == &invite_code_tag) {
1235+
tags.push(invite_code_tag);
1236+
modified = true;
1237+
}
1238+
1239+
// if we already recommended this federation, return the event id
1240+
// no need to send another recommendation
1241+
if !modified {
1242+
return Ok(e.id);
1243+
}
1244+
1245+
EventBuilder::new(kind, e.content.clone(), tags)
1246+
}
1247+
None => EventBuilder::new(kind, "", [invite_code_tag]),
1248+
};
1249+
1250+
// send the event
1251+
Ok(self.client.send_event_builder(builder).await?)
1252+
}
1253+
11981254
/// Queries our relays for federation announcements
11991255
pub async fn discover_federations(&self) -> Result<Vec<NostrDiscoveredFedimint>, MutinyError> {
12001256
// get contacts by npub

mutiny-wasm/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,14 @@ impl MutinyWallet {
11751175
Ok(self.inner.recover_federation_backups().await?)
11761176
}
11771177

1178+
/// Creates a recommendation event for a federation
1179+
pub async fn recommend_federation(&self, invite_code: String) -> Result<String, MutinyJsError> {
1180+
let invite_code =
1181+
InviteCode::from_str(&invite_code).map_err(|_| MutinyJsError::InvalidArgumentsError)?;
1182+
let event_id = self.inner.nostr.recommend_federation(&invite_code).await?;
1183+
Ok(event_id.to_hex())
1184+
}
1185+
11781186
/// Queries our relays for federation announcements
11791187
pub async fn discover_federations(
11801188
&self,

0 commit comments

Comments
 (0)