qualia_client_core/api/
dashboard.rs1#![allow(non_snake_case)]
4
5use super::*;
6
7use crate::qapp_registry;
8use crate::state::*;
9
10pub fn run_engine_command(cmd: String) -> String {
11 match cmd.as_str() {
12 "ingest_bench" => profile_energy_circumstance(),
13 "zk_screen" => format!(
14 "Daemon: {} | Ollama: {}",
15 daemon_status(),
16 check_ollama_status()
17 ),
18 _ => "Unknown command".to_string(),
19 }
20}
21
22pub fn toggle_window() {
25 }
27
28#[derive(Clone, serde::Serialize, serde::Deserialize)]
33pub struct DirectoryState {
34 pub actors: Vec<Actor>,
35 pub rules: Vec<DelegationRule>,
36 pub front_doors: Vec<FrontDoor>,
37 pub installed_qapps: Vec<qapp_registry::RegisteredQapp>,
38}
39
40#[derive(Clone, serde::Serialize, serde::Deserialize)]
41pub struct SignedDirectoryState {
42 pub state: DirectoryState,
43 pub signature_hex: String,
44}
45
46pub fn save_directory_state() {
47 let state = crate::state::APP_STATE.get().unwrap();
48 let home = std::env::var("USERPROFILE").unwrap_or_else(|_| "C:\\".to_string());
49 let qualia_dir = std::path::PathBuf::from(home).join(".qualia");
50 if !qualia_dir.exists() {
51 let _ = std::fs::create_dir_all(&qualia_dir);
52 }
53
54 let ds = DirectoryState {
55 actors: state.directory_actors.lock().unwrap().clone(),
56 rules: state.delegation_rules.lock().unwrap().clone(),
57 front_doors: state.front_doors.lock().unwrap().clone(),
58 installed_qapps: state.installed_qapps.lock().unwrap().clone(),
59 };
60
61 let payload = serde_json::to_string(&ds).unwrap();
62 let vault = state.key_vault.lock().unwrap();
63 let sig = vault.sign_payload(&vault.derive_key("persistence"), payload.as_bytes());
66 let sig_hex = hex::encode(sig.to_bytes());
67
68 let signed_state = SignedDirectoryState {
69 state: ds,
70 signature_hex: sig_hex,
71 };
72
73 let state_path = qualia_dir.join("directory_state.json");
74 let _ = std::fs::write(
75 &state_path,
76 serde_json::to_string_pretty(&signed_state).unwrap(),
77 );
78}
79
80pub fn load_directory_state(vault: &qualia_core_db::key_vault::KeyVault) -> DirectoryState {
81 let home = std::env::var("USERPROFILE").unwrap_or_else(|_| "C:\\".to_string());
82 let state_path = std::path::PathBuf::from(home)
83 .join(".qualia")
84 .join("directory_state.json");
85
86 if state_path.exists() {
87 if let Ok(content) = std::fs::read_to_string(&state_path) {
88 if let Ok(signed_state) = serde_json::from_str::<SignedDirectoryState>(&content) {
89 let payload = serde_json::to_string(&signed_state.state).unwrap();
90 let sig_bytes = hex::decode(&signed_state.signature_hex).unwrap_or_default();
91 if sig_bytes.len() == 64 {
92 let mut sig_arr = [0u8; 64];
93 sig_arr.copy_from_slice(&sig_bytes);
94 let persistence_key = vault.derive_key("persistence");
95 let pk = ed25519_dalek::VerifyingKey::from(&persistence_key);
96 if qualia_core_db::key_vault::KeyVault::verify_signature(
97 pk.as_bytes(),
98 payload.as_bytes(),
99 &sig_arr,
100 )
101 .is_ok()
102 {
103 return signed_state.state;
104 } else {
105 eprintln!("WARNING: directory_state.json signature validation failed! Tampering detected.");
106 }
107 }
108 }
109 }
110 }
111
112 DirectoryState {
113 actors: Vec::new(),
114 rules: Vec::new(),
115 front_doors: Vec::new(),
116 installed_qapps: Vec::new(),
117 }
118}
119
120pub fn get_front_doors() -> Result<Vec<FrontDoor>, String> {
121 let state = crate::state::APP_STATE.get().unwrap();
122 let doors = state.front_doors.lock().unwrap().clone();
123 Ok(doors)
124}
125
126pub fn generate_front_door(label: String) -> Result<FrontDoor, String> {
127 let state = crate::state::APP_STATE.get().unwrap();
128 use std::time::{SystemTime, UNIX_EPOCH};
129 let now = SystemTime::now()
130 .duration_since(UNIX_EPOCH)
131 .unwrap()
132 .as_millis();
133
134 let vault = state.key_vault.lock().unwrap();
135 let fd_id = format!("fd-{}", now);
136 let derived_key = vault.derive_key(&fd_id);
137 let pub_key_hex = hex::encode(ed25519_dalek::VerifyingKey::from(&derived_key).as_bytes());
138 let did_uri = format!("did:qualia:frontdoor:{}", pub_key_hex);
139
140 let door = FrontDoor {
144 id: fd_id,
145 did_uri,
146 label,
147 created_at: now.to_string(),
148 routing_hints: vec![],
149 };
150
151 drop(vault);
152 state.front_doors.lock().unwrap().push(door.clone());
153 save_directory_state();
154 Ok(door)
155}
156
157pub fn get_directory_actors() -> Result<Vec<Actor>, String> {
158 let state = crate::state::APP_STATE.get().unwrap();
159 let actors = state.directory_actors.lock().unwrap().clone();
160 Ok(actors)
161}
162
163pub fn add_directory_actor(actor: Actor) -> Result<(), String> {
164 let state = crate::state::APP_STATE.get().unwrap();
165 state.directory_actors.lock().unwrap().push(actor);
166 save_directory_state();
167 Ok(())
168}
169
170pub fn get_delegation_rules() -> Result<Vec<DelegationRule>, String> {
171 let state = crate::state::APP_STATE.get().unwrap();
172 let rules = state.delegation_rules.lock().unwrap().clone();
173 Ok(rules)
174}
175
176pub fn add_delegation_rule(rule: DelegationRule) -> Result<(), String> {
177 let state = crate::state::APP_STATE.get().unwrap();
178 state.delegation_rules.lock().unwrap().push(rule);
179 save_directory_state();
180 Ok(())
181}