diff --git a/Sources/ElixxirDAppsSDK/Cancellable.swift b/Sources/ElixxirDAppsSDK/Cancellable.swift
new file mode 100644
index 0000000000000000000000000000000000000000..1984e3f10916319e9e88959aa7f21f554d0d0e27
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/Cancellable.swift
@@ -0,0 +1,11 @@
+public final class Cancellable {
+  public init(cancel: @escaping () -> Void) {
+    self.cancel = cancel
+  }
+
+  deinit {
+    cancel()
+  }
+
+  public let cancel: () -> Void
+}
diff --git a/Sources/ElixxirDAppsSDK/Client.swift b/Sources/ElixxirDAppsSDK/Client.swift
index 1ceef52cf61f1cf34ce52278c1fc1d924f9969f3..01c50419586ed9b19f0fcd8e0ecca5fcdb5969b1 100644
--- a/Sources/ElixxirDAppsSDK/Client.swift
+++ b/Sources/ElixxirDAppsSDK/Client.swift
@@ -6,6 +6,7 @@ public struct Client {
   public var makeIdentity: IdentityMaker
   public var connect: ConnectionMaker
   public var waitForDelivery: MessageDeliveryWaiter
+  public var networkHealth: NetworkHealthListener
 }
 
 extension Client {
@@ -15,7 +16,8 @@ extension Client {
       waitForNetwork: .live(bindingsClient: bindingsClient),
       makeIdentity: .live(bindingsClient: bindingsClient),
       connect: .live(bindingsClient: bindingsClient),
-      waitForDelivery: .live(bindingsClient: bindingsClient)
+      waitForDelivery: .live(bindingsClient: bindingsClient),
+      networkHealth: .live(bindingsClient: bindingsClient)
     )
   }
 }
@@ -27,7 +29,8 @@ extension Client {
     waitForNetwork: .failing,
     makeIdentity: .failing,
     connect: .failing,
-    waitForDelivery: .failing
+    waitForDelivery: .failing,
+    networkHealth: .failing
   )
 }
 #endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkHealthListener.swift b/Sources/ElixxirDAppsSDK/NetworkHealthListener.swift
new file mode 100644
index 0000000000000000000000000000000000000000..69419b2e403e0230d92356cfffd370432d4057ed
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkHealthListener.swift
@@ -0,0 +1,42 @@
+import Bindings
+
+public struct NetworkHealthListener {
+  public var listen: (@escaping (Bool) -> Void) -> Cancellable
+
+  public func callAsFunction(callback: @escaping (Bool) -> Void) -> Cancellable {
+    listen(callback)
+  }
+}
+
+extension NetworkHealthListener {
+  public static func live(bindingsClient: BindingsClient) -> NetworkHealthListener {
+    NetworkHealthListener { callback in
+      let listener = Listener(onCallback: callback)
+      let id = bindingsClient.registerNetworkHealthCB(listener)
+      return Cancellable {
+        bindingsClient.unregisterNetworkHealthCB(id)
+      }
+    }
+  }
+}
+
+private final class Listener: NSObject, BindingsNetworkHealthCallbackProtocol {
+  init(onCallback: @escaping (Bool) -> Void) {
+    self.onCallback = onCallback
+    super.init()
+  }
+
+  let onCallback: (Bool) -> Void
+
+  func callback(_ p0: Bool) {
+    onCallback(p0)
+  }
+}
+
+#if DEBUG
+extension NetworkHealthListener {
+  public static let failing = NetworkHealthListener { _ in
+    fatalError("Not implemented")
+  }
+}
+#endif