// file: crates/ksp-app-wallet-desk/tests/release_compliance.rs // version: 5 //! Release-wide deterministic compliance canaries for Wallet Desk. fn app_root() -> std::path::PathBuf { return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); } fn read_text(path: &std::path::Path) -> String { let source = std::fs::read_to_string(path); assert!(source.is_ok(), "unable to read {}", path.display()); return match source { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => String::new(), }; } fn read_rust_source_tree(root: &std::path::Path) -> String { let entries = std::fs::read_dir(root); assert!(entries.is_ok(), "unable to enumerate {}", root.display()); let entries = match entries { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return String::new(), }; let mut paths = std::vec::Vec::new(); for entry in entries { let entry = match entry { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => continue, }; let path = entry.path(); if path.extension().and_then(std::ffi::OsStr::to_str) == std::option::Option::Some("rs") { paths.push(path); } } paths.sort(); let mut combined = String::new(); for path in paths { combined.push_str(read_text(path.as_path()).as_str()); combined.push('\n'); } return combined; } fn struct_field_lines(source: &str, name: &str) -> String { let marker = std::format!("struct {name}"); let start = source.find(marker.as_str()); assert!(start.is_some(), "missing struct {name}"); let start = match start { std::option::Option::Some(value) => value, std::option::Option::None => return String::new(), }; let block = source[start..].split("}\n").next().unwrap_or_default(); return block.lines().filter(|line| return line.trim_start().starts_with("pub(crate) ")).collect::>().join("\n"); } #[test] fn backend_keeps_config_wallet_transport_and_logging_ownership_boundaries() { let root = app_root(); let source = read_rust_source_tree(root.join("src").as_path()); for forbidden in [ "std::env::var(", "std::env::var_os(", "std::env::vars(", "reqwest::", "solana_keypair::", "solana_pubkey::", "solana_signer::", "solana_signature::", ] { assert!(!source.contains(forbidden), "Wallet Desk backend bypasses an owned boundary through {forbidden}"); } let tracing_path = ["tracing", "::"].concat(); let tracing_use = std::format!("use {tracing_path}"); for line in source.lines() { let trimmed = line.trim_start(); assert!(!trimmed.starts_with(tracing_use.as_str()), "Wallet Desk backend must not import tracing directly: {trimmed}"); assert!(!trimmed.starts_with(tracing_path.as_str()), "Wallet Desk backend must not emit through tracing directly: {trimmed}"); } assert!(source.contains("ksp_config_lib::ConfigEnvironment::load")); assert!(source.contains("ksp_wallet_lib::")); assert!(source.contains("ksp_onchain_transport_lib::")); assert!(source.contains("ksp_logging_lib::")); } #[test] fn frontend_has_no_direct_filesystem_network_or_secret_persistence_surface() { let root = app_root(); let package = read_text(root.join("package.json").as_path()); let main = read_text(root.join("frontend/ts/main.ts").as_path()); let invoke = read_text(root.join("frontend/ts/invoke.ts").as_path()); let frontend_log = read_text(root.join("frontend/ts/frontend_log.ts").as_path()); let splash = read_text(root.join("frontend/ts/splash.ts").as_path()); let html = read_text(root.join("frontend/main.html").as_path()); let combined = std::format!("{main}\n{invoke}\n{frontend_log}\n{splash}\n{html}"); for forbidden in [ "@tauri-apps/plugin-dialog", "@tauri-apps/plugin-fs", "navigator.clipboard", "localStorage", "sessionStorage", "window.alert", "window.confirm", "window.prompt", "XMLHttpRequest", "new WebSocket", "EventSource", "fetch(", "KSP_SECRET_WALLET_PASS_", "sourcePath", "source_path", "destinationPath", "destination_path", ] { assert!(!combined.contains(forbidden), "frontend contains forbidden direct surface {forbidden}"); } assert!(!package.contains("@tauri-apps/plugin-dialog")); assert!(!package.contains("@tauri-apps/plugin-fs")); } #[test] fn response_dtos_keep_secret_key_material_out_of_ipc() { let root = app_root(); let session = read_text(root.join("src/wallet_session.rs").as_path()); let balance = read_text(root.join("src/wallet_balance.rs").as_path()); let import = read_text(root.join("src/wallet_import.rs").as_path()); let export = read_text(root.join("src/wallet_export.rs").as_path()); let security = read_text(root.join("src/wallet_security.rs").as_path()); let common = read_text(root.join("src/dto_common.rs").as_path()); for (source, name) in [ (session.as_str(), "WalletAuthorizedDto"), (session.as_str(), "WalletSessionDto"), (balance.as_str(), "WalletBalanceDto"), (import.as_str(), "WalletTransferInspectionDto"), (export.as_str(), "WalletExportResultDto"), (security.as_str(), "WalletViewSecurityStatusDto"), (common.as_str(), "RuntimeStatusDto"), ] { let fields = struct_field_lines(source, name); for forbidden in ["password", "secret_key", "private_key", "keypair_bytes", "ciphertext"] { assert!(!fields.contains(forbidden), "response DTO {name} contains forbidden field material {forbidden}"); } } let inspection = struct_field_lines(import.as_str(), "WalletTransferInspectionDto"); let export_result = struct_field_lines(export.as_str(), "WalletExportResultDto"); assert!(!inspection.contains("path")); assert!(!export_result.contains("path")); assert!(!export_result.contains("content")); assert!(!export_result.contains("bytes")); } #[test] fn wallet_desk_dependency_firewall_and_tauri_capabilities_are_minimal() { let root = app_root(); let manifest = read_text(root.join("Cargo.toml").as_path()); for line in manifest.lines() { let trimmed = line.trim_start(); assert!(!trimmed.starts_with("solana-"), "Wallet Desk must consume Solana behavior through KSP crates: {trimmed}"); assert!(!trimmed.starts_with("reqwest "), "Wallet Desk must consume HTTP through Transport: {trimmed}"); assert!(!trimmed.starts_with("tracing "), "Wallet Desk must consume logging through the KSP facade/Tauri adapter: {trimmed}"); } let capability_source = read_text(root.join("capabilities/default.json").as_path()); let capability = serde_json::from_str::(capability_source.as_str()); assert!(capability.is_ok(), "Wallet Desk capability JSON should parse"); let capability = match capability { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let permissions = capability.get("permissions").and_then(serde_json::Value::as_array); assert!(permissions.is_some()); let permissions = match permissions { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert_eq!(permissions.len(), 2); assert_eq!(permissions[0].as_str(), std::option::Option::Some("core:default")); assert_eq!(permissions[1].as_str(), std::option::Option::Some("tracing:default")); let tauri = read_text(root.join("tauri.conf.json").as_path()); assert!(tauri.contains("\"csp\": null")); assert!(!capability_source.contains("dialog:")); assert!(!capability_source.contains("fs:")); } #[test] fn packaged_resources_include_only_registered_config_sources_and_schemas() { let root = app_root(); let tauri_source = read_text(root.join("tauri.conf.json").as_path()); let tauri = serde_json::from_str::(tauri_source.as_str()); assert!(tauri.is_ok(), "Wallet Desk Tauri config should parse"); let tauri = match tauri { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let resources = tauri.pointer("/bundle/resources").and_then(serde_json::Value::as_object); assert!(resources.is_some(), "Wallet Desk package must declare Config resources"); let resources = match resources { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert_eq!(resources.len(), 8); for (source, destination) in resources { let destination = destination.as_str(); assert!(destination.is_some(), "resource destination must be textual"); let destination = match destination { std::option::Option::Some(value) => value, std::option::Option::None => continue, }; assert!(source.starts_with("../../config/")); assert!(destination.starts_with("config/")); for forbidden in [ksp_config_lib::DEFAULT_DOTENV_PATH, "wallets", "logs", "secret", "private"] { assert!(!source.contains(forbidden), "mutable/secret runtime resource must not be bundled: {source}"); assert!(!destination.contains(forbidden), "mutable/secret runtime destination must not be bundled: {destination}"); } } }