upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/signing.rs
blob: 7ec796aa904da4ba852c727f24bc2ee70fa101a2 (plain)
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))
    }
}