diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift
index f9ceb75fdf29afbda5362c20139003d77ebb131f..565dccc645fa11eabea768dccf2ee4e1f9df9475 100644
--- a/Examples/xx-messenger/Package.swift
+++ b/Examples/xx-messenger/Package.swift
@@ -141,6 +141,7 @@ let package = Package(
       name: "UserSearchFeature",
       dependencies: [
         .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"),
       ],
diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
index 5d7777802ed09dcfb2e36b14ba2a5b55f1fe906e..00415b4382a796f43ab1749e9ec3e4b6139c2562 100644
--- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
+++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
@@ -50,7 +50,10 @@ extension AppEnvironment {
             UserSearchEnvironment(
               messenger: messenger,
               mainQueue: mainQueue,
-              bgQueue: bgQueue
+              bgQueue: bgQueue,
+              result: {
+                UserSearchResultEnvironment()
+              }
             )
           }
         )
diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift
index 86a13c0ec97966619bea881f5ac0b8c9de962fed..9d16d8f5fb18510ca0d794dfd4fd3933cf5faa4e 100644
--- a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift
+++ b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchFeature.swift
@@ -1,4 +1,5 @@
 import ComposableArchitecture
+import ComposablePresentation
 import Foundation
 import XCTestDynamicOverlay
 import XXClient
@@ -11,34 +12,12 @@ public struct UserSearchState: Equatable {
     case phone
   }
 
-  public struct Result: Equatable, Identifiable {
-    public init(
-      id: Data,
-      contact: Contact,
-      username: String? = nil,
-      email: String? = nil,
-      phone: String? = nil
-    ) {
-      self.id = id
-      self.contact = contact
-      self.username = username
-      self.email = email
-      self.phone = phone
-    }
-
-    public var id: Data
-    public var contact: XXClient.Contact
-    public var username: String?
-    public var email: String?
-    public var phone: String?
-  }
-
   public init(
     focusedField: Field? = nil,
     query: MessengerSearchUsers.Query = .init(),
     isSearching: Bool = false,
     failure: String? = nil,
-    results: IdentifiedArrayOf<Result> = []
+    results: IdentifiedArrayOf<UserSearchResultState> = []
   ) {
     self.focusedField = focusedField
     self.query = query
@@ -51,7 +30,7 @@ public struct UserSearchState: Equatable {
   @BindableState public var query: MessengerSearchUsers.Query
   public var isSearching: Bool
   public var failure: String?
-  public var results: IdentifiedArrayOf<Result>
+  public var results: IdentifiedArrayOf<UserSearchResultState>
 }
 
 public enum UserSearchAction: Equatable, BindableAction {
@@ -59,22 +38,26 @@ public enum UserSearchAction: Equatable, BindableAction {
   case didFail(String)
   case didSucceed([Contact])
   case binding(BindingAction<UserSearchState>)
+  case result(id: UserSearchResultState.ID, action: UserSearchResultAction)
 }
 
 public struct UserSearchEnvironment {
   public init(
     messenger: Messenger,
     mainQueue: AnySchedulerOf<DispatchQueue>,
-    bgQueue: AnySchedulerOf<DispatchQueue>
+    bgQueue: AnySchedulerOf<DispatchQueue>,
+    result: @escaping () -> UserSearchResultEnvironment
   ) {
     self.messenger = messenger
     self.mainQueue = mainQueue
     self.bgQueue = bgQueue
+    self.result = result
   }
 
   public var messenger: Messenger
   public var mainQueue: AnySchedulerOf<DispatchQueue>
   public var bgQueue: AnySchedulerOf<DispatchQueue>
+  public var result: () -> UserSearchResultEnvironment
 }
 
 #if DEBUG
@@ -82,7 +65,8 @@ extension UserSearchEnvironment {
   public static let unimplemented = UserSearchEnvironment(
     messenger: .unimplemented,
     mainQueue: .unimplemented,
-    bgQueue: .unimplemented
+    bgQueue: .unimplemented,
+    result: { .unimplemented }
   )
 }
 #endif
@@ -111,14 +95,7 @@ public let userSearchReducer = Reducer<UserSearchState, UserSearchAction, UserSe
     state.failure = nil
     state.results = IdentifiedArray(uniqueElements: contacts.compactMap { contact in
       guard let id = try? contact.getId() else { return nil }
-      let facts = (try? contact.getFacts()) ?? []
-      return UserSearchState.Result(
-        id: id,
-        contact: contact,
-        username: facts.first(where: { $0.type == 0 })?.fact,
-        email: facts.first(where: { $0.type == 1 })?.fact,
-        phone: facts.first(where: { $0.type == 2 })?.fact
-      )
+      return UserSearchResultState(id: id, contact: contact)
     })
     return .none
 
@@ -128,8 +105,14 @@ public let userSearchReducer = Reducer<UserSearchState, UserSearchAction, UserSe
     state.results = []
     return .none
 
-  case .binding(_):
+  case .binding(_), .result(_, _):
     return .none
   }
 }
 .binding()
+.presenting(
+  forEach: userSearchResultReducer,
+  state: \.results,
+  action: /UserSearchAction.result(id:action:),
+  environment: { $0.result() }
+)
diff --git a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift
index 266938a29b096d05f695c2f39f55f8c0fb993442..e149ac2a9f4d7485a80331e6ac816e87f8b41aaf 100644
--- a/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift
+++ b/Examples/xx-messenger/Sources/UserSearchFeature/UserSearchView.swift
@@ -15,14 +15,12 @@ public struct UserSearchView: View {
     var query: MessengerSearchUsers.Query
     var isSearching: Bool
     var failure: String?
-    var results: IdentifiedArrayOf<UserSearchState.Result>
 
     init(state: UserSearchState) {
       focusedField = state.focusedField
       query = state.query
       isSearching = state.isSearching
       failure = state.failure
-      results = state.results
     }
   }
 
@@ -87,23 +85,13 @@ public struct UserSearchView: View {
           }
         }
 
-        ForEach(viewStore.results) { result in
-          Section {
-            if let username = result.username {
-              Text(username)
-            }
-            if let email = result.email {
-              Text(email)
-            }
-            if let phone = result.phone {
-              Text(phone)
-            }
-            if result.username == nil, result.email == nil, result.phone == nil {
-              Image(systemName: "questionmark")
-                .frame(maxWidth: .infinity)
-            }
-          }
-        }
+        ForEachStore(
+          store.scope(
+            state: \.results,
+            action: UserSearchAction.result(id:action:)
+          ),
+          content: UserSearchResultView.init(store:)
+        )
       }
       .onChange(of: viewStore.focusedField) { focusedField = $0 }
       .onChange(of: focusedField) { viewStore.send(.set(\.$focusedField, $0)) }
diff --git a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift
index 8d2f414a0a6c4fa130ea285863ae92ef80f70c21..a96afd9590cfdd4532f2c93716c6f5237a9c2096 100644
--- a/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift
+++ b/Examples/xx-messenger/Tests/UserSearchFeatureTests/UserSearchFeatureTests.swift
@@ -19,23 +19,12 @@ final class UserSearchFeatureTests: XCTestCase {
 
     var contact1 = Contact.unimplemented("contact-1".data(using: .utf8)!)
     contact1.getIdFromContact.run = { _ in "contact-1-id".data(using: .utf8)! }
-    contact1.getFactsFromContact.run = { _ in
-      [Fact(fact: "contact-1-username", type: 0),
-       Fact(fact: "contact-1-email", type: 1),
-       Fact(fact: "contact-1-phone", type: 2)]
-    }
     var contact2 = Contact.unimplemented("contact-1".data(using: .utf8)!)
     contact2.getIdFromContact.run = { _ in "contact-2-id".data(using: .utf8)! }
-    contact2.getFactsFromContact.run = { _ in
-      [Fact(fact: "contact-2-username", type: 0),
-       Fact(fact: "contact-2-email", type: 1),
-       Fact(fact: "contact-2-phone", type: 2)]
-    }
     var contact3 = Contact.unimplemented("contact-3".data(using: .utf8)!)
     contact3.getIdFromContact.run = { _ in throw GetIdFromContactError() }
     var contact4 = Contact.unimplemented("contact-4".data(using: .utf8)!)
     contact4.getIdFromContact.run = { _ in "contact-4-id".data(using: .utf8)! }
-    contact4.getFactsFromContact.run = { _ in throw GetFactsFromContactError() }
     let contacts = [contact1, contact2, contact3, contact4]
 
     store.environment.bgQueue = .immediate
@@ -64,27 +53,9 @@ final class UserSearchFeatureTests: XCTestCase {
       $0.isSearching = false
       $0.failure = nil
       $0.results = [
-        .init(
-          id: "contact-1-id".data(using: .utf8)!,
-          contact: contact1,
-          username: "contact-1-username",
-          email: "contact-1-email",
-          phone: "contact-1-phone"
-        ),
-        .init(
-          id: "contact-2-id".data(using: .utf8)!,
-          contact: contact2,
-          username: "contact-2-username",
-          email: "contact-2-email",
-          phone: "contact-2-phone"
-        ),
-        .init(
-          id: "contact-4-id".data(using: .utf8)!,
-          contact: contact4,
-          username: nil,
-          email: nil,
-          phone: nil
-        )
+        .init(id: "contact-1-id".data(using: .utf8)!, contact: contact1),
+        .init(id: "contact-2-id".data(using: .utf8)!, contact: contact2),
+        .init(id: "contact-4-id".data(using: .utf8)!, contact: contact4)
       ]
     }
   }