diff --git a/Examples/xx-messenger/Package.swift b/Examples/xx-messenger/Package.swift
index 1cab487ef6b858745e56cce7eda49a3e6c9d4a89..4dad2c2bf992cff93e37f2f6f7dcfd24356602c9 100644
--- a/Examples/xx-messenger/Package.swift
+++ b/Examples/xx-messenger/Package.swift
@@ -90,6 +90,7 @@ let package = Package(
         .target(name: "CheckContactAuthFeature"),
         .target(name: "ConfirmRequestFeature"),
         .target(name: "ContactFeature"),
+        .target(name: "ContactLookupFeature"),
         .target(name: "ContactsFeature"),
         .target(name: "HomeFeature"),
         .target(name: "MyContactFeature"),
@@ -192,6 +193,7 @@ let package = Package(
         .target(name: "ChatFeature"),
         .target(name: "CheckContactAuthFeature"),
         .target(name: "ConfirmRequestFeature"),
+        .target(name: "ContactLookupFeature"),
         .target(name: "SendRequestFeature"),
         .target(name: "VerifyContactFeature"),
         .product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
diff --git a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
index 3cf2cb0b065eda90aeff16cf1ce76f14297fd012..34d9f80675fd106a479ea9707c193ab810344222 100644
--- a/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
+++ b/Examples/xx-messenger/Sources/AppFeature/AppEnvironment+Live.swift
@@ -37,6 +37,9 @@ extension AppEnvironment {
       db: dbManager.getDB,
       mainQueue: mainQueue,
       bgQueue: bgQueue,
+      lookup: {
+        ContactLookupEnvironment()
+      },
       sendRequest: {
         SendRequestEnvironment(
           messenger: messenger,
diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift
index 993796e4bf4f286a29fdb7319fb39332074c68da..16c6a9a6cba3d1bf335070d44aab052af1b2b913 100644
--- a/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift
+++ b/Examples/xx-messenger/Sources/ContactFeature/ContactFeature.swift
@@ -4,6 +4,7 @@ import CheckContactAuthFeature
 import ComposableArchitecture
 import ComposablePresentation
 import ConfirmRequestFeature
+import ContactLookupFeature
 import Foundation
 import SendRequestFeature
 import VerifyContactFeature
@@ -20,6 +21,7 @@ public struct ContactState: Equatable {
     importUsername: Bool = true,
     importEmail: Bool = true,
     importPhone: Bool = true,
+    lookup: ContactLookupState? = nil,
     sendRequest: SendRequestState? = nil,
     verifyContact: VerifyContactState? = nil,
     confirmRequest: ConfirmRequestState? = nil,
@@ -32,6 +34,7 @@ public struct ContactState: Equatable {
     self.importUsername = importUsername
     self.importEmail = importEmail
     self.importPhone = importPhone
+    self.lookup = lookup
     self.sendRequest = sendRequest
     self.verifyContact = verifyContact
     self.confirmRequest = confirmRequest
@@ -45,6 +48,7 @@ public struct ContactState: Equatable {
   @BindableState public var importUsername: Bool
   @BindableState public var importEmail: Bool
   @BindableState public var importPhone: Bool
+  public var lookup: ContactLookupState?
   public var sendRequest: SendRequestState?
   public var verifyContact: VerifyContactState?
   public var confirmRequest: ConfirmRequestState?
@@ -56,6 +60,9 @@ public enum ContactAction: Equatable, BindableAction {
   case start
   case dbContactFetched(XXModels.Contact?)
   case importFactsTapped
+  case lookupTapped
+  case lookupDismissed
+  case lookup(ContactLookupAction)
   case sendRequestTapped
   case sendRequestDismissed
   case sendRequest(SendRequestAction)
@@ -80,6 +87,7 @@ public struct ContactEnvironment {
     db: DBManagerGetDB,
     mainQueue: AnySchedulerOf<DispatchQueue>,
     bgQueue: AnySchedulerOf<DispatchQueue>,
+    lookup: @escaping () -> ContactLookupEnvironment,
     sendRequest: @escaping () -> SendRequestEnvironment,
     verifyContact: @escaping () -> VerifyContactEnvironment,
     confirmRequest: @escaping () -> ConfirmRequestEnvironment,
@@ -90,6 +98,7 @@ public struct ContactEnvironment {
     self.db = db
     self.mainQueue = mainQueue
     self.bgQueue = bgQueue
+    self.lookup = lookup
     self.sendRequest = sendRequest
     self.verifyContact = verifyContact
     self.confirmRequest = confirmRequest
@@ -101,6 +110,7 @@ public struct ContactEnvironment {
   public var db: DBManagerGetDB
   public var mainQueue: AnySchedulerOf<DispatchQueue>
   public var bgQueue: AnySchedulerOf<DispatchQueue>
+  public var lookup: () -> ContactLookupEnvironment
   public var sendRequest: () -> SendRequestEnvironment
   public var verifyContact: () -> VerifyContactEnvironment
   public var confirmRequest: () -> ConfirmRequestEnvironment
@@ -115,6 +125,7 @@ extension ContactEnvironment {
     db: .unimplemented,
     mainQueue: .unimplemented,
     bgQueue: .unimplemented,
+    lookup: { .unimplemented },
     sendRequest: { .unimplemented },
     verifyContact: { .unimplemented },
     confirmRequest: { .unimplemented },
@@ -163,6 +174,14 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm
     .receive(on: env.mainQueue)
     .eraseToEffect()
 
+  case .lookupTapped:
+    state.lookup = ContactLookupState(id: state.id)
+    return .none
+
+  case .lookupDismissed:
+    state.lookup = nil
+    return .none
+
   case .sendRequestTapped:
     if let xxContact = state.xxContact {
       state.sendRequest = SendRequestState(contact: xxContact)
@@ -223,11 +242,20 @@ public let contactReducer = Reducer<ContactState, ContactAction, ContactEnvironm
     state.chat = nil
     return .none
 
-  case .binding(_), .sendRequest(_), .verifyContact(_), .confirmRequest(_), .checkAuth(_), .chat(_):
+  case .binding(_), .lookup(_), .sendRequest(_),
+      .verifyContact(_), .confirmRequest(_),
+      .checkAuth(_), .chat(_):
     return .none
   }
 }
 .binding()
+.presenting(
+  contactLookupReducer,
+  state: .keyPath(\.lookup),
+  id: .notNil(),
+  action: /ContactAction.lookup,
+  environment: { $0.lookup() }
+)
 .presenting(
   sendRequestReducer,
   state: .keyPath(\.sendRequest),
diff --git a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift
index 2afc08f5bf4d74355c6f7558180f938237aaee94..5bfe475b44aca55fffbbcb787135788422dc1a87 100644
--- a/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift
+++ b/Examples/xx-messenger/Sources/ContactFeature/ContactView.swift
@@ -4,6 +4,7 @@ import CheckContactAuthFeature
 import ComposableArchitecture
 import ComposablePresentation
 import ConfirmRequestFeature
+import ContactLookupFeature
 import SendRequestFeature
 import SwiftUI
 import VerifyContactFeature
@@ -26,6 +27,7 @@ public struct ContactView: View {
     var importUsername: Bool
     var importEmail: Bool
     var importPhone: Bool
+    var canLookup: Bool
     var canSendRequest: Bool
     var canVerifyContact: Bool
     var canConfirmRequest: Bool
@@ -40,6 +42,7 @@ public struct ContactView: View {
       importUsername = state.importUsername
       importEmail = state.importEmail
       importPhone = state.importPhone
+      canLookup = state.dbContact?.id != nil
       canSendRequest = state.xxContact != nil || state.dbContact?.marshaled != nil
       canVerifyContact = state.dbContact?.marshaled != nil
       canConfirmRequest = state.dbContact?.marshaled != nil
@@ -121,6 +124,17 @@ public struct ContactView: View {
           Section {
             ContactAuthStatusView(dbContact.authStatus)
 
+            Button {
+              viewStore.send(.lookupTapped)
+            } label: {
+              HStack {
+                Text("Lookup")
+                Spacer()
+                Image(systemName: "chevron.forward")
+              }
+            }
+            .disabled(!viewStore.canLookup)
+
             Button {
               viewStore.send(.sendRequestTapped)
             } label: {
@@ -186,6 +200,15 @@ public struct ContactView: View {
       }
       .navigationTitle("Contact")
       .task { viewStore.send(.start) }
+      .background(NavigationLinkWithStore(
+        store.scope(
+          state: \.lookup,
+          action: ContactAction.lookup
+        ),
+        mapState: replayNonNil(),
+        onDeactivate: { viewStore.send(.lookupDismissed) },
+        destination: ContactLookupView.init(store:)
+      ))
       .background(NavigationLinkWithStore(
         store.scope(
           state: \.sendRequest,
diff --git a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift
index feeccc98094da76d1f5ebd21122a4b3214afbcb7..a8f9f144eb3e2ff6efa99ca844039b7b9d74f619 100644
--- a/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift
+++ b/Examples/xx-messenger/Tests/ContactFeatureTests/ContactFeatureTests.swift
@@ -3,6 +3,7 @@ import CheckContactAuthFeature
 import Combine
 import ComposableArchitecture
 import ConfirmRequestFeature
+import ContactLookupFeature
 import CustomDump
 import SendRequestFeature
 import VerifyContactFeature
@@ -99,6 +100,37 @@ final class ContactFeatureTests: XCTestCase {
     XCTAssertNoDifference(dbDidSaveContact, [expectedSavedContact])
   }
 
+  func testLookupTapped() {
+    let contactId = "contact-id".data(using: .utf8)!
+    let store = TestStore(
+      initialState: ContactState(
+        id: contactId
+      ),
+      reducer: contactReducer,
+      environment: .unimplemented
+    )
+
+    store.send(.lookupTapped) {
+      $0.lookup = ContactLookupState(id: contactId)
+    }
+  }
+
+  func testLookupDismissed() {
+    let contactId = "contact-id".data(using: .utf8)!
+    let store = TestStore(
+      initialState: ContactState(
+        id: contactId,
+        lookup: ContactLookupState(id: contactId)
+      ),
+      reducer: contactReducer,
+      environment: .unimplemented
+    )
+
+    store.send(.lookupDismissed) {
+      $0.lookup = nil
+    }
+  }
+
   func testSendRequestWithDBContact() {
     var dbContact = XXModels.Contact(id: "contact-id".data(using: .utf8)!)
     dbContact.marshaled = "contact-data".data(using: .utf8)!