Skip to main content

alpine_protocol_sdk/
quickstart.rs

1use std::env;
2use std::path::Path;
3
4use crate::network_health::NetworkHealthReport;
5use crate::trust::TrustConfig;
6
7#[derive(Debug, Clone)]
8pub struct QuickstartItem {
9    pub name: String,
10    pub ok: bool,
11    pub detail: String,
12}
13
14#[derive(Debug, Clone)]
15pub struct QuickstartChecklist {
16    pub items: Vec<QuickstartItem>,
17}
18
19impl QuickstartChecklist {
20    pub fn run(config: Option<&TrustConfig>) -> Self {
21        let mut items = Vec::new();
22
23        let attesters_url = env::var("ALPINE_ATTESTERS_URL").ok();
24        let root_key = env::var("ALPINE_ROOT_PUBKEY_B64").ok();
25        items.push(QuickstartItem {
26            name: "ALPINE_ATTESTERS_URL".to_string(),
27            ok: attesters_url.is_some(),
28            detail: attesters_url
29                .map(|_| "set".to_string())
30                .unwrap_or_else(|| "missing".to_string()),
31        });
32        items.push(QuickstartItem {
33            name: "ALPINE_ROOT_PUBKEY_B64".to_string(),
34            ok: root_key.is_some(),
35            detail: root_key
36                .map(|_| "set".to_string())
37                .unwrap_or_else(|| "missing".to_string()),
38        });
39
40        if let Some(cfg) = config {
41            let path = if let Some(override_path) = &cfg.override_path {
42                override_path.as_path()
43            } else {
44                cfg.cache_path.as_path()
45            };
46            let exists = Path::new(path).exists();
47            items.push(QuickstartItem {
48                name: "trust_bundle".to_string(),
49                ok: exists,
50                detail: if exists {
51                    format!("found at {}", path.display())
52                } else {
53                    format!("missing at {}", path.display())
54                },
55            });
56        }
57
58        let health = NetworkHealthReport::probe();
59        let detail = if health.ok() {
60            "udp ready".to_string()
61        } else {
62            let mut parts = Vec::new();
63            if !health.udp_bind_ok {
64                parts.push("udp bind failed");
65            }
66            if !health.broadcast_ok {
67                parts.push("broadcast blocked");
68            }
69            if !health.multicast_ok {
70                parts.push("multicast blocked");
71            }
72            if parts.is_empty() {
73                parts.push("udp health unknown");
74            }
75            parts.join(", ")
76        };
77        items.push(QuickstartItem {
78            name: "udp reachability".to_string(),
79            ok: health.ok(),
80            detail,
81        });
82
83        Self { items }
84    }
85
86    pub fn ok(&self) -> bool {
87        self.items.iter().all(|item| item.ok)
88    }
89
90    pub fn summary(&self) -> String {
91        let mut lines = Vec::new();
92        for item in &self.items {
93            let status = if item.ok { "ok" } else { "missing" };
94            lines.push(format!("{}: {} ({})", item.name, status, item.detail));
95        }
96        lines.join("\n")
97    }
98}