alpine_protocol_sdk/
quickstart.rs1use 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}