diff --git a/App/client-ios.xcodeproj/project.pbxproj b/App/client-ios.xcodeproj/project.pbxproj
index a3615f3201af5b3a10ab768fcd6283c37af38c1f..bddd3873d8a672f63620f6732ff81d1cc9826096 100644
--- a/App/client-ios.xcodeproj/project.pbxproj
+++ b/App/client-ios.xcodeproj/project.pbxproj
@@ -448,7 +448,7 @@
 				CODE_SIGN_ENTITLEMENTS = "client-ios/Resources/client-ios.entitlements";
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 259;
+				CURRENT_PROJECT_VERSION = 266;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
@@ -487,7 +487,7 @@
 				CODE_SIGN_ENTITLEMENTS = "client-ios/Resources/client-ios.entitlements";
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 259;
+				CURRENT_PROJECT_VERSION = 266;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
@@ -522,7 +522,7 @@
 				CODE_SIGN_ENTITLEMENTS = NotificationExtension/NotificationExtension.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 259;
+				CURRENT_PROJECT_VERSION = 266;
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -553,7 +553,7 @@
 				CODE_SIGN_ENTITLEMENTS = NotificationExtension/NotificationExtension.entitlements;
 				CODE_SIGN_IDENTITY = "Apple Development";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 259;
+				CURRENT_PROJECT_VERSION = 266;
 				DEVELOPMENT_TEAM = S6JDM2WW29;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
diff --git a/App/client-ios.xcodeproj/xcshareddata/xcschemes/Release.xcscheme b/App/client-ios.xcodeproj/xcshareddata/xcschemes/Release.xcscheme
index 800c200df2b4ad94d75e5144e7951bdcd91611f2..b47f627ae04ed4310d32bd7d0d0f1e5176aa6b0b 100644
--- a/App/client-ios.xcodeproj/xcshareddata/xcschemes/Release.xcscheme
+++ b/App/client-ios.xcodeproj/xcshareddata/xcschemes/Release.xcscheme
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
    LastUpgradeVersion = "1200"
-   version = "1.7">
+   version = "1.8">
    <BuildAction
       parallelizeBuildables = "YES"
       buildImplicitDependencies = "YES">
diff --git a/App/client-ios/Resources/Info.plist b/App/client-ios/Resources/Info.plist
index d8cb845b40392068f453251c9c0aa72cd00979db..ee4d813d2e0ccc94a932d66a36070d80705cab5b 100644
--- a/App/client-ios/Resources/Info.plist
+++ b/App/client-ios/Resources/Info.plist
@@ -105,6 +105,6 @@
 	<key>UIViewControllerBasedStatusBarAppearance</key>
 	<true/>
 	<key>isReportingOptional</key>
-	<false/>
+	<true/>
 </dict>
 </plist>
diff --git a/Package.swift b/Package.swift
index c7012b91b7ea7166428d28193ca4e0c1d2e12ff6..8d4ef5559502d9c460fc78f7ef983fd72e941b4e 100644
--- a/Package.swift
+++ b/Package.swift
@@ -115,9 +115,9 @@ let package = Package(
             .upToNextMajor(from: "1.6.0")
         ),
         .package(
-//            path: "../elixxir-dapps-sdk-swift"
-            url: "https://git.xx.network/elixxir/elixxir-dapps-sdk-swift",
-            branch: "development"
+            path: "../elixxir-dapps-sdk-swift"
+//            url: "https://git.xx.network/elixxir/elixxir-dapps-sdk-swift",
+//            branch: "development"
         ),
         .package(
             url: "https://git.xx.network/elixxir/client-ios-db.git",
@@ -414,6 +414,7 @@ let package = Package(
                 .target(name: "DropboxFeature"),
                 .target(name: "GoogleDriveFeature"),
                 .target(name: "DependencyInjection"),
+                .product(name: "XXDatabase", package: "client-ios-db"),
                 .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"),
             ]
         ),
@@ -446,6 +447,7 @@ let package = Package(
                 .target(name: "Defaults"),
                 .target(name: "Keychain"),
                 .target(name: "Voxophone"),
+                .target(name: "Models"),
                 .target(name: "Permissions"),
                 .target(name: "Presentation"),
                 .target(name: "DrawerFeature"),
@@ -501,6 +503,7 @@ let package = Package(
                 .target(name: "Defaults"),
                 .target(name: "PushFeature"),
                 .target(name: "Permissions"),
+                .target(name: "BackupFeature"),
                 .target(name: "DropboxFeature"),
                 .target(name: "VersionChecking"),
                 .target(name: "ReportingFeature"),
diff --git a/Sources/App/AppDelegate.swift b/Sources/App/AppDelegate.swift
index 4ea40cf53608c20392ba77811f139963e8300e07..26b76e3ede2160f5bcce6ed1e2f1018adfa1d98f 100644
--- a/Sources/App/AppDelegate.swift
+++ b/Sources/App/AppDelegate.swift
@@ -17,197 +17,196 @@ import XXClient
 import XXMessengerClient
 
 public class AppDelegate: UIResponder, UIApplicationDelegate {
-    @Dependency private var pushRouter: PushRouter
-    @Dependency private var pushHandler: PushHandling
-    @Dependency private var crashReporter: CrashReporter
-    @Dependency private var dropboxService: DropboxInterface
-
-    @KeyObject(.hideAppList, defaultValue: false) var hideAppList: Bool
-    @KeyObject(.recordingLogs, defaultValue: true) var recordingLogs: Bool
-    @KeyObject(.crashReporting, defaultValue: true) var isCrashReportingEnabled: Bool
-
-    var calledStopNetwork = false
-    var forceFailedPendingMessages = false
-
-    var coverView: UIView?
-    var backgroundTimer: Timer?
-    public var window: UIWindow?
-
-    public func application(
-        _ application: UIApplication,
-        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
-    ) -> Bool {
-        #if DEBUG
-        DependencyRegistrator.registerForMock()
-        #else
-        DependencyRegistrator.registerForLive()
-        #endif
-
-        if recordingLogs {
-            XXLogger.start()
-        }
-
-        crashReporter.configure()
-        crashReporter.setEnabled(isCrashReportingEnabled)
-
-        UNUserNotificationCenter.current().delegate = self
-
-        let window = Window()
-        let navController = UINavigationController(rootViewController: LaunchController())
-        window.rootViewController = StatusBarViewController(ToastViewController(navController))
-        window.backgroundColor = UIColor.white
-        window.makeKeyAndVisible()
-        self.window = window
-
-        DependencyInjection.Container.shared.register(
-            PushRouter.live(navigationController: navController)
-        )
-
-        return true
+  @Dependency private var pushRouter: PushRouter
+  @Dependency private var pushHandler: PushHandling
+  @Dependency private var crashReporter: CrashReporter
+  @Dependency private var dropboxService: DropboxInterface
+
+  @KeyObject(.hideAppList, defaultValue: false) var hideAppList: Bool
+  @KeyObject(.recordingLogs, defaultValue: true) var recordingLogs: Bool
+  @KeyObject(.crashReporting, defaultValue: true) var isCrashReportingEnabled: Bool
+
+  var calledStopNetwork = false
+  var forceFailedPendingMessages = false
+
+  var coverView: UIView?
+  var backgroundTimer: Timer?
+  public var window: UIWindow?
+
+  public func application(
+    _ application: UIApplication,
+    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+  ) -> Bool {
+#if DEBUG
+    DependencyRegistrator.registerForMock()
+#else
+    DependencyRegistrator.registerForLive()
+#endif
+
+    if recordingLogs {
+      XXLogger.start()
     }
 
-    public func application(application: UIApplication, shouldAllowExtensionPointIdentifier: String) -> Bool {
-        false
-    }
-
-    public func applicationDidEnterBackground(_ application: UIApplication) {
-        if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
-            let database = try? DependencyInjection.Container.shared.resolve() as Database,
-            let cMix = messenger.cMix.get() {
-                let backgroundTask = application.beginBackgroundTask(withName: "xx.stop.network") {}
-
-                backgroundTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { timer in
-                    print(">>> .backgroundTimeRemaining: \(UIApplication.shared.backgroundTimeRemaining)")
-
-                    guard UIApplication.shared.backgroundTimeRemaining > 8 else {
-                        if !self.calledStopNetwork {
-                            self.calledStopNetwork = true
-                            try! cMix.stopNetworkFollower()
-                            print(">>> Called stopNetworkFollower")
-                        } else {
-                            if cMix.hasRunningProcesses() == false {
-                                application.endBackgroundTask(backgroundTask)
-                                timer.invalidate()
-                            }
-                        }
-
-                        return
-                    }
-
-                    guard UIApplication.shared.backgroundTimeRemaining > 9 else {
-                        if !self.forceFailedPendingMessages {
-                            self.forceFailedPendingMessages = true
-
-                            let query = Message.Query(status: [.sending])
-                            let assignment = Message.Assignments(status: .sendingFailed)
-                            _ = try? database.bulkUpdateMessages(query, assignment)
-                        }
-
-                        return
-                    }
-                })
+    crashReporter.configure()
+    crashReporter.setEnabled(isCrashReportingEnabled)
+
+    UNUserNotificationCenter.current().delegate = self
+
+    let window = Window()
+    let navController = UINavigationController(rootViewController: LaunchController())
+    window.rootViewController = StatusBarViewController(ToastViewController(navController))
+    window.backgroundColor = UIColor.white
+    window.makeKeyAndVisible()
+    self.window = window
+
+    DependencyInjection.Container.shared.register(
+      PushRouter.live(navigationController: navController)
+    )
+
+    return true
+  }
+
+  public func application(application: UIApplication, shouldAllowExtensionPointIdentifier: String) -> Bool {
+    false
+  }
+
+  public func applicationDidEnterBackground(_ application: UIApplication) {
+    if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
+       let database = try? DependencyInjection.Container.shared.resolve() as Database,
+       let cMix = try? messenger.cMix.tryGet() {
+      let backgroundTask = application.beginBackgroundTask(withName: "xx.stop.network") {}
+
+      backgroundTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { timer in
+        print(">>> .backgroundTimeRemaining: \(UIApplication.shared.backgroundTimeRemaining)")
+
+        guard UIApplication.shared.backgroundTimeRemaining > 8 else {
+          if !self.calledStopNetwork {
+            self.calledStopNetwork = true
+            try! messenger.stop()
+            print(">>> Called stopNetworkFollower")
+          } else {
+            if cMix.hasRunningProcesses() == false {
+              application.endBackgroundTask(backgroundTask)
+              timer.invalidate()
+            }
+          }
+
+          return
         }
-    }
 
-    public func applicationWillResignActive(_ application: UIApplication) {
-        if hideAppList {
-            coverView?.removeFromSuperview()
-            coverView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
-            coverView?.frame = window?.bounds ?? .zero
-            window?.addSubview(coverView!)
-        }
-    }
-    
-    public func applicationWillTerminate(_ application: UIApplication) {
-        if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
-            let cMix = messenger.cMix.get() {
-            try? cMix.stopNetworkFollower()
-        }
-    }
+        guard UIApplication.shared.backgroundTimeRemaining > 9 else {
+          if !self.forceFailedPendingMessages {
+            self.forceFailedPendingMessages = true
 
-    public func applicationWillEnterForeground(_ application: UIApplication) {
-        if backgroundTimer != nil {
-            backgroundTimer?.invalidate()
-            backgroundTimer = nil
-            print(">>> Invalidated background timer")
-        }
+            let query = Message.Query(status: [.sending])
+            let assignment = Message.Assignments(status: .sendingFailed)
+            _ = try? database.bulkUpdateMessages(query, assignment)
+          }
 
-        if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
-            let cMix = messenger.cMix.get() {
-            guard self.calledStopNetwork == true else { return }
-            try? cMix.startNetworkFollower(timeoutMS: 10_000)
-            print(">>> Called startNetworkFollower")
-            self.calledStopNetwork = false
+          return
         }
+      })
     }
-
-    public func applicationDidBecomeActive(_ application: UIApplication) {
-        application.applicationIconBadgeNumber = 0
-        coverView?.removeFromSuperview()
+  }
+
+  public func applicationWillResignActive(_ application: UIApplication) {
+    if hideAppList {
+      coverView?.removeFromSuperview()
+      coverView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
+      coverView?.frame = window?.bounds ?? .zero
+      window?.addSubview(coverView!)
     }
+  }
 
-    public func application(
-        _ app: UIApplication,
-        open url: URL,
-        options: [UIApplication.OpenURLOptionsKey : Any] = [:]
-    ) -> Bool {
-        dropboxService.handleOpenUrl(url)
+  public func applicationWillTerminate(_ application: UIApplication) {
+    if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger {
+      try? messenger.stop()
     }
+  }
 
-    public func application(
-        _ application: UIApplication,
-        continue userActivity: NSUserActivity,
-        restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
-    ) -> Bool {
-        guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
-              let incomingURL = userActivity.webpageURL,
-              let username = getUsernameFromInvitationDeepLink(incomingURL),
-              let router = try? DependencyInjection.Container.shared.resolve() as PushRouter else {
-            return false
-        }
+  public func applicationWillEnterForeground(_ application: UIApplication) {
+    if backgroundTimer != nil {
+      backgroundTimer?.invalidate()
+      backgroundTimer = nil
+      print(">>> Invalidated background timer")
+    }
 
-        router.navigateTo(.search(username: username), {})
-        return true
+    if let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger,
+       let cMix = messenger.cMix.get() {
+      guard self.calledStopNetwork == true else { return }
+      try? cMix.startNetworkFollower(timeoutMS: 10_000)
+      print(">>> Called startNetworkFollower")
+      self.calledStopNetwork = false
     }
+  }
+
+  public func applicationDidBecomeActive(_ application: UIApplication) {
+    application.applicationIconBadgeNumber = 0
+    coverView?.removeFromSuperview()
+  }
+
+  public func application(
+    _ app: UIApplication,
+    open url: URL,
+    options: [UIApplication.OpenURLOptionsKey : Any] = [:]
+  ) -> Bool {
+    dropboxService.handleOpenUrl(url)
+  }
+
+  public func application(
+    _ application: UIApplication,
+    continue userActivity: NSUserActivity,
+    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
+  ) -> Bool {
+    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
+          let incomingURL = userActivity.webpageURL,
+          let username = getUsernameFromInvitationDeepLink(incomingURL),
+          let router = try? DependencyInjection.Container.shared.resolve() as PushRouter else {
+      return false
+    }
+
+    router.navigateTo(.search(username: username), {})
+    return true
+  }
 }
 
 func getUsernameFromInvitationDeepLink(_ url: URL) -> String? {
-    if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
-       components.scheme == "https",
-       components.host == "elixxir.io",
-       components.path == "/connect",
-       let queryItem = components.queryItems?.first(where: { $0.name == "username" }),
-       let username = queryItem.value {
-        return username
-    }
-
-    return nil
+  if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
+     components.scheme == "https",
+     components.host == "elixxir.io",
+     components.path == "/connect",
+     let queryItem = components.queryItems?.first(where: { $0.name == "username" }),
+     let username = queryItem.value {
+    return username
+  }
+
+  return nil
 }
 
 // MARK: Notifications
 
 extension AppDelegate: UNUserNotificationCenterDelegate {
-    public func userNotificationCenter(
-        _ center: UNUserNotificationCenter,
-        didReceive response: UNNotificationResponse,
-        withCompletionHandler completionHandler: @escaping () -> Void
-    ) {
-        let userInfo = response.notification.request.content.userInfo
-        pushHandler.handleAction(pushRouter, userInfo, completionHandler)
-    }
-
-    public func application(
-        _ application: UIApplication,
-        didReceiveRemoteNotification notification: [AnyHashable: Any],
-        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
-    ) {
-        pushHandler.handlePush(notification, completionHandler)
-    }
-
-    public func application(
-        _: UIApplication,
-        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
-    ) {
-        pushHandler.registerToken(deviceToken)
-    }
+  public func userNotificationCenter(
+    _ center: UNUserNotificationCenter,
+    didReceive response: UNNotificationResponse,
+    withCompletionHandler completionHandler: @escaping () -> Void
+  ) {
+    let userInfo = response.notification.request.content.userInfo
+    pushHandler.handleAction(pushRouter, userInfo, completionHandler)
+  }
+
+  public func application(
+    _ application: UIApplication,
+    didReceiveRemoteNotification notification: [AnyHashable: Any],
+    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
+  ) {
+    pushHandler.handlePush(notification, completionHandler)
+  }
+
+  public func application(
+    _: UIApplication,
+    didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
+  ) {
+    pushHandler.registerToken(deviceToken)
+  }
 }
diff --git a/Sources/App/DependencyRegistrator.swift b/Sources/App/DependencyRegistrator.swift
index f1d31d5d61f2b5569afde8542631ed9128d252f0..4f2c9a0b5fdb0c0a588920024053a113b5001f3e 100644
--- a/Sources/App/DependencyRegistrator.swift
+++ b/Sources/App/DependencyRegistrator.swift
@@ -192,7 +192,7 @@ struct DependencyRegistrator {
                 successFactory: RestoreSuccessController.init,
                 chatListFactory: ChatListController.init,
                 restoreFactory: RestoreController.init(_:),
-                passphraseFactory: RestorePassphraseController.init(_:)
+                passphraseFactory: RestorePassphraseController.init(_:_:)
             ) as RestoreCoordinating)
 
         container.register(
diff --git a/Sources/BackupFeature/Controllers/BackupPassphraseController.swift b/Sources/BackupFeature/Controllers/BackupPassphraseController.swift
index 97c23d21b497a643a7850f3b9147723053dd1e9e..5021b438717d18a72e144d2a13e8372bd21073a8 100644
--- a/Sources/BackupFeature/Controllers/BackupPassphraseController.swift
+++ b/Sources/BackupFeature/Controllers/BackupPassphraseController.swift
@@ -4,70 +4,70 @@ import Combine
 import InputField
 
 public final class BackupPassphraseController: UIViewController {
-    lazy private var screenView = BackupPassphraseView()
+  lazy private var screenView = BackupPassphraseView()
 
-    private var passphrase = "" {
-        didSet {
-            switch Validator.backupPassphrase.validate(passphrase) {
-            case .success:
-                screenView.continueButton.isEnabled = true
-            case .failure:
-                screenView.continueButton.isEnabled = false
-            }
-        }
+  private var passphrase = "" {
+    didSet {
+      switch Validator.backupPassphrase.validate(passphrase) {
+      case .success:
+        screenView.continueButton.isEnabled = true
+      case .failure:
+        screenView.continueButton.isEnabled = false
+      }
     }
+  }
 
-    private let cancelClosure: EmptyClosure
-    private let stringClosure: StringClosure
-    private var cancellables = Set<AnyCancellable>()
+  private let cancelClosure: EmptyClosure
+  private let stringClosure: StringClosure
+  private var cancellables = Set<AnyCancellable>()
 
-    public init(
-        _ cancelClosure: @escaping EmptyClosure,
-        _ stringClosure: @escaping StringClosure
-    ) {
-        self.stringClosure = stringClosure
-        self.cancelClosure = cancelClosure
-        super.init(nibName: nil, bundle: nil)
-    }
+  public init(
+    _ cancelClosure: @escaping EmptyClosure,
+    _ stringClosure: @escaping StringClosure
+  ) {
+    self.stringClosure = stringClosure
+    self.cancelClosure = cancelClosure
+    super.init(nibName: nil, bundle: nil)
+  }
 
-    required init?(coder: NSCoder) { nil }
+  required init?(coder: NSCoder) { nil }
 
-    public override func loadView() {
-        view = screenView
-    }
+  public override func loadView() {
+    view = screenView
+  }
 
-    public override func viewDidLoad() {
-        super.viewDidLoad()
-        setupBindings()
-    }
+  public override func viewDidLoad() {
+    super.viewDidLoad()
+    setupBindings()
+  }
 
-    private func setupBindings() {
-        screenView
-            .inputField
-            .returnPublisher
-            .sink { [unowned self] in
-                screenView.inputField.endEditing(true)
-            }.store(in: &cancellables)
+  private func setupBindings() {
+    screenView
+      .inputField
+      .returnPublisher
+      .sink { [unowned self] in
+        screenView.inputField.endEditing(true)
+      }.store(in: &cancellables)
 
-        screenView
-            .inputField
-            .textPublisher
-            .sink { [unowned self] in
-                passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines)
-            }.store(in: &cancellables)
+    screenView
+      .inputField
+      .textPublisher
+      .sink { [unowned self] in
+        passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines)
+      }.store(in: &cancellables)
 
-        screenView
-            .continueButton
-            .publisher(for: .touchUpInside)
-            .sink { [unowned self] in
-                dismiss(animated: true) { self.stringClosure(self.passphrase) }
-            }.store(in: &cancellables)
+    screenView
+      .continueButton
+      .publisher(for: .touchUpInside)
+      .sink { [unowned self] in
+        dismiss(animated: true) { self.stringClosure(self.passphrase) }
+      }.store(in: &cancellables)
 
-        screenView
-            .cancelButton
-            .publisher(for: .touchUpInside)
-            .sink { [unowned self] in
-                dismiss(animated: true) { self.cancelClosure() }
-            }.store(in: &cancellables)
-    }
+    screenView
+      .cancelButton
+      .publisher(for: .touchUpInside)
+      .sink { [unowned self] in
+        dismiss(animated: true) { self.cancelClosure() }
+      }.store(in: &cancellables)
+  }
 }
diff --git a/Sources/BackupFeature/Service/BackupService.swift b/Sources/BackupFeature/Service/BackupService.swift
index 788fd7d454ff95f4614ce7e49d4a381af4761596..1d4857924384d0cc263f947f46a87fc0bd8bc86f 100644
--- a/Sources/BackupFeature/Service/BackupService.swift
+++ b/Sources/BackupFeature/Service/BackupService.swift
@@ -13,368 +13,355 @@ import XXClient
 import XXMessengerClient
 
 public final class BackupService {
-    @Dependency var messenger: Messenger
-    @Dependency var sftpService: SFTPService
-    @Dependency var icloudService: iCloudInterface
-    @Dependency var dropboxService: DropboxInterface
-    @Dependency var networkManager: NetworkMonitoring
-    @Dependency var keychainHandler: KeychainHandling
-    @Dependency var driveService: GoogleDriveInterface
-
-    @KeyObject(.email, defaultValue: nil) var email: String?
-    @KeyObject(.phone, defaultValue: nil) var phone: String?
-    @KeyObject(.username, defaultValue: nil) var username: String?
-
-    var manager: XXClient.Backup?
-
-    @KeyObject(.backupSettings, defaultValue: Data()) private var storedSettings: Data
-
-    public var settingsPublisher: AnyPublisher<BackupSettings, Never> {
-        settings.handleEvents(receiveSubscription: { [weak self] _ in
-            guard let self = self else { return }
-
-            let lastRefreshDate = self.settingsLastRefreshedDate ?? Date.distantPast
-
-            if Date().timeIntervalSince(lastRefreshDate) < 10 { return }
-
-            self.settingsLastRefreshedDate = Date()
-            self.refreshConnections()
-            self.refreshBackups()
-        }).eraseToAnyPublisher()
-    }
-
-    private var connType: ConnectionType = .wifi
-    private var settingsLastRefreshedDate: Date?
-    private var cancellables = Set<AnyCancellable>()
-    private lazy var settings = CurrentValueSubject<BackupSettings, Never>(.init(fromData: storedSettings))
-
-    public init() {
-        settings
-            .dropFirst()
-            .removeDuplicates()
-            .sink { [unowned self] in storedSettings = $0.toData() }
-            .store(in: &cancellables)
-
-        networkManager.connType
-            .receive(on: DispatchQueue.main)
-            .sink { [unowned self] in connType = $0 }
-            .store(in: &cancellables)
-    }
+  @Dependency var messenger: Messenger
+  @Dependency var sftpService: SFTPService
+  @Dependency var icloudService: iCloudInterface
+  @Dependency var dropboxService: DropboxInterface
+  @Dependency var networkManager: NetworkMonitoring
+  @Dependency var keychainHandler: KeychainHandling
+  @Dependency var driveService: GoogleDriveInterface
+
+  @KeyObject(.username, defaultValue: nil) var username: String?
+  @KeyObject(.backupSettings, defaultValue: Data()) private var storedSettings: Data
+
+  public var settingsPublisher: AnyPublisher<BackupSettings, Never> {
+    settings.handleEvents(receiveSubscription: { [weak self] _ in
+      guard let self = self else { return }
+
+      let lastRefreshDate = self.settingsLastRefreshedDate ?? Date.distantPast
+
+      if Date().timeIntervalSince(lastRefreshDate) < 10 { return }
+
+      self.settingsLastRefreshedDate = Date()
+      self.refreshConnections()
+      self.refreshBackups()
+    }).eraseToAnyPublisher()
+  }
+
+  private var connType: ConnectionType = .wifi
+  private var settingsLastRefreshedDate: Date?
+  private var cancellables = Set<AnyCancellable>()
+  private lazy var settings = CurrentValueSubject<BackupSettings, Never>(.init(fromData: storedSettings))
+
+  public init() {
+    settings
+      .dropFirst()
+      .removeDuplicates()
+      .sink { [unowned self] in storedSettings = $0.toData() }
+      .store(in: &cancellables)
+
+    networkManager.connType
+      .receive(on: DispatchQueue.main)
+      .sink { [unowned self] in connType = $0 }
+      .store(in: &cancellables)
+  }
 }
 
 extension BackupService {
-    public func initializeBackup(passphrase: String) {
-        manager = try! InitializeBackup.live(
-            e2eId: messenger.e2e.get()!.getId(),
-            udId: messenger.ud.get()!.getId(),
-            password: passphrase,
-            callback: .init(handle: { [weak self] backupData in
-                self?.updateBackup(data: backupData)
-            })
-        )
+  public func stopBackups() {
+    print(">>> [AccountBackup] Requested to stop backup mechanism")
 
-        didUpdateFacts()
+    if messenger.isBackupRunning() == true {
+      print(">>> [AccountBackup] messenger.isBackupRunning() == true")
+      try! messenger.stopBackup()
+
+      print(">>> [AccountBackup] Stopped backup mechanism")
     }
+  }
 
-    public func didUpdateFacts() {
-        if let manager = manager {
-            let currentFacts = try! JSONEncoder().encode(
-                BackupParams(
-                    username: username!,
-                    email: email,
-                    phone: phone
-                )
-            )
-
-          print(">>> Will addJSON: \(String(data: currentFacts, encoding: .utf8)!)")
-            manager.addJSON(String(data: currentFacts, encoding: .utf8)!)
-        }
+  public func initializeBackup(passphrase: String) {
+    try! messenger.startBackup(
+      password: passphrase,
+      params: .init(username: username!)
+    )
 
-        performBackup()
-    }
+    print(">>> [AccountBackup] Initialized backup mechanism")
+  }
 
-    public func performBackupIfAutomaticIsEnabled() {
-        guard settings.value.automaticBackups == true else { return }
-        performBackup()
-    }
+  public func performBackupIfAutomaticIsEnabled() {
+    print(">>> [AccountBackup] Requested backup if automatic is enabled")
 
-    public func performBackup() {
-      print(">>> Did call performBackup()")
+    guard settings.value.automaticBackups == true else { return }
+    performBackup()
+  }
 
-        guard let directoryUrl = try? FileManager.default.url(
-            for: .applicationSupportDirectory,
-            in: .userDomainMask,
-            appropriateFor: nil,
-            create: true
-        ) else { fatalError("Couldn't generate the URL to persist the backup") }
+  public func performBackup() {
+    print(">>> [AccountBackup] Requested backup without explicitly passing data")
 
-        let fileUrl = directoryUrl
-            .appendingPathComponent("backup")
-            .appendingPathExtension("xxm")
+    guard let directoryUrl = try? FileManager.default.url(
+      for: .applicationSupportDirectory,
+      in: .userDomainMask,
+      appropriateFor: nil,
+      create: true
+    ) else { fatalError("Couldn't generate the URL to persist the backup") }
 
-        guard let data = try? Data(contentsOf: fileUrl) else {
-            print(">>> Tried to backup arbitrarily but there was nothing to be backed up. Aborting...")
-            return
-        }
+    let fileUrl = directoryUrl
+      .appendingPathComponent("backup")
+      .appendingPathExtension("xxm")
 
-        performBackup(data: data)
+    guard let data = try? Data(contentsOf: fileUrl) else {
+      print(">>> [AccountBackup] Tried to backup arbitrarily but there was nothing to be backed up. Aborting...")
+      return
     }
 
-    public func updateBackup(data: Data) {
-      print(">>> Did call updateBackup(data)")
+    performBackup(data: data)
+  }
 
-        guard let directoryUrl = try? FileManager.default.url(
-            for: .applicationSupportDirectory,
-            in: .userDomainMask,
-            appropriateFor: nil,
-            create: true
-        ) else { fatalError("Couldn't generate the URL to persist the backup") }
+  public func updateBackup(data: Data) {
+    print(">>> [AccountBackup] Requested to update backup passing data")
 
-        let fileUrl = directoryUrl
-            .appendingPathComponent("backup")
-            .appendingPathExtension("xxm")
+    guard let directoryUrl = try? FileManager.default.url(
+      for: .applicationSupportDirectory,
+      in: .userDomainMask,
+      appropriateFor: nil,
+      create: true
+    ) else { fatalError("Couldn't generate the URL to persist the backup") }
 
-        do {
-            try data.write(to: fileUrl)
-        } catch {
-            fatalError("Couldn't write backup to fileurl")
-        }
+    let fileUrl = directoryUrl
+      .appendingPathComponent("backup")
+      .appendingPathExtension("xxm")
 
-        let isWifiOnly = settings.value.wifiOnlyBackup
-        let isAutomaticEnabled = settings.value.automaticBackups
-        let hasEnabledService = settings.value.enabledService != nil
+    do {
+      try data.write(to: fileUrl)
+    } catch {
+      fatalError("Couldn't write backup to fileurl")
+    }
 
-        if isWifiOnly {
-            guard connType == .wifi else { return }
-        } else {
-            guard connType != .unknown else { return }
-        }
+    let isWifiOnly = settings.value.wifiOnlyBackup
+    let isAutomaticEnabled = settings.value.automaticBackups
+    let hasEnabledService = settings.value.enabledService != nil
 
-        if isAutomaticEnabled && hasEnabledService {
-            performBackup()
-        }
+    if isWifiOnly {
+      guard connType == .wifi else { return }
+    } else {
+      guard connType != .unknown else { return }
     }
 
-    public func setBackupOnlyOnWifi(_ enabled: Bool) {
-        settings.value.wifiOnlyBackup = enabled
+    if isAutomaticEnabled && hasEnabledService {
+      performBackup()
+    }
+  }
+
+  public func setBackupOnlyOnWifi(_ enabled: Bool) {
+    settings.value.wifiOnlyBackup = enabled
+  }
+
+  public func setBackupAutomatically(_ enabled: Bool) {
+    settings.value.automaticBackups = enabled
+
+    guard enabled else { return }
+    performBackup()
+  }
+
+  public func toggle(service: CloudService, enabling: Bool) {
+    settings.value.enabledService = enabling ? service : nil
+  }
+
+  public func authorize(service: CloudService, presenting screen: UIViewController) {
+    switch service {
+    case .drive:
+      driveService.authorize(presenting: screen) { [weak self] _ in
+        guard let self = self else { return }
+        self.refreshConnections()
+        self.refreshBackups()
+      }
+    case .icloud:
+      if !icloudService.isAuthorized() {
+        icloudService.openSettings()
+      } else {
+        refreshConnections()
+        refreshBackups()
+      }
+    case .dropbox:
+      if !dropboxService.isAuthorized() {
+        dropboxService.authorize(presenting: screen)
+          .sink { [weak self] _ in
+            guard let self = self else { return }
+            self.refreshConnections()
+            self.refreshBackups()
+          }.store(in: &cancellables)
+      }
+    case .sftp:
+      if !sftpService.isAuthorized() {
+        sftpService.authorizeFlow((screen, { [weak self] in
+          guard let self = self else { return }
+          screen.navigationController?.popViewController(animated: true)
+          self.refreshConnections()
+          self.refreshBackups()
+        }))
+      }
     }
+  }
+}
 
-    public func setBackupAutomatically(_ enabled: Bool) {
-        settings.value.automaticBackups = enabled
+extension BackupService {
+  private func refreshConnections() {
+    if icloudService.isAuthorized() && !settings.value.connectedServices.contains(.icloud) {
+      settings.value.connectedServices.insert(.icloud)
+    } else if !icloudService.isAuthorized() && settings.value.connectedServices.contains(.icloud) {
+      settings.value.connectedServices.remove(.icloud)
+    }
 
-        guard enabled else { return }
-        performBackup()
+    if dropboxService.isAuthorized() && !settings.value.connectedServices.contains(.dropbox) {
+      settings.value.connectedServices.insert(.dropbox)
+    } else if !dropboxService.isAuthorized() && settings.value.connectedServices.contains(.dropbox) {
+      settings.value.connectedServices.remove(.dropbox)
     }
 
-    public func toggle(service: CloudService, enabling: Bool) {
-        settings.value.enabledService = enabling ? service : nil
+    if sftpService.isAuthorized() && !settings.value.connectedServices.contains(.sftp) {
+      settings.value.connectedServices.insert(.sftp)
+    } else if !sftpService.isAuthorized() && settings.value.connectedServices.contains(.sftp) {
+      settings.value.connectedServices.remove(.sftp)
     }
 
-    public func authorize(service: CloudService, presenting screen: UIViewController) {
-        switch service {
-        case .drive:
-            driveService.authorize(presenting: screen) { [weak self] _ in
-                guard let self = self else { return }
-                self.refreshConnections()
-                self.refreshBackups()
-            }
-        case .icloud:
-            if !icloudService.isAuthorized() {
-                icloudService.openSettings()
-            } else {
-                refreshConnections()
-                refreshBackups()
-            }
-        case .dropbox:
-            if !dropboxService.isAuthorized() {
-                dropboxService.authorize(presenting: screen)
-                    .sink { [weak self] _ in
-                        guard let self = self else { return }
-                        self.refreshConnections()
-                        self.refreshBackups()
-                    }.store(in: &cancellables)
-            }
-        case .sftp:
-            if !sftpService.isAuthorized() {
-                sftpService.authorizeFlow((screen, { [weak self] in
-                    guard let self = self else { return }
-                    screen.navigationController?.popViewController(animated: true)
-                    self.refreshConnections()
-                    self.refreshBackups()
-                }))
-            }
-        }
+    driveService.isAuthorized { [weak settings] isAuthorized in
+      guard let settings = settings else { return }
+
+      if isAuthorized && !settings.value.connectedServices.contains(.drive) {
+        settings.value.connectedServices.insert(.drive)
+      } else if !isAuthorized && settings.value.connectedServices.contains(.drive) {
+        settings.value.connectedServices.remove(.drive)
+      }
     }
-}
+  }
 
-extension BackupService {
-    private func refreshConnections() {
-        if icloudService.isAuthorized() && !settings.value.connectedServices.contains(.icloud) {
-            settings.value.connectedServices.insert(.icloud)
-        } else if !icloudService.isAuthorized() && settings.value.connectedServices.contains(.icloud) {
-            settings.value.connectedServices.remove(.icloud)
-        }
+  private func refreshBackups() {
+    if icloudService.isAuthorized() {
+      icloudService.downloadMetadata { [weak settings] in
+        guard let settings = settings else { return }
 
-        if dropboxService.isAuthorized() && !settings.value.connectedServices.contains(.dropbox) {
-            settings.value.connectedServices.insert(.dropbox)
-        } else if !dropboxService.isAuthorized() && settings.value.connectedServices.contains(.dropbox) {
-            settings.value.connectedServices.remove(.dropbox)
+        guard let metadata = try? $0.get() else {
+          settings.value.backups[.icloud] = nil
+          return
         }
 
-        if sftpService.isAuthorized() && !settings.value.connectedServices.contains(.sftp) {
-            settings.value.connectedServices.insert(.sftp)
-        } else if !sftpService.isAuthorized() && settings.value.connectedServices.contains(.sftp) {
-            settings.value.connectedServices.remove(.sftp)
-        }
+        settings.value.backups[.icloud] = BackupModel(
+          id: metadata.path,
+          date: metadata.modifiedDate,
+          size: metadata.size
+        )
+      }
+    }
 
-        driveService.isAuthorized { [weak settings] isAuthorized in
-            guard let settings = settings else { return }
+    if sftpService.isAuthorized() {
+      sftpService.fetchMetadata { [weak settings] in
+        guard let settings = settings else { return }
 
-            if isAuthorized && !settings.value.connectedServices.contains(.drive) {
-                settings.value.connectedServices.insert(.drive)
-            } else if !isAuthorized && settings.value.connectedServices.contains(.drive) {
-                settings.value.connectedServices.remove(.drive)
-            }
+        guard let metadata = try? $0.get()?.backup else {
+          settings.value.backups[.sftp] = nil
+          return
         }
+
+        settings.value.backups[.sftp] = BackupModel(
+          id: metadata.id,
+          date: metadata.date,
+          size: metadata.size
+        )
+      }
     }
 
-    private func refreshBackups() {
-        if icloudService.isAuthorized() {
-            icloudService.downloadMetadata { [weak settings] in
-                guard let settings = settings else { return }
-
-                guard let metadata = try? $0.get() else {
-                    settings.value.backups[.icloud] = nil
-                    return
-                }
-
-                settings.value.backups[.icloud] = BackupModel(
-                    id: metadata.path,
-                    date: metadata.modifiedDate,
-                    size: metadata.size
-                )
-            }
-        }
+    if dropboxService.isAuthorized() {
+      dropboxService.downloadMetadata { [weak settings] in
+        guard let settings = settings else { return }
 
-        if sftpService.isAuthorized() {
-            sftpService.fetchMetadata { [weak settings] in
-                guard let settings = settings else { return }
-
-                guard let metadata = try? $0.get()?.backup else {
-                    settings.value.backups[.sftp] = nil
-                    return
-                }
-
-                settings.value.backups[.sftp] = BackupModel(
-                    id: metadata.id,
-                    date: metadata.date,
-                    size: metadata.size
-                )
-            }
+        guard let metadata = try? $0.get() else {
+          settings.value.backups[.dropbox] = nil
+          return
         }
 
-        if dropboxService.isAuthorized() {
-            dropboxService.downloadMetadata { [weak settings] in
-                guard let settings = settings else { return }
-
-                guard let metadata = try? $0.get() else {
-                    settings.value.backups[.dropbox] = nil
-                    return
-                }
-
-                settings.value.backups[.dropbox] = BackupModel(
-                    id: metadata.path,
-                    date: metadata.modifiedDate,
-                    size: metadata.size
-                )
-            }
-        }
+        settings.value.backups[.dropbox] = BackupModel(
+          id: metadata.path,
+          date: metadata.modifiedDate,
+          size: metadata.size
+        )
+      }
+    }
 
-        driveService.isAuthorized { [weak settings] isAuthorized  in
-            guard let settings = settings else { return }
-
-            if isAuthorized {
-                self.driveService.downloadMetadata {
-                    guard let metadata = try? $0.get() else { return }
-
-                    settings.value.backups[.drive] = BackupModel(
-                        id: metadata.identifier,
-                        date: metadata.modifiedDate,
-                        size: metadata.size
-                    )
-                }
-            } else {
-                settings.value.backups[.drive] = nil
-            }
+    driveService.isAuthorized { [weak settings] isAuthorized  in
+      guard let settings = settings else { return }
+
+      if isAuthorized {
+        self.driveService.downloadMetadata {
+          guard let metadata = try? $0.get() else { return }
+
+          settings.value.backups[.drive] = BackupModel(
+            id: metadata.identifier,
+            date: metadata.modifiedDate,
+            size: metadata.size
+          )
         }
+      } else {
+        settings.value.backups[.drive] = nil
+      }
     }
+  }
 
-    private func performBackup(data: Data) {
-      print(">>> Did call performBackup(data)")
+  private func performBackup(data: Data) {
+    print(">>> Did call performBackup(data)")
 
-        guard let enabledService = settings.value.enabledService else {
-            fatalError("Trying to backup but nothing is enabled")
-        }
+    guard let enabledService = settings.value.enabledService else {
+      fatalError("Trying to backup but nothing is enabled")
+    }
 
-        let url = URL(fileURLWithPath: NSTemporaryDirectory())
-            .appendingPathComponent(UUID().uuidString)
+    let url = URL(fileURLWithPath: NSTemporaryDirectory())
+      .appendingPathComponent(UUID().uuidString)
 
-        do {
-            try data.write(to: url, options: .atomic)
-        } catch {
-            print(">>> Couldn't write to temp: \(error.localizedDescription)")
-            return
-        }
+    do {
+      try data.write(to: url, options: .atomic)
+    } catch {
+      print(">>> Couldn't write to temp: \(error.localizedDescription)")
+      return
+    }
 
-        switch enabledService {
-        case .drive:
-            driveService.uploadBackup(url) {
-                switch $0 {
-                case .success(let metadata):
-                    self.settings.value.backups[.drive] = .init(
-                        id: metadata.identifier,
-                        date: metadata.modifiedDate,
-                        size: metadata.size
-                    )
-                case .failure(let error):
-                    print(error.localizedDescription)
-                }
-            }
-        case .icloud:
-            icloudService.uploadBackup(url) {
-                switch $0 {
-                case .success(let metadata):
-                    self.settings.value.backups[.icloud] = .init(
-                        id: metadata.path,
-                        date: metadata.modifiedDate,
-                        size: metadata.size
-                    )
-                case .failure(let error):
-                    print(error.localizedDescription)
-                }
-            }
-        case .dropbox:
-            dropboxService.uploadBackup(url) {
-                switch $0 {
-                case .success(let metadata):
-                    self.settings.value.backups[.dropbox] = .init(
-                        id: metadata.path,
-                        date: metadata.modifiedDate,
-                        size: metadata.size
-                    )
-                case .failure(let error):
-                    print(error.localizedDescription)
-                }
-            }
-        case .sftp:
-            sftpService.uploadBackup(url: url) {
-                switch $0 {
-                case .success(let backup):
-                    self.settings.value.backups[.sftp] = backup
-                case .failure(let error):
-                    print(error.localizedDescription)
-                }
-            }
+    switch enabledService {
+    case .drive:
+      driveService.uploadBackup(url) {
+        switch $0 {
+        case .success(let metadata):
+          self.settings.value.backups[.drive] = .init(
+            id: metadata.identifier,
+            date: metadata.modifiedDate,
+            size: metadata.size
+          )
+        case .failure(let error):
+          print(error.localizedDescription)
+        }
+      }
+    case .icloud:
+      icloudService.uploadBackup(url) {
+        switch $0 {
+        case .success(let metadata):
+          self.settings.value.backups[.icloud] = .init(
+            id: metadata.path,
+            date: metadata.modifiedDate,
+            size: metadata.size
+          )
+        case .failure(let error):
+          print(error.localizedDescription)
+        }
+      }
+    case .dropbox:
+      dropboxService.uploadBackup(url) {
+        switch $0 {
+        case .success(let metadata):
+          self.settings.value.backups[.dropbox] = .init(
+            id: metadata.path,
+            date: metadata.modifiedDate,
+            size: metadata.size
+          )
+        case .failure(let error):
+          print(error.localizedDescription)
+        }
+      }
+    case .sftp:
+      sftpService.uploadBackup(url: url) {
+        switch $0 {
+        case .success(let backup):
+          self.settings.value.backups[.sftp] = backup
+        case .failure(let error):
+          print(error.localizedDescription)
         }
+      }
     }
+  }
 }
diff --git a/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift b/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift
index 4b398f9028bf284019a1155ef4e1f0011dab165a..74ce209fbf6b2d71a81bb3e93a88fa9838150ea3 100644
--- a/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift
+++ b/Sources/BackupFeature/ViewModels/BackupConfigViewModel.swift
@@ -10,104 +10,97 @@ import Foundation
 import DependencyInjection
 
 enum BackupActionState {
-    case backupFinished
-    case backupAllowed(Bool)
-    case backupInProgress(Float, Float)
+  case backupFinished
+  case backupAllowed(Bool)
+  case backupInProgress(Float, Float)
 }
 
 struct BackupConfigViewModel {
-    var didTapBackupNow: () -> Void
-    var didChooseWifiOnly: (Bool) -> Void
-    var didChooseAutomatic: (Bool) -> Void
-    var didToggleService: (UIViewController, CloudService, Bool) -> Void
-    var didTapService: (CloudService, UIViewController) -> Void
+  var didTapBackupNow: () -> Void
+  var didChooseWifiOnly: (Bool) -> Void
+  var didChooseAutomatic: (Bool) -> Void
+  var didToggleService: (UIViewController, CloudService, Bool) -> Void
+  var didTapService: (CloudService, UIViewController) -> Void
 
-    var wifiOnly: () -> AnyPublisher<Bool, Never>
-    var automatic: () -> AnyPublisher<Bool, Never>
-    var lastBackup: () -> AnyPublisher<BackupModel?, Never>
-    var actionState: () -> AnyPublisher<BackupActionState, Never>
-    var enabledService: () -> AnyPublisher<CloudService?, Never>
-    var connectedServices: () -> AnyPublisher<Set<CloudService>, Never>
+  var wifiOnly: () -> AnyPublisher<Bool, Never>
+  var automatic: () -> AnyPublisher<Bool, Never>
+  var lastBackup: () -> AnyPublisher<BackupModel?, Never>
+  var actionState: () -> AnyPublisher<BackupActionState, Never>
+  var enabledService: () -> AnyPublisher<CloudService?, Never>
+  var connectedServices: () -> AnyPublisher<Set<CloudService>, Never>
 }
 
 extension BackupConfigViewModel {
-    static func live() -> Self {
-        class Context {
-            @Dependency var hud: HUD
-            @Dependency var service: BackupService
-            @Dependency var coordinator: BackupCoordinating
-        }
-
-        let context = Context()
-
-        return .init(
-            didTapBackupNow: {
-                context.service.performBackup()
-                context.hud.update(with: .on)
-                DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
-                    context.hud.update(with: .none)
-                }
-            },
-            didChooseWifiOnly: context.service.setBackupOnlyOnWifi(_:),
-            didChooseAutomatic: context.service.setBackupAutomatically(_:),
-            didToggleService: { controller, service, enabling in
-                guard enabling == true else {
-                    context.service.toggle(service: service, enabling: false)
-                    if let manager = context.service.manager {
-                        if manager.isRunning() {
-                            try! manager.stop()
-                        }
+  static func live() -> Self {
+    class Context {
+      @Dependency var hud: HUD
+      @Dependency var service: BackupService
+      @Dependency var coordinator: BackupCoordinating
+    }
 
-                        context.service.manager = nil
-                    }
+    let context = Context()
 
-                    return
-                }
+    return .init(
+      didTapBackupNow: {
+        context.service.performBackup()
+        context.hud.update(with: .on)
+        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
+          context.hud.update(with: .none)
+        }
+      },
+      didChooseWifiOnly: context.service.setBackupOnlyOnWifi(_:),
+      didChooseAutomatic: context.service.setBackupAutomatically(_:),
+      didToggleService: { controller, service, enabling in
+        guard enabling == true else {
+          context.service.toggle(service: service, enabling: false)
+          context.service.stopBackups()
+          return
+        }
 
-                context.coordinator.toPassphrase(from: controller, cancelClosure: {
-                    context.service.toggle(service: service, enabling: false)
-                }, passphraseClosure: { passphrase in
-                    context.hud.update(with: .onTitle("Initializing and securing your backup file will take few seconds, please keep the app open."))
-                  context.service.toggle(service: service, enabling: enabling)
-                  context.service.initializeBackup(passphrase: passphrase)
-                  context.hud.update(with: .none)
-                })
-            },
-            didTapService: context.service.authorize,
-            wifiOnly: {
-                context.service.settingsPublisher
-                    .map(\.wifiOnlyBackup)
-                    .eraseToAnyPublisher()
-            },
-            automatic: {
-                context.service.settingsPublisher
-                    .map(\.automaticBackups)
-                    .eraseToAnyPublisher()
-            },
-            lastBackup: {
-                context.service.settingsPublisher
-                    .map {
-                        guard let enabledService = $0.enabledService else { return nil }
-                        return $0.backups[enabledService]
-                    }.eraseToAnyPublisher()
-            },
-            actionState: {
-                context.service.settingsPublisher
-                    .map(\.enabledService)
-                    .map { BackupActionState.backupAllowed($0 != nil) }
-                    .eraseToAnyPublisher()
-            },
-            enabledService: {
-                context.service.settingsPublisher
-                    .map(\.enabledService)
-                    .eraseToAnyPublisher()
-            },
-            connectedServices: {
-                context.service.settingsPublisher
-                    .map(\.connectedServices)
-                    .removeDuplicates()
-                    .eraseToAnyPublisher()
-            }
-        )
-    }
+        context.coordinator.toPassphrase(from: controller, cancelClosure: {
+          context.service.toggle(service: service, enabling: false)
+        }, passphraseClosure: { passphrase in
+          context.hud.update(with: .onTitle("Initializing and securing your backup file will take few seconds, please keep the app open."))
+          context.service.toggle(service: service, enabling: enabling)
+          context.service.initializeBackup(passphrase: passphrase)
+          context.hud.update(with: .none)
+        })
+      },
+      didTapService: context.service.authorize,
+      wifiOnly: {
+        context.service.settingsPublisher
+          .map(\.wifiOnlyBackup)
+          .eraseToAnyPublisher()
+      },
+      automatic: {
+        context.service.settingsPublisher
+          .map(\.automaticBackups)
+          .eraseToAnyPublisher()
+      },
+      lastBackup: {
+        context.service.settingsPublisher
+          .map {
+            guard let enabledService = $0.enabledService else { return nil }
+            return $0.backups[enabledService]
+          }.eraseToAnyPublisher()
+      },
+      actionState: {
+        context.service.settingsPublisher
+          .map(\.enabledService)
+          .map { BackupActionState.backupAllowed($0 != nil) }
+          .eraseToAnyPublisher()
+      },
+      enabledService: {
+        context.service.settingsPublisher
+          .map(\.enabledService)
+          .eraseToAnyPublisher()
+      },
+      connectedServices: {
+        context.service.settingsPublisher
+          .map(\.connectedServices)
+          .removeDuplicates()
+          .eraseToAnyPublisher()
+      }
+    )
+  }
 }
diff --git a/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift b/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift
index 1329609d408d1fb1f262aa4cc4883b7cf1d5b9bd..7e5bc8ea026b1f68378a3935594616a9a16ebee8 100644
--- a/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift
+++ b/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift
@@ -60,7 +60,7 @@ final class GroupChatViewModel {
 
     var messages: AnyPublisher<[ArraySection<ChatSection, Message>], Never> {
         database.fetchMessagesPublisher(.init(chat: .group(info.group.id)))
-            .assertNoFailure()
+        .replaceError(with: [])
             .map { messages -> [ArraySection<ChatSection, Message>] in
                 let groupedByDate = Dictionary(grouping: messages) { domainModel -> Date in
                     let components = Calendar.current.dateComponents([.day, .month, .year], from: domainModel.date)
diff --git a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
index 0b348894d743841ce4c52ac192723e0211986503..d06d88f7eb5c2e6917a891dab8d062cb2723bc02 100644
--- a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
+++ b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift
@@ -105,13 +105,13 @@ final class SingleChatViewModel: NSObject {
         updateRecentState(contact)
 
         database.fetchContactsPublisher(Contact.Query(id: [contact.id]))
-            .assertNoFailure()
+        .replaceError(with: [])
             .compactMap { $0.first }
             .sink { [unowned self] in contactSubject.send($0) }
             .store(in: &cancellables)
 
         database.fetchMessagesPublisher(.init(chat: .direct(myId, contact.id)))
-            .assertNoFailure()
+        .replaceError(with: [])
             .map {
                 let groupedByDate = Dictionary(grouping: $0) { domainModel -> Date in
                     let components = Calendar.current.dateComponents([.day, .month, .year], from: domainModel.date)
diff --git a/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift b/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift
index ac787dd2ea58eeaaa584114991a83f0ca8c88dca..32b7e99a945568919a6b5bbde947515944490f87 100644
--- a/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift
+++ b/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift
@@ -57,7 +57,7 @@ final class ChatListViewModel {
         )
 
         return database.fetchContactsPublisher(query)
-            .assertNoFailure()
+        .replaceError(with: [])
             .map {
                 let section = SectionId()
                 var snapshot = RecentsSnapshot()
@@ -75,7 +75,7 @@ final class ChatListViewModel {
 
         return Publishers.CombineLatest3(
             database.fetchContactsPublisher(contactsQuery)
-                .assertNoFailure()
+              .replaceError(with: [])
                 .map { $0.filter { $0.id != self.myId }},
             chatsPublisher,
             searchSubject
@@ -140,8 +140,8 @@ final class ChatListViewModel {
         )
 
         return Publishers.CombineLatest(
-            database.fetchContactsPublisher(contactsQuery).assertNoFailure(),
-            database.fetchGroupsPublisher(groupQuery).assertNoFailure()
+            database.fetchContactsPublisher(contactsQuery).replaceError(with: []),
+            database.fetchGroupsPublisher(groupQuery).replaceError(with: [])
         )
         .map { $0.0.count + $0.1.count }
         .eraseToAnyPublisher()
@@ -170,7 +170,7 @@ final class ChatListViewModel {
                     authStatus: [.participating]
                 )
             ))
-        .assertNoFailure()
+        .replaceError(with: [])
         .sink { [unowned self] in chatsSubject.send($0) }
         .store(in: &cancellables)
     }
diff --git a/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift b/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift
index 548cc89bcdb37202d318b75d9ff82d8042170d01..2f1364c5306724b14a08ed3592d4af6b094efd86 100644
--- a/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift
+++ b/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift
@@ -26,7 +26,7 @@ final class ContactListViewModel {
         )
 
         return database.fetchContactsPublisher(query)
-            .assertNoFailure()
+        .replaceError(with: [])
             .map { $0.filter { $0.id != self.myId }}
             .eraseToAnyPublisher()
     }
@@ -51,8 +51,10 @@ final class ContactListViewModel {
         )
 
         return Publishers.CombineLatest(
-            database.fetchContactsPublisher(contactsQuery).assertNoFailure(),
-            database.fetchGroupsPublisher(groupQuery).assertNoFailure()
+            database.fetchContactsPublisher(contactsQuery)
+              .replaceError(with: []),
+            database.fetchGroupsPublisher(groupQuery)
+              .replaceError(with: [])
         )
         .map { $0.0.count + $0.1.count }
         .eraseToAnyPublisher()
diff --git a/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift b/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift
index f292c7cb7ed4589007e86a565cd0ad5100b91ff4..08314f15ff9c16729e88e4ada4270ceef6ad3277 100644
--- a/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift
+++ b/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift
@@ -62,7 +62,7 @@ final class CreateGroupViewModel {
         )
 
         database.fetchContactsPublisher(query)
-            .assertNoFailure()
+        .replaceError(with: [])
             .map { $0.filter { $0.id != self.myId }}
             .map { $0.sorted(by: { $0.username! < $1.username! })}
             .sink { [unowned self] in
diff --git a/Sources/LaunchFeature/LaunchViewModel.swift b/Sources/LaunchFeature/LaunchViewModel.swift
index fb6f56c3c9aa472a6fa12b1d7867b0f30728be85..79fafead16257f18d3310e00891ad76b14cb59d9 100644
--- a/Sources/LaunchFeature/LaunchViewModel.swift
+++ b/Sources/LaunchFeature/LaunchViewModel.swift
@@ -9,6 +9,7 @@ import Keychain
 import Foundation
 import Permissions
 import ToastFeature
+import BackupFeature
 import DropboxFeature
 import VersionChecking
 import ReportingFeature
@@ -25,692 +26,695 @@ import XXMessengerClient
 import NetworkMonitor
 
 struct Update {
-    let content: String
-    let urlString: String
-    let positiveActionTitle: String
-    let negativeActionTitle: String?
-    let actionStyle: CapsuleButtonStyle
+  let content: String
+  let urlString: String
+  let positiveActionTitle: String
+  let negativeActionTitle: String?
+  let actionStyle: CapsuleButtonStyle
 }
 
 enum LaunchRoute {
-    case chats
-    case update(Update)
-    case onboarding
+  case chats
+  case update(Update)
+  case onboarding
 }
 
 final class LaunchViewModel {
-    @Dependency var database: Database
-    @Dependency var versionChecker: VersionChecker
-    @Dependency var dropboxService: DropboxInterface
-    @Dependency var fetchBannedList: FetchBannedList
-    @Dependency var reportingStatus: ReportingStatus
-    @Dependency var toastController: ToastController
-    @Dependency var keychainHandler: KeychainHandling
-    @Dependency var networkMonitor: NetworkMonitoring
-    @Dependency var processBannedList: ProcessBannedList
-    @Dependency var permissionHandler: PermissionHandling
-
-    @KeyObject(.username, defaultValue: nil) var username: String?
-    @KeyObject(.biometrics, defaultValue: false) var isBiometricsOn: Bool
-    @KeyObject(.dummyTrafficOn, defaultValue: false) var dummyTrafficOn: Bool
-
-    var hudPublisher: AnyPublisher<HUDStatus, Never> {
-        hudSubject.eraseToAnyPublisher()
-    }
-
-    var authCallbacksCancellable: Cancellable?
-    var networkCallbacksCancellable: Cancellable?
-    var messageListenerCallbacksCancellable: Cancellable?
-
-    var routePublisher: AnyPublisher<LaunchRoute, Never> {
-        routeSubject.eraseToAnyPublisher()
-    }
-
-    var mainScheduler: AnySchedulerOf<DispatchQueue> = {
-        DispatchQueue.main.eraseToAnyScheduler()
-    }()
-
-    var backgroundScheduler: AnySchedulerOf<DispatchQueue> = {
-        DispatchQueue.global().eraseToAnyScheduler()
-    }()
-
-    private var cancellables = Set<AnyCancellable>()
-    private let routeSubject = PassthroughSubject<LaunchRoute, Never>()
-    private let hudSubject = CurrentValueSubject<HUDStatus, Never>(.none)
-
-    func viewDidAppear() {
-        mainScheduler.schedule(after: .init(.now() + 1)) { [weak self] in
-            guard let self = self else { return }
-
-            self.hudSubject.send(.on)
-
-            self.versionChecker().sink { [unowned self] in
-                switch $0 {
-                case .upToDate:
-                    self.updateBannedList {
-                        self.updateErrors {
-                            self.continueWithInitialization()
-                        }
-                    }
-                case .failure(let error):
-                    self.versionFailed(error: error)
-                case .updateRequired(let info):
-                    self.versionUpdateRequired(info)
-                case .updateRecommended(let info):
-                    self.versionUpdateRecommended(info)
-                }
-            }.store(in: &self.cancellables)
+  @Dependency var database: Database
+  @Dependency var backupService: BackupService
+  @Dependency var versionChecker: VersionChecker
+  @Dependency var dropboxService: DropboxInterface
+  @Dependency var fetchBannedList: FetchBannedList
+  @Dependency var reportingStatus: ReportingStatus
+  @Dependency var toastController: ToastController
+  @Dependency var keychainHandler: KeychainHandling
+  @Dependency var networkMonitor: NetworkMonitoring
+  @Dependency var processBannedList: ProcessBannedList
+  @Dependency var permissionHandler: PermissionHandling
+
+  @KeyObject(.username, defaultValue: nil) var username: String?
+  @KeyObject(.biometrics, defaultValue: false) var isBiometricsOn: Bool
+  @KeyObject(.dummyTrafficOn, defaultValue: false) var dummyTrafficOn: Bool
+
+  var hudPublisher: AnyPublisher<HUDStatus, Never> {
+    hudSubject.eraseToAnyPublisher()
+  }
+
+  var authCallbacksCancellable: Cancellable?
+  var backupCallbackCancellable: Cancellable?
+  var networkCallbacksCancellable: Cancellable?
+  var messageListenerCallbacksCancellable: Cancellable?
+
+  var routePublisher: AnyPublisher<LaunchRoute, Never> {
+    routeSubject.eraseToAnyPublisher()
+  }
+
+  var backgroundScheduler: AnySchedulerOf<DispatchQueue> = {
+    DispatchQueue.global().eraseToAnyScheduler()
+  }()
+
+  private var cancellables = Set<AnyCancellable>()
+  private let routeSubject = PassthroughSubject<LaunchRoute, Never>()
+  private let hudSubject = CurrentValueSubject<HUDStatus, Never>(.none)
+
+  func viewDidAppear() {
+    backgroundScheduler.schedule(after: .init(.now() + 1)) { [weak self] in
+      guard let self = self else { return }
+
+      self.hudSubject.send(.on)
+
+      self.versionChecker().sink { [unowned self] in
+        switch $0 {
+        case .upToDate:
+          self.updateBannedList {
+            self.updateErrors {
+              self.continueWithInitialization()
+            }
+          }
+        case .failure(let error):
+          self.versionFailed(error: error)
+        case .updateRequired(let info):
+          self.versionUpdateRequired(info)
+        case .updateRecommended(let info):
+          self.versionUpdateRecommended(info)
         }
+      }.store(in: &self.cancellables)
     }
+  }
 
-    func continueWithInitialization() {
-        do {
-            try self.setupDatabase()
+  func continueWithInitialization() {
+    do {
+      try self.setupDatabase()
 
-            let messenger = makeMessenger()
-            DependencyInjection.Container.shared.register(messenger)
+      let messenger = makeMessenger()
+      DependencyInjection.Container.shared.register(messenger)
 
-            setupLogWriter()
-            setupAuthCallback(messenger)
-            setupMessageCallback(messenger)
+      setupLogWriter()
+      setupAuthCallback(messenger)
+      setupBackupCallback(messenger)
+      setupMessageCallback(messenger)
 
-            if messenger.isLoaded() == false {
-                if messenger.isCreated() == false {
-                    try messenger.create()
-                }
-
-                try messenger.load()
-            }
+      if messenger.isLoaded() == false {
+        if messenger.isCreated() == false {
+          try messenger.create()
+        }
 
-            try messenger.start()
+        try messenger.load()
+      }
 
-            if messenger.isConnected() == false {
-                try messenger.connect()
-                try messenger.listenForMessages()
-            }
+      try messenger.start()
 
-            try generateGroupManager(messenger)
-            try generateTrafficManager(messenger)
-            try generateTransferManager(messenger)
-            listenToNetworkUpdates(messenger)
-
-            if messenger.isLoggedIn() == false {
-                if try messenger.isRegistered() {
-                    try messenger.logIn()
-                    hudSubject.send(.none)
-                    routeSubject.send(.chats)
-                } else {
-                    dropboxService.unlink()
-                    hudSubject.send(.none)
-                    routeSubject.send(.onboarding)
-                }
-            } else {
-                hudSubject.send(.none)
-                routeSubject.send(.chats)
-            }
+      if messenger.isConnected() == false {
+        try messenger.connect()
+        try messenger.listenForMessages()
+      }
 
-            // TODO: Biometric auth
+      try generateGroupManager(messenger)
+      try generateTrafficManager(messenger)
+      try generateTransferManager(messenger)
+      listenToNetworkUpdates(messenger)
 
-        } catch {
-            let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription)
-            hudSubject.send(.error(.init(content: xxError)))
+      if messenger.isLoggedIn() == false {
+        if try messenger.isRegistered() {
+          try messenger.logIn()
+          hudSubject.send(.none)
+          routeSubject.send(.chats)
+        } else {
+          dropboxService.unlink()
+          hudSubject.send(.none)
+          routeSubject.send(.onboarding)
         }
-    }
-
-    private func cleanUp() {
-//        try? cMixManager.remove()
-//        try? keychainHandler.clear()
-    }
-
-    private func presentOnboardingFlow() {
+      } else {
         hudSubject.send(.none)
-        routeSubject.send(.onboarding)
-    }
+        routeSubject.send(.chats)
+      }
 
-    private func setupDatabase() throws {
-        let legacyOldPath = NSSearchPathForDirectoriesInDomains(
-            .documentDirectory, .userDomainMask, true
-        )[0].appending("/xxmessenger.sqlite")
+      if !messenger.isBackupRunning() {
+        try? messenger.resumeBackup()
+      }
 
-        let legacyPath = FileManager.default
-            .containerURL(forSecurityApplicationGroupIdentifier: "group.elixxir.messenger")!
-            .appendingPathComponent("database")
-            .appendingPathExtension("sqlite").path
+      // TODO: Biometric auth
 
-        let dbExistsInLegacyOldPath = FileManager.default.fileExists(atPath: legacyOldPath)
-        let dbExistsInLegacyPath = FileManager.default.fileExists(atPath: legacyPath)
-
-        if dbExistsInLegacyOldPath && !dbExistsInLegacyPath {
-            try? FileManager.default.moveItem(atPath: legacyOldPath, toPath: legacyPath)
-        }
+    } catch {
+      let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription)
+      hudSubject.send(.error(.init(content: xxError)))
+    }
+  }
 
-        let dbPath = FileManager.default
-            .containerURL(forSecurityApplicationGroupIdentifier: "group.elixxir.messenger")!
-            .appendingPathComponent("xxm_database")
-            .appendingPathExtension("sqlite").path
+  private func cleanUp() {
+    //        try? cMixManager.remove()
+    //        try? keychainHandler.clear()
+  }
 
-        let database = try Database.onDisk(path: dbPath)
+  private func presentOnboardingFlow() {
+    hudSubject.send(.none)
+    routeSubject.send(.onboarding)
+  }
 
-        if dbExistsInLegacyPath {
-            try Migrator.live()(
-                try .init(path: legacyPath),
-                to: database,
-                myContactId: Data(), //client.bindings.myId,
-                meMarshaled: Data() //client.bindings.meMarshalled
-            )
+  private func setupDatabase() throws {
+    let legacyOldPath = NSSearchPathForDirectoriesInDomains(
+      .documentDirectory, .userDomainMask, true
+    )[0].appending("/xxmessenger.sqlite")
 
-            try FileManager.default.moveItem(atPath: legacyPath, toPath: legacyPath.appending("-backup"))
-        }
+    let legacyPath = FileManager.default
+      .containerURL(forSecurityApplicationGroupIdentifier: "group.elixxir.messenger")!
+      .appendingPathComponent("database")
+      .appendingPathExtension("sqlite").path
 
-        DependencyInjection.Container.shared.register(database)
+    let dbExistsInLegacyOldPath = FileManager.default.fileExists(atPath: legacyOldPath)
+    let dbExistsInLegacyPath = FileManager.default.fileExists(atPath: legacyPath)
 
-        _ = try? database.bulkUpdateContacts(.init(authStatus: [.requesting]), .init(authStatus: .requestFailed))
-        _ = try? database.bulkUpdateContacts(.init(authStatus: [.confirming]), .init(authStatus: .confirmationFailed))
-        _ = try? database.bulkUpdateContacts(.init(authStatus: [.verificationInProgress]), .init(authStatus: .verificationFailed))
+    if dbExistsInLegacyOldPath && !dbExistsInLegacyPath {
+      try? FileManager.default.moveItem(atPath: legacyOldPath, toPath: legacyPath)
     }
 
-    func getContactWith(userId: Data) -> XXModels.Contact? {
-        let query = Contact.Query(
-            id: [userId],
-            isBlocked: reportingStatus.isEnabled() ? false : nil,
-            isBanned: reportingStatus.isEnabled() ? false : nil
-        )
-
-        guard let database: Database = try? DependencyInjection.Container.shared.resolve(),
-              let contact = try? database.fetchContacts(query).first else {
-            return nil
-        }
-
-        return contact
-    }
+    let dbPath = FileManager.default
+      .containerURL(forSecurityApplicationGroupIdentifier: "group.elixxir.messenger")!
+      .appendingPathComponent("xxm_database")
+      .appendingPathExtension("sqlite").path
 
-    func getGroupInfoWith(groupId: Data) -> GroupInfo? {
-        let query = GroupInfo.Query(groupId: groupId)
+    let database = try Database.onDisk(path: dbPath)
 
-        guard let database: Database = try? DependencyInjection.Container.shared.resolve(),
-              let info = try? database.fetchGroupInfos(query).first else {
-            return nil
-        }
+    if dbExistsInLegacyPath {
+      try Migrator.live()(
+        try .init(path: legacyPath),
+        to: database,
+        myContactId: Data(), //client.bindings.myId,
+        meMarshaled: Data() //client.bindings.meMarshalled
+      )
 
-        return info
+      try FileManager.default.moveItem(atPath: legacyPath, toPath: legacyPath.appending("-backup"))
     }
 
-    private func versionFailed(error: Error) {
-        let title = Localized.Launch.Version.failed
-        let content = error.localizedDescription
-        let hudError = HUDError(content: content, title: title, dismissable: false)
+    DependencyInjection.Container.shared.register(database)
 
-        hudSubject.send(.error(hudError))
-    }
-
-    private func versionUpdateRequired(_ info: DappVersionInformation) {
-        hudSubject.send(.none)
+    _ = try? database.bulkUpdateContacts(.init(authStatus: [.requesting]), .init(authStatus: .requestFailed))
+    _ = try? database.bulkUpdateContacts(.init(authStatus: [.confirming]), .init(authStatus: .confirmationFailed))
+    _ = try? database.bulkUpdateContacts(.init(authStatus: [.verificationInProgress]), .init(authStatus: .verificationFailed))
+  }
 
-        let model = Update(
-            content: info.minimumMessage,
-            urlString: info.appUrl,
-            positiveActionTitle: Localized.Launch.Version.Required.positive,
-            negativeActionTitle: nil,
-            actionStyle: .brandColored
-        )
+  func getContactWith(userId: Data) -> XXModels.Contact? {
+    let query = Contact.Query(
+      id: [userId],
+      isBlocked: reportingStatus.isEnabled() ? false : nil,
+      isBanned: reportingStatus.isEnabled() ? false : nil
+    )
 
-        routeSubject.send(.update(model))
+    guard let database: Database = try? DependencyInjection.Container.shared.resolve(),
+          let contact = try? database.fetchContacts(query).first else {
+      return nil
     }
 
-    private func versionUpdateRecommended(_ info: DappVersionInformation) {
-        hudSubject.send(.none)
+    return contact
+  }
 
-        let model = Update(
-            content: Localized.Launch.Version.Recommended.title,
-            urlString: info.appUrl,
-            positiveActionTitle: Localized.Launch.Version.Recommended.positive,
-            negativeActionTitle: Localized.Launch.Version.Recommended.negative,
-            actionStyle: .simplestColoredRed
-        )
+  func getGroupInfoWith(groupId: Data) -> GroupInfo? {
+    let query = GroupInfo.Query(groupId: groupId)
 
-        routeSubject.send(.update(model))
+    guard let database: Database = try? DependencyInjection.Container.shared.resolve(),
+          let info = try? database.fetchGroupInfos(query).first else {
+      return nil
     }
 
-    private func checkBiometrics(completion: @escaping (Result<Bool, Error>) -> Void) {
-        if permissionHandler.isBiometricsAvailable && isBiometricsOn {
-            permissionHandler.requestBiometrics {
-                switch $0 {
-                case .success(let granted):
-                    completion(.success(granted))
-
-                case .failure(let error):
-                    completion(.failure(error))
-                }
-            }
-        } else {
-            completion(.success(true))
+    return info
+  }
+
+  private func versionFailed(error: Error) {
+    let title = Localized.Launch.Version.failed
+    let content = error.localizedDescription
+    let hudError = HUDError(content: content, title: title, dismissable: false)
+
+    hudSubject.send(.error(hudError))
+  }
+
+  private func versionUpdateRequired(_ info: DappVersionInformation) {
+    hudSubject.send(.none)
+
+    let model = Update(
+      content: info.minimumMessage,
+      urlString: info.appUrl,
+      positiveActionTitle: Localized.Launch.Version.Required.positive,
+      negativeActionTitle: nil,
+      actionStyle: .brandColored
+    )
+
+    routeSubject.send(.update(model))
+  }
+
+  private func versionUpdateRecommended(_ info: DappVersionInformation) {
+    hudSubject.send(.none)
+
+    let model = Update(
+      content: Localized.Launch.Version.Recommended.title,
+      urlString: info.appUrl,
+      positiveActionTitle: Localized.Launch.Version.Recommended.positive,
+      negativeActionTitle: Localized.Launch.Version.Recommended.negative,
+      actionStyle: .simplestColoredRed
+    )
+
+    routeSubject.send(.update(model))
+  }
+
+  private func checkBiometrics(completion: @escaping (Result<Bool, Error>) -> Void) {
+    if permissionHandler.isBiometricsAvailable && isBiometricsOn {
+      permissionHandler.requestBiometrics {
+        switch $0 {
+        case .success(let granted):
+          completion(.success(granted))
+
+        case .failure(let error):
+          completion(.failure(error))
         }
+      }
+    } else {
+      completion(.success(true))
     }
-
-    private func updateErrors(completion: @escaping () -> Void) {
-        let errorsURLString = "https://git.xx.network/elixxir/client-error-database/-/raw/main/clientErrors.json"
-
-        URLSession.shared.dataTask(with: URL(string: errorsURLString)!) { [weak self] data, _, error in
-            guard let self = self else { return }
-
-            guard error == nil else {
-                print(">>> Issue when trying to download errors json: \(error!.localizedDescription)")
-                self.updateErrors(completion: completion)
-                return
-            }
-
-            guard let data = data, let json = String(data: data, encoding: .utf8) else {
-                print(">>> Issue when trying to unwrap errors json")
-                return
-            }
-
-            do {
-                try UpdateCommonErrors.live(jsonFile: json)
-                completion()
-            } catch {
-                print(">>> Issue when trying to update common errors: \(error.localizedDescription)")
-            }
-        }.resume()
-    }
-
-    private func updateBannedList(completion: @escaping () -> Void) {
-        fetchBannedList { result in
-            switch result {
-            case .failure(_):
-                DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
-                    self.updateBannedList(completion: completion)
-                }
-            case .success(let data):
-                self.processBannedList(data, completion: completion)
-            }
+  }
+
+  private func updateErrors(completion: @escaping () -> Void) {
+    let errorsURLString = "https://git.xx.network/elixxir/client-error-database/-/raw/main/clientErrors.json"
+
+    URLSession.shared.dataTask(with: URL(string: errorsURLString)!) { [weak self] data, _, error in
+      guard let self = self else { return }
+
+      guard error == nil else {
+        print(">>> Issue when trying to download errors json: \(error!.localizedDescription)")
+        self.updateErrors(completion: completion)
+        return
+      }
+
+      guard let data = data, let json = String(data: data, encoding: .utf8) else {
+        print(">>> Issue when trying to unwrap errors json")
+        return
+      }
+
+      do {
+        try UpdateCommonErrors.live(jsonFile: json)
+        completion()
+      } catch {
+        print(">>> Issue when trying to update common errors: \(error.localizedDescription)")
+      }
+    }.resume()
+  }
+
+  private func updateBannedList(completion: @escaping () -> Void) {
+    fetchBannedList { result in
+      switch result {
+      case .failure(_):
+        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+          self.updateBannedList(completion: completion)
         }
+      case .success(let data):
+        self.processBannedList(data, completion: completion)
+      }
     }
-
-    private func processBannedList(_ data: Data, completion: @escaping () -> Void) {
-        processBannedList(
-            data: data,
-            forEach: { result in
-                switch result {
-                case .success(let userId):
-                    let query = Contact.Query(id: [userId])
-                    if var contact = try! database.fetchContacts(query).first {
-                        if contact.isBanned == false {
-                            contact.isBanned = true
-                            try! database.saveContact(contact)
-                            self.enqueueBanWarning(contact: contact)
-                        }
-                    } else {
-                        try! database.saveContact(.init(id: userId, isBanned: true))
-                    }
-
-                case .failure(_):
-                    break
-                }
-            },
-            completion: { result in
-                switch result {
-                case .failure(_):
-                    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
-                        self.updateBannedList(completion: completion)
-                    }
-
-                case .success(_):
-                    completion()
-                }
+  }
+
+  private func processBannedList(_ data: Data, completion: @escaping () -> Void) {
+    processBannedList(
+      data: data,
+      forEach: { result in
+        switch result {
+        case .success(let userId):
+          let query = Contact.Query(id: [userId])
+          if var contact = try! database.fetchContacts(query).first {
+            if contact.isBanned == false {
+              contact.isBanned = true
+              try! database.saveContact(contact)
+              self.enqueueBanWarning(contact: contact)
             }
-        )
-    }
+          } else {
+            try! database.saveContact(.init(id: userId, isBanned: true))
+          }
 
-    private func enqueueBanWarning(contact: XXModels.Contact) {
-        let name = (contact.nickname ?? contact.username) ?? "One of your contacts"
-        toastController.enqueueToast(model: .init(
-            title: "\(name) has been banned for offensive content.",
-            leftImage: Asset.requestSentToaster.image
-        ))
-    }
+        case .failure(_):
+          break
+        }
+      },
+      completion: { result in
+        switch result {
+        case .failure(_):
+          DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+            self.updateBannedList(completion: completion)
+          }
+
+        case .success(_):
+          completion()
+        }
+      }
+    )
+  }
+
+  private func enqueueBanWarning(contact: XXModels.Contact) {
+    let name = (contact.nickname ?? contact.username) ?? "One of your contacts"
+    toastController.enqueueToast(model: .init(
+      title: "\(name) has been banned for offensive content.",
+      leftImage: Asset.requestSentToaster.image
+    ))
+  }
 }
 
 extension LaunchViewModel {
-    private func generateGroupManager(_ messenger: Messenger) throws {
-        let manager = try NewGroupChat.live(
-            e2eId: messenger.e2e()!.getId(),
-            groupRequest: .init(handle: { [weak self] group in
-                guard let self = self else { return }
-                self.handleGroupRequest(from: group, messenger: messenger)
-            }),
-            groupChatProcessor: .init(handle: { result in
-                switch result {
-                case .success(let cb):
-
-                    print("Incoming GroupMessage:")
-                    print("- groupId: \(cb.decryptedMessage.groupId.base64EncodedString().prefix(10))...")
-                    print("- senderId: \(cb.decryptedMessage.senderId.base64EncodedString().prefix(10))...")
-                    print("- messageId: \(cb.decryptedMessage.messageId.base64EncodedString().prefix(10))...")
-
-                    if let payload = try? Payload(with: cb.decryptedMessage.payload) {
-                        print("- payload.text: \(payload.text)")
-
-                        if let reply = payload.reply {
-                            print("- payload.reply.senderId: \(reply.senderId.base64EncodedString().prefix(10))...")
-                            print("- payload.reply.messageId: \(reply.messageId.base64EncodedString().prefix(10))...")
-                        } else {
-                            print("- payload.reply: ∅")
-                        }
-                    }
-                    print("")
-
-                    guard let payload = try? Payload(with: cb.decryptedMessage.payload) else {
-                        fatalError("Couldn't decode payload: \(String(data: cb.decryptedMessage.payload, encoding: .utf8) ?? "nil")")
-                    }
-
-                    let msg = Message(
-                        networkId: cb.decryptedMessage.messageId,
-                        senderId: cb.decryptedMessage.senderId,
-                        recipientId: nil,
-                        groupId: cb.decryptedMessage.groupId,
-                        date: Date.fromTimestamp(Int(cb.decryptedMessage.timestamp)),
-                        status: .received,
-                        isUnread: true,
-                        text: payload.text,
-                        replyMessageId: payload.reply?.messageId,
-                        roundURL: "https://google.com.br",
-                        fileTransferId: nil
-                    )
-
-                    _ = try? self.database.saveMessage(msg)
-
-                case .failure(let error):
-                    break
-                }
-            })
-        )
-
-        DependencyInjection.Container.shared.register(manager)
-    }
-
-    private func generateTransferManager(_ messenger: Messenger) throws {
-        let manager = try InitFileTransfer.live(
-            e2eId: messenger.e2e()!.getId(),
-            callback: .init(handle: { [weak self] in
-                guard let self = self else { return }
-
-                switch $0 {
-                case .success(let receivedFile):
-                    self.handleIncomingTransfer(receivedFile, messenger: messenger)
-                case .failure(let error):
-                    print(error.localizedDescription)
-                }
-            })
-        )
+  private func generateGroupManager(_ messenger: Messenger) throws {
+    let manager = try NewGroupChat.live(
+      e2eId: messenger.e2e()!.getId(),
+      groupRequest: .init(handle: { [weak self] group in
+        guard let self = self else { return }
+        self.handleGroupRequest(from: group, messenger: messenger)
+      }),
+      groupChatProcessor: .init(handle: { result in
+        switch result {
+        case .success(let cb):
+
+          print("Incoming GroupMessage:")
+          print("- groupId: \(cb.decryptedMessage.groupId.base64EncodedString().prefix(10))...")
+          print("- senderId: \(cb.decryptedMessage.senderId.base64EncodedString().prefix(10))...")
+          print("- messageId: \(cb.decryptedMessage.messageId.base64EncodedString().prefix(10))...")
+
+          if let payload = try? Payload(with: cb.decryptedMessage.payload) {
+            print("- payload.text: \(payload.text)")
+
+            if let reply = payload.reply {
+              print("- payload.reply.senderId: \(reply.senderId.base64EncodedString().prefix(10))...")
+              print("- payload.reply.messageId: \(reply.messageId.base64EncodedString().prefix(10))...")
+            } else {
+              print("- payload.reply: ∅")
+            }
+          }
+          print("")
+
+          guard let payload = try? Payload(with: cb.decryptedMessage.payload) else {
+            fatalError("Couldn't decode payload: \(String(data: cb.decryptedMessage.payload, encoding: .utf8) ?? "nil")")
+          }
+
+          let msg = Message(
+            networkId: cb.decryptedMessage.messageId,
+            senderId: cb.decryptedMessage.senderId,
+            recipientId: nil,
+            groupId: cb.decryptedMessage.groupId,
+            date: Date.fromTimestamp(Int(cb.decryptedMessage.timestamp)),
+            status: .received,
+            isUnread: true,
+            text: payload.text,
+            replyMessageId: payload.reply?.messageId,
+            roundURL: "https://google.com.br",
+            fileTransferId: nil
+          )
+
+          _ = try? self.database.saveMessage(msg)
+
+        case .failure(let error):
+          break
+        }
+      })
+    )
+
+    DependencyInjection.Container.shared.register(manager)
+  }
+
+  private func generateTransferManager(_ messenger: Messenger) throws {
+    let manager = try InitFileTransfer.live(
+      e2eId: messenger.e2e()!.getId(),
+      callback: .init(handle: { [weak self] in
+        guard let self = self else { return }
+
+        switch $0 {
+        case .success(let receivedFile):
+          self.handleIncomingTransfer(receivedFile, messenger: messenger)
+        case .failure(let error):
+          print(error.localizedDescription)
+        }
+      })
+    )
 
-        DependencyInjection.Container.shared.register(manager)
-    }
+    DependencyInjection.Container.shared.register(manager)
+  }
 
-    private func generateTrafficManager(_ messenger: Messenger) throws {
-        let manager = try NewDummyTrafficManager.live(
-            cMixId: messenger.e2e()!.getId()
-        )
+  private func generateTrafficManager(_ messenger: Messenger) throws {
+    let manager = try NewDummyTrafficManager.live(
+      cMixId: messenger.e2e()!.getId()
+    )
 
-        DependencyInjection.Container.shared.register(manager)
-        try! manager.setStatus(dummyTrafficOn)
-    }
+    DependencyInjection.Container.shared.register(manager)
+    try! manager.setStatus(dummyTrafficOn)
+  }
 }
 
 extension LaunchViewModel {
-    private func handleDirectRequest(from contact: XXClient.Contact) {
-        guard let id = try? contact.getId() else {
-            fatalError("Couldn't extract ID from contact request arrived.")
-        }
-
-        if let _ = try? database.fetchContacts(.init(id: [id])).first {
-            print(">>> Tried to handle request from pre-existing contact.")
-            return
-        }
-
-        let facts = try? contact.getFacts()
-        let email = facts?.first(where: { $0.type == .email })?.value
-        let phone = facts?.first(where: { $0.type == .phone })?.value
-        let username = facts?.first(where: { $0.type == .username })?.value
-
-        var model = try! database.saveContact(.init(
-            id: id,
-            marshaled: contact.data,
-            username: username,
-            email: email,
-            phone: phone,
-            nickname: nil,
-            photo: nil,
-            authStatus: .verificationInProgress,
-            isRecent: true,
-            createdAt: Date()
-        ))
+  private func handleDirectRequest(from contact: XXClient.Contact) {
+    guard let id = try? contact.getId() else {
+      fatalError("Couldn't extract ID from contact request arrived.")
+    }
 
-        do {
-            let messenger: Messenger = try DependencyInjection.Container.shared.resolve()
-            try messenger.waitForNetwork()
+    if let _ = try? database.fetchContacts(.init(id: [id])).first {
+      print(">>> Tried to handle request from pre-existing contact.")
+      return
+    }
 
-            if try messenger.verifyContact(contact) {
-                print(">>> [messenger.verifyContact \(#file):\(#line)]")
+    let facts = try? contact.getFacts()
+    let email = facts?.first(where: { $0.type == .email })?.value
+    let phone = facts?.first(where: { $0.type == .phone })?.value
+    let username = facts?.first(where: { $0.type == .username })?.value
+
+    var model = try! database.saveContact(.init(
+      id: id,
+      marshaled: contact.data,
+      username: username,
+      email: email,
+      phone: phone,
+      nickname: nil,
+      photo: nil,
+      authStatus: .verificationInProgress,
+      isRecent: true,
+      createdAt: Date()
+    ))
+
+    do {
+      let messenger: Messenger = try DependencyInjection.Container.shared.resolve()
+      try messenger.waitForNetwork()
+
+      if try messenger.verifyContact(contact) {
+        print(">>> [messenger.verifyContact \(#file):\(#line)]")
+
+        model.authStatus = .verified
+        model = try database.saveContact(model)
+      } else {
+        print(">>> [messenger.verifyContact \(#file):\(#line)]")
+        try database.deleteContact(model)
+      }
+    } catch {
+      print(">>> [messenger.verifyContact] thrown an exception: \(error.localizedDescription)")
+
+      model.authStatus = .verificationFailed
+      model = try! database.saveContact(model)
+    }
+  }
 
-                model.authStatus = .verified
-                model = try database.saveContact(model)
-            } else {
-                print(">>> [messenger.verifyContact \(#file):\(#line)]")
-                try database.deleteContact(model)
-            }
-        } catch {
-            print(">>> [messenger.verifyContact] thrown an exception: \(error.localizedDescription)")
+  private func handleConfirm(from contact: XXClient.Contact) {
+    guard let id = try? contact.getId() else {
+      fatalError("Couldn't extract ID from contact confirmation arrived.")
+    }
 
-            model.authStatus = .verificationFailed
-            model = try! database.saveContact(model)
-        }
+    guard var existentContact = try? database.fetchContacts(.init(id: [id])).first else {
+      print(">>> Tried to handle a confirmation from someone that is not a contact yet")
+      return
     }
 
-    private func handleConfirm(from contact: XXClient.Contact) {
-        guard let id = try? contact.getId() else {
-            fatalError("Couldn't extract ID from contact confirmation arrived.")
-        }
+    existentContact.isRecent = true
+    existentContact.authStatus = .friend
+    try! database.saveContact(existentContact)
+  }
 
-        guard var existentContact = try? database.fetchContacts(.init(id: [id])).first else {
-            print(">>> Tried to handle a confirmation from someone that is not a contact yet")
-            return
-        }
+  private func handleReset(from user: XXClient.Contact) {
+    if var contact = try? database.fetchContacts(.init(id: [user.getId()])).first {
+      contact.authStatus = .friend
+      _ = try? database.saveContact(contact)
+    }
+  }
 
-        existentContact.isRecent = true
-        existentContact.authStatus = .friend
-        try! database.saveContact(existentContact)
+  private func handleGroupRequest(from group: XXClient.Group, messenger: Messenger) {
+    if let _ = try? database.fetchGroups(.init(id: [group.getId()])).first {
+      print(">>> Tried to handle a group request that is already handled")
+      return
     }
 
-    private func handleReset(from user: XXClient.Contact) {
-        if var contact = try? database.fetchContacts(.init(id: [user.getId()])).first {
-            contact.authStatus = .friend
-            _ = try? database.saveContact(contact)
-        }
+    guard var members = try? group.getMembership(), let leader = members.first else {
+      fatalError("Failed to get group membership/leader")
     }
 
-    private func handleGroupRequest(from group: XXClient.Group, messenger: Messenger) {
-        if let _ = try? database.fetchGroups(.init(id: [group.getId()])).first {
-            print(">>> Tried to handle a group request that is already handled")
-            return
-        }
+    try! database.saveGroup(.init(
+      id: group.getId(),
+      name: String(data: group.getName(), encoding: .utf8)!,
+      leaderId: leader.id,
+      createdAt: Date.fromMSTimestamp(group.getCreatedMS()),
+      authStatus: .pending,
+      serialized: group.serialize()
+    ))
+
+    if let initMessageData = group.getInitMessage(),
+       let initMessage = String(data: initMessageData, encoding: .utf8) {
+      try! database.saveMessage(.init(
+        senderId: leader.id,
+        recipientId: nil,
+        groupId: group.getId(),
+        date: Date.fromMSTimestamp(group.getCreatedMS()),
+        status: .received,
+        isUnread: true,
+        text: initMessage
+      ))
+    }
 
-        guard var members = try? group.getMembership(), let leader = members.first else {
-            fatalError("Failed to get group membership/leader")
-        }
+    print(">>> All members in the arrived group request:")
+    members.forEach { print(">>> \($0.id.base64EncodedString().prefix(10))...") }
+    print(">>> My ud.id is: \(try! messenger.ud.get()!.getContact().getId().base64EncodedString().prefix(10))...")
+    print(">>> My e2e.id is: \(try! messenger.e2e.get()!.getContact().getId().base64EncodedString().prefix(10))...")
+
+    let friends = try! database.fetchContacts(.init(
+      id: Set(members.map(\.id)),
+      authStatus: [
+        .friend,
+        .hidden,
+        .requesting,
+        .confirming,
+        .verificationInProgress,
+        .verified,
+        .requested,
+        .requestFailed,
+        .verificationFailed,
+        .confirmationFailed
+      ]
+    ))
+
+    print(">>> These people I already know:")
+    friends.forEach {
+      print(">>> Username: \($0.username), authStatus: \($0.authStatus.rawValue), id: \($0.id.base64EncodedString().prefix(10))...")
+    }
 
-        try! database.saveGroup(.init(
-            id: group.getId(),
-            name: String(data: group.getName(), encoding: .utf8)!,
-            leaderId: leader.id,
-            createdAt: Date.fromMSTimestamp(group.getCreatedMS()),
-            authStatus: .pending,
-            serialized: group.serialize()
+    let strangers = Set(members.map(\.id)).subtracting(Set(friends.map(\.id)))
+
+    strangers.forEach {
+      if let stranger = try? database.fetchContacts(.init(id: [$0])).first {
+        print(">>> This is a stranger, but I already knew about his/her existance: \(stranger.id.base64EncodedString().prefix(10))...")
+      } else {
+        print(">>> This is a complete stranger. Storing on the db: \($0.base64EncodedString().prefix(10))...")
+
+        try! database.saveContact(.init(
+          id: $0,
+          marshaled: nil,
+          username: "Fetching...",
+          email: nil,
+          phone: nil,
+          nickname: nil,
+          photo: nil,
+          authStatus: .stranger,
+          isRecent: false,
+          isBlocked: false,
+          isBanned: false,
+          createdAt: Date.fromMSTimestamp(group.getCreatedMS())
         ))
+      }
+    }
 
-        if let initMessageData = group.getInitMessage(),
-            let initMessage = String(data: initMessageData, encoding: .utf8) {
-            try! database.saveMessage(.init(
-                senderId: leader.id,
-                recipientId: nil,
-                groupId: group.getId(),
-                date: Date.fromMSTimestamp(group.getCreatedMS()),
-                status: .received,
-                isUnread: true,
-                text: initMessage
-            ))
-        }
+    members.forEach {
+      let model = XXModels.GroupMember(groupId: group.getId(), contactId: $0.id)
+      _ = try? database.saveGroupMember(model)
+    }
 
-        print(">>> All members in the arrived group request:")
-        members.forEach { print(">>> \($0.id.base64EncodedString().prefix(10))...") }
-        print(">>> My ud.id is: \(try! messenger.ud.get()!.getContact().getId().base64EncodedString().prefix(10))...")
-        print(">>> My e2e.id is: \(try! messenger.e2e.get()!.getContact().getId().base64EncodedString().prefix(10))...")
-
-        let friends = try! database.fetchContacts(.init(
-            id: Set(members.map(\.id)),
-            authStatus: [
-                .friend,
-                .hidden,
-                .requesting,
-                .confirming,
-                .verificationInProgress,
-                .verified,
-                .requested,
-                .requestFailed,
-                .verificationFailed,
-                .confirmationFailed
-            ]
-        ))
+    print(">>> Performing a multi-lookup for group strangers:")
 
-        print(">>> These people I already know:")
-        friends.forEach {
-            print(">>> Username: \($0.username), authStatus: \($0.authStatus.rawValue), id: \($0.id.base64EncodedString().prefix(10))...")
-        }
+    do {
+      let multiLookup = try messenger.lookupContacts(ids: strangers.map { $0 })
 
-        let strangers = Set(members.map(\.id)).subtracting(Set(friends.map(\.id)))
+      for user in multiLookup.contacts {
+        print(">>> Found stranger w/ id: \(try! user.getId().base64EncodedString().prefix(10))...")
 
-        strangers.forEach {
-            if let stranger = try? database.fetchContacts(.init(id: [$0])).first {
-                print(">>> This is a stranger, but I already knew about his/her existance: \(stranger.id.base64EncodedString().prefix(10))...")
-            } else {
-                print(">>> This is a complete stranger. Storing on the db: \($0.base64EncodedString().prefix(10))...")
-
-                try! database.saveContact(.init(
-                    id: $0,
-                    marshaled: nil,
-                    username: "Fetching...",
-                    email: nil,
-                    phone: nil,
-                    nickname: nil,
-                    photo: nil,
-                    authStatus: .stranger,
-                    isRecent: false,
-                    isBlocked: false,
-                    isBanned: false,
-                    createdAt: Date.fromMSTimestamp(group.getCreatedMS())
-                ))
-            }
-        }
-
-        members.forEach {
-            let model = XXModels.GroupMember(groupId: group.getId(), contactId: $0.id)
-            _ = try? database.saveGroupMember(model)
+        if var foo = try? self.database.fetchContacts(.init(id: [user.getId()])).first,
+           let username = try? user.getFact(.username)?.value {
+          foo.username = username
+          print(">>> Set username: \(username) for \(try! user.getId().base64EncodedString().prefix(10))...")
+          _ = try? self.database.saveContact(foo)
         }
+      }
 
-        print(">>> Performing a multi-lookup for group strangers:")
-
-        do {
-            let multiLookup = try messenger.lookupContacts(ids: strangers.map { $0 })
-
-            for user in multiLookup.contacts {
-                print(">>> Found stranger w/ id: \(try! user.getId().base64EncodedString().prefix(10))...")
-
-                if var foo = try? self.database.fetchContacts(.init(id: [user.getId()])).first,
-                   let username = try? user.getFact(.username)?.value {
-                    foo.username = username
-                    print(">>> Set username: \(username) for \(try! user.getId().base64EncodedString().prefix(10))...")
-                    _ = try? self.database.saveContact(foo)
-                }
-            }
-
-            for error in multiLookup.errors {
-                print(">>> Failure on Multilookup: \(error.localizedDescription)")
-            }
+      for error in multiLookup.errors {
+        print(">>> Failure on Multilookup: \(error.localizedDescription)")
+      }
 
-            for failedId in multiLookup.failedIds {
-                print(">>> Failed id: \(failedId.base64EncodedString().prefix(10))...")
-            }
-        } catch {
-            print(">>> Exception on multilookup: \(error.localizedDescription)")
-        }
+      for failedId in multiLookup.failedIds {
+        print(">>> Failed id: \(failedId.base64EncodedString().prefix(10))...")
+      }
+    } catch {
+      print(">>> Exception on multilookup: \(error.localizedDescription)")
     }
+  }
 }
 
 extension LaunchViewModel {
-    private func handleIncomingTransfer(_ receivedFile: ReceivedFile, messenger: Messenger) {
-        if var model = try? database.saveFileTransfer(.init(
-            id: receivedFile.transferId,
-            contactId: receivedFile.senderId,
-            name: receivedFile.name,
-            type: receivedFile.type,
-            data: nil,
-            progress: 0.0,
-            isIncoming: true,
-            createdAt: Date()
-        )) {
-            try! database.saveMessage(.init(
-                networkId: nil,
-                senderId: receivedFile.senderId,
-                recipientId: messenger.e2e.get()!.getContact().getId(),
-                groupId: nil,
-                date: Date(),
-                status: .receiving,
-                isUnread: false,
-                text: "",
-                replyMessageId: nil,
-                roundURL: nil,
-                fileTransferId: model.id
-            ))
-
-            if let manager: XXClient.FileTransfer = try? DependencyInjection.Container.shared.resolve() {
-                print(">>> registerReceivedProgressCallback")
-
-                try! manager.registerReceivedProgressCallback(
-                    transferId: receivedFile.transferId,
-                    period: 1_000,
-                    callback: .init(handle: { [weak self] in
-                        guard let self = self else { return }
-                        switch $0 {
-                        case .success(let cb):
-                            if cb.progress.completed {
-                                model.progress = 100
-                                model.data = try! manager.receive(transferId: receivedFile.transferId)
-                            } else {
-                                model.progress = Float(cb.progress.transmitted/cb.progress.total)
-                            }
-
-                            model = try! self.database.saveFileTransfer(model)
-
-                        case .failure(let error):
-                            print(error.localizedDescription)
-                        }
-                    })
-                )
-            } else {
-//                print(DependencyInjection.Container.shared.dependencies)
+  private func handleIncomingTransfer(_ receivedFile: ReceivedFile, messenger: Messenger) {
+    if var model = try? database.saveFileTransfer(.init(
+      id: receivedFile.transferId,
+      contactId: receivedFile.senderId,
+      name: receivedFile.name,
+      type: receivedFile.type,
+      data: nil,
+      progress: 0.0,
+      isIncoming: true,
+      createdAt: Date()
+    )) {
+      try! database.saveMessage(.init(
+        networkId: nil,
+        senderId: receivedFile.senderId,
+        recipientId: messenger.e2e.get()!.getContact().getId(),
+        groupId: nil,
+        date: Date(),
+        status: .receiving,
+        isUnread: false,
+        text: "",
+        replyMessageId: nil,
+        roundURL: nil,
+        fileTransferId: model.id
+      ))
+
+      if let manager: XXClient.FileTransfer = try? DependencyInjection.Container.shared.resolve() {
+        print(">>> registerReceivedProgressCallback")
+
+        try! manager.registerReceivedProgressCallback(
+          transferId: receivedFile.transferId,
+          period: 1_000,
+          callback: .init(handle: { [weak self] in
+            guard let self = self else { return }
+            switch $0 {
+            case .success(let cb):
+              if cb.progress.completed {
+                model.progress = 100
+                model.data = try! manager.receive(transferId: receivedFile.transferId)
+              } else {
+                model.progress = Float(cb.progress.transmitted/cb.progress.total)
+              }
+
+              model = try! self.database.saveFileTransfer(model)
+
+            case .failure(let error):
+              print(error.localizedDescription)
             }
-        }
-    }
-
-    private func setupLogWriter() {
-        _ = try! SetLogLevel.live(.debug)
-        RegisterLogWriter.live(.init(handle: { XXLogger.live().debug($0) }))
+          })
+        )
+      } else {
+        //                print(DependencyInjection.Container.shared.dependencies)
+      }
     }
-
-    private func makeMessenger() -> Messenger {
-        var environment: MessengerEnvironment = .live()
-        environment.ndfEnvironment = .mainnet
-        environment.udAddress = "46.101.98.49:18001"
-        environment.udCert = """
+  }
+
+  private func setupLogWriter() {
+    _ = try! SetLogLevel.live(.debug)
+    RegisterLogWriter.live(.init(handle: { XXLogger.live().debug($0) }))
+  }
+
+  private func makeMessenger() -> Messenger {
+    var environment: MessengerEnvironment = .live()
+    environment.ndfEnvironment = .mainnet
+    environment.udAddress = "46.101.98.49:18001"
+    environment.udCert = """
             -----BEGIN CERTIFICATE-----
             MIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV
             BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx
@@ -733,60 +737,67 @@ extension LaunchViewModel {
             6m52PyzMNV+2N21IPppKwA==
             -----END CERTIFICATE-----
             """.data(using: .utf8)!
-        environment.udContact = """
+    environment.udContact = """
       <xxc(2)7mbKFLE201WzH4SGxAOpHjjehwztIV+KGifi5L/PYPcDkAZiB9kZo+Dl3Vc7dD2SdZCFMOJVgwqGzfYRDkjc8RGEllBqNxq2sRRX09iQVef0kJQUgJCHNCOcvm6Ki0JJwvjLceyFh36iwK8oLbhLgqEZY86UScdACTyBCzBIab3ob5mBthYc3mheV88yq5PGF2DQ+dEvueUm+QhOSfwzppAJA/rpW9Wq9xzYcQzaqc3ztAGYfm2BBAHS7HVmkCbvZ/K07Xrl4EBPGHJYq12tWAN/C3mcbbBYUOQXyEzbSl/mO7sL3ORr0B4FMuqCi8EdlD6RO52pVhY+Cg6roRH1t5Ng1JxPt8Mv1yyjbifPhZ5fLKwxBz8UiFORfk0/jnhwgm25LRHqtNRRUlYXLvhv0HhqyYTUt17WNtCLATSVbqLrFGdy2EGadn8mP+kQNHp93f27d/uHgBNNe7LpuYCJMdWpoG6bOqmHEftxt0/MIQA8fTtTm3jJzv+7/QjZJDvQIv0SNdp8HFogpuwde+GuS4BcY7v5xz+ArGWcRR63ct2z83MqQEn9ODr1/gAAAgA7szRpDDQIdFUQo9mkWg8xBA==xxc>
       """.data(using: .utf8)
 
-        return Messenger.live(environment)
-    }
-
-    private func setupAuthCallback(_ messenger: Messenger) {
-        authCallbacksCancellable = messenger.registerAuthCallbacks(
-            AuthCallbacks(handle: {
-                switch $0 {
-                case .confirm(contact: let contact, receptionId: _, ephemeralId: _, roundId: _):
-                    self.handleConfirm(from: contact)
-                case .request(contact: let contact, receptionId: _, ephemeralId: _, roundId: _):
-                    self.handleDirectRequest(from: contact)
-                case .reset(contact: let contact, receptionId: _, ephemeralId: _, roundId: _):
-                    self.handleReset(from: contact)
-                }
-            })
-        )
-    }
-
-    private func setupMessageCallback(_ messenger: Messenger) {
-        messageListenerCallbacksCancellable = messenger.registerMessageListener(.init(handle: {
-            guard let payload = try? Payload(with: $0.payload) else {
-                fatalError("Couldn't decode payload: \(String(data: $0.payload, encoding: .utf8) ?? "nil")")
-            }
-
-            try! self.database.saveMessage(.init(
-                networkId: $0.id,
-                senderId: $0.sender,
-                recipientId: messenger.e2e.get()!.getContact().getId(),
-                groupId: nil,
-                date: Date.fromTimestamp($0.timestamp),
-                status: .received,
-                isUnread: true,
-                text: payload.text,
-                replyMessageId: payload.reply?.messageId,
-                roundURL: $0.roundURL,
-                fileTransferId: nil
-            ))
-
-            if var contact = try? self.database.fetchContacts(.init(id: [$0.sender])).first {
-                contact.isRecent = false
-                try! self.database.saveContact(contact)
-            }
-        }))
-    }
-
-    private func listenToNetworkUpdates(_ messenger: Messenger) {
-        networkMonitor.start()
-        networkCallbacksCancellable = messenger.cMix.get()!.addHealthCallback(.init(handle: { [weak self] in
-            guard let self = self else { return }
-            self.networkMonitor.update($0)
-        }))
-    }
+    return Messenger.live(environment)
+  }
+
+  private func setupAuthCallback(_ messenger: Messenger) {
+    authCallbacksCancellable = messenger.registerAuthCallbacks(
+      AuthCallbacks(handle: {
+        switch $0 {
+        case .confirm(contact: let contact, receptionId: _, ephemeralId: _, roundId: _):
+          self.handleConfirm(from: contact)
+        case .request(contact: let contact, receptionId: _, ephemeralId: _, roundId: _):
+          self.handleDirectRequest(from: contact)
+        case .reset(contact: let contact, receptionId: _, ephemeralId: _, roundId: _):
+          self.handleReset(from: contact)
+        }
+      })
+    )
+  }
+
+  private func setupBackupCallback(_ messenger: Messenger) {
+    backupCallbackCancellable = messenger.registerBackupCallback(.init(handle: { [weak self] in
+      print(">>> Backup callback from bindings got called")
+      self?.backupService.updateBackup(data: $0)
+    }))
+  }
+
+  private func setupMessageCallback(_ messenger: Messenger) {
+    messageListenerCallbacksCancellable = messenger.registerMessageListener(.init(handle: {
+      guard let payload = try? Payload(with: $0.payload) else {
+        fatalError("Couldn't decode payload: \(String(data: $0.payload, encoding: .utf8) ?? "nil")")
+      }
+
+      try! self.database.saveMessage(.init(
+        networkId: $0.id,
+        senderId: $0.sender,
+        recipientId: messenger.e2e.get()!.getContact().getId(),
+        groupId: nil,
+        date: Date.fromTimestamp($0.timestamp),
+        status: .received,
+        isUnread: true,
+        text: payload.text,
+        replyMessageId: payload.reply?.messageId,
+        roundURL: $0.roundURL,
+        fileTransferId: nil
+      ))
+
+      if var contact = try? self.database.fetchContacts(.init(id: [$0.sender])).first {
+        contact.isRecent = false
+        try! self.database.saveContact(contact)
+      }
+    }))
+  }
+
+  private func listenToNetworkUpdates(_ messenger: Messenger) {
+    networkMonitor.start()
+    networkCallbacksCancellable = messenger.cMix.get()!.addHealthCallback(.init(handle: { [weak self] in
+      guard let self = self else { return }
+      self.networkMonitor.update($0)
+    }))
+  }
 }
diff --git a/Sources/MenuFeature/ViewModels/MenuViewModel.swift b/Sources/MenuFeature/ViewModels/MenuViewModel.swift
index ce8161fe4e1c248a0a841f8560751cba05be0213..9d56f10abf0cf3bde167b10c96f54e8663fa3a2b 100644
--- a/Sources/MenuFeature/ViewModels/MenuViewModel.swift
+++ b/Sources/MenuFeature/ViewModels/MenuViewModel.swift
@@ -33,8 +33,10 @@ final class MenuViewModel {
         )
 
         return Publishers.CombineLatest(
-            database.fetchContactsPublisher(contactsQuery).assertNoFailure(),
-            database.fetchGroupsPublisher(groupQuery).assertNoFailure()
+          database.fetchContactsPublisher(contactsQuery)
+            .replaceError(with: []),
+          database.fetchGroupsPublisher(groupQuery)
+            .replaceError(with: [])
         )
         .map { $0.0.count + $0.1.count }
         .eraseToAnyPublisher()
diff --git a/Sources/Models/BackupSettings.swift b/Sources/Models/BackupSettings.swift
index 89194c24e359664a54701e51b46799c3659604b9..d52cb1f0e33149b70a22337f56c23d6814d7f7be 100644
--- a/Sources/Models/BackupSettings.swift
+++ b/Sources/Models/BackupSettings.swift
@@ -29,7 +29,7 @@ public struct BackupSettings: Equatable, Codable {
         let settings = try? PropertyListDecoder().decode(BackupSettings.self, from: data)
         self.init(
             wifiOnlyBackup: settings?.wifiOnlyBackup ?? false,
-            automaticBackups: settings?.automaticBackups ?? false,
+            automaticBackups: settings?.automaticBackups ?? true,
             enabledService: settings?.enabledService,
             connectedServices: settings?.connectedServices ?? [],
             backups: settings?.backups ?? [:]
diff --git a/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift
index 7e6f3751cedcceb2ee077fa2c12b60a4c466c744..d7eb5db970117df0d24c0fe33a464bef841d141e 100644
--- a/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift
+++ b/Sources/ProfileFeature/ViewModels/ProfileCodeViewModel.swift
@@ -7,9 +7,8 @@ import XXClient
 import Foundation
 import InputField
 import CombineSchedulers
-import DependencyInjection
 import XXMessengerClient
-import BackupFeature
+import DependencyInjection
 
 struct ProfileCodeViewState: Equatable {
     var input: String = ""
@@ -19,7 +18,6 @@ struct ProfileCodeViewState: Equatable {
 
 final class ProfileCodeViewModel {
     @Dependency var messenger: Messenger
-    @Dependency var backupService: BackupService
 
     @KeyObject(.email, defaultValue: nil) var email: String?
     @KeyObject(.phone, defaultValue: nil) var phone: String?
@@ -82,8 +80,6 @@ final class ProfileCodeViewModel {
                     self.phone = self.confirmation.content
                 }
 
-                self.backupService.didUpdateFacts()
-
                 self.timer?.invalidate()
                 self.hudRelay.send(.none)
                 self.completionRelay.send(self.confirmation)
diff --git a/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift
index 252acd4974aa48cefed3a71b390d14fc62208d9c..1d01467d8e20b16aff653bb67e5a441292b802d6 100644
--- a/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift
+++ b/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift
@@ -4,114 +4,114 @@ import Shared
 import Models
 import Combine
 import Defaults
+import XXClient
 import Countries
 import Foundation
 import Permissions
-import XXClient
 import CombineSchedulers
 import DependencyInjection
 import XXMessengerClient
 
 enum ProfileNavigationRoutes {
-    case none
-    case library
-    case libraryPermission
+  case none
+  case library
+  case libraryPermission
 }
 
 struct ProfileViewState: Equatable {
-    var email: String?
-    var phone: String?
-    var photo: UIImage?
+  var email: String?
+  var phone: String?
+  var photo: UIImage?
 }
 
 final class ProfileViewModel {
-    @KeyObject(.avatar, defaultValue: nil) var avatar: Data?
-    @KeyObject(.email, defaultValue: nil) var emailStored: String?
-    @KeyObject(.phone, defaultValue: nil) var phoneStored: String?
-    @KeyObject(.username, defaultValue: nil) var username: String?
-    @KeyObject(.sharingEmail, defaultValue: false) var isEmailSharing: Bool
-    @KeyObject(.sharingPhone, defaultValue: false) var isPhoneSharing: Bool
+  @KeyObject(.avatar, defaultValue: nil) var avatar: Data?
+  @KeyObject(.email, defaultValue: nil) var emailStored: String?
+  @KeyObject(.phone, defaultValue: nil) var phoneStored: String?
+  @KeyObject(.username, defaultValue: nil) var username: String?
+  @KeyObject(.sharingEmail, defaultValue: false) var isEmailSharing: Bool
+  @KeyObject(.sharingPhone, defaultValue: false) var isPhoneSharing: Bool
 
-    @Dependency var messenger: Messenger
-    @Dependency private var permissions: PermissionHandling
+  @Dependency var messenger: Messenger
+  @Dependency private var permissions: PermissionHandling
 
-    var name: String { username! }
+  var name: String { username! }
 
-    var state: AnyPublisher<ProfileViewState, Never> { stateRelay.eraseToAnyPublisher() }
-    private let stateRelay = CurrentValueSubject<ProfileViewState, Never>(.init())
+  var state: AnyPublisher<ProfileViewState, Never> { stateRelay.eraseToAnyPublisher() }
+  private let stateRelay = CurrentValueSubject<ProfileViewState, Never>(.init())
 
-    var hud: AnyPublisher<HUDStatus, Never> { hudRelay.eraseToAnyPublisher() }
-    private let hudRelay = CurrentValueSubject<HUDStatus, Never>(.none)
+  var hud: AnyPublisher<HUDStatus, Never> { hudRelay.eraseToAnyPublisher() }
+  private let hudRelay = CurrentValueSubject<HUDStatus, Never>(.none)
 
-    var navigation: AnyPublisher<ProfileNavigationRoutes, Never> { navigationRoutes.eraseToAnyPublisher() }
-    private let navigationRoutes = PassthroughSubject<ProfileNavigationRoutes, Never>()
+  var navigation: AnyPublisher<ProfileNavigationRoutes, Never> { navigationRoutes.eraseToAnyPublisher() }
+  private let navigationRoutes = PassthroughSubject<ProfileNavigationRoutes, Never>()
 
-    var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler()
-
-    init() {
-        refresh()
-    }
+  var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler()
 
-    func refresh() {
-        var cleanPhone = phoneStored
+  init() {
+    refresh()
+  }
 
-        if let phone = cleanPhone {
-            let country = Country.findFrom(phone)
-            cleanPhone = "\(country.prefix)\(phone.dropLast(2))"
-        }
+  func refresh() {
+    var cleanPhone = phoneStored
 
-        stateRelay.value = .init(
-            email: emailStored,
-            phone: cleanPhone,
-            photo: avatar != nil ? UIImage(data: avatar!) : nil
-        )
+    if let phone = cleanPhone {
+      let country = Country.findFrom(phone)
+      cleanPhone = "\(country.prefix)\(phone.dropLast(2))"
     }
 
-    func didRequestLibraryAccess() {
-        if permissions.isPhotosAllowed {
-            navigationRoutes.send(.library)
-        } else {
-            navigationRoutes.send(.libraryPermission)
-        }
+    stateRelay.value = .init(
+      email: emailStored,
+      phone: cleanPhone,
+      photo: avatar != nil ? UIImage(data: avatar!) : nil
+    )
+  }
+
+  func didRequestLibraryAccess() {
+    if permissions.isPhotosAllowed {
+      navigationRoutes.send(.library)
+    } else {
+      navigationRoutes.send(.libraryPermission)
     }
+  }
 
-    func didNavigateSomewhere() {
-        navigationRoutes.send(.none)
-    }
+  func didNavigateSomewhere() {
+    navigationRoutes.send(.none)
+  }
 
-    func didChoosePhoto(_ photo: UIImage) {
-        stateRelay.value.photo = photo
-        avatar = photo.jpegData(compressionQuality: 0.0)
-    }
+  func didChoosePhoto(_ photo: UIImage) {
+    stateRelay.value.photo = photo
+    avatar = photo.jpegData(compressionQuality: 0.0)
+  }
+
+  func didTapDelete(isEmail: Bool) {
+    hudRelay.send(.on)
+
+    backgroundScheduler.schedule { [weak self] in
+      guard let self = self else { return }
 
-    func didTapDelete(isEmail: Bool) {
-        hudRelay.send(.on)
-
-        backgroundScheduler.schedule { [weak self] in
-            guard let self = self else { return }
-
-            do {
-                try self.messenger.ud.get()!.removeFact(
-                    .init(
-                        type: isEmail ? .email : .phone,
-                        value: isEmail ? self.emailStored! : self.phoneStored!
-                    )
-                )
-
-                if isEmail {
-                    self.emailStored = nil
-                    self.isEmailSharing = false
-                } else {
-                    self.phoneStored = nil
-                    self.isPhoneSharing = false
-                }
-
-                self.hudRelay.send(.none)
-                self.refresh()
-            } catch {
-                let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription)
-                self.hudRelay.send(.error(.init(content: xxError)))
-            }
+      do {
+        try self.messenger.ud.get()!.removeFact(
+          .init(
+            type: isEmail ? .email : .phone,
+            value: isEmail ? self.emailStored! : self.phoneStored!
+          )
+        )
+
+        if isEmail {
+          self.emailStored = nil
+          self.isEmailSharing = false
+        } else {
+          self.phoneStored = nil
+          self.isPhoneSharing = false
         }
+
+        self.hudRelay.send(.none)
+        self.refresh()
+      } catch {
+        let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription)
+        self.hudRelay.send(.error(.init(content: xxError)))
+      }
     }
+  }
 }
diff --git a/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift
index 1a3fb575a3978b2f2ab889ade23cc846b24fd8b1..e570e286c30e54f136873acf4feba2923f792748 100644
--- a/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift
+++ b/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift
@@ -33,7 +33,7 @@ final class RequestsFailedViewModel {
 
     init() {
         database.fetchContactsPublisher(.init(authStatus: [.requestFailed, .confirmationFailed]))
-            .assertNoFailure()
+        .replaceError(with: [])
             .map { data -> NSDiffableDataSourceSnapshot<Section, Request> in
                 var snapshot = NSDiffableDataSourceSnapshot<Section, Request>()
                 snapshot.appendSections([.appearing])
diff --git a/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift
index 7eacdc19544448e73ddcd75ce64f90e0f78364c4..fd1cc9b51dbf39625d22e709fb17c815586e131b 100644
--- a/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift
+++ b/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift
@@ -80,8 +80,13 @@ final class RequestsReceivedViewModel {
             isBanned: reportingStatus.isEnabled() ? false : nil
         )
 
-        let groupStream = database.fetchGroupsPublisher(groupsQuery).assertNoFailure()
-        let contactsStream = database.fetchContactsPublisher(contactsQuery).assertNoFailure()
+        let groupStream = database
+        .fetchGroupsPublisher(groupsQuery)
+        .replaceError(with: [])
+
+      let contactsStream = database
+        .fetchContactsPublisher(contactsQuery)
+        .replaceError(with: [])
 
         Publishers.CombineLatest3(
             groupStream,
@@ -212,7 +217,7 @@ final class RequestsReceivedViewModel {
     ) {
         if let info = try? database.fetchGroupInfos(.init(groupId: group.id)).first {
             database.fetchContactsPublisher(.init(id: Set(info.members.map(\.id))))
-                .assertNoFailure()
+            .replaceError(with: [])
                 .sink { members in
                     let withUsername = members
                         .filter { $0.username != nil }
diff --git a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift
index 6d9457b562e85d780f0abeec4ae227581a90ef8f..e23720943c3e900c1c322c2d717a4884a97c6d27 100644
--- a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift
+++ b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift
@@ -53,7 +53,7 @@ final class RequestsSentViewModel {
         )
 
         database.fetchContactsPublisher(query)
-            .assertNoFailure()
+        .replaceError(with: [])
             .removeDuplicates()
             .map { data -> NSDiffableDataSourceSnapshot<Section, RequestSent> in
                 var snapshot = NSDiffableDataSourceSnapshot<Section, RequestSent>()
diff --git a/Sources/RestoreFeature/Controllers/RestoreController.swift b/Sources/RestoreFeature/Controllers/RestoreController.swift
index 5ba058c634a7e790927794f6a981a91368acee05..83af547638a6b8ec1808ec234f76adb801fd44ba 100644
--- a/Sources/RestoreFeature/Controllers/RestoreController.swift
+++ b/Sources/RestoreFeature/Controllers/RestoreController.swift
@@ -1,8 +1,8 @@
 import UIKit
 import Models
 import Shared
-import DrawerFeature
 import Combine
+import DrawerFeature
 import DependencyInjection
 
 public final class RestoreController: UIViewController {
@@ -56,9 +56,13 @@ public final class RestoreController: UIViewController {
                 screenView.updateFor(step: $0)
 
                 if $0 == .wrongPass {
-                    coordinator.toPassphrase(from: self) { pass in
-                        self.viewModel.retryWith(passphrase: pass)
+                  coordinator.toPassphrase(
+                    from: self,
+                    cancelClosure: { self.dismiss(animated: true) },
+                    passphraseClosure: { pwd in
+                      self.viewModel.retryWith(passphrase: pwd)
                     }
+                  )
 
                     return
                 }
@@ -81,9 +85,13 @@ public final class RestoreController: UIViewController {
         screenView.restoreButton
             .publisher(for: .touchUpInside)
             .sink { [unowned self] in
-                coordinator.toPassphrase(from: self) { passphrase in
-                    self.viewModel.didTapRestore(passphrase: passphrase)
+              coordinator.toPassphrase(
+                from: self,
+                cancelClosure: { self.dismiss(animated: true) },
+                passphraseClosure: { pwd in
+                  self.viewModel.didTapRestore(passphrase: pwd)
                 }
+              )
             }.store(in: &cancellables)
     }
 
diff --git a/Sources/RestoreFeature/Controllers/RestorePassphraseController.swift b/Sources/RestoreFeature/Controllers/RestorePassphraseController.swift
index 4d19e356729508ea5b688bb8435e09c602b5c8a6..67dd450b68baef63bccc07257c652705288d97d0 100644
--- a/Sources/RestoreFeature/Controllers/RestorePassphraseController.swift
+++ b/Sources/RestoreFeature/Controllers/RestorePassphraseController.swift
@@ -2,92 +2,71 @@ import UIKit
 import Shared
 import Combine
 import InputField
-import ScrollViewController
 
 public final class RestorePassphraseController: UIViewController {
-    lazy private var screenView = RestorePassphraseView()
-
-    private var passphrase = "" {
-        didSet {
-            switch Validator.backupPassphrase.validate(passphrase) {
-            case .success:
-                screenView.continueButton.isEnabled = true
-            case .failure:
-                screenView.continueButton.isEnabled = false
-            }
-        }
-    }
-
-    private let completion: StringClosure
-    private var cancellables = Set<AnyCancellable>()
-    private let keyboardListener = KeyboardFrameChangeListener(notificationCenter: .default)
-
-    public init(_ completion: @escaping StringClosure) {
-        self.completion = completion
-        super.init(nibName: nil, bundle: nil)
-    }
-
-    required init?(coder: NSCoder) { nil }
-
-    public override func loadView() {
-        let view = UIView()
-        view.addSubview(screenView)
-
-        screenView.snp.makeConstraints { make in
-            make.top.equalToSuperview()
-            make.left.equalToSuperview()
-            make.right.equalToSuperview()
-            make.bottom.equalToSuperview().offset(0)
-        }
-
-        self.view = view
-    }
-
-    public override func viewDidLoad() {
-        super.viewDidLoad()
-        setupKeyboard()
-        setupBindings()
-
+  lazy private var screenView = RestorePassphraseView()
+
+  private var passphrase = "" {
+    didSet {
+      switch Validator.backupPassphrase.validate(passphrase) {
+      case .success:
+        screenView.continueButton.isEnabled = true
+      case .failure:
         screenView.continueButton.isEnabled = false
+      }
     }
-
-    private func setupKeyboard() {
-        keyboardListener.keyboardFrameWillChange = { [weak self] keyboard in
-            guard let self = self else { return }
-
-            let inset = self.view.frame.height - self.view.convert(keyboard.frame, from: nil).minY
-
-            self.screenView.snp.updateConstraints {
-                $0.bottom.equalToSuperview().offset(-inset)
-            }
-
-            self.view.setNeedsLayout()
-
-            UIView.animate(withDuration: keyboard.animationDuration) {
-                self.view.layoutIfNeeded()
-            }
+  }
+
+  private let cancelClosure: EmptyClosure
+  private let stringClosure: StringClosure
+  private var cancellables = Set<AnyCancellable>()
+
+  public init(
+    _ cancelClosure: @escaping EmptyClosure,
+    _ stringClosure: @escaping StringClosure
+  ) {
+    self.stringClosure = stringClosure
+    self.cancelClosure = cancelClosure
+    super.init(nibName: nil, bundle: nil)
+  }
+
+  required init?(coder: NSCoder) { nil }
+
+  public override func loadView() {
+    view = screenView
+  }
+
+  public override func viewDidLoad() {
+    super.viewDidLoad()
+
+    screenView
+      .inputField
+      .returnPublisher
+      .sink { [unowned self] in
+        screenView.inputField.endEditing(true)
+      }.store(in: &cancellables)
+
+    screenView
+      .inputField
+      .textPublisher
+      .sink { [unowned self] in
+        passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines)
+      }.store(in: &cancellables)
+
+    screenView
+      .continueButton
+      .publisher(for: .touchUpInside)
+      .sink { [unowned self] in
+        dismiss(animated: true) {
+          self.stringClosure(self.passphrase)
         }
-    }
-
-    private func setupBindings() {
-        screenView.inputField.returnPublisher
-            .sink { [unowned self] in screenView.inputField.endEditing(true) }
-            .store(in: &cancellables)
-
-        screenView.cancelButton
-            .publisher(for: .touchUpInside)
-            .sink { [unowned self] in dismiss(animated: true) }
-            .store(in: &cancellables)
-
-        screenView.inputField
-            .textPublisher
-            .sink { [unowned self] in passphrase = $0.trimmingCharacters(in: .whitespacesAndNewlines) }
-            .store(in: &cancellables)
-
-        screenView.continueButton
-            .publisher(for: .touchUpInside)
-            .sink { [unowned self] in
-                dismiss(animated: true, completion: { self.completion(self.passphrase) })
-            }.store(in: &cancellables)
-    }
+      }.store(in: &cancellables)
+
+    screenView
+      .cancelButton
+      .publisher(for: .touchUpInside)
+      .sink { [unowned self] in
+        dismiss(animated: true)
+      }.store(in: &cancellables)
+  }
 }
diff --git a/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift b/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift
index b5f5d05716247e1fa164a935c8bc72f25f5b5969..83c698fb30595098474fcf5e324f3723eee4cf59 100644
--- a/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift
+++ b/Sources/RestoreFeature/Coordinator/RestoreCoordinator.swift
@@ -2,66 +2,96 @@ import UIKit
 import Models
 import Shared
 import Presentation
+import ScrollViewController
 
 public protocol RestoreCoordinating {
-    func toChats(from: UIViewController)
-    func toSuccess(from: UIViewController)
-    func toDrawer(_: UIViewController, from: UIViewController)
-    func toPassphrase(from: UIViewController, _: @escaping StringClosure)
-    func toRestore(with: RestoreSettings, from: UIViewController)
+  func toChats(from: UIViewController)
+  func toSuccess(from: UIViewController)
+  func toDrawer(_: UIViewController, from: UIViewController)
+  func toRestore(with: RestoreSettings, from: UIViewController)
+
+  func toPassphrase(
+    from: UIViewController,
+    cancelClosure: @escaping EmptyClosure,
+    passphraseClosure: @escaping StringClosure
+  )
 }
 
 public struct RestoreCoordinator: RestoreCoordinating {
-    var pushPresenter: Presenting = PushPresenter()
-    var bottomPresenter: Presenting = BottomPresenter()
-    var replacePresenter: Presenting = ReplacePresenter()
+  var pushPresenter: Presenting = PushPresenter()
+  var bottomPresenter: Presenting = BottomPresenter()
+  var replacePresenter: Presenting = ReplacePresenter()
+  var fullscreenPresenter: Presenting = FullscreenPresenter()
+
+  var successFactory: () -> UIViewController
+  var chatListFactory: () -> UIViewController
+  var restoreFactory: (RestoreSettings) -> UIViewController
 
-    var successFactory: () -> UIViewController
-    var chatListFactory: () -> UIViewController
-    var restoreFactory: (RestoreSettings) -> UIViewController
-    var passphraseFactory: (@escaping StringClosure) -> UIViewController
+  var passphraseFactory: (
+    @escaping EmptyClosure,
+    @escaping StringClosure
+  ) -> UIViewController
 
-    public init(
-        successFactory: @escaping () -> UIViewController,
-        chatListFactory: @escaping () -> UIViewController,
-        restoreFactory: @escaping (RestoreSettings) -> UIViewController,
-        passphraseFactory: @escaping (@escaping StringClosure) -> UIViewController
-    ) {
-        self.successFactory = successFactory
-        self.restoreFactory = restoreFactory
-        self.chatListFactory = chatListFactory
-        self.passphraseFactory = passphraseFactory
-    }
+  public init(
+    successFactory: @escaping () -> UIViewController,
+    chatListFactory: @escaping () -> UIViewController,
+    restoreFactory: @escaping (RestoreSettings) -> UIViewController,
+    passphraseFactory: @escaping (
+      @escaping EmptyClosure,
+      @escaping StringClosure
+    ) -> UIViewController
+  ) {
+    self.successFactory = successFactory
+    self.restoreFactory = restoreFactory
+    self.chatListFactory = chatListFactory
+    self.passphraseFactory = passphraseFactory
+  }
 }
 
 public extension RestoreCoordinator {
-    func toRestore(
-        with settings: RestoreSettings,
-        from parent: UIViewController
-    ) {
-        let screen = restoreFactory(settings)
-        pushPresenter.present(screen, from: parent)
-    }
+  func toRestore(
+    with settings: RestoreSettings,
+    from parent: UIViewController
+  ) {
+    let screen = restoreFactory(settings)
+    pushPresenter.present(screen, from: parent)
+  }
+
+  func toChats(from parent: UIViewController) {
+    let screen = chatListFactory()
+    replacePresenter.present(screen, from: parent)
+  }
 
-    func toChats(from parent: UIViewController) {
-        let screen = chatListFactory()
-        replacePresenter.present(screen, from: parent)
-    }
+  func toSuccess(from parent: UIViewController) {
+    let screen = successFactory()
+    replacePresenter.present(screen, from: parent)
+  }
 
-    func toSuccess(from parent: UIViewController) {
-        let screen = successFactory()
-        replacePresenter.present(screen, from: parent)
-    }
+  func toDrawer(_ drawer: UIViewController, from parent: UIViewController) {
+    bottomPresenter.present(drawer, from: parent)
+  }
+
+  func toPassphrase(
+    from parent: UIViewController,
+    cancelClosure: @escaping EmptyClosure,
+    passphraseClosure: @escaping StringClosure
+  ) {
+    let screen = passphraseFactory(cancelClosure, passphraseClosure)
+    let target = ScrollViewController.embedding(screen)
+    fullscreenPresenter.present(target, from: parent)
+  }
+}
 
-    func toDrawer(_ drawer: UIViewController, from parent: UIViewController) {
-        bottomPresenter.present(drawer, from: parent)
-    }
+extension ScrollViewController {
+  static func embedding(_ viewController: UIViewController) -> ScrollViewController {
+    let scrollViewController = ScrollViewController()
+    scrollViewController.addChild(viewController)
+    scrollViewController.contentView = viewController.view
+    scrollViewController.wrapperView.handlesTouchesOutsideContent = false
+    scrollViewController.wrapperView.alignContentToBottom = true
+    scrollViewController.scrollView.bounces = false
 
-    func toPassphrase(
-        from parent: UIViewController,
-        _ completion: @escaping StringClosure
-    ) {
-        let screen = passphraseFactory(completion)
-        bottomPresenter.present(screen, from: parent)
-    }
+    viewController.didMove(toParent: scrollViewController)
+    return scrollViewController
+  }
 }
diff --git a/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift b/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift
index ec1895dc2721ab6d695d76d859f36033ebaf1fcd..bbf4daa2d9b4c714c763ffa7f8ab981139110125 100644
--- a/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift
+++ b/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift
@@ -12,171 +12,213 @@ import iCloudFeature
 import DropboxFeature
 import GoogleDriveFeature
 
+import XXModels
+import XXDatabase
+
 import XXClient
 import XXMessengerClient
 
 enum RestorationStep {
-    case idle(CloudService, BackupModel?)
-    case downloading(Float, Float)
-    case failDownload(Error)
-    case wrongPass
-    case parsingData
-    case done
+  case idle(CloudService, BackupModel?)
+  case downloading(Float, Float)
+  case failDownload(Error)
+  case wrongPass
+  case parsingData
+  case done
 }
 
 extension RestorationStep: Equatable {
-    static func ==(lhs: RestorationStep, rhs: RestorationStep) -> Bool {
-        switch (lhs, rhs) {
-        case (.done, .done), (.wrongPass, .wrongPass):
-            return true
-        case let (.failDownload(a), .failDownload(b)):
-            return a.localizedDescription == b.localizedDescription
-        case let (.downloading(a, b), .downloading(c, d)):
-            return a == c && b == d
-        case (.idle, _), (.downloading, _), (.parsingData, _),
-            (.done, _), (.failDownload, _), (.wrongPass, _):
-            return false
-        }
+  static func ==(lhs: RestorationStep, rhs: RestorationStep) -> Bool {
+    switch (lhs, rhs) {
+    case (.done, .done), (.wrongPass, .wrongPass):
+      return true
+    case let (.failDownload(a), .failDownload(b)):
+      return a.localizedDescription == b.localizedDescription
+    case let (.downloading(a, b), .downloading(c, d)):
+      return a == c && b == d
+    case (.idle, _), (.downloading, _), (.parsingData, _),
+      (.done, _), (.failDownload, _), (.wrongPass, _):
+      return false
     }
+  }
 }
 
 final class RestoreViewModel {
-    @Dependency var messenger: Messenger
-    @Dependency private var sftpService: SFTPService
-    @Dependency private var iCloudService: iCloudInterface
-    @Dependency private var dropboxService: DropboxInterface
-    @Dependency private var googleService: GoogleDriveInterface
-
-    @KeyObject(.username, defaultValue: nil) var username: String?
-    @KeyObject(.phone, defaultValue: nil) var phone: String?
-    @KeyObject(.email, defaultValue: nil) var email: String?
-
-    var step: AnyPublisher<RestorationStep, Never> {
-        stepRelay.eraseToAnyPublisher()
+  @Dependency var database: Database
+  @Dependency var messenger: Messenger
+  @Dependency var sftpService: SFTPService
+  @Dependency var iCloudService: iCloudInterface
+  @Dependency var dropboxService: DropboxInterface
+  @Dependency var googleService: GoogleDriveInterface
+
+  @KeyObject(.username, defaultValue: nil) var username: String?
+  @KeyObject(.phone, defaultValue: nil) var phone: String?
+  @KeyObject(.email, defaultValue: nil) var email: String?
+
+  var step: AnyPublisher<RestorationStep, Never> {
+    stepRelay.eraseToAnyPublisher()
+  }
+
+  // TO REFACTOR:
+  //
+  private var pendingData: Data?
+
+  private var passphrase: String!
+  private let settings: RestoreSettings
+  private let stepRelay: CurrentValueSubject<RestorationStep, Never>
+
+  init(settings: RestoreSettings) {
+    self.settings = settings
+    self.stepRelay = .init(.idle(settings.cloudService, settings.backup))
+  }
+
+  func retryWith(passphrase: String) {
+    self.passphrase = passphrase
+    continueRestoring(data: pendingData!)
+  }
+
+  func didTapRestore(passphrase: String) {
+    self.passphrase = passphrase
+
+    guard let backup = settings.backup else { fatalError() }
+
+    stepRelay.send(.downloading(0.0, backup.size))
+
+    switch settings.cloudService {
+    case .drive:
+      downloadBackupForDrive(backup)
+    case .dropbox:
+      downloadBackupForDropbox(backup)
+    case .icloud:
+      downloadBackupForiCloud(backup)
+    case .sftp:
+      downloadBackupForSFTP(backup)
     }
-
-    // TO REFACTOR:
-    //
-    private var pendingData: Data?
-
-    private var passphrase: String!
-    private let settings: RestoreSettings
-    private let stepRelay: CurrentValueSubject<RestorationStep, Never>
-
-    init(settings: RestoreSettings) {
-        self.settings = settings
-        self.stepRelay = .init(.idle(settings.cloudService, settings.backup))
+  }
+
+  private func downloadBackupForSFTP(_ backup: BackupModel) {
+    sftpService.downloadBackup(path: backup.id) { [weak self] in
+      guard let self = self else { return }
+      self.stepRelay.send(.downloading(backup.size, backup.size))
+
+      switch $0 {
+      case .success(let data):
+        self.continueRestoring(data: data)
+      case .failure(let error):
+        self.stepRelay.send(.failDownload(error))
+      }
     }
-
-    func retryWith(passphrase: String) {
-        self.passphrase = passphrase
-        continueRestoring(data: pendingData!)
+  }
+
+  private func downloadBackupForDropbox(_ backup: BackupModel) {
+    dropboxService.downloadBackup(backup.id) { [weak self] in
+      guard let self = self else { return }
+      self.stepRelay.send(.downloading(backup.size, backup.size))
+
+      switch $0 {
+      case .success(let data):
+        self.continueRestoring(data: data)
+      case .failure(let error):
+        self.stepRelay.send(.failDownload(error))
+      }
     }
-
-    func didTapRestore(passphrase: String) {
-        self.passphrase = passphrase
-
-        guard let backup = settings.backup else { fatalError() }
-
-        stepRelay.send(.downloading(0.0, backup.size))
-
-        switch settings.cloudService {
-        case .drive:
-            downloadBackupForDrive(backup)
-        case .dropbox:
-            downloadBackupForDropbox(backup)
-        case .icloud:
-            downloadBackupForiCloud(backup)
-        case .sftp:
-            downloadBackupForSFTP(backup)
-        }
-    }
-
-    private func downloadBackupForSFTP(_ backup: BackupModel) {
-        sftpService.downloadBackup(path: backup.id) { [weak self] in
-            guard let self = self else { return }
-            self.stepRelay.send(.downloading(backup.size, backup.size))
-
-            switch $0 {
-            case .success(let data):
-                self.continueRestoring(data: data)
-            case .failure(let error):
-                self.stepRelay.send(.failDownload(error))
-            }
-        }
+  }
+
+  private func downloadBackupForiCloud(_ backup: BackupModel) {
+    iCloudService.downloadBackup(backup.id) { [weak self] in
+      guard let self = self else { return }
+      self.stepRelay.send(.downloading(backup.size, backup.size))
+
+      switch $0 {
+      case .success(let data):
+        self.continueRestoring(data: data)
+      case .failure(let error):
+        self.stepRelay.send(.failDownload(error))
+      }
     }
-
-    private func downloadBackupForDropbox(_ backup: BackupModel) {
-        dropboxService.downloadBackup(backup.id) { [weak self] in
-            guard let self = self else { return }
-            self.stepRelay.send(.downloading(backup.size, backup.size))
-
-            switch $0 {
-            case .success(let data):
-                self.continueRestoring(data: data)
-            case .failure(let error):
-                self.stepRelay.send(.failDownload(error))
-            }
-        }
+  }
+
+  private func downloadBackupForDrive(_ backup: BackupModel) {
+    googleService.downloadBackup(backup.id) { [weak self] in
+      if let stepRelay = self?.stepRelay {
+        stepRelay.send(.downloading($0, backup.size))
+      }
+    } _: { [weak self] in
+      guard let self = self else { return }
+
+      switch $0 {
+      case .success(let data):
+        self.continueRestoring(data: data)
+      case .failure(let error):
+        self.stepRelay.send(.failDownload(error))
+      }
     }
-
-    private func downloadBackupForiCloud(_ backup: BackupModel) {
-        iCloudService.downloadBackup(backup.id) { [weak self] in
-            guard let self = self else { return }
-            self.stepRelay.send(.downloading(backup.size, backup.size))
-
-            switch $0 {
-            case .success(let data):
-                self.continueRestoring(data: data)
-            case .failure(let error):
-                self.stepRelay.send(.failDownload(error))
-            }
+  }
+
+  private func continueRestoring(data: Data) {
+    stepRelay.send(.parsingData)
+
+    DispatchQueue.global().async { [weak self] in
+      guard let self = self else { return }
+
+      do {
+        print(">>> Calling messenger destroy")
+        try self.messenger.destroy()
+
+        print(">>> Calling restore backup")
+        let result = try self.messenger.restoreBackup(
+          backupData: data,
+          backupPassphrase: self.passphrase
+        )
+
+        self.username = result.restoredParams.username
+        let facts = try self.messenger.ud.tryGet().getFacts()
+        self.email = facts.get(.email)?.value
+        self.phone = facts.get(.phone)?.value
+
+        print(">>> Calling wait for network")
+        try self.messenger.waitForNetwork()
+
+        print(">>> Calling waitForNodes")
+        try self.messenger.waitForNodes(
+          targetRatio: 0.5,
+          sleepInterval: 3,
+          retries: 15,
+          onProgress: { print(">>> \($0)") }
+        )
+
+        print(">>> Calling multilookup")
+        let multilookup = try self.messenger.lookupContacts(ids: result.restoredContacts)
+
+        multilookup.contacts.forEach {
+          print(">>> Found \(try! $0.getFact(.username)?.value)")
+
+          try! self.database.saveContact(.init(
+            id: try $0.getId(),
+            marshaled: $0.data,
+            username: try? $0.getFact(.username)?.value,
+            email: nil,
+            phone: nil,
+            nickname: try? $0.getFact(.username)?.value,
+            photo: nil,
+            authStatus: .friend,
+            isRecent: false,
+            isBlocked: false,
+            isBanned: false,
+            createdAt: Date()
+          ))
         }
-    }
 
-    private func downloadBackupForDrive(_ backup: BackupModel) {
-        googleService.downloadBackup(backup.id) { [weak self] in
-            if let stepRelay = self?.stepRelay {
-                stepRelay.send(.downloading($0, backup.size))
-            }
-        } _: { [weak self] in
-            guard let self = self else { return }
-
-            switch $0 {
-            case .success(let data):
-                self.continueRestoring(data: data)
-            case .failure(let error):
-                self.stepRelay.send(.failDownload(error))
-            }
+        multilookup.errors.forEach {
+          print(">>> Error: \($0.localizedDescription)")
         }
-    }
-
-    private func continueRestoring(data: Data) {
-        stepRelay.send(.parsingData)
 
-        DispatchQueue.global().async { [weak self] in
-            guard let self = self else { return }
-
-            do {
-                let result = try self.messenger.restoreBackup(
-                    backupData: data,
-                    backupPassphrase: self.passphrase
-                )
-
-                print(">>> Finished restoring on bindings")
-
-                self.username = result.restoredParams.username
-                self.email = result.restoredParams.email
-                self.phone = result.restoredParams.phone
-
-                //let restoreContacts = result.restoredContacts
-
-                self.stepRelay.send(.done)
-            } catch {
-                print(">>> Error on restoration: \(error.localizedDescription)")
-                self.pendingData = data
-                self.stepRelay.send(.wrongPass)
-            }
-        }
+        self.stepRelay.send(.done)
+      } catch {
+        print(">>> Error on restoration: \(error.localizedDescription)")
+        self.pendingData = data
+        self.stepRelay.send(.wrongPass)
+      }
     }
+  }
 }
diff --git a/Sources/RestoreFeature/Views/RestorePassphraseView.swift b/Sources/RestoreFeature/Views/RestorePassphraseView.swift
index d54fbd4a7577fe1f13d1813cf2047f3956eb8832..6dfaa4d716ae2a354ab9afa4a0d9563df97cc3f8 100644
--- a/Sources/RestoreFeature/Views/RestorePassphraseView.swift
+++ b/Sources/RestoreFeature/Views/RestorePassphraseView.swift
@@ -3,65 +3,78 @@ import Shared
 import InputField
 
 final class RestorePassphraseView: UIView {
-    let titleLabel = UILabel()
-    let subtitleLabel = UILabel()
-    let inputField = InputField()
-    let stackView = UIStackView()
-    let continueButton = CapsuleButton()
-    let cancelButton = CapsuleButton()
+  let titleLabel = UILabel()
+  let subtitleLabel = UILabel()
+  let inputField = InputField()
+  let stackView = UIStackView()
+  let continueButton = CapsuleButton()
+  let cancelButton = CapsuleButton()
 
-    init() {
-        super.init(frame: .zero)
-        setup()
-    }
-
-    required init?(coder: NSCoder) { nil }
+  init() {
+    super.init(frame: .zero)
+    layer.cornerRadius = 40
+    backgroundColor = Asset.neutralWhite.color
+    layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
 
-    private func setup() {
-        layer.cornerRadius = 40
-        backgroundColor = Asset.neutralWhite.color
-        layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
+    setupInput()
+    setupLabels()
+    setupButtons()
+    setupStackView()
+  }
 
-        subtitleLabel.numberOfLines = 0
-        titleLabel.textColor = Asset.neutralActive.color
-        subtitleLabel.textColor = Asset.neutralActive.color
+  required init?(coder: NSCoder) { nil }
 
-        inputField.setup(
-            style: .regular,
-            title: "Passphrase",
-            placeholder: "* * * * * *",
-            subtitleColor: Asset.neutralDisabled.color
-        )
+  private func setupInput() {
+    inputField.setup(
+      style: .regular,
+      title: Localized.Backup.Passphrase.Input.title,
+      placeholder: Localized.Backup.Passphrase.Input.placeholder,
+      rightView: .toggleSecureEntry,
+      subtitleColor: Asset.neutralDisabled.color,
+      allowsEmptySpace: false,
+      autocapitalization: .none,
+      contentType: .password
+    )
+  }
 
-        titleLabel.text = "Backup password"
-        titleLabel.textAlignment = .left
-        titleLabel.font = Fonts.Mulish.bold.font(size: 26.0)
+  private func setupLabels() {
+    titleLabel.textAlignment = .left
+    titleLabel.textColor = Asset.neutralActive.color
+    titleLabel.font = Fonts.Mulish.bold.font(size: 26.0)
+    titleLabel.text = Localized.Backup.Restore.Passphrase.title
 
-        subtitleLabel.text = "Please enter your backup password that you used when you did the backup setup"
-        subtitleLabel.textAlignment = .left
-        subtitleLabel.font = Fonts.Mulish.regular.font(size: 16.0)
+    subtitleLabel.numberOfLines = 0
+    subtitleLabel.textAlignment = .left
+    subtitleLabel.textColor = Asset.neutralActive.color
+    subtitleLabel.font = Fonts.Mulish.regular.font(size: 16.0)
+    subtitleLabel.text = Localized.Backup.Restore.Passphrase.subtitle
+  }
 
-        continueButton.setStyle(.brandColored)
-        continueButton.setTitle("Continue", for: .normal)
+  private func setupButtons() {
+    cancelButton.setStyle(.seeThrough)
+    cancelButton.setTitle(Localized.Backup.Passphrase.cancel, for: .normal)
 
-        cancelButton.setStyle(.seeThrough)
-        cancelButton.setTitle("Cancel", for: .normal)
+    continueButton.isEnabled = false
+    continueButton.setStyle(.brandColored)
+    continueButton.setTitle(Localized.Backup.Passphrase.continue, for: .normal)
+  }
 
-        stackView.spacing = 20
-        stackView.axis = .vertical
-        stackView.addArrangedSubview(titleLabel)
-        stackView.addArrangedSubview(subtitleLabel)
-        stackView.addArrangedSubview(inputField)
-        stackView.addArrangedSubview(continueButton)
-        stackView.addArrangedSubview(cancelButton)
+  private func setupStackView() {
+    stackView.spacing = 20
+    stackView.axis = .vertical
+    stackView.addArrangedSubview(titleLabel)
+    stackView.addArrangedSubview(subtitleLabel)
+    stackView.addArrangedSubview(inputField)
+    stackView.addArrangedSubview(continueButton)
+    stackView.addArrangedSubview(cancelButton)
 
-        addSubview(stackView)
+    addSubview(stackView)
 
-        stackView.snp.makeConstraints { make in
-            make.top.equalToSuperview().offset(60)
-            make.left.equalToSuperview().offset(50)
-            make.right.equalToSuperview().offset(-50)
-            make.bottom.equalToSuperview().offset(-70)
-        }
+    stackView.snp.makeConstraints {
+      $0.top.equalToSuperview().offset(60)
+      $0.left.equalToSuperview().offset(50)
+      $0.right.equalToSuperview().offset(-50)
+      $0.bottom.equalToSuperview().offset(-70)
     }
+  }
 }
diff --git a/Sources/Shared/AutoGenerated/Strings.swift b/Sources/Shared/AutoGenerated/Strings.swift
index 207d794348897f39bcbbf7f0d0278ad933a8ca75..4ced950dd511ef22ad7f25f4ddb1c1192587ed7e 100644
--- a/Sources/Shared/AutoGenerated/Strings.swift
+++ b/Sources/Shared/AutoGenerated/Strings.swift
@@ -290,6 +290,14 @@ public enum Localized {
         public static let title = Localized.tr("Localizable", "backup.passphrase.input.title")
       }
     }
+    public enum Restore {
+      public enum Passphrase {
+        /// Please enter your backup password that you used when you did the backup setup
+        public static let subtitle = Localized.tr("Localizable", "backup.restore.passphrase.subtitle")
+        /// Backup password
+        public static let title = Localized.tr("Localizable", "backup.restore.passphrase.title")
+      }
+    }
     public enum Setup {
       /// Setup your #backup service#.
       public static let title = Localized.tr("Localizable", "backup.setup.title")
diff --git a/Sources/Shared/Resources/en.lproj/Localizable.strings b/Sources/Shared/Resources/en.lproj/Localizable.strings
index 0f0ebae69110ac84168b49e9579bc87d02073dc5..3dfbb4a622ecde1973cc79fb0e692d78add2cefa 100644
--- a/Sources/Shared/Resources/en.lproj/Localizable.strings
+++ b/Sources/Shared/Resources/en.lproj/Localizable.strings
@@ -668,6 +668,10 @@
 = "Set password and continue";
 "backup.passphrase.cancel"
 = "Cancel";
+"backup.restore.passphrase.title"
+= "Backup password";
+"backup.restore.passphrase.subtitle"
+= "Please enter your backup password that you used when you did the backup setup";
 
 "backup.iCloud"
 = "iCloud";
diff --git a/Sources/iCloudFeature/iCloudService.swift b/Sources/iCloudFeature/iCloudService.swift
index 0c766b9f963972246982d5e396aa476a0467cb20..9c804211e759b7901af2f2917e8d071d9de2ffa2 100644
--- a/Sources/iCloudFeature/iCloudService.swift
+++ b/Sources/iCloudFeature/iCloudService.swift
@@ -18,8 +18,7 @@ public struct iCloudService: iCloudInterface {
 
     public func downloadMetadata(_ completion: @escaping (Result<iCloudMetadata?, Error>) -> Void) {
         guard let documentsProvider = documentsProvider else {
-            // TODO: Use some generic error
-            fatalError()
+            fatalError("ICloud wasn't set properly, force crashed due to lack of fallback")
         }
 
         documentsProvider.contentsOfDirectory(path: "/", completionHandler: { contents, error in
diff --git a/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved b/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 8e2d54ed77fa92338542461e10b1aeb094c77987..b1639bc2fd1a68e6e0ac6a9ed6ba62404e56b029 100644
--- a/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -99,15 +99,6 @@
         "version" : "1.3.0"
       }
     },
-    {
-      "identity" : "elixxir-dapps-sdk-swift",
-      "kind" : "remoteSourceControl",
-      "location" : "https://git.xx.network/elixxir/elixxir-dapps-sdk-swift",
-      "state" : {
-        "branch" : "development",
-        "revision" : "d011281416542b38e302f3ac59b6c658d6438caa"
-      }
-    },
     {
       "identity" : "fileprovider",
       "kind" : "remoteSourceControl",