diff --git a/Cargo.lock b/Cargo.lock
index a0ad2d91a..2aec593a3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1525,7 +1525,7 @@ dependencies = [
 
 [[package]]
 name = "mutiny-wasm"
-version = "1.14.4"
+version = "1.14.5"
 dependencies = [
  "anyhow",
  "async-trait",
diff --git a/mutiny-core/src/lib.rs b/mutiny-core/src/lib.rs
index c9fac490b..7d07e83cb 100644
--- a/mutiny-core/src/lib.rs
+++ b/mutiny-core/src/lib.rs
@@ -28,7 +28,7 @@ mod networking;
 mod node;
 pub mod nodemanager;
 mod onchain;
-mod peermanager;
+pub mod peermanager;
 pub mod scorer;
 pub mod storage;
 mod subscription;
@@ -51,6 +51,7 @@ use crate::messagehandler::CommonLnEventCallback;
 use crate::nodemanager::NodeManager;
 use crate::nodemanager::{ChannelClosure, MutinyBip21RawMaterials};
 pub use crate::onchain::BroadcastTx1InMultiOut;
+use crate::peermanager::CONNECTED_PEER_MANAGER;
 use crate::storage::{get_invoice_by_hash, DEVICE_LOCK_KEY, LND_CHANNELS_SNAPSHOT_KEY};
 use crate::utils::{now, sleep, spawn, spawn_with_handle, StopHandle};
 use crate::vss::VSS_MANAGER;
@@ -847,9 +848,11 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
             };
 
         let pending = VSS_MANAGER.get_pending_writes();
-        if pending.is_empty()
-            || (pending.len() == 1 && pending.iter().any(|(key, _)| key == DEVICE_LOCK_KEY))
-        {
+        let only_device_lock_vss_pending =
+            pending.len() == 1 && pending.iter().any(|(key, _)| key == DEVICE_LOCK_KEY);
+        let can_update_snapshot = (pending.is_empty() || only_device_lock_vss_pending)
+            && CONNECTED_PEER_MANAGER.is_any_connected();
+        if can_update_snapshot {
             let second_lnd_snapshot =
                 match fetch_lnd_channels_snapshot(&Client::new(), lsp_url, &node_id, &logger).await
                 {
diff --git a/mutiny-core/src/messagehandler.rs b/mutiny-core/src/messagehandler.rs
index 18f2e7c64..81d06769e 100644
--- a/mutiny-core/src/messagehandler.rs
+++ b/mutiny-core/src/messagehandler.rs
@@ -10,6 +10,7 @@ use lightning::util::ser::{Writeable, Writer};
 use serde::{Deserialize, Serialize};
 
 use crate::node::LiquidityManager;
+use crate::peermanager::CONNECTED_PEER_MANAGER;
 use crate::storage::MutinyStorage;
 
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
@@ -175,6 +176,14 @@ impl<S: MutinyStorage> CustomMessageHandler for MutinyMessageHandler<S> {
         msg: &lightning::ln::msgs::Init,
         inbound: bool,
     ) -> Result<(), ()> {
+        CONNECTED_PEER_MANAGER.add_peer(
+            *their_node_id,
+            inbound,
+            msg.remote_network_address
+                .as_ref()
+                .map(|addr| format!("{}", addr)),
+        );
+
         if let Some(cb) = self.ln_event_callback.clone() {
             let event = CommonLnEvent::OnConnect {
                 their_node_id: their_node_id.to_string(),
@@ -190,6 +199,8 @@ impl<S: MutinyStorage> CustomMessageHandler for MutinyMessageHandler<S> {
     }
 
     fn peer_disconnected(&self, their_node_id: &PublicKey) {
+        CONNECTED_PEER_MANAGER.remove_peer(their_node_id);
+
         if let Some(cb) = self.ln_event_callback.clone() {
             let event = CommonLnEvent::OnDisconnect {
                 their_node_id: their_node_id.to_string(),
diff --git a/mutiny-core/src/peermanager.rs b/mutiny-core/src/peermanager.rs
index 6faaa2abb..ab387f46b 100644
--- a/mutiny-core/src/peermanager.rs
+++ b/mutiny-core/src/peermanager.rs
@@ -24,8 +24,10 @@ use lightning::routing::gossip::NodeId;
 use lightning::util::logger::Logger;
 use lightning::{ln::msgs::SocketAddress, log_warn};
 use lightning::{log_debug, log_error};
+use std::collections::HashMap;
 use std::sync::atomic::AtomicBool;
 use std::sync::Arc;
+use utils::Mutex;
 
 #[cfg(target_arch = "wasm32")]
 use crate::networking::ws_socket::WsTcpSocketDescriptor;
@@ -36,6 +38,9 @@ use lightning::ln::peer_handler::SocketDescriptor as LdkSocketDescriptor;
 #[cfg(target_arch = "wasm32")]
 use crate::networking::proxy::WsProxy;
 
+pub static CONNECTED_PEER_MANAGER: once_cell::sync::Lazy<ConnectedPeerManager> =
+    once_cell::sync::Lazy::new(ConnectedPeerManager::default);
+
 #[allow(dead_code)]
 pub trait PeerManager: Send + Sync + 'static {
     fn get_peer_node_ids(&self) -> Vec<PublicKey>;
@@ -581,3 +586,82 @@ fn try_parse_addr_string(addr: &str) -> (Option<std::net::SocketAddr>, Option<So
     });
     (socket_addr, net_addr)
 }
+
+#[derive(Debug, Clone)]
+pub struct ConnectedPeerInfo {
+    pub inbound: bool,
+    pub remote_address: Option<String>,
+    pub connected_at_timestamp: u64,
+}
+
+pub struct ConnectedPeerManager {
+    peers: Arc<Mutex<HashMap<PublicKey, ConnectedPeerInfo>>>,
+    logger: Mutex<Option<Arc<MutinyLogger>>>,
+}
+
+impl Default for ConnectedPeerManager {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl ConnectedPeerManager {
+    pub fn new() -> Self {
+        Self {
+            peers: Arc::new(Mutex::new(HashMap::new())),
+            logger: Mutex::new(None),
+        }
+    }
+
+    pub fn set_logger(&self, logger: Arc<MutinyLogger>) {
+        let mut lock = self.logger.lock().unwrap();
+        *lock = Some(logger);
+    }
+
+    pub fn add_peer(
+        &self,
+        their_node_id: PublicKey,
+        inbound: bool,
+        remote_address: Option<String>,
+    ) {
+        let timestamp = utils::now().as_secs();
+
+        let info = ConnectedPeerInfo {
+            inbound,
+            remote_address,
+            connected_at_timestamp: timestamp,
+        };
+
+        let mut peers = self.peers.lock().unwrap();
+        let inserted = peers.insert(their_node_id, info).is_none();
+        let logger = {
+            let guard = self.logger.lock().expect("Failed to lock logger");
+            guard.clone()
+        };
+        if inserted {
+            if let Some(logger) = logger {
+                log_debug!(logger, "Connected to peer: {}", their_node_id);
+            }
+        }
+    }
+
+    pub fn remove_peer(&self, their_node_id: &PublicKey) {
+        let mut peers = self.peers.lock().unwrap();
+        let removed = peers.remove(their_node_id).is_some();
+
+        let logger = {
+            let guard = self.logger.lock().expect("Failed to lock logger");
+            guard.clone()
+        };
+        if removed {
+            if let Some(logger) = logger {
+                log_debug!(logger, "Disconnected from peer: {}", their_node_id);
+            }
+        }
+    }
+
+    pub fn is_any_connected(&self) -> bool {
+        let lock = self.peers.lock().unwrap();
+        !lock.is_empty()
+    }
+}
diff --git a/mutiny-core/src/vss.rs b/mutiny-core/src/vss.rs
index 92e61a393..b1f949718 100644
--- a/mutiny-core/src/vss.rs
+++ b/mutiny-core/src/vss.rs
@@ -250,10 +250,10 @@ impl VssManager {
 
     pub fn get_pending_writes(&self) -> Vec<(String, VssPendingWrite)> {
         self.check_timeout();
-        let writes = self.pending_writes.lock().expect(
-            "
-            Failed to lock pending writes",
-        );
+        let writes = self
+            .pending_writes
+            .lock()
+            .expect("Failed to lock pending writes");
         writes.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
     }
 
@@ -271,33 +271,30 @@ impl VssManager {
     }
 
     pub fn on_complete_write(&self, key: String) {
-        let mut pending_writes = self.pending_writes.lock().expect(
-            "
-            Failed to lock pending writes",
-        );
+        let mut pending_writes = self
+            .pending_writes
+            .lock()
+            .expect("Failed to lock pending writes");
         pending_writes.remove(&key);
     }
 
     pub fn has_in_progress(&self) -> bool {
         self.check_timeout();
-        let writes = self.pending_writes.lock().expect(
-            "
-            Failed to lock pending writes",
-        );
+        let writes = self
+            .pending_writes
+            .lock()
+            .expect("Failed to lock pending writes");
         !writes.is_empty()
     }
 
     fn check_timeout(&self) {
         let current_time = utils::now().as_secs();
-        let mut writes = self.pending_writes.lock().expect(
-            "
-            Failed to lock pending writes",
-        );
+        let mut writes = self
+            .pending_writes
+            .lock()
+            .expect("Failed to lock pending writes");
         let logger = {
-            let guard = self.logger.lock().expect(
-                "
-                Failed to lock logger",
-            );
+            let guard = self.logger.lock().expect("Failed to lock logger");
             guard.clone()
         };
         writes.retain(|key, write| {
diff --git a/mutiny-wasm/Cargo.toml b/mutiny-wasm/Cargo.toml
index 395de77b7..70b648f08 100644
--- a/mutiny-wasm/Cargo.toml
+++ b/mutiny-wasm/Cargo.toml
@@ -2,7 +2,7 @@ cargo-features = ["per-package-target"]
 
 [package]
 name = "mutiny-wasm"
-version = "1.14.4"
+version = "1.14.5"
 edition = "2021"
 authors = ["utxostack"]
 forced-target = "wasm32-unknown-unknown"
diff --git a/mutiny-wasm/src/lib.rs b/mutiny-wasm/src/lib.rs
index f231b2043..6f3016dfd 100644
--- a/mutiny-wasm/src/lib.rs
+++ b/mutiny-wasm/src/lib.rs
@@ -32,6 +32,7 @@ use mutiny_core::authmanager::AuthManager;
 use mutiny_core::encrypt::decrypt_with_password;
 use mutiny_core::error::MutinyError;
 use mutiny_core::messagehandler::{CommonLnEvent, CommonLnEventCallback};
+use mutiny_core::peermanager::CONNECTED_PEER_MANAGER;
 use mutiny_core::storage::{DeviceLock, MutinyStorage, DEVICE_LOCK_KEY};
 use mutiny_core::utils::sleep;
 use mutiny_core::vss::{MutinyVssClient, VSS_MANAGER};
@@ -225,6 +226,7 @@ impl MutinyWallet {
         log_info!(logger, "Node version {version}");
 
         VSS_MANAGER.set_logger(logger.clone());
+        CONNECTED_PEER_MANAGER.set_logger(logger.clone());
 
         let cipher = password
             .as_ref()