diff --git a/Examples/xx-messenger/.swiftpm/xcode/xcshareddata/xcschemes/ContactsFeature.xcscheme b/Examples/xx-messenger/.swiftpm/xcode/xcshareddata/xcschemes/ContactsFeature.xcscheme
new file mode 100644
index 0000000000000000000000000000000000000000..feb1a4909f8c4e947ab8005e055ad9a9d9e61884
--- /dev/null
+++ b/Examples/xx-messenger/.swiftpm/xcode/xcshareddata/xcschemes/ContactsFeature.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 = "ContactsFeature"
+               BuildableName = "ContactsFeature"
+               BlueprintName = "ContactsFeature"
+               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 = "ContactsFeatureTests"
+               BuildableName = "ContactsFeatureTests"
+               BlueprintName = "ContactsFeatureTests"
+               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 = "ContactsFeature"
+            BuildableName = "ContactsFeature"
+            BlueprintName = "ContactsFeature"
+            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 77b97a0f38f4516e0ae9b60feeb18364dbb02247..5df8eb39dd57b9f788e430521dd637d0e48e1b64 100644
--- a/Examples/xx-messenger/Package.swift
+++ b/Examples/xx-messenger/Package.swift
@@ -21,6 +21,7 @@ let package = Package(
     .library(name: "AppCore", targets: ["AppCore"]),
     .library(name: "AppFeature", targets: ["AppFeature"]),
     .library(name: "ContactFeature", targets: ["ContactFeature"]),
+    .library(name: "ContactsFeature", targets: ["ContactsFeature"]),
     .library(name: "HomeFeature", targets: ["HomeFeature"]),
     .library(name: "RegisterFeature", targets: ["RegisterFeature"]),
     .library(name: "RestoreFeature", targets: ["RestoreFeature"]),
@@ -72,6 +73,7 @@ let package = Package(
       dependencies: [
         .target(name: "AppCore"),
         .target(name: "ContactFeature"),
+        .target(name: "ContactsFeature"),
         .target(name: "HomeFeature"),
         .target(name: "RegisterFeature"),
         .target(name: "RestoreFeature"),
@@ -111,10 +113,31 @@ let package = Package(
       ],
       swiftSettings: swiftSettings
     ),
+    .target(
+      name: "ContactsFeature",
+      dependencies: [
+        .target(name: "AppCore"),
+        .target(name: "ContactFeature"),
+        .product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
+        .product(name: "ComposablePresentation", package: "swift-composable-presentation"),
+        .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
+        .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"),
+        .product(name: "XXModels", package: "client-ios-db"),
+      ],
+      swiftSettings: swiftSettings
+    ),
+    .testTarget(
+      name: "ContactsFeatureTests",
+      dependencies: [
+        .target(name: "ContactsFeature"),
+      ],
+      swiftSettings: swiftSettings
+    ),
     .target(
       name: "HomeFeature",
       dependencies: [
         .target(name: "AppCore"),
+        .target(name: "ContactsFeature"),
         .target(name: "RegisterFeature"),
         .target(name: "UserSearchFeature"),
         .product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
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 0d7cb106a1c962bb00f93bd1668ae0e80dbcc173..9d31f6f70a3f7dd3e87b943466febea60557f6af 100644
--- a/Examples/xx-messenger/Project/XXMessenger.xcodeproj/xcshareddata/xcschemes/XXMessenger.xcscheme
+++ b/Examples/xx-messenger/Project/XXMessenger.xcodeproj/xcshareddata/xcschemes/XXMessenger.xcscheme
@@ -59,6 +59,16 @@
                ReferencedContainer = "container:..">
             </BuildableReference>
          </TestableReference>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "ContactsFeatureTests"
+               BuildableName = "ContactsFeatureTests"
+               BlueprintName = "ContactsFeatureTests"
+               ReferencedContainer = "container:..">
+            </BuildableReference>
+         </TestableReference>
          <TestableReference
             skipped = "NO">
             <BuildableReference
diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
index 01e315198e89816e8a7f8054bf0c791d707b9d30..61bfba1f3163cf119e610606f9d89ea67a122171 100644
--- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
+++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
@@ -1,5 +1,6 @@
 import AppCore
 import ContactFeature
+import ContactsFeature
 import Foundation
 import HomeFeature
 import RegisterFeature
@@ -18,6 +19,21 @@ extension AppEnvironment {
     let mainQueue = DispatchQueue.main.eraseToAnyScheduler()
     let bgQueue = DispatchQueue.global(qos: .background).eraseToAnyScheduler()
 
+    let contactEnvironment = ContactEnvironment(
+      messenger: messenger,
+      db: dbManager.getDB,
+      mainQueue: mainQueue,
+      bgQueue: bgQueue,
+      sendRequest: {
+        SendRequestEnvironment(
+          messenger: messenger,
+          db: dbManager.getDB,
+          mainQueue: mainQueue,
+          bgQueue: bgQueue
+        )
+      }
+    )
+
     return AppEnvironment(
       dbManager: dbManager,
       messenger: messenger,
@@ -48,27 +64,21 @@ extension AppEnvironment {
               bgQueue: bgQueue
             )
           },
+          contacts: {
+            ContactsEnvironment(
+              messenger: messenger,
+              db: dbManager.getDB,
+              mainQueue: mainQueue,
+              bgQueue: bgQueue,
+              contact: { contactEnvironment }
+            )
+          },
           userSearch: {
             UserSearchEnvironment(
               messenger: messenger,
               mainQueue: mainQueue,
               bgQueue: bgQueue,
-              contact: {
-                ContactEnvironment(
-                  messenger: messenger,
-                  db: dbManager.getDB,
-                  mainQueue: mainQueue,
-                  bgQueue: bgQueue,
-                  sendRequest: {
-                    SendRequestEnvironment(
-                      messenger: messenger,
-                      db: dbManager.getDB,
-                      mainQueue: mainQueue,
-                      bgQueue: bgQueue
-                    )
-                  }
-                )
-              }
+              contact: { contactEnvironment }
             )
           }
         )
diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift
new file mode 100644
index 0000000000000000000000000000000000000000..1ded89de4cbf9dd44014395e3e79bf6ff2fdcc20
--- /dev/null
+++ b/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift
@@ -0,0 +1,109 @@
+import AppCore
+import ComposableArchitecture
+import ComposablePresentation
+import ContactFeature
+import Foundation
+import XCTestDynamicOverlay
+import XXClient
+import XXMessengerClient
+import XXModels
+
+public struct ContactsState: Equatable {
+  public init(
+    myId: Data? = nil,
+    contacts: IdentifiedArrayOf<XXModels.Contact> = [],
+    contact: ContactState? = nil
+  ) {
+    self.myId = myId
+    self.contacts = contacts
+    self.contact = contact
+  }
+
+  public var myId: Data?
+  public var contacts: IdentifiedArrayOf<XXModels.Contact>
+  public var contact: ContactState?
+}
+
+public enum ContactsAction: Equatable {
+  case start
+  case didFetchContacts([XXModels.Contact])
+  case contactSelected(XXModels.Contact)
+  case contactDismissed
+  case contact(ContactAction)
+}
+
+public struct ContactsEnvironment {
+  public init(
+    messenger: Messenger,
+    db: DBManagerGetDB,
+    mainQueue: AnySchedulerOf<DispatchQueue>,
+    bgQueue: AnySchedulerOf<DispatchQueue>,
+    contact: @escaping () -> ContactEnvironment
+  ) {
+    self.messenger = messenger
+    self.db = db
+    self.mainQueue = mainQueue
+    self.bgQueue = bgQueue
+    self.contact = contact
+  }
+
+  public var messenger: Messenger
+  public var db: DBManagerGetDB
+  public var mainQueue: AnySchedulerOf<DispatchQueue>
+  public var bgQueue: AnySchedulerOf<DispatchQueue>
+  public var contact: () -> ContactEnvironment
+}
+
+#if DEBUG
+extension ContactsEnvironment {
+  public static let unimplemented = ContactsEnvironment(
+    messenger: .unimplemented,
+    db: .unimplemented,
+    mainQueue: .unimplemented,
+    bgQueue: .unimplemented,
+    contact: { .unimplemented }
+  )
+}
+#endif
+
+public let contactsReducer = Reducer<ContactsState, ContactsAction, ContactsEnvironment>
+{ state, action, env in
+  switch action {
+  case .start:
+    state.myId = try? env.messenger.e2e.tryGet().getContact().getId()
+    return Effect
+      .catching { try env.db() }
+      .flatMap { $0.fetchContactsPublisher(.init()) }
+      .assertNoFailure()
+      .map(ContactsAction.didFetchContacts)
+      .subscribe(on: env.bgQueue)
+      .receive(on: env.mainQueue)
+      .eraseToEffect()
+
+  case .didFetchContacts(var contacts):
+    if let myId = state.myId,
+       let myIndex = contacts.firstIndex(where: { $0.id == myId }) {
+      contacts.move(fromOffsets: [myIndex], toOffset: contacts.startIndex)
+    }
+    state.contacts = IdentifiedArray(uniqueElements: contacts)
+    return .none
+
+  case .contactSelected(let contact):
+    state.contact = ContactState(id: contact.id, dbContact: contact)
+    return .none
+
+  case .contactDismissed:
+    state.contact = nil
+    return .none
+
+  case .contact(_):
+    return .none
+  }
+}
+.presenting(
+  contactReducer,
+  state: .keyPath(\.contact),
+  id: .keyPath(\.?.id),
+  action: /ContactsAction.contact,
+  environment: { $0.contact() }
+)
diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..b7798685cf75d851adba765f751c6fb5a47ceea0
--- /dev/null
+++ b/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift
@@ -0,0 +1,107 @@
+import AppCore
+import ComposableArchitecture
+import ComposablePresentation
+import ContactFeature
+import SwiftUI
+import XXModels
+
+public struct ContactsView: View {
+  public init(store: Store<ContactsState, ContactsAction>) {
+    self.store = store
+  }
+
+  let store: Store<ContactsState, ContactsAction>
+
+  struct ViewState: Equatable {
+    var myId: Data?
+    var contacts: IdentifiedArrayOf<XXModels.Contact>
+
+    init(state: ContactsState) {
+      myId = state.myId
+      contacts = state.contacts
+    }
+  }
+
+  public var body: some View {
+    WithViewStore(store.scope(state: ViewState.init)) { viewStore in
+      Form {
+        ForEach(viewStore.contacts) { contact in
+          if contact.id == viewStore.myId {
+            Section {
+              VStack(alignment: .leading, spacing: 8) {
+                Label(contact.username ?? "", systemImage: "person")
+                Label(contact.email ?? "", systemImage: "envelope")
+                Label(contact.phone ?? "", systemImage: "phone")
+              }
+              .font(.callout)
+              .tint(Color.primary)
+            } header: {
+              Text("My contact")
+            }
+          } else {
+            Section {
+              Button {
+                viewStore.send(.contactSelected(contact))
+              } label: {
+                HStack {
+                  VStack(alignment: .leading, spacing: 8) {
+                    Label(contact.username ?? "", systemImage: "person")
+                    Label(contact.email ?? "", systemImage: "envelope")
+                    Label(contact.phone ?? "", systemImage: "phone")
+                  }
+                  .font(.callout)
+                  .tint(Color.primary)
+                  Spacer()
+                  Image(systemName: "chevron.forward")
+                }
+              }
+              ContactAuthStatusView(contact.authStatus)
+            }
+          }
+        }
+      }
+      .navigationTitle("Contacts")
+      .task { viewStore.send(.start) }
+      .background(NavigationLinkWithStore(
+        store.scope(
+          state: \.contact,
+          action: ContactsAction.contact
+        ),
+        onDeactivate: { viewStore.send(.contactDismissed) },
+        destination: ContactView.init(store:)
+      ))
+    }
+  }
+}
+
+#if DEBUG
+public struct ContactsView_Previews: PreviewProvider {
+  public static var previews: some View {
+    NavigationView {
+      ContactsView(store: Store(
+        initialState: ContactsState(
+          contacts: [
+            .init(
+              id: "1".data(using: .utf8)!,
+              username: "John Doe",
+              email: "john@doe.com",
+              phone: "+1234567890",
+              authStatus: .friend
+            ),
+            .init(
+              id: "2".data(using: .utf8)!,
+              username: "Alice Unknown",
+              authStatus: .requested
+            ),
+            .init(
+              id: "3".data(using: .utf8)!
+            ),
+          ]
+        ),
+        reducer: .empty,
+        environment: ()
+      ))
+    }
+  }
+}
+#endif
diff --git a/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift b/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift
index 9df6d745b07e282095cac03a0d978646795af301..faa5757c43a4e22a9c8c3b7dd7a99ee83e059a84 100644
--- a/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift
+++ b/Examples/xx-messenger/Sources/HomeFeature/HomeFeature.swift
@@ -2,6 +2,7 @@ import AppCore
 import Combine
 import ComposableArchitecture
 import ComposablePresentation
+import ContactsFeature
 import Foundation
 import RegisterFeature
 import UserSearchFeature
@@ -16,6 +17,7 @@ public struct HomeState: Equatable {
     isDeletingAccount: Bool = false,
     alert: AlertState<HomeAction>? = nil,
     register: RegisterState? = nil,
+    contacts: ContactsState? = nil,
     userSearch: UserSearchState? = nil
   ) {
     self.failure = failure
@@ -23,6 +25,7 @@ public struct HomeState: Equatable {
     self.isDeletingAccount = isDeletingAccount
     self.alert = alert
     self.register = register
+    self.contacts = contacts
     self.userSearch = userSearch
   }
 
@@ -32,6 +35,7 @@ public struct HomeState: Equatable {
   public var isDeletingAccount: Bool
   public var alert: AlertState<HomeAction>?
   public var register: RegisterState?
+  public var contacts: ContactsState?
   public var userSearch: UserSearchState?
 }
 
@@ -64,7 +68,10 @@ public enum HomeAction: Equatable {
   case didDismissRegister
   case userSearchButtonTapped
   case didDismissUserSearch
+  case contactsButtonTapped
+  case didDismissContacts
   case register(RegisterAction)
+  case contacts(ContactsAction)
   case userSearch(UserSearchAction)
 }
 
@@ -75,6 +82,7 @@ public struct HomeEnvironment {
     mainQueue: AnySchedulerOf<DispatchQueue>,
     bgQueue: AnySchedulerOf<DispatchQueue>,
     register: @escaping () -> RegisterEnvironment,
+    contacts: @escaping () -> ContactsEnvironment,
     userSearch: @escaping () -> UserSearchEnvironment
   ) {
     self.messenger = messenger
@@ -82,6 +90,7 @@ public struct HomeEnvironment {
     self.mainQueue = mainQueue
     self.bgQueue = bgQueue
     self.register = register
+    self.contacts = contacts
     self.userSearch = userSearch
   }
 
@@ -90,6 +99,7 @@ public struct HomeEnvironment {
   public var mainQueue: AnySchedulerOf<DispatchQueue>
   public var bgQueue: AnySchedulerOf<DispatchQueue>
   public var register: () -> RegisterEnvironment
+  public var contacts: () -> ContactsEnvironment
   public var userSearch: () -> UserSearchEnvironment
 }
 
@@ -100,6 +110,7 @@ extension HomeEnvironment {
     mainQueue: .unimplemented,
     bgQueue: .unimplemented,
     register: { .unimplemented },
+    contacts: { .unimplemented },
     userSearch: { .unimplemented }
   )
 }
@@ -238,11 +249,19 @@ public let homeReducer = Reducer<HomeState, HomeAction, HomeEnvironment>
     state.userSearch = nil
     return .none
 
+  case .contactsButtonTapped:
+    state.contacts = ContactsState()
+    return .none
+
+  case .didDismissContacts:
+    state.contacts = nil
+    return .none
+
   case .register(.finished):
     state.register = nil
     return Effect(value: .messenger(.start))
 
-  case .register(_), .userSearch(_):
+  case .register(_), .contacts(_), .userSearch(_):
     return .none
   }
 }
@@ -253,6 +272,13 @@ public let homeReducer = Reducer<HomeState, HomeAction, HomeEnvironment>
   action: /HomeAction.register,
   environment: { $0.register() }
 )
+.presenting(
+  contactsReducer,
+  state: .keyPath(\.contacts),
+  id: .notNil(),
+  action: /HomeAction.contacts,
+  environment: { $0.contacts() }
+)
 .presenting(
   userSearchReducer,
   state: .keyPath(\.userSearch),
diff --git a/Examples/xx-messenger/Sources/HomeFeature/HomeView.swift b/Examples/xx-messenger/Sources/HomeFeature/HomeView.swift
index e52e8d1b7fb94004fc29b4cb82041400467dbe8c..414bf928d0f2eb0e17b692cacd7cd2c8030b789a 100644
--- a/Examples/xx-messenger/Sources/HomeFeature/HomeView.swift
+++ b/Examples/xx-messenger/Sources/HomeFeature/HomeView.swift
@@ -1,5 +1,6 @@
 import ComposableArchitecture
 import ComposablePresentation
+import ContactsFeature
 import RegisterFeature
 import SwiftUI
 import UserSearchFeature
@@ -88,6 +89,16 @@ public struct HomeView: View {
           }
 
           Section {
+            Button {
+              viewStore.send(.contactsButtonTapped)
+            } label: {
+              HStack {
+                Text("Contacts")
+                Spacer()
+                Image(systemName: "chevron.forward")
+              }
+            }
+
             Button {
               viewStore.send(.userSearchButtonTapped)
             } label: {
@@ -123,6 +134,16 @@ public struct HomeView: View {
           store.scope(state: \.alert),
           dismiss: HomeAction.didDismissAlert
         )
+        .background(NavigationLinkWithStore(
+          store.scope(
+            state: \.contacts,
+            action: HomeAction.contacts
+          ),
+          onDeactivate: {
+            viewStore.send(.didDismissContacts)
+          },
+          destination: ContactsView.init(store:)
+        ))
         .background(NavigationLinkWithStore(
           store.scope(
             state: \.userSearch,
diff --git a/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift b/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift
new file mode 100644
index 0000000000000000000000000000000000000000..a0c0291ef79865fa6c1f3d1ffeb25235bd520acf
--- /dev/null
+++ b/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift
@@ -0,0 +1,97 @@
+import Combine
+import ComposableArchitecture
+import ContactFeature
+import CustomDump
+import XCTest
+import XXClient
+import XXMessengerClient
+import XXModels
+@testable import ContactsFeature
+
+final class ContactsFeatureTests: XCTestCase {
+  func testStart() {
+    let store = TestStore(
+      initialState: ContactsState(),
+      reducer: contactsReducer,
+      environment: .unimplemented
+    )
+
+    let myId = "2".data(using: .utf8)!
+    var didFetchContacts: [XXModels.Contact.Query] = []
+    let contactsPublisher = PassthroughSubject<[XXModels.Contact], Error>()
+
+    store.environment.mainQueue = .immediate
+    store.environment.bgQueue = .immediate
+    store.environment.messenger.e2e.get = {
+      var e2e: E2E = .unimplemented
+      e2e.getContact.run = {
+        var contact: XXClient.Contact = .unimplemented(Data())
+        contact.getIdFromContact.run = { _ in myId }
+        return contact
+      }
+      return e2e
+    }
+    store.environment.db.run = {
+      var db: Database = .failing
+      db.fetchContactsPublisher.run = { query in
+        didFetchContacts.append(query)
+        return contactsPublisher.eraseToAnyPublisher()
+      }
+      return db
+    }
+
+    store.send(.start) {
+      $0.myId = myId
+    }
+
+    XCTAssertNoDifference(didFetchContacts, [XXModels.Contact.Query()])
+
+    let contacts: [XXModels.Contact] = [
+      .init(id: "1".data(using: .utf8)!),
+      .init(id: "2".data(using: .utf8)!),
+      .init(id: "3".data(using: .utf8)!),
+    ]
+    contactsPublisher.send(contacts)
+
+    store.receive(.didFetchContacts(contacts)) {
+      $0.contacts = IdentifiedArray(uniqueElements: [
+        contacts[1],
+        contacts[0],
+        contacts[2],
+      ])
+    }
+
+    contactsPublisher.send(completion: .finished)
+  }
+
+  func testSelectContact() {
+    let store = TestStore(
+      initialState: ContactsState(),
+      reducer: contactsReducer,
+      environment: .unimplemented
+    )
+
+    let contact = XXModels.Contact(id: "id".data(using: .utf8)!)
+
+    store.send(.contactSelected(contact)) {
+      $0.contact = ContactState(id: contact.id, dbContact: contact)
+    }
+  }
+
+  func testDismissContact() {
+    let store = TestStore(
+      initialState: ContactsState(
+        contact: ContactState(
+          id: "id".data(using: .utf8)!,
+          dbContact: Contact(id: "id".data(using: .utf8)!)
+        )
+      ),
+      reducer: contactsReducer,
+      environment: .unimplemented
+    )
+
+    store.send(.contactDismissed) {
+      $0.contact = nil
+    }
+  }
+}
diff --git a/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift b/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift
index 2d7f6dafd6f5833483112c9e7bea9912be90314e..89aef4c9f00a7d887f3b1f6bfead0063ade5f263 100644
--- a/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift
+++ b/Examples/xx-messenger/Tests/HomeFeatureTests/HomeFeatureTests.swift
@@ -1,4 +1,5 @@
 import ComposableArchitecture
+import ContactsFeature
 import RegisterFeature
 import UserSearchFeature
 import XCTest
@@ -464,4 +465,30 @@ final class HomeFeatureTests: XCTestCase {
       $0.userSearch = nil
     }
   }
+
+  func testContactsButtonTapped() {
+    let store = TestStore(
+      initialState: HomeState(),
+      reducer: homeReducer,
+      environment: .unimplemented
+    )
+
+    store.send(.contactsButtonTapped) {
+      $0.contacts = ContactsState()
+    }
+  }
+
+  func testDidDismissContacts() {
+    let store = TestStore(
+      initialState: HomeState(
+        contacts: ContactsState()
+      ),
+      reducer: homeReducer,
+      environment: .unimplemented
+    )
+
+    store.send(.didDismissContacts) {
+      $0.contacts = nil
+    }
+  }
 }