diff --git a/Examples/xx-messenger/.swiftpm/xcode/xcshareddata/xcschemes/CheckContactAuthFeature.xcscheme b/Examples/xx-messenger/.swiftpm/xcode/xcshareddata/xcschemes/CheckContactAuthFeature.xcscheme
new file mode 100644
index 0000000000000000000000000000000000000000..17099adba157e5f3e5b943744dbe3cdf5b17706d
--- /dev/null
+++ b/Examples/xx-messenger/.swiftpm/xcode/xcshareddata/xcschemes/CheckContactAuthFeature.xcscheme
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1400"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "CheckContactAuthFeature"
+               BuildableName = "CheckContactAuthFeature"
+               BlueprintName = "CheckContactAuthFeature"
+               ReferencedContainer = "container:">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      codeCoverageEnabled = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "CheckContactAuthFeatureTests"
+               BuildableName = "CheckContactAuthFeatureTests"
+               BlueprintName = "CheckContactAuthFeatureTests"
+               ReferencedContainer = "container:">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "CheckContactAuthFeature"
+            BuildableName = "CheckContactAuthFeature"
+            BlueprintName = "CheckContactAuthFeature"
+            ReferencedContainer = "container:">
+         </BuildableReference>
+      </MacroExpansion>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>
diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift
index 3548cd17ae609a6d59d2722f9bf91556499a09c4..01878fbd634c1e36d0be0f56b53331ba7b8b0d71 100644
--- a/Examples/xx-messenger/Package.swift
+++ b/Examples/xx-messenger/Package.swift
@@ -20,6 +20,7 @@ let package = Package(
   products: [
     .library(name: "AppCore", targets: ["AppCore"]),
     .library(name: "AppFeature", targets: ["AppFeature"]),
+    .library(name: "CheckContactAuthFeature", targets: ["CheckContactAuthFeature"]),
     .library(name: "ContactFeature", targets: ["ContactFeature"]),
     .library(name: "ContactsFeature", targets: ["ContactsFeature"]),
     .library(name: "HomeFeature", targets: ["HomeFeature"]),
@@ -97,6 +98,21 @@ let package = Package(
       ],
       swiftSettings: swiftSettings
     ),
+    .target(
+      name: "CheckContactAuthFeature",
+      dependencies: [
+        .product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
+        .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
+        .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"),
+        .product(name: "XXModels", package: "client-ios-db"),
+      ]
+    ),
+    .testTarget(
+      name: "CheckContactAuthFeatureTests",
+      dependencies: [
+        .target(name: "CheckContactAuthFeature"),
+      ]
+    ),
     .target(
       name: "ContactFeature",
       dependencies: [
diff --git a/Examples/xx-messenger/Project/XXMessenger.xcodeproj/xcshareddata/xcschemes/XXMessenger.xcscheme b/Examples/xx-messenger/Project/XXMessenger.xcodeproj/xcshareddata/xcschemes/XXMessenger.xcscheme
index 71af5875f2d25543ac07848467cbd1417bde92cc..85d232415d82af42337d1fceea8eadb26369b000 100644
--- a/Examples/xx-messenger/Project/XXMessenger.xcodeproj/xcshareddata/xcschemes/XXMessenger.xcscheme
+++ b/Examples/xx-messenger/Project/XXMessenger.xcodeproj/xcshareddata/xcschemes/XXMessenger.xcscheme
@@ -49,6 +49,16 @@
                ReferencedContainer = "container:..">
             </BuildableReference>
          </TestableReference>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "CheckContactAuthFeatureTests"
+               BuildableName = "CheckContactAuthFeatureTests"
+               BlueprintName = "CheckContactAuthFeatureTests"
+               ReferencedContainer = "container:..">
+            </BuildableReference>
+         </TestableReference>
          <TestableReference
             skipped = "NO">
             <BuildableReference
diff --git a/Examples/xx-messenger/Sources/CheckContactAuthFeature/CheckContactAuthFeature.swift b/Examples/xx-messenger/Sources/CheckContactAuthFeature/CheckContactAuthFeature.swift
new file mode 100644
index 0000000000000000000000000000000000000000..119ff27a2f2a73a772c0e9cf1c97cf7d983e285a
--- /dev/null
+++ b/Examples/xx-messenger/Sources/CheckContactAuthFeature/CheckContactAuthFeature.swift
@@ -0,0 +1,84 @@
+import ComposableArchitecture
+import Foundation
+import XCTestDynamicOverlay
+import XXClient
+import XXMessengerClient
+
+public struct CheckContactAuthState: Equatable {
+  public enum Result: Equatable {
+    case success(Bool)
+    case failure(String)
+  }
+
+  public init(
+    contact: Contact,
+    isChecking: Bool = false,
+    result: Result? = nil
+  ) {
+    self.contact = contact
+    self.isChecking = isChecking
+    self.result = result
+  }
+
+  public var contact: Contact
+  public var isChecking: Bool
+  public var result: Result?
+}
+
+public enum CheckContactAuthAction: Equatable {
+  case checkTapped
+  case didCheck(CheckContactAuthState.Result)
+}
+
+public struct CheckContactAuthEnvironment {
+  public init(
+    messenger: Messenger,
+    mainQueue: AnySchedulerOf<DispatchQueue>,
+    bgQueue: AnySchedulerOf<DispatchQueue>
+  ) {
+    self.messenger = messenger
+    self.mainQueue = mainQueue
+    self.bgQueue = bgQueue
+  }
+
+  public var messenger: Messenger
+  public var mainQueue: AnySchedulerOf<DispatchQueue>
+  public var bgQueue: AnySchedulerOf<DispatchQueue>
+}
+
+#if DEBUG
+extension CheckContactAuthEnvironment {
+  public static let unimplemented = CheckContactAuthEnvironment(
+    messenger: .unimplemented,
+    mainQueue: .unimplemented,
+    bgQueue: .unimplemented
+  )
+}
+#endif
+
+public let checkContactAuthReducer = Reducer<CheckContactAuthState, CheckContactAuthAction, CheckContactAuthEnvironment>
+{ state, action, env in
+  switch action {
+  case .checkTapped:
+    state.isChecking = true
+    state.result = nil
+    return Effect.result { [state] in
+      do {
+        let e2e = try env.messenger.e2e.tryGet()
+        let contactId = try state.contact.getId()
+        let result = try e2e.hasAuthenticatedChannel(partnerId: contactId)
+        return .success(.didCheck(.success(result)))
+      } catch {
+        return .success(.didCheck(.failure(error.localizedDescription)))
+      }
+    }
+    .subscribe(on: env.bgQueue)
+    .receive(on: env.mainQueue)
+    .eraseToEffect()
+
+  case .didCheck(let result):
+    state.isChecking = false
+    state.result = result
+    return .none
+  }
+}
diff --git a/Examples/xx-messenger/Sources/CheckContactAuthFeature/CheckContactAuthView.swift b/Examples/xx-messenger/Sources/CheckContactAuthFeature/CheckContactAuthView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..dd2e7894e256c67f4a1ddcf421877dcbfbac63cc
--- /dev/null
+++ b/Examples/xx-messenger/Sources/CheckContactAuthFeature/CheckContactAuthView.swift
@@ -0,0 +1,101 @@
+import ComposableArchitecture
+import SwiftUI
+import XXClient
+
+public struct CheckContactAuthView: View {
+  public init(store: Store<CheckContactAuthState, CheckContactAuthAction>) {
+    self.store = store
+  }
+
+  let store: Store<CheckContactAuthState, CheckContactAuthAction>
+
+  struct ViewState: Equatable {
+    var username: String?
+    var email: String?
+    var phone: String?
+    var isChecking: Bool
+    var result: CheckContactAuthState.Result?
+
+    init(state: CheckContactAuthState) {
+      username = try? state.contact.getFact(.username)?.value
+      email = try? state.contact.getFact(.email)?.value
+      phone = try? state.contact.getFact(.phone)?.value
+      isChecking = state.isChecking
+      result = state.result
+    }
+  }
+
+  public var body: some View {
+    WithViewStore(store.scope(state: ViewState.init)) { viewStore in
+      Form {
+        Section {
+          Label(viewStore.username ?? "", systemImage: "person")
+          Label(viewStore.email ?? "", systemImage: "envelope")
+          Label(viewStore.phone ?? "", systemImage: "phone")
+        } header: {
+          Text("Facts")
+        }
+
+        Section {
+          Button {
+            viewStore.send(.checkTapped)
+          } label: {
+            HStack {
+              Text("Check")
+              Spacer()
+              if viewStore.isChecking {
+                ProgressView()
+              } else {
+                Image(systemName: "play")
+              }
+            }
+          }
+          .disabled(viewStore.isChecking)
+        }
+
+        if let result = viewStore.result {
+          Section {
+            HStack {
+              switch result {
+              case .success(true):
+                Text("Authorized")
+                Spacer()
+                Image(systemName: "person.fill.checkmark")
+
+              case .success(false):
+                Text("Not authorized")
+                Spacer()
+                Image(systemName: "person.fill.xmark")
+
+              case .failure(_):
+                Text("Checking status failed")
+                Spacer()
+                Image(systemName: "xmark")
+              }
+            }
+            if case .failure(let failure) = result {
+              Text(failure)
+            }
+          } header: {
+            Text("Result")
+          }
+        }
+      }
+      .navigationTitle("Check connection")
+    }
+  }
+}
+
+#if DEBUG
+public struct CheckContactAuthView_Previews: PreviewProvider {
+  public static var previews: some View {
+    CheckContactAuthView(store: Store(
+      initialState: CheckContactAuthState(
+        contact: .unimplemented("contact-data".data(using: .utf8)!)
+      ),
+      reducer: .empty,
+      environment: ()
+    ))
+  }
+}
+#endif
diff --git a/Examples/xx-messenger/Tests/CheckContactAuthFeatureTests/CheckContactAuthFeatureTests.swift b/Examples/xx-messenger/Tests/CheckContactAuthFeatureTests/CheckContactAuthFeatureTests.swift
new file mode 100644
index 0000000000000000000000000000000000000000..1c36e33e9d43509b986c0bce4d9bd4304ef9cd6e
--- /dev/null
+++ b/Examples/xx-messenger/Tests/CheckContactAuthFeatureTests/CheckContactAuthFeatureTests.swift
@@ -0,0 +1,110 @@
+import ComposableArchitecture
+import XCTest
+import XXClient
+@testable import CheckContactAuthFeature
+
+final class CheckContactAuthFeatureTests: XCTestCase {
+  func testCheck() {
+    var contact = Contact.unimplemented("contact-data".data(using: .utf8)!)
+    let contactId = "contact-id".data(using: .utf8)!
+    contact.getIdFromContact.run = { _ in contactId }
+
+    let store = TestStore(
+      initialState: CheckContactAuthState(
+        contact: contact
+      ),
+      reducer: checkContactAuthReducer,
+      environment: .unimplemented
+    )
+
+    var didCheckPartnerId: [Data] = []
+
+    store.environment.mainQueue = .immediate
+    store.environment.bgQueue = .immediate
+    store.environment.messenger.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.hasAuthenticatedChannel.run = { partnerId in
+        didCheckPartnerId.append(partnerId)
+        return true
+      }
+      return e2e
+    }
+
+    store.send(.checkTapped) {
+      $0.isChecking = true
+      $0.result = nil
+    }
+
+    store.receive(.didCheck(.success(true))) {
+      $0.isChecking = false
+      $0.result = .success(true)
+    }
+  }
+
+  func testCheckNoConnection() {
+    var contact = Contact.unimplemented("contact-data".data(using: .utf8)!)
+    let contactId = "contact-id".data(using: .utf8)!
+    contact.getIdFromContact.run = { _ in contactId }
+
+    let store = TestStore(
+      initialState: CheckContactAuthState(
+        contact: contact
+      ),
+      reducer: checkContactAuthReducer,
+      environment: .unimplemented
+    )
+
+    store.environment.mainQueue = .immediate
+    store.environment.bgQueue = .immediate
+    store.environment.messenger.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.hasAuthenticatedChannel.run = { _ in false }
+      return e2e
+    }
+
+    store.send(.checkTapped) {
+      $0.isChecking = true
+      $0.result = nil
+    }
+
+    store.receive(.didCheck(.success(false))) {
+      $0.isChecking = false
+      $0.result = .success(false)
+    }
+  }
+
+  func testCheckFailure() {
+    var contact = Contact.unimplemented("contact-data".data(using: .utf8)!)
+    let contactId = "contact-id".data(using: .utf8)!
+    contact.getIdFromContact.run = { _ in contactId }
+
+    let store = TestStore(
+      initialState: CheckContactAuthState(
+        contact: contact
+      ),
+      reducer: checkContactAuthReducer,
+      environment: .unimplemented
+    )
+
+    struct Failure: Error {}
+    let error = Failure()
+
+    store.environment.mainQueue = .immediate
+    store.environment.bgQueue = .immediate
+    store.environment.messenger.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.hasAuthenticatedChannel.run = { _ in throw error }
+      return e2e
+    }
+
+    store.send(.checkTapped) {
+      $0.isChecking = true
+      $0.result = nil
+    }
+
+    store.receive(.didCheck(.failure(error.localizedDescription))) {
+      $0.isChecking = false
+      $0.result = .failure(error.localizedDescription)
+    }
+  }
+}