1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
use crate::discovery::DiscoveredRepo;
use crate::health::GraspServer;
use anyhow::{Context, Result};
use nostr_sdk::prelude::*;
pub struct OptionalSigner {
keys: Option<Keys>,
}
impl OptionalSigner {
pub fn none() -> Self {
Self { keys: None }
}
pub fn from_nsec(nsec: &str) -> Result<Self> {
let keys = Keys::parse(nsec).context("failed to parse nsec")?;
Ok(Self { keys: Some(keys) })
}
pub fn is_available(&self) -> bool {
self.keys.is_some()
}
pub async fn build_updated_announcement(
&self,
original: &DiscoveredRepo,
additional_servers: &[GraspServer],
) -> Result<Option<Event>> {
let keys = match &self.keys {
Some(k) => k,
None => {
tracing::debug!("no signer available, skipping announcement update");
return Ok(None);
}
};
if additional_servers.is_empty() {
return Ok(None);
}
let pk_hex = original.pubkey.to_hex();
let mut new_clone_urls: Vec<String> = original.clone_urls.clone();
for server in additional_servers {
let url = server.clone_url(&pk_hex, &original.identifier);
if !new_clone_urls.contains(&url) {
new_clone_urls.push(url);
}
}
let mut tags: Vec<Tag> = vec![
Tag::custom(TagKind::Custom("d".into()), [&original.identifier]),
];
for url in &new_clone_urls {
tags.push(Tag::custom(TagKind::Custom("clone".into()), [url.as_str()]));
}
for url in &original.relay_urls {
tags.push(Tag::custom(
TagKind::Custom("relays".into()),
[url.as_str()],
));
}
let builder = EventBuilder::new(Kind::Custom(30617), "").tags(tags);
let event = builder.sign_with_keys(keys)?;
tracing::info!(
identifier = %original.identifier,
added = additional_servers.len(),
"built updated announcement with additional clone URLs"
);
Ok(Some(event))
}
}
|