use anyhow::{Error, Result}; use futures_util::{SinkExt, StreamExt}; use tokio_tungstenite::tungstenite::Message; use crate::peers; use sdk_common::network::{AnkFlag, Envelope}; pub async fn bootstrap_connect_and_sync(bootstrap_url: String) -> Result<()> { log::info!("Connecting to bootstrap: {}", bootstrap_url); let (ws_stream, _) = tokio_tungstenite::connect_async(&bootstrap_url).await?; log::info!("Connected to bootstrap successfully"); let (mut write, mut read) = ws_stream.split(); // Send our empty Sync (we don't share, just ask implicitly) let ask = Envelope { flag: AnkFlag::Sync, content: serde_json::json!({"peers": []}).to_string() }; log::info!("Sending sync request to bootstrap"); write.send(Message::Text(serde_json::to_string(&ask)?)).await?; // Wait one message for peer list if let Some(Ok(Message::Text(txt))) = read.next().await { log::info!("Received response from bootstrap: {}", txt); if let Ok(env) = serde_json::from_str::(&txt) { log::info!("Parsed envelope with flag: {:?}", env.flag); if let AnkFlag::Sync = env.flag { if let Ok(val) = serde_json::from_str::(&env.content) { if let Some(arr) = val.get("peers").and_then(|v| v.as_array()) { for v in arr { if let Some(url) = v.as_str() { peers::add_peer(url); } } } } } else { log::warn!("Bootstrap response is not a Sync message, flag: {:?}", env.flag); } } else { log::warn!("Failed to parse bootstrap response as envelope: {}", txt); } } else { log::warn!("No response received from bootstrap"); } // Optionally request one faucet if configured is handled by higher layer log::info!("Bootstrap sync completed"); Ok(()) }