Update Fedimint configuration and enhance onboarding process
- Upgraded Fedimint version to v0.10.0 in docker-compose.yml and manifest.yml, adding support for the built-in Guardian UI. - Modified .gitignore to exclude deploy-config.sh script. - Enhanced onboarding process in AuthManager to persist onboarding state and validate password strength during user setup. - Updated API to handle onboarding completion and password change requests, ensuring a smoother user experience. - Improved configuration management to support Nostr discovery and Tor proxy settings, enhancing node identity features.
This commit is contained in:
@@ -53,11 +53,15 @@ impl DockerPackageScanner {
|
||||
let mut ui_containers: HashMap<String, String> = HashMap::new();
|
||||
for container in &containers {
|
||||
if container.name.ends_with("-ui") {
|
||||
// Map bitcoin-ui -> bitcoin, lnd-ui -> lnd
|
||||
// Map fedimint-ui -> fedimint, lnd-ui -> lnd (normalize archy- prefix for lookup)
|
||||
let parent_app = container.name.strip_suffix("-ui").unwrap_or(&container.name);
|
||||
let canonical_id = parent_app
|
||||
.strip_prefix("archy-")
|
||||
.unwrap_or(parent_app)
|
||||
.to_string();
|
||||
if !container.ports.is_empty() {
|
||||
if let Some(ui_address) = extract_lan_address(&container.ports) {
|
||||
ui_containers.insert(parent_app.to_string(), ui_address);
|
||||
ui_containers.insert(canonical_id, ui_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,6 +113,14 @@ impl DockerPackageScanner {
|
||||
// But web UI is always on port 8240
|
||||
debug!("Tailscale detected, using port 8240");
|
||||
Some("http://localhost:8240".to_string())
|
||||
} else if app_id == "fedimint" {
|
||||
// Fedimint built-in Guardian UI on port 8175
|
||||
debug!("Using fedimint built-in Guardian UI: http://localhost:8175");
|
||||
Some("http://localhost:8175".to_string())
|
||||
} else if app_id == "mempool-electrs" || app_id == "electrs" {
|
||||
// Electrs UI runs on host at port 50002
|
||||
debug!("Using electrs-ui for mempool-electrs: http://localhost:50002");
|
||||
Some("http://localhost:50002".to_string())
|
||||
} else {
|
||||
// Extract port from the main container
|
||||
extract_lan_address(&container.ports)
|
||||
@@ -119,6 +131,8 @@ impl DockerPackageScanner {
|
||||
// Convert container state to package/service state
|
||||
let (package_state, service_status) = convert_state(&container.state);
|
||||
|
||||
let tor_address = read_tor_address(&app_id);
|
||||
|
||||
let package = PackageDataEntry {
|
||||
state: package_state.clone(),
|
||||
static_files: StaticFiles {
|
||||
@@ -143,11 +157,11 @@ impl DockerPackageScanner {
|
||||
donation_url: None,
|
||||
author: Some("Archipelago".to_string()),
|
||||
website: lan_address.clone(),
|
||||
interfaces: if lan_address.is_some() {
|
||||
interfaces: if lan_address.is_some() || tor_address.is_some() {
|
||||
Some(Interfaces {
|
||||
main: Some(MainInterface {
|
||||
ui: Some("true".to_string()),
|
||||
tor_config: None,
|
||||
tor_config: tor_address.clone(),
|
||||
lan_config: None,
|
||||
}),
|
||||
})
|
||||
@@ -159,13 +173,17 @@ impl DockerPackageScanner {
|
||||
current_dependents: HashMap::new(),
|
||||
current_dependencies: HashMap::new(),
|
||||
last_backup: None,
|
||||
interface_addresses: if let Some(addr) = lan_address {
|
||||
interface_addresses: if lan_address.is_some() || tor_address.is_some() {
|
||||
let mut addresses = HashMap::new();
|
||||
// Only include tor_address if we have a real v3 .onion (not placeholder)
|
||||
let tor = tor_address
|
||||
.filter(|s| is_real_onion_address(s))
|
||||
.unwrap_or_default();
|
||||
addresses.insert(
|
||||
"main".to_string(),
|
||||
InterfaceAddress {
|
||||
tor_address: format!("{}.onion", app_id),
|
||||
lan_address: Some(addr),
|
||||
tor_address: tor,
|
||||
lan_address: lan_address,
|
||||
},
|
||||
);
|
||||
addresses
|
||||
@@ -227,7 +245,7 @@ fn get_app_metadata(app_id: &str) -> AppMetadata {
|
||||
"fedimint" => AppMetadata {
|
||||
title: "Fedimint".to_string(),
|
||||
description: "Federated Bitcoin mint".to_string(),
|
||||
icon: "/assets/img/icon-fedimint.jpeg".to_string(),
|
||||
icon: "/assets/img/app-icons/fedimint.png".to_string(),
|
||||
repo: "https://github.com/fedimint/fedimint".to_string(),
|
||||
},
|
||||
"morphos" | "morphos-server" => AppMetadata {
|
||||
@@ -248,6 +266,12 @@ fn get_app_metadata(app_id: &str) -> AppMetadata {
|
||||
icon: "/assets/img/app-icons/mempool.webp".to_string(),
|
||||
repo: "https://github.com/mempool/mempool".to_string(),
|
||||
},
|
||||
"mempool-electrs" | "electrs" => AppMetadata {
|
||||
title: "Electrs".to_string(),
|
||||
description: "Electrum protocol indexer for Bitcoin. Powers Mempool and other Electrum clients.".to_string(),
|
||||
icon: "/assets/img/app-icons/electrs.svg".to_string(),
|
||||
repo: "https://github.com/romanz/electrs".to_string(),
|
||||
},
|
||||
"ollama" => AppMetadata {
|
||||
title: "Ollama".to_string(),
|
||||
description: "Run large language models locally".to_string(),
|
||||
@@ -347,6 +371,40 @@ fn get_app_metadata(app_id: &str) -> AppMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
/// Map app_id to Tor hidden service directory name.
|
||||
/// "archipelago" is the main web UI (nginx port 80).
|
||||
/// Supports container names from deploy (archy-*, btcpay-server, etc.).
|
||||
fn tor_service_name(app_id: &str) -> Option<&'static str> {
|
||||
match app_id {
|
||||
"archipelago" => Some("archipelago"),
|
||||
"lnd" | "lnd-ui" => Some("lnd"),
|
||||
"btcpay" | "btcpay-server" | "btcpayserver" => Some("btcpay"),
|
||||
"mempool" | "mempool-web" | "mempool-frontend" => Some("mempool"),
|
||||
"fedimint" => Some("fedimint"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// V3 onion addresses are 56 base32 chars + ".onion". Placeholders like "btcpay.onion" are not real.
|
||||
fn is_real_onion_address(s: &str) -> bool {
|
||||
s.ends_with(".onion") && s.len() >= 60 && s.len() <= 70
|
||||
}
|
||||
|
||||
/// Read real .onion address from Tor hidden service hostname file.
|
||||
/// Service name "archipelago" is for the main web UI (nginx port 80).
|
||||
/// Uses TOR_DATA_DIR env var if set, else /var/lib/archipelago/tor.
|
||||
pub fn read_tor_address(app_id: &str) -> Option<String> {
|
||||
let service = tor_service_name(app_id)?;
|
||||
let base = std::env::var("TOR_DATA_DIR").unwrap_or_else(|_| "/var/lib/archipelago/tor".to_string());
|
||||
let path = std::path::Path::new(&base)
|
||||
.join(format!("hidden_service_{}", service))
|
||||
.join("hostname");
|
||||
std::fs::read_to_string(&path)
|
||||
.ok()
|
||||
.map(|s| s.trim().to_string())
|
||||
.filter(|s| s.ends_with(".onion") && !s.is_empty())
|
||||
}
|
||||
|
||||
fn extract_lan_address(ports: &[String]) -> Option<String> {
|
||||
for port_str in ports {
|
||||
// Parse port strings like "0.0.0.0:18443->18443/tcp" or "0.0.0.0:18443-18444->18443-18444/tcp"
|
||||
|
||||
Reference in New Issue
Block a user