From 561ccc0689f3e9399d9d7265cb501d0548e9f8c3 Mon Sep 17 00:00:00 2001 From: Lukas Korba Date: Thu, 1 Jun 2023 16:05:35 +0200 Subject: [PATCH] [#750] Batch of Dependency Packages Vol IV (#756) Last 4 dependencies modularized - URIParser - UserPreferencesStorage - WalletConfigProvider - WalletStorage --- modules/Package.swift | 54 ++++- .../Dependencies/URIParser/URIParser.swift | 18 ++ .../URIParser/URIParserInterface.swift | 7 +- .../URIParser/URIParserLive.swift | 16 ++ .../URIParser/URIParserTest.swift | 2 +- .../UserPreferencesStorage.swift | 32 +-- .../UserPreferencesStorageInterface.swift | 38 ++++ .../UserPreferencesStorageLive.swift | 4 +- .../UserPreferencesStorageMocks.swift | 4 +- .../UserDefaultsWalletConfigStorage.swift | 25 ++- .../WalletConfigProvider.swift | 13 +- .../WalletConfigProviderInterface.swift | 9 +- .../WalletConfigProviderLiveKey.swift | 6 +- .../WalletConfigProviderTestKey.swift | 5 +- .../WalletStorage/WalletStorage.swift | 45 ++-- .../WalletStorageInterface.swift | 33 ++- .../WalletStorage/WalletStorageLiveKey.swift | 4 +- .../WalletStorage/WalletStorageTestKey.swift | 4 +- modules/Sources/Models/StoredWallet.swift | 45 ++++ .../Sources}/Models/WalletConfig.swift | 18 +- secant.xcodeproj/project.pbxproj | 202 +++++------------- secant/Dependencies/URIParser/URIParser.swift | 23 -- .../URIParser/URIParserLive.swift | 18 -- .../UserPreferencesStorageInterface.swift | 38 ---- .../BalanceBreakdownStore.swift | 1 + .../ImportWallet/ImportWalletStore.swift | 1 + .../OnboardingFlow/OnboardingFlowStore.swift | 1 + .../Views/OnboardingHeaderView.swift | 1 + secant/Features/Root/RootDebug.swift | 1 + secant/Features/Root/RootStore.swift | 4 + secant/Features/Root/RootView.swift | 1 + secant/Features/Scan/ScanStore.swift | 3 +- secant/Models/StoredWallet.swift | 32 --- .../HomeTests/HomeFeatureFlagTests.swift | 2 + .../OnboardingFlowFeatureFlagTests.swift | 4 +- ...PhraseValidationFlowFeatureFlagTests.swift | 1 + secantTests/RootTests/RootTests.swift | 1 + secantTests/ScanTests/ScanTests.swift | 4 +- secantTests/SendTests/SendTests.swift | 2 + secantTests/SettingsTests/SettingsTests.swift | 1 + .../UtilTests/SecItemClientTests.swift | 2 + .../UserPreferencesStorageTests.swift | 1 + .../UtilTests/WalletStorageTests.swift | 2 + .../WalletConfigProviderTests.swift | 4 +- 44 files changed, 374 insertions(+), 358 deletions(-) create mode 100644 modules/Sources/Dependencies/URIParser/URIParser.swift rename {secant => modules/Sources}/Dependencies/URIParser/URIParserInterface.swift (64%) create mode 100644 modules/Sources/Dependencies/URIParser/URIParserLive.swift rename {secant => modules/Sources}/Dependencies/URIParser/URIParserTest.swift (88%) rename {secant => modules/Sources}/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift (82%) create mode 100644 modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift rename {secant => modules/Sources}/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift (92%) rename {secant => modules/Sources}/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift (94%) rename {secant => modules/Sources}/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift (73%) rename {secant => modules/Sources}/Dependencies/WalletConfigProvider/WalletConfigProvider.swift (89%) rename {secant => modules/Sources}/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift (56%) rename {secant => modules/Sources}/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift (68%) rename {secant => modules/Sources}/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift (86%) rename {secant => modules/Sources}/Dependencies/WalletStorage/WalletStorage.swift (86%) rename {secant => modules/Sources}/Dependencies/WalletStorage/WalletStorageInterface.swift (73%) rename {secant => modules/Sources}/Dependencies/WalletStorage/WalletStorageLiveKey.swift (87%) rename {secant => modules/Sources}/Dependencies/WalletStorage/WalletStorageTestKey.swift (92%) create mode 100644 modules/Sources/Models/StoredWallet.swift rename {secant => modules/Sources}/Models/WalletConfig.swift (68%) delete mode 100644 secant/Dependencies/URIParser/URIParser.swift delete mode 100644 secant/Dependencies/URIParser/URIParserLive.swift delete mode 100644 secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift delete mode 100644 secant/Models/StoredWallet.swift diff --git a/modules/Package.swift b/modules/Package.swift index 65a4e648..0216faf2 100644 --- a/modules/Package.swift +++ b/modules/Package.swift @@ -32,8 +32,12 @@ let package = Package( .library(name: "SecItem", targets: ["SecItem"]), .library(name: "SupportDataGenerator", targets: ["SupportDataGenerator"]), .library(name: "UIComponents", targets: ["UIComponents"]), - .library(name: "Utils", targets: ["Utils"]), + .library(name: "URIParser", targets: ["URIParser"]), .library(name: "UserDefaults", targets: ["UserDefaults"]), + .library(name: "UserPreferencesStorage", targets: ["UserPreferencesStorage"]), + .library(name: "Utils", targets: ["Utils"]), + .library(name: "WalletConfigProvider", targets: ["WalletConfigProvider"]), + .library(name: "WalletStorage", targets: ["WalletStorage"]), .library(name: "ZcashSDKEnvironment", targets: ["ZcashSDKEnvironment"]) ], dependencies: [ @@ -154,7 +158,8 @@ let package = Package( dependencies: [ "Utils", "UIComponents" - ] + ], + path: "Sources/Models" ), .target( name: "NumberFormatter", @@ -228,13 +233,17 @@ let package = Package( dependencies: [ "Generated", "Utils" - ] + ], + path: "Sources/UIComponents" ), .target( - name: "Utils", + name: "URIParser", dependencies: [ + "DerivationTool", + .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), .product(name: "ZcashLightClientKit", package: "ZcashLightClientKit") - ] + ], + path: "Sources/Dependencies/URIParser" ), .target( name: "UserDefaults", @@ -243,6 +252,41 @@ let package = Package( ], path: "Sources/Dependencies/UserDefaults" ), + .target( + name: "UserPreferencesStorage", + dependencies: [ + .product(name: "ComposableArchitecture", package: "swift-composable-architecture") + ], + path: "Sources/Dependencies/UserPreferencesStorage" + ), + .target( + name: "Utils", + dependencies: [ + .product(name: "ZcashLightClientKit", package: "ZcashLightClientKit") + ], + path: "Sources/Utils" + ), + .target( + name: "WalletConfigProvider", + dependencies: [ + "Utils", + "Models", + .product(name: "ComposableArchitecture", package: "swift-composable-architecture") + ], + path: "Sources/Dependencies/WalletConfigProvider" + ), + .target( + name: "WalletStorage", + dependencies: [ + "Utils", + "SecItem", + "MnemonicClient", + "Models", + .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), + .product(name: "ZcashLightClientKit", package: "ZcashLightClientKit") + ], + path: "Sources/Dependencies/WalletStorage" + ), .target( name: "ZcashSDKEnvironment", dependencies: [ diff --git a/modules/Sources/Dependencies/URIParser/URIParser.swift b/modules/Sources/Dependencies/URIParser/URIParser.swift new file mode 100644 index 00000000..dcb11282 --- /dev/null +++ b/modules/Sources/Dependencies/URIParser/URIParser.swift @@ -0,0 +1,18 @@ +// +// URIParser.swift +// secant-testnet +// +// Created by Lukáš Korba on 17.05.2022. +// + +import Foundation +import ZcashLightClientKit +import DerivationTool + +public struct URIParser { + public enum URIParserError: Error { } + + public func isValidURI(_ uri: String, network: NetworkType) -> Bool { + DerivationToolClient.live().isZcashAddress(uri, network) + } +} diff --git a/secant/Dependencies/URIParser/URIParserInterface.swift b/modules/Sources/Dependencies/URIParser/URIParserInterface.swift similarity index 64% rename from secant/Dependencies/URIParser/URIParserInterface.swift rename to modules/Sources/Dependencies/URIParser/URIParserInterface.swift index d5fc4c12..dc7d48a6 100644 --- a/secant/Dependencies/URIParser/URIParserInterface.swift +++ b/modules/Sources/Dependencies/URIParser/URIParserInterface.swift @@ -7,15 +7,16 @@ import Foundation import ComposableArchitecture +import ZcashLightClientKit extension DependencyValues { - var uriParser: URIParserClient { + public var uriParser: URIParserClient { get { self[URIParserClient.self] } set { self[URIParserClient.self] = newValue } } } -struct URIParserClient { - var isValidURI: (String) -> Bool +public struct URIParserClient { + public var isValidURI: (String, NetworkType) -> Bool } diff --git a/modules/Sources/Dependencies/URIParser/URIParserLive.swift b/modules/Sources/Dependencies/URIParser/URIParserLive.swift new file mode 100644 index 00000000..7985b509 --- /dev/null +++ b/modules/Sources/Dependencies/URIParser/URIParserLive.swift @@ -0,0 +1,16 @@ +// +// URIParserLive.swift +// secant-testnet +// +// Created by Lukáš Korba on 15.11.2022. +// + +import ComposableArchitecture + +extension URIParserClient: DependencyKey { + public static let liveValue = Self( + isValidURI: { uri, network in + URIParser().isValidURI(uri, network: network) + } + ) +} diff --git a/secant/Dependencies/URIParser/URIParserTest.swift b/modules/Sources/Dependencies/URIParser/URIParserTest.swift similarity index 88% rename from secant/Dependencies/URIParser/URIParserTest.swift rename to modules/Sources/Dependencies/URIParser/URIParserTest.swift index dd56b029..dbfbb3fe 100644 --- a/secant/Dependencies/URIParser/URIParserTest.swift +++ b/modules/Sources/Dependencies/URIParser/URIParserTest.swift @@ -9,7 +9,7 @@ import ComposableArchitecture import XCTestDynamicOverlay extension URIParserClient: TestDependencyKey { - static let testValue = Self( + public static let testValue = Self( isValidURI: XCTUnimplemented("\(Self.self).isValidURI", placeholder: false) ) } diff --git a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift similarity index 82% rename from secant/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift rename to modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift index 369beb3d..359feef7 100644 --- a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift +++ b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorage.swift @@ -11,8 +11,8 @@ import UserDefaults /// Live implementation of the `UserPreferences` using User Defaults /// according to https://developer.apple.com/documentation/foundation/userdefaults /// the UserDefaults class is thread-safe. -struct UserPreferencesStorage { - enum Constants: String, CaseIterable { +public struct UserPreferencesStorage { + public enum Constants: String, CaseIterable { case zcashActiveAppSessionFrom case zcashCurrency case zcashFiatConverted @@ -31,7 +31,7 @@ struct UserPreferencesStorage { private let userDefaults: UserDefaultsClient - init( + public init( appSessionFrom: TimeInterval, convertedCurrency: String, fiatConvertion: Bool, @@ -50,61 +50,61 @@ struct UserPreferencesStorage { } /// From when the app is on and uninterrupted - var activeAppSessionFrom: TimeInterval { + public var activeAppSessionFrom: TimeInterval { getValue(forKey: Constants.zcashActiveAppSessionFrom.rawValue, default: appSessionFrom) } - func setActiveAppSessionFrom(_ timeInterval: TimeInterval) async { + public func setActiveAppSessionFrom(_ timeInterval: TimeInterval) async { await setValue(timeInterval, forKey: Constants.zcashActiveAppSessionFrom.rawValue) } /// What is the set up currency - var currency: String { + public var currency: String { getValue(forKey: Constants.zcashCurrency.rawValue, default: convertedCurrency) } - func setCurrency(_ string: String) async { + public func setCurrency(_ string: String) async { await setValue(string, forKey: Constants.zcashCurrency.rawValue) } /// Whether the fiat conversion is on/off - var isFiatConverted: Bool { + public var isFiatConverted: Bool { getValue(forKey: Constants.zcashFiatConverted.rawValue, default: fiatConvertion) } - func setIsFiatConverted(_ bool: Bool) async { + public func setIsFiatConverted(_ bool: Bool) async { await setValue(bool, forKey: Constants.zcashFiatConverted.rawValue) } /// Whether user finished recovery phrase backup test - var isRecoveryPhraseTestCompleted: Bool { + public var isRecoveryPhraseTestCompleted: Bool { getValue(forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue, default: recoveryPhraseTestCompleted) } - func setIsRecoveryPhraseTestCompleted(_ bool: Bool) async { + public func setIsRecoveryPhraseTestCompleted(_ bool: Bool) async { await setValue(bool, forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue) } /// Whether the user has been autoshielded in the running session - var isSessionAutoshielded: Bool { + public var isSessionAutoshielded: Bool { getValue(forKey: Constants.zcashSessionAutoshielded.rawValue, default: sessionAutoshielded) } - func setIsSessionAutoshielded(_ bool: Bool) async { + public func setIsSessionAutoshielded(_ bool: Bool) async { await setValue(bool, forKey: Constants.zcashSessionAutoshielded.rawValue) } /// Whether the user has opted out of crash reporting - var isUserOptedOutOfCrashReporting: Bool { + public var isUserOptedOutOfCrashReporting: Bool { getValue(forKey: Constants.zcashUserOptedOutOfCrashReporting.rawValue, default: false) } - func setIsUserOptedOutOfCrashReporting(_ bool: Bool) async { + public func setIsUserOptedOutOfCrashReporting(_ bool: Bool) async { await setValue(bool, forKey: Constants.zcashUserOptedOutOfCrashReporting.rawValue) } /// Use carefully: Deletes all user preferences from the User Defaults - func removeAll() { + public func removeAll() { for key in Constants.allCases { userDefaults.remove(key.rawValue) } diff --git a/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift new file mode 100644 index 00000000..6e8f7296 --- /dev/null +++ b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift @@ -0,0 +1,38 @@ +// +// UserPreferencesStorageInterface.swift +// secant-testnet +// +// Created by Francisco Gindre on 2/6/23. +// + +import Foundation +import ComposableArchitecture + +extension DependencyValues { + public var userStoredPreferences: UserPreferencesStorageClient { + get { self[UserPreferencesStorageClient.self] } + set { self[UserPreferencesStorageClient.self] = newValue } + } +} + +public struct UserPreferencesStorageClient { + public var activeAppSessionFrom: () -> TimeInterval + public var setActiveAppSessionFrom: (TimeInterval) async -> Void + + public var currency: () -> String + public var setCurrenty: (String) async -> Void + + public var isFiatConverted: () -> Bool + public var setIsFiatConverted: (Bool) async -> Void + + public var isRecoveryPhraseTestCompleted: () -> Bool + public var setIsRecoveryPhraseTestCompleted: (Bool) async -> Void + + public var isSessionAutoshielded: () -> Bool + public var setIsSessionAutoshielded: (Bool) async -> Void + + public var isUserOptedOutOfCrashReporting: () -> Bool + public var setIsUserOptedOutOfCrashReporting: (Bool) async -> Void + + public var removeAll: () async -> Void +} diff --git a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift similarity index 92% rename from secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift rename to modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift index 236c2b24..0efcb865 100644 --- a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift +++ b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageLive.swift @@ -9,7 +9,7 @@ import Foundation import ComposableArchitecture extension UserPreferencesStorageClient: DependencyKey { - static var liveValue: UserPreferencesStorageClient = { + public static var liveValue: UserPreferencesStorageClient = { let live = UserPreferencesStorage.live return UserPreferencesStorageClient( @@ -35,7 +35,7 @@ extension UserPreferencesStorageClient: DependencyKey { } extension UserPreferencesStorage { - static let live = UserPreferencesStorage( + public static let live = UserPreferencesStorage( appSessionFrom: Date().timeIntervalSince1970, convertedCurrency: "USD", fiatConvertion: true, diff --git a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift similarity index 94% rename from secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift rename to modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift index 28d58e8c..df3886e1 100644 --- a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift +++ b/modules/Sources/Dependencies/UserPreferencesStorage/UserPreferencesStorageMocks.swift @@ -9,7 +9,7 @@ import Foundation import ComposableArchitecture extension UserPreferencesStorageClient: TestDependencyKey { - static var testValue = { + public static var testValue = { let mock = UserPreferencesStorage.mock return UserPreferencesStorageClient( @@ -35,7 +35,7 @@ extension UserPreferencesStorageClient: TestDependencyKey { } extension UserPreferencesStorage { - static let mock = UserPreferencesStorage( + public static let mock = UserPreferencesStorage( appSessionFrom: 1651039606.0, convertedCurrency: "USD", fiatConvertion: true, diff --git a/secant/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift b/modules/Sources/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift similarity index 73% rename from secant/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift rename to modules/Sources/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift index c5d0ad4f..7d1aee85 100644 --- a/secant/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift +++ b/modules/Sources/Dependencies/WalletConfigProvider/UserDefaultsWalletConfigStorage.swift @@ -7,23 +7,26 @@ import Foundation import Utils +import Models -typealias UserDefaultsWalletConfigProvider = UserDefaultsWalletConfigStorage -typealias UserDefaultsWalletConfigProviderCache = UserDefaultsWalletConfigStorage +public typealias UserDefaultsWalletConfigProvider = UserDefaultsWalletConfigStorage +public typealias UserDefaultsWalletConfigProviderCache = UserDefaultsWalletConfigStorage -struct UserDefaultsWalletConfigStorage { +public struct UserDefaultsWalletConfigStorage { private let userDefaults = UserDefaults.standard - enum InternalError: Error { + public enum InternalError: Error { case noValueStored case unableToDeserializeData } - enum Constants { - static let providerKey = "feature_flags_ud_config_provider" - static let cacheKey = "feature_flags_ud_config_cache" + public enum Constants { + public static let providerKey = "feature_flags_ud_config_provider" + public static let cacheKey = "feature_flags_ud_config_cache" } + public init() {} + private func load(key: String) async throws -> WalletConfig { guard let data = userDefaults.data(forKey: key) else { throw InternalError.noValueStored } do { @@ -45,7 +48,7 @@ struct UserDefaultsWalletConfigStorage { } // This is used only in debug menu to change configuration for specific flag - func store(featureFlag: FeatureFlag, isEnabled: Bool) async { + public func store(featureFlag: FeatureFlag, isEnabled: Bool) async { let currentConfig = (try? await load(key: Constants.providerKey)) ?? WalletConfig.default var rawFlags = currentConfig.flags rawFlags[featureFlag] = isEnabled @@ -55,13 +58,13 @@ struct UserDefaultsWalletConfigStorage { } extension UserDefaultsWalletConfigStorage: WalletConfigSourceProvider { - func load() async throws -> WalletConfig { + public func load() async throws -> WalletConfig { return try await load(key: Constants.providerKey) } } extension UserDefaultsWalletConfigStorage: WalletConfigProviderCache { - func load() async -> WalletConfig? { + public func load() async -> WalletConfig? { do { return try await load(key: Constants.cacheKey) } catch { @@ -70,7 +73,7 @@ extension UserDefaultsWalletConfigStorage: WalletConfigProviderCache { } } - func store(_ configuration: WalletConfig) async { + public func store(_ configuration: WalletConfig) async { await store(flags: configuration.flags, key: Constants.cacheKey) } } diff --git a/secant/Dependencies/WalletConfigProvider/WalletConfigProvider.swift b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProvider.swift similarity index 89% rename from secant/Dependencies/WalletConfigProvider/WalletConfigProvider.swift rename to modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProvider.swift index 4782b7a5..913e4942 100644 --- a/secant/Dependencies/WalletConfigProvider/WalletConfigProvider.swift +++ b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProvider.swift @@ -8,15 +8,16 @@ import Foundation import Combine import Utils +import Models -struct WalletConfigProvider { +public struct WalletConfigProvider { /// Objects that fetches flags configuration from some source. It can be fetched from user defaults or some backend API for example. It depends /// on implementation. private let configSourceProvider: WalletConfigSourceProvider /// Object that caches provided flags configuration. private let cache: WalletConfigProviderCache - init(configSourceProvider: WalletConfigSourceProvider, cache: WalletConfigProviderCache) { + public init(configSourceProvider: WalletConfigSourceProvider, cache: WalletConfigProviderCache) { self.configSourceProvider = configSourceProvider self.cache = cache } @@ -30,7 +31,7 @@ struct WalletConfigProvider { /// configuration. /// /// Merged configuration is stored in cache. - func load() -> AnyPublisher { + public func load() -> AnyPublisher { let publisher = PassthroughSubject() Task { let config = await load() @@ -61,7 +62,7 @@ struct WalletConfigProvider { } // This is used only in debug menu to change configuration for specific flag - func update(featureFlag: FeatureFlag, isEnabled: Bool) -> AnyPublisher { + public func update(featureFlag: FeatureFlag, isEnabled: Bool) -> AnyPublisher { let publisher = PassthroughSubject() Task { await update(featureFlag: featureFlag, isEnabled: isEnabled) @@ -90,11 +91,11 @@ struct WalletConfigProvider { } } -protocol WalletConfigSourceProvider { +public protocol WalletConfigSourceProvider { func load() async throws -> WalletConfig } -protocol WalletConfigProviderCache { +public protocol WalletConfigProviderCache { func load() async -> WalletConfig? func store(_ configuration: WalletConfig) async } diff --git a/secant/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift similarity index 56% rename from secant/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift rename to modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift index 25424cc9..89f60188 100644 --- a/secant/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift +++ b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderInterface.swift @@ -8,15 +8,16 @@ import ComposableArchitecture import Foundation import Combine +import Models extension DependencyValues { - var walletConfigProvider: WalletConfigProviderClient { + public var walletConfigProvider: WalletConfigProviderClient { get { self[WalletConfigProviderClient.self] } set { self[WalletConfigProviderClient.self] = newValue } } } -struct WalletConfigProviderClient { - let load: () -> AnyPublisher - let update: (FeatureFlag, Bool) -> AnyPublisher +public struct WalletConfigProviderClient { + public let load: () -> AnyPublisher + public let update: (FeatureFlag, Bool) -> AnyPublisher } diff --git a/secant/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift similarity index 68% rename from secant/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift rename to modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift index b703ca54..243f9b3a 100644 --- a/secant/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift +++ b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderLiveKey.swift @@ -9,16 +9,16 @@ import ComposableArchitecture import Foundation extension WalletConfigProviderClient: DependencyKey { - static let liveValue = WalletConfigProviderClient.live() + public static let liveValue = WalletConfigProviderClient.live() - private static var defaultWalletConfigProvider: WalletConfigProvider { + public static var defaultWalletConfigProvider: WalletConfigProvider { WalletConfigProvider( configSourceProvider: UserDefaultsWalletConfigProvider(), cache: UserDefaultsWalletConfigProviderCache() ) } - static func live(walletConfigProvider: WalletConfigProvider = WalletConfigProviderClient.defaultWalletConfigProvider) -> Self { + public static func live(walletConfigProvider: WalletConfigProvider = WalletConfigProviderClient.defaultWalletConfigProvider) -> Self { Self( load: { walletConfigProvider.load() }, update: { flag, isEnabled in diff --git a/secant/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift similarity index 86% rename from secant/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift rename to modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift index aca91575..d6cf474d 100644 --- a/secant/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift +++ b/modules/Sources/Dependencies/WalletConfigProvider/WalletConfigProviderTestKey.swift @@ -8,16 +8,17 @@ import ComposableArchitecture import XCTestDynamicOverlay import Combine +import Models extension WalletConfigProviderClient: TestDependencyKey { - static let testValue = Self( + public static let testValue = Self( load: XCTUnimplemented("\(Self.self).load", placeholder: Just(WalletConfig.default).eraseToAnyPublisher()), update: XCTUnimplemented("\(Self.self).update") ) } extension WalletConfigProviderClient { - static let noOp = Self( + public static let noOp = Self( load: { Just(WalletConfig.default).eraseToAnyPublisher() }, update: { _, _ in Just(Void()).eraseToAnyPublisher() } ) diff --git a/secant/Dependencies/WalletStorage/WalletStorage.swift b/modules/Sources/Dependencies/WalletStorage/WalletStorage.swift similarity index 86% rename from secant/Dependencies/WalletStorage/WalletStorage.swift rename to modules/Sources/Dependencies/WalletStorage/WalletStorage.swift index 0b5e24ca..dedd2e17 100644 --- a/secant/Dependencies/WalletStorage/WalletStorage.swift +++ b/modules/Sources/Dependencies/WalletStorage/WalletStorage.swift @@ -10,18 +10,19 @@ import MnemonicSwift import ZcashLightClientKit import Utils import SecItem +import Models /// Zcash implementation of the keychain that is not universal but designed to deliver functionality needed by the wallet itself. /// All the APIs should be thread safe according to official doc: /// https://developer.apple.com/documentation/security/certificate_key_and_trust_services/working_with_concurrency?language=objc -struct WalletStorage { - enum Constants { - static let zcashStoredWallet = "zcashStoredWallet" +public struct WalletStorage { + public enum Constants { + public static let zcashStoredWallet = "zcashStoredWallet" /// Versioning of the stored data - static let zcashKeychainVersion = 1 + public static let zcashKeychainVersion = 1 } - enum KeychainError: Error, Equatable { + public enum KeychainError: Error, Equatable { case decoding case duplicate case encoding @@ -29,7 +30,7 @@ struct WalletStorage { case unknown(OSStatus) } - enum WalletStorageError: Error { + public enum WalletStorageError: Error { case alreadyImported case uninitializedWallet case storageError(Error) @@ -38,13 +39,13 @@ struct WalletStorage { } private let secItem: SecItemClient - var zcashStoredWalletPrefix = "" + public var zcashStoredWalletPrefix = "" - init(secItem: SecItemClient) { + public init(secItem: SecItemClient) { self.secItem = secItem } - func importWallet( + public func importWallet( bip39 phrase: String, birthday: BlockHeight?, language: MnemonicLanguageType = .english, @@ -76,7 +77,7 @@ struct WalletStorage { } } - func exportWallet() throws -> StoredWallet { + public func exportWallet() throws -> StoredWallet { guard let data = data(forKey: Constants.zcashStoredWallet) else { throw WalletStorageError.uninitializedWallet } @@ -92,7 +93,7 @@ struct WalletStorage { return wallet } - func areKeysPresent() throws -> Bool { + public func areKeysPresent() throws -> Bool { do { _ = try exportWallet() } catch { @@ -103,7 +104,7 @@ struct WalletStorage { return true } - func updateBirthday(_ height: BlockHeight) throws { + public func updateBirthday(_ height: BlockHeight) throws { do { var wallet = try exportWallet() wallet.birthday = Birthday(height) @@ -118,7 +119,7 @@ struct WalletStorage { } } - func markUserPassedPhraseBackupTest(_ flag: Bool = true) throws { + public func markUserPassedPhraseBackupTest(_ flag: Bool = true) throws { do { var wallet = try exportWallet() wallet.hasUserPassedPhraseBackupTest = flag @@ -133,13 +134,13 @@ struct WalletStorage { } } - func nukeWallet() { + public func nukeWallet() { deleteData(forKey: Constants.zcashStoredWallet) } // MARK: - Wallet Storage Codable & Query helpers - func decode(json: Data, as clazz: T.Type) throws -> T? { + public func decode(json: Data, as clazz: T.Type) throws -> T? { do { let decoder = JSONDecoder() let data = try decoder.decode(T.self, from: json) @@ -149,7 +150,7 @@ struct WalletStorage { } } - func encode(object: T) throws -> Data? { + public func encode(object: T) throws -> Data? { do { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted @@ -159,7 +160,7 @@ struct WalletStorage { } } - func baseQuery(forAccount account: String = "", andKey forKey: String) -> [String: Any] { + public func baseQuery(forAccount account: String = "", andKey forKey: String) -> [String: Any] { let query: [String: AnyObject] = [ /// Uniquely identify this keychain accessor kSecAttrService as String: (zcashStoredWalletPrefix + forKey) as AnyObject, @@ -175,7 +176,7 @@ struct WalletStorage { return query } - func restoreQuery(forAccount account: String = "", andKey forKey: String) -> [String: Any] { + public func restoreQuery(forAccount account: String = "", andKey forKey: String) -> [String: Any] { var query = baseQuery(forAccount: account, andKey: forKey) query[kSecMatchLimit as String] = kSecMatchLimitOne query[kSecReturnData as String] = kCFBooleanTrue @@ -187,7 +188,7 @@ struct WalletStorage { } /// Restore data for key - func data( + public func data( forKey: String, account: String = "" ) -> Data? { @@ -201,7 +202,7 @@ struct WalletStorage { /// Use carefully: Deletes data for key @discardableResult - func deleteData( + public func deleteData( forKey: String, account: String = "" ) -> Bool { @@ -213,7 +214,7 @@ struct WalletStorage { } /// Store data for key - func setData( + public func setData( _ data: Data, forKey: String, account: String = "" @@ -234,7 +235,7 @@ struct WalletStorage { } /// Use carefully: Update data for key - func updateData( + public func updateData( _ data: Data, forKey: String, account: String = "" diff --git a/secant/Dependencies/WalletStorage/WalletStorageInterface.swift b/modules/Sources/Dependencies/WalletStorage/WalletStorageInterface.swift similarity index 73% rename from secant/Dependencies/WalletStorage/WalletStorageInterface.swift rename to modules/Sources/Dependencies/WalletStorage/WalletStorageInterface.swift index 8db89643..6c9a1a55 100644 --- a/secant/Dependencies/WalletStorage/WalletStorageInterface.swift +++ b/modules/Sources/Dependencies/WalletStorage/WalletStorageInterface.swift @@ -8,9 +8,10 @@ import ComposableArchitecture import MnemonicSwift import ZcashLightClientKit +import Models extension DependencyValues { - var walletStorage: WalletStorageClient { + public var walletStorage: WalletStorageClient { get { self[WalletStorageClient.self] } set { self[WalletStorageClient.self] = newValue } } @@ -22,7 +23,7 @@ extension DependencyValues { /// properties that live on the `WalletStorageClient` type. Because of this, you can instantiate /// the `WalletStorageClient` with your own implementation of these functions for testing purposes, /// or you can use one of the built in static versions of the `WalletStorageClient`. -struct WalletStorageClient { +public struct WalletStorageClient { /// Store recovery phrase and optionally even birthday to the secured and persistent storage. /// This function creates an instance of `StoredWallet` and automatically handles versioning of the stored data. /// @@ -35,7 +36,7 @@ struct WalletStorageClient { /// - `WalletStorageError.unsupportedLanguage`: when mnemonic's language is anything other than English /// - `WalletStorageError.alreadyImported` when valid wallet is already in the storage /// - `WalletStorageError.storageError` when some unrecognized error occurred - let importWallet: (String, BlockHeight?, MnemonicLanguageType, Bool) throws -> Void + public let importWallet: (String, BlockHeight?, MnemonicLanguageType, Bool) throws -> Void /// Load the representation of the wallet from the persistent and secured storage. /// @@ -44,12 +45,12 @@ struct WalletStorageClient { /// - `WalletStorageError.uninitializedWallet`: when no wallet's data is found in the keychain. /// - `WalletStorageError.storageError` when some unrecognized error occurred. /// - `WalletStorageError.unsupportedVersion` when wallet's version stored in the keychain is outdated. - var exportWallet: () throws -> StoredWallet + public var exportWallet: () throws -> StoredWallet /// Check if the wallet representation `StoredWallet` is present in the persistent storage. /// /// - Returns: the information whether some wallet is stored or is not available - var areKeysPresent: () throws -> Bool + public var areKeysPresent: () throws -> Bool /// Update the birthday in the securely stored wallet. /// @@ -58,7 +59,7 @@ struct WalletStorageClient { /// - Throws: /// - `WalletStorage.KeychainError.encoding`: when encoding the wallet's data failed. /// - `WalletStorageError.storageError` when some unrecognized error occurred. - let updateBirthday: (BlockHeight) throws -> Void + public let updateBirthday: (BlockHeight) throws -> Void /// Update the information that user has passed the recovery phrase backup test. /// The function doesn't take any parameters, default value is the user hasn't passed the test @@ -67,9 +68,25 @@ struct WalletStorageClient { /// - Throws: /// - `WalletStorage.KeychainError.encoding`: when encoding the wallet's data failed. /// - `WalletStorageError.storageError` when some unrecognized error occurred. - let markUserPassedPhraseBackupTest: (Bool) throws -> Void + public let markUserPassedPhraseBackupTest: (Bool) throws -> Void /// Use carefully: deletes the stored wallet. /// There's no fate but what we make for ourselves - Sarah Connor. - let nukeWallet: () -> Void + public let nukeWallet: () -> Void + + public init( + importWallet: @escaping (String, BlockHeight?, MnemonicLanguageType, Bool) throws -> Void, + exportWallet: @escaping () throws -> StoredWallet, + areKeysPresent: @escaping () throws -> Bool, + updateBirthday: @escaping (BlockHeight) throws -> Void, + markUserPassedPhraseBackupTest: @escaping (Bool) throws -> Void, + nukeWallet: @escaping () -> Void + ) { + self.importWallet = importWallet + self.exportWallet = exportWallet + self.areKeysPresent = areKeysPresent + self.updateBirthday = updateBirthday + self.markUserPassedPhraseBackupTest = markUserPassedPhraseBackupTest + self.nukeWallet = nukeWallet + } } diff --git a/secant/Dependencies/WalletStorage/WalletStorageLiveKey.swift b/modules/Sources/Dependencies/WalletStorage/WalletStorageLiveKey.swift similarity index 87% rename from secant/Dependencies/WalletStorage/WalletStorageLiveKey.swift rename to modules/Sources/Dependencies/WalletStorage/WalletStorageLiveKey.swift index 4a6990b2..6c47a6c0 100644 --- a/secant/Dependencies/WalletStorage/WalletStorageLiveKey.swift +++ b/modules/Sources/Dependencies/WalletStorage/WalletStorageLiveKey.swift @@ -11,9 +11,9 @@ import ZcashLightClientKit import ComposableArchitecture extension WalletStorageClient: DependencyKey { - static let liveValue = WalletStorageClient.live() + public static let liveValue = WalletStorageClient.live() - static func live(walletStorage: WalletStorage = WalletStorage(secItem: .live)) -> Self { + public static func live(walletStorage: WalletStorage = WalletStorage(secItem: .live)) -> Self { Self( importWallet: { bip39, birthday, language, hasUserPassedPhraseBackupTest in try walletStorage.importWallet( diff --git a/secant/Dependencies/WalletStorage/WalletStorageTestKey.swift b/modules/Sources/Dependencies/WalletStorage/WalletStorageTestKey.swift similarity index 92% rename from secant/Dependencies/WalletStorage/WalletStorageTestKey.swift rename to modules/Sources/Dependencies/WalletStorage/WalletStorageTestKey.swift index 55af5f91..a3737bc4 100644 --- a/secant/Dependencies/WalletStorage/WalletStorageTestKey.swift +++ b/modules/Sources/Dependencies/WalletStorage/WalletStorageTestKey.swift @@ -9,7 +9,7 @@ import ComposableArchitecture import XCTestDynamicOverlay extension WalletStorageClient: TestDependencyKey { - static let testValue = Self( + public static let testValue = Self( importWallet: XCTUnimplemented("\(Self.self).importWallet"), exportWallet: XCTUnimplemented("\(Self.self).exportWallet", placeholder: .placeholder), areKeysPresent: XCTUnimplemented("\(Self.self).areKeysPresent", placeholder: false), @@ -20,7 +20,7 @@ extension WalletStorageClient: TestDependencyKey { } extension WalletStorageClient { - static let noOp = Self( + public static let noOp = Self( importWallet: { _, _, _, _ in }, exportWallet: { .placeholder }, areKeysPresent: { false }, diff --git a/modules/Sources/Models/StoredWallet.swift b/modules/Sources/Models/StoredWallet.swift new file mode 100644 index 00000000..4035dc63 --- /dev/null +++ b/modules/Sources/Models/StoredWallet.swift @@ -0,0 +1,45 @@ +// +// StoredWallet.swift +// secant-testnet +// +// Created by Lukáš Korba on 13.05.2022. +// + +import Foundation +import ZcashLightClientKit +import MnemonicSwift +import Utils + +/// Representation of the wallet stored in the persistent storage (typically keychain, handled by `WalletStorage`). +public struct StoredWallet: Codable, Equatable { + public let language: MnemonicLanguageType + public let seedPhrase: SeedPhrase + public let version: Int + + public var birthday: Birthday? + public var hasUserPassedPhraseBackupTest: Bool + + public init( + language: MnemonicLanguageType, + seedPhrase: SeedPhrase, + version: Int, + birthday: Birthday? = nil, + hasUserPassedPhraseBackupTest: Bool + ) { + self.language = language + self.seedPhrase = seedPhrase + self.version = version + self.birthday = birthday + self.hasUserPassedPhraseBackupTest = hasUserPassedPhraseBackupTest + } +} + +extension StoredWallet { + public static let placeholder = Self( + language: .english, + seedPhrase: SeedPhrase(RecoveryPhrase.testPhrase.joined(separator: " ")), + version: 0, + birthday: Birthday(0), + hasUserPassedPhraseBackupTest: false + ) +} diff --git a/secant/Models/WalletConfig.swift b/modules/Sources/Models/WalletConfig.swift similarity index 68% rename from secant/Models/WalletConfig.swift rename to modules/Sources/Models/WalletConfig.swift index daccb220..077480fe 100644 --- a/secant/Models/WalletConfig.swift +++ b/modules/Sources/Models/WalletConfig.swift @@ -5,7 +5,7 @@ // Created by Michal Fousek on 23.02.2023. // -enum FeatureFlag: String, CaseIterable, Codable { +public enum FeatureFlag: String, CaseIterable, Codable { // These two flags should stay here because those are used in tests. It's not super nice but there is probably no other way. case testFlag1 case testFlag2 @@ -13,7 +13,7 @@ enum FeatureFlag: String, CaseIterable, Codable { case testBackupPhraseFlow case showFiatConversion - var enabledByDefault: Bool { + public var enabledByDefault: Bool { switch self { case .testFlag1, .testFlag2: return false case .onboardingFlow: return false @@ -23,20 +23,24 @@ enum FeatureFlag: String, CaseIterable, Codable { } } -struct WalletConfig: Equatable { - typealias RawFlags = [FeatureFlag: Bool] +public struct WalletConfig: Equatable { + public typealias RawFlags = [FeatureFlag: Bool] - let flags: RawFlags + public let flags: RawFlags - func isEnabled(_ featureFlag: FeatureFlag) -> Bool { + public func isEnabled(_ featureFlag: FeatureFlag) -> Bool { return flags[featureFlag, default: false] } - static var `default`: WalletConfig = { + public static var `default`: WalletConfig = { let defaultSettings = FeatureFlag.allCases .filter { $0 != .testFlag1 && $0 != .testFlag2 } .map { ($0, $0.enabledByDefault) } return WalletConfig(flags: Dictionary(uniqueKeysWithValues: defaultSettings)) }() + + public init(flags: RawFlags) { + self.flags = flags + } } diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index c54a648c..121d0d5d 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -16,7 +16,6 @@ 0D26AE9C299E8196005260EE /* ZcashBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0DE282D2DD600C374E8 /* ZcashBadge.swift */; }; 0D26AE9D299E8196005260EE /* CrashReporterTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103F298C406F00CC9DE9 /* CrashReporterTestKey.swift */; }; 0D26AEA0299E8196005260EE /* SandboxStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */; }; - 0D26AEA3299E8196005260EE /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911442848EEB90073DD9A /* UserPreferencesStorage.swift */; }; 0D26AEA5299E8196005260EE /* TransactionSendingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DA414628E4385800F8CC61 /* TransactionSendingView.swift */; }; 0D26AEA6299E8196005260EE /* WalletEventsFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E6273B501F0021B49A /* WalletEventsFlowView.swift */; }; 0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103D298C3FA600CC9DE9 /* CrashReporterLiveKey.swift */; }; @@ -36,7 +35,6 @@ 0D26AECF299E8196005260EE /* CurrencySelectionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */; }; 0D26AED2299E8196005260EE /* BalanceBreakdownStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F6289BC58C00A6796F /* BalanceBreakdownStore.swift */; }; 0D26AED3299E8196005260EE /* SyncStatusSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */; }; - 0D26AED6299E8196005260EE /* UserPreferencesStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6316FF29919970007D873F /* UserPreferencesStorageInterface.swift */; }; 0D26AEDA299E8196005260EE /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; }; 0D26AEDB299E8196005260EE /* ProfileStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5027680DD000A2DB75 /* ProfileStore.swift */; }; 0D26AEDC299E8196005260EE /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; }; @@ -61,17 +59,13 @@ 0D26AF0E299E8196005260EE /* MultiLineTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */; }; 0D26AF0F299E8196005260EE /* DebugFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */; }; 0D26AF11299E8196005260EE /* LottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6612322878338C00C75B70 /* LottieAnimation.swift */; }; - 0D26AF12299E8196005260EE /* UserPreferencesStorageMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C82923C953003D0F8B /* UserPreferencesStorageMocks.swift */; }; 0D26AF13299E8196005260EE /* RecoveryPhraseDisplayStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D3D04092728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift */; }; 0D26AF18299E8196005260EE /* WalletEventsFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96B41E3273B501F0021B49A /* WalletEventsFlowStore.swift */; }; - 0D26AF19299E8196005260EE /* StoredWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0E5282E7B1100C374E8 /* StoredWallet.swift */; }; 0D26AF1B299E8196005260EE /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.swift */; }; 0D26AF1E299E8196005260EE /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB619287310EC00A02233 /* QRCodeGenerator.swift */; }; 0D26AF20299E8196005260EE /* UInt+SuperscriptText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */; }; 0D26AF23299E8196005260EE /* SendFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B72740403600592F76 /* SendFlowStore.swift */; }; 0D26AF24299E8196005260EE /* SecantApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0826B364170058B01E /* SecantApp.swift */; }; - 0D26AF26299E8196005260EE /* WalletStorageLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863992923935B003D0F8B /* WalletStorageLiveKey.swift */; }; - 0D26AF27299E8196005260EE /* WalletStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863982923935B003D0F8B /* WalletStorageInterface.swift */; }; 0D26AF2D299E8196005260EE /* DebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C832809B606004E65FE /* DebugMenu.swift */; }; 0D26AF37299E8196005260EE /* ScanUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0F528327F6F00C374E8 /* ScanUIView.swift */; }; 0D26AF3A299E8196005260EE /* OnboardingContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5C27467F7700709571 /* OnboardingContentView.swift */; }; @@ -93,15 +87,12 @@ 0D26AF54299E8196005260EE /* CrashReporterInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103B298C3E4800CC9DE9 /* CrashReporterInterface.swift */; }; 0D26AF55299E8196005260EE /* ProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5227680DD000A2DB75 /* ProfileView.swift */; }; 0D26AF56299E8196005260EE /* ScanStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A5E27680DF600A2DB75 /* ScanStore.swift */; }; - 0D26AF59299E8196005260EE /* WalletStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911472848EEB90073DD9A /* WalletStorage.swift */; }; 0D26AF5C299E8196005260EE /* WelcomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* WelcomeStore.swift */; }; 0D26AF5F299E8196005260EE /* SendFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165CA2741AB5D00592F76 /* SendFlowView.swift */; }; - 0D26AF61299E8196005260EE /* WalletStorageTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863972923935B003D0F8B /* WalletStorageTestKey.swift */; }; 0D26AF62299E8196005260EE /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D0781C3278750E30083ACD7 /* WelcomeView.swift */; }; 0D26AF64299E8196005260EE /* SettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A6227680DFE00A2DB75 /* SettingsStore.swift */; }; 0D26AF65299E8196005260EE /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; }; 0D26AF66299E8196005260EE /* ZcashSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D0781C7278776D20083ACD7 /* ZcashSymbol.swift */; }; - 0D26AF67299E8196005260EE /* UserPreferencesStorageLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C62923C93B003D0F8B /* UserPreferencesStorageLive.swift */; }; 0D26AF68299E8196005260EE /* TransactionAmountTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CA27FB09990082C926 /* TransactionAmountTextField.swift */; }; 0D26AF69299E8196005260EE /* AddressDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB61E2874143800A02233 /* AddressDetailsView.swift */; }; 0D26AF6A299E8196005260EE /* ClearBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */; }; @@ -129,7 +120,6 @@ 0D4E7A1026B364180058B01E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0F26B364180058B01E /* Preview Assets.xcassets */; }; 0D573CB629C106E900B97379 /* About.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E4AA4F729BF76BB00752BB3 /* About.swift */; }; 0D5D9B8F2914620700DBD03F /* URLRouting in Frameworks */ = {isa = PBXBuildFile; productRef = 0D5D9B8E2914620700DBD03F /* URLRouting */; }; - 0D63170029919970007D873F /* UserPreferencesStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D6316FF29919970007D873F /* UserPreferencesStorageInterface.swift */; }; 0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */; }; 0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */; }; 0DF482BA2787ADA800EB37D6 /* ConditionalModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF482B92787ADA800EB37D6 /* ConditionalModifier.swift */; }; @@ -161,18 +151,6 @@ 34DA414728E4385800F8CC61 /* TransactionSendingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DA414628E4385800F8CC61 /* TransactionSendingView.swift */; }; 34DA414928E439CD00F8CC61 /* sendingTransaction.json in Resources */ = {isa = PBXBuildFile; fileRef = 34DA414828E439CD00F8CC61 /* sendingTransaction.json */; }; 34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E0AF1028DEE5220034CF37 /* Wedge.swift */; }; - 34F682E529A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; }; - 34F682E629A75EB60022C079 /* WalletConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682E429A75EB60022C079 /* WalletConfig.swift */; }; - 34F682EC29A763FD0022C079 /* WalletConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */; }; - 34F682ED29A763FD0022C079 /* WalletConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */; }; - 34F682EF29A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */; }; - 34F682F029A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */; }; - 34F682F229A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */; }; - 34F682F329A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */; }; - 34F682F529A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */; }; - 34F682F629A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */; }; - 34F682F829A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */; }; - 34F682F929A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */; }; 6654C73A2715A38000901167 /* ComposableArchitecture in Frameworks */ = {isa = PBXBuildFile; productRef = 6654C7392715A38000901167 /* ComposableArchitecture */; }; 6654C73E2715A41300901167 /* OnboardingFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C73D2715A41300901167 /* OnboardingFlowStore.swift */; }; 66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; }; @@ -211,12 +189,16 @@ 9E0031A42A272BC7003DFCEB /* SDKSynchronizer in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031A32A272BC7003DFCEB /* SDKSynchronizer */; }; 9E0031A62A272BC8003DFCEB /* SupportDataGenerator in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031A52A272BC8003DFCEB /* SupportDataGenerator */; }; 9E0031A82A272BC8003DFCEB /* UserDefaults in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031A72A272BC8003DFCEB /* UserDefaults */; }; + 9E0031AA2A276BC1003DFCEB /* URIParser in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031A92A276BC1003DFCEB /* URIParser */; }; + 9E0031AC2A276BC6003DFCEB /* URIParser in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031AB2A276BC6003DFCEB /* URIParser */; }; + 9E0031AE2A276C56003DFCEB /* UserPreferencesStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031AD2A276C56003DFCEB /* UserPreferencesStorage */; }; + 9E0031B02A276C5D003DFCEB /* UserPreferencesStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031AF2A276C5D003DFCEB /* UserPreferencesStorage */; }; + 9E0031B22A27723E003DFCEB /* WalletConfigProvider in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031B12A27723E003DFCEB /* WalletConfigProvider */; }; + 9E0031B42A27723E003DFCEB /* WalletStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031B32A27723E003DFCEB /* WalletStorage */; }; + 9E0031B62A27724D003DFCEB /* WalletConfigProvider in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031B52A27724D003DFCEB /* WalletConfigProvider */; }; + 9E0031B82A27724D003DFCEB /* WalletStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031B72A27724D003DFCEB /* WalletStorage */; }; 9E0310B52A24A4CA0021F995 /* FileManager in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0310B42A24A4CA0021F995 /* FileManager */; }; 9E0310C52A24A4E60021F995 /* FileManager in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0310C42A24A4E60021F995 /* FileManager */; }; - 9E0310CB2A24BB420021F995 /* URIParserLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310C72A24BB420021F995 /* URIParserLive.swift */; }; - 9E0310CC2A24BB420021F995 /* URIParserInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310C82A24BB420021F995 /* URIParserInterface.swift */; }; - 9E0310CD2A24BB420021F995 /* URIParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310C92A24BB420021F995 /* URIParser.swift */; }; - 9E0310CE2A24BB420021F995 /* URIParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310CA2A24BB420021F995 /* URIParserTest.swift */; }; 9E0F5741297E7F1D005304FA /* TCALogging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5740297E7F1C005304FA /* TCALogging.swift */; }; 9E0F5743297EB96C005304FA /* TCALoggerReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5742297EB96C005304FA /* TCALoggerReducer.swift */; }; 9E2AC0FF27D8EC120042AA47 /* MnemonicSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9E2AC0FE27D8EC120042AA47 /* MnemonicSwift */; }; @@ -282,7 +264,6 @@ 9E3451C429C857DF00177D16 /* View+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E92AF0728530EBF007367AD /* View+UIImage.swift */; }; 9E3451C529C857E400177D16 /* WalletEventsSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6112869882D00A02233 /* WalletEventsSnapshotTests.swift */; }; 9E3451C629C857E700177D16 /* WelcomeSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ECC8E28589E150099D5A2 /* WelcomeSnapshotTests.swift */; }; - 9E39114A2848EEB90073DD9A /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911442848EEB90073DD9A /* UserPreferencesStorage.swift */; }; 9E486DE529B637AF003E6945 /* ImportBirthdayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */; }; 9E486DE629B637AF003E6945 /* ImportBirthdayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */; }; 9E486DF029B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DEF29B9EE84003E6945 /* KeyboardAdaptive.swift */; }; @@ -311,15 +292,10 @@ 9E7CB6202874143800A02233 /* AddressDetailsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB61F2874143800A02233 /* AddressDetailsStore.swift */; }; 9E7CB6212874143800A02233 /* AddressDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB61E2874143800A02233 /* AddressDetailsView.swift */; }; 9E7FE0DF282D2DD600C374E8 /* ZcashBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0DE282D2DD600C374E8 /* ZcashBadge.swift */; }; - 9E7FE0E6282E7B1100C374E8 /* StoredWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0E5282E7B1100C374E8 /* StoredWallet.swift */; }; 9E7FE0F628327F6F00C374E8 /* ScanUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0F528327F6F00C374E8 /* ScanUIView.swift */; }; 9E7FE0F92832824C00C374E8 /* QRCodeScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7FE0F82832824C00C374E8 /* QRCodeScanView.swift */; }; 9E80C44C2A25E8EC0049E6A7 /* MnemonicClient in Frameworks */ = {isa = PBXBuildFile; productRef = 9E80C44B2A25E8EC0049E6A7 /* MnemonicClient */; }; 9E80C4522A25E8FA0049E6A7 /* MnemonicClient in Frameworks */ = {isa = PBXBuildFile; productRef = 9E80C4512A25E8FA0049E6A7 /* MnemonicClient */; }; - 9E80C4672A25EAFB0049E6A7 /* URIParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310C92A24BB420021F995 /* URIParser.swift */; }; - 9E80C4682A25EAFB0049E6A7 /* URIParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310CA2A24BB420021F995 /* URIParserTest.swift */; }; - 9E80C4692A25EAFB0049E6A7 /* URIParserLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310C72A24BB420021F995 /* URIParserLive.swift */; }; - 9E80C46A2A25EAFB0049E6A7 /* URIParserInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0310C82A24BB420021F995 /* URIParserInterface.swift */; }; 9E852D6129B098F400CF4AC1 /* RootDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D6029B098F400CF4AC1 /* RootDebug.swift */; }; 9E852D6229B098F400CF4AC1 /* RootDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E852D6029B098F400CF4AC1 /* RootDebug.swift */; }; 9E9074FF2A260FE400269308 /* WalletEvent+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9074FE2A260FE400269308 /* WalletEvent+View.swift */; }; @@ -343,12 +319,6 @@ 9EAFEB902808183D00199FC9 /* SandboxStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */; }; 9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.swift */; }; 9EAFEB9228081E9400199FC9 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874EF273C4DE200F0E875 /* HomeView.swift */; }; - 9EB8639A2923935B003D0F8B /* WalletStorageTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863972923935B003D0F8B /* WalletStorageTestKey.swift */; }; - 9EB8639B2923935B003D0F8B /* WalletStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863982923935B003D0F8B /* WalletStorageInterface.swift */; }; - 9EB8639C2923935B003D0F8B /* WalletStorageLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863992923935B003D0F8B /* WalletStorageLiveKey.swift */; }; - 9EB8639D29239405003D0F8B /* WalletStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E3911472848EEB90073DD9A /* WalletStorage.swift */; }; - 9EB863C72923C93B003D0F8B /* UserPreferencesStorageLive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C62923C93B003D0F8B /* UserPreferencesStorageLive.swift */; }; - 9EB863C92923C953003D0F8B /* UserPreferencesStorageMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EB863C82923C953003D0F8B /* UserPreferencesStorageMocks.swift */; }; 9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135F27F043CC0075AF48 /* AppDelegate.swift */; }; 9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; }; F93673D62742CB840099C6AF /* Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93673D52742CB840099C6AF /* Previews.swift */; }; @@ -411,7 +381,6 @@ 0D4E7A2126B364180058B01E /* secantUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = secantUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 0D4E7A2526B364180058B01E /* secantUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secantUITests.swift; sourceTree = ""; }; 0D4E7A2726B364180058B01E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 0D6316FF29919970007D873F /* UserPreferencesStorageInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageInterface.swift; sourceTree = ""; }; 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UInt+SuperscriptText.swift"; sourceTree = ""; }; 0DB4E0B02881F2DB00947B78 /* WalletBalance+testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletBalance+testing.swift"; sourceTree = ""; }; 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DesignGuide.swift; sourceTree = ""; }; @@ -448,21 +417,11 @@ 34DA414828E439CD00F8CC61 /* sendingTransaction.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = sendingTransaction.json; sourceTree = ""; }; 34E0AF1028DEE5220034CF37 /* Wedge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wedge.swift; sourceTree = ""; }; 34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderTests.swift; sourceTree = ""; }; - 34F682E429A75EB60022C079 /* WalletConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfig.swift; sourceTree = ""; }; - 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProvider.swift; sourceTree = ""; }; - 34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderInterface.swift; sourceTree = ""; }; - 34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderLiveKey.swift; sourceTree = ""; }; - 34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderTestKey.swift; sourceTree = ""; }; - 34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsWalletConfigStorage.swift; sourceTree = ""; }; 6654C73D2715A41300901167 /* OnboardingFlowStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFlowStore.swift; sourceTree = ""; }; 6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingStoreTests.swift; sourceTree = ""; }; 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = ""; }; 9E01F8272833CDA0000EFC57 /* ScanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanTests.swift; sourceTree = ""; }; 9E02B56B27FED475005B809B /* DatabaseFilesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseFilesTests.swift; sourceTree = ""; }; - 9E0310C72A24BB420021F995 /* URIParserLive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URIParserLive.swift; sourceTree = ""; }; - 9E0310C82A24BB420021F995 /* URIParserInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URIParserInterface.swift; sourceTree = ""; }; - 9E0310C92A24BB420021F995 /* URIParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URIParser.swift; sourceTree = ""; }; - 9E0310CA2A24BB420021F995 /* URIParserTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URIParserTest.swift; sourceTree = ""; }; 9E0F5740297E7F1C005304FA /* TCALogging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCALogging.swift; sourceTree = ""; }; 9E0F5742297EB96C005304FA /* TCALoggerReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCALoggerReducer.swift; sourceTree = ""; }; 9E0F574A2980260D005304FA /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = ""; }; @@ -480,8 +439,6 @@ 9E39112D283F91600073DD9A /* ZatoshiTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZatoshiTests.swift; sourceTree = ""; }; 9E391131284644580073DD9A /* AppInitializationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInitializationTests.swift; sourceTree = ""; }; 9E3911382848AD500073DD9A /* HomeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTests.swift; sourceTree = ""; }; - 9E3911442848EEB90073DD9A /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = ""; }; - 9E3911472848EEB90073DD9A /* WalletStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorage.swift; sourceTree = ""; }; 9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportBirthdayView.swift; sourceTree = ""; }; 9E486DEF29B9EE84003E6945 /* KeyboardAdaptive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardAdaptive.swift; sourceTree = ""; }; 9E486DF229B9EEC4003E6945 /* UIResponder+Current.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Current.swift"; sourceTree = ""; }; @@ -514,7 +471,6 @@ 9E7CB6232874246800A02233 /* ProfileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTests.swift; sourceTree = ""; }; 9E7CB6262874269F00A02233 /* ProfileSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSnapshotTests.swift; sourceTree = ""; }; 9E7FE0DE282D2DD600C374E8 /* ZcashBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZcashBadge.swift; sourceTree = ""; }; - 9E7FE0E5282E7B1100C374E8 /* StoredWallet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoredWallet.swift; sourceTree = ""; }; 9E7FE0F528327F6F00C374E8 /* ScanUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanUIView.swift; sourceTree = ""; }; 9E7FE0F82832824C00C374E8 /* QRCodeScanView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeScanView.swift; sourceTree = ""; }; 9E852D5B29AF8EB200CF4AC1 /* RecoveryPhraseValidationFlowFeatureFlagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidationFlowFeatureFlagTests.swift; sourceTree = ""; }; @@ -542,11 +498,6 @@ 9EAFEB8D2808183D00199FC9 /* SandboxView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxView.swift; sourceTree = ""; }; 9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxStore.swift; sourceTree = ""; }; 9EB7D14A2A20C6BC00F35E03 /* modules */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = modules; sourceTree = ""; }; - 9EB863972923935B003D0F8B /* WalletStorageTestKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorageTestKey.swift; sourceTree = ""; }; - 9EB863982923935B003D0F8B /* WalletStorageInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorageInterface.swift; sourceTree = ""; }; - 9EB863992923935B003D0F8B /* WalletStorageLiveKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletStorageLiveKey.swift; sourceTree = ""; }; - 9EB863C62923C93B003D0F8B /* UserPreferencesStorageLive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageLive.swift; sourceTree = ""; }; - 9EB863C82923C953003D0F8B /* UserPreferencesStorageMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageMocks.swift; sourceTree = ""; }; 9EDDEA9F2829610D00B4100C /* CurrencySelectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencySelectionTests.swift; sourceTree = ""; }; 9EDDEAA02829610D00B4100C /* TransactionAmountInputTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAmountInputTests.swift; sourceTree = ""; }; 9EDDEAA12829610D00B4100C /* TransactionAddressInputTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAddressInputTests.swift; sourceTree = ""; }; @@ -590,7 +541,9 @@ 9E00316E2A272746003DFCEB /* AppVersion in Frameworks */, 9E0031A02A272BB7003DFCEB /* UserDefaults in Frameworks */, 0D26AF74299E8196005260EE /* FirebaseCrashlytics in Frameworks */, + 9E0031B62A27724D003DFCEB /* WalletConfigProvider in Frameworks */, 9E0031742A272747003DFCEB /* DatabaseFiles in Frameworks */, + 9E0031AC2A276BC6003DFCEB /* URIParser in Frameworks */, 9E0031942A272A61003DFCEB /* Pasteboard in Frameworks */, 9E9075142A2691B700269308 /* ZcashSDKEnvironment in Frameworks */, 9E00319E2A272BB6003DFCEB /* SupportDataGenerator in Frameworks */, @@ -604,10 +557,12 @@ 0D26AF76299E8196005260EE /* ComposableArchitecture in Frameworks */, 9E00319C2A272BB6003DFCEB /* SDKSynchronizer in Frameworks */, 9E9075062A2689D600269308 /* RecoveryPhraseValidationFlow in Frameworks */, + 9E0031B82A27724D003DFCEB /* WalletStorage in Frameworks */, 9E90750C2A268CDC00269308 /* SecItem in Frameworks */, 9E00317A2A272747003DFCEB /* DerivationTool in Frameworks */, 9E0031842A27299A003DFCEB /* FeedbackGenerator in Frameworks */, 9E9075042A2681FF00269308 /* Generated in Frameworks */, + 9E0031AE2A276C56003DFCEB /* UserPreferencesStorage in Frameworks */, 9E80C4522A25E8FA0049E6A7 /* MnemonicClient in Frameworks */, 9E00319A2A272BB6003DFCEB /* ReviewRequest in Frameworks */, 0D26AF77299E8196005260EE /* Parsing in Frameworks */, @@ -627,7 +582,9 @@ 9E0031602A272736003DFCEB /* AppVersion in Frameworks */, 9E0031A82A272BC8003DFCEB /* UserDefaults in Frameworks */, 9E0031662A272736003DFCEB /* DatabaseFiles in Frameworks */, + 9E0031B22A27723E003DFCEB /* WalletConfigProvider in Frameworks */, 9E9075122A2691B200269308 /* ZcashSDKEnvironment in Frameworks */, + 9E0031AA2A276BC1003DFCEB /* URIParser in Frameworks */, 9E00318C2A272A52003DFCEB /* Pasteboard in Frameworks */, 9E0310B52A24A4CA0021F995 /* FileManager in Frameworks */, 9E0031A62A272BC8003DFCEB /* SupportDataGenerator in Frameworks */, @@ -641,10 +598,12 @@ 6654C73A2715A38000901167 /* ComposableArchitecture in Frameworks */, 9E0031A42A272BC7003DFCEB /* SDKSynchronizer in Frameworks */, 9E9075082A2689DB00269308 /* RecoveryPhraseValidationFlow in Frameworks */, + 9E0031B42A27723E003DFCEB /* WalletStorage in Frameworks */, 9E00316C2A272736003DFCEB /* DerivationTool in Frameworks */, 9E90750A2A268CD700269308 /* SecItem in Frameworks */, 9E0031802A272991003DFCEB /* FeedbackGenerator in Frameworks */, 9EAB466D285A0468002904A0 /* Parsing in Frameworks */, + 9E0031B02A276C5D003DFCEB /* UserPreferencesStorage in Frameworks */, 9E00317C2A2728CC003DFCEB /* FirebaseCrashlytics in Frameworks */, 9E0031A22A272BC7003DFCEB /* ReviewRequest in Frameworks */, 9E9075022A2681F700269308 /* Generated in Frameworks */, @@ -788,9 +747,7 @@ children = ( 9EF8135F27F043CC0075AF48 /* AppDelegate.swift */, 9EF8139B27F47AED0075AF48 /* InitializationState.swift */, - 9E7FE0E5282E7B1100C374E8 /* StoredWallet.swift */, 9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */, - 34F682E429A75EB60022C079 /* WalletConfig.swift */, ); path = Models; sourceTree = ""; @@ -902,18 +859,6 @@ path = WalletConfigProviderTests; sourceTree = ""; }; - 34F682EA29A763F00022C079 /* WalletConfigProvider */ = { - isa = PBXGroup; - children = ( - 34F682EB29A763FD0022C079 /* WalletConfigProvider.swift */, - 34F682F729A775C10022C079 /* UserDefaultsWalletConfigStorage.swift */, - 34F682EE29A7640A0022C079 /* WalletConfigProviderInterface.swift */, - 34F682F129A764120022C079 /* WalletConfigProviderLiveKey.swift */, - 34F682F429A7641B0022C079 /* WalletConfigProviderTestKey.swift */, - ); - path = WalletConfigProvider; - sourceTree = ""; - }; 6654C73B2715A3F000901167 /* Features */ = { isa = PBXGroup; children = ( @@ -984,17 +929,6 @@ path = ScanTests; sourceTree = ""; }; - 9E0310C62A24BB230021F995 /* URIParser */ = { - isa = PBXGroup; - children = ( - 9E0310C92A24BB420021F995 /* URIParser.swift */, - 9E0310C82A24BB420021F995 /* URIParserInterface.swift */, - 9E0310C72A24BB420021F995 /* URIParserLive.swift */, - 9E0310CA2A24BB420021F995 /* URIParserTest.swift */, - ); - path = URIParser; - sourceTree = ""; - }; 9E0F573F297E7F00005304FA /* Logging */ = { isa = PBXGroup; children = ( @@ -1282,10 +1216,6 @@ isa = PBXGroup; children = ( 0D767873298C374F0047E085 /* CrashReporter */, - 9E0310C62A24BB230021F995 /* URIParser */, - 9EB863B72923C55A003D0F8B /* UserPreferencesStorage */, - 34F682EA29A763F00022C079 /* WalletConfigProvider */, - 9EB86396292392F6003D0F8B /* WalletStorage */, ); path = Dependencies; sourceTree = ""; @@ -1459,28 +1389,6 @@ path = Sandbox; sourceTree = ""; }; - 9EB86396292392F6003D0F8B /* WalletStorage */ = { - isa = PBXGroup; - children = ( - 9E3911472848EEB90073DD9A /* WalletStorage.swift */, - 9EB863982923935B003D0F8B /* WalletStorageInterface.swift */, - 9EB863992923935B003D0F8B /* WalletStorageLiveKey.swift */, - 9EB863972923935B003D0F8B /* WalletStorageTestKey.swift */, - ); - path = WalletStorage; - sourceTree = ""; - }; - 9EB863B72923C55A003D0F8B /* UserPreferencesStorage */ = { - isa = PBXGroup; - children = ( - 9E3911442848EEB90073DD9A /* UserPreferencesStorage.swift */, - 9EB863C62923C93B003D0F8B /* UserPreferencesStorageLive.swift */, - 9EB863C82923C953003D0F8B /* UserPreferencesStorageMocks.swift */, - 0D6316FF29919970007D873F /* UserPreferencesStorageInterface.swift */, - ); - path = UserPreferencesStorage; - sourceTree = ""; - }; 9EF8135927ECC25E0075AF48 /* UtilTests */ = { isa = PBXGroup; children = ( @@ -1638,6 +1546,10 @@ 9E00319B2A272BB6003DFCEB /* SDKSynchronizer */, 9E00319D2A272BB6003DFCEB /* SupportDataGenerator */, 9E00319F2A272BB7003DFCEB /* UserDefaults */, + 9E0031AB2A276BC6003DFCEB /* URIParser */, + 9E0031AD2A276C56003DFCEB /* UserPreferencesStorage */, + 9E0031B52A27724D003DFCEB /* WalletConfigProvider */, + 9E0031B72A27724D003DFCEB /* WalletStorage */, ); productName = secant; productReference = 0D26AF94299E8196005260EE /* secant-mainnet.app */; @@ -1691,6 +1603,10 @@ 9E0031A32A272BC7003DFCEB /* SDKSynchronizer */, 9E0031A52A272BC8003DFCEB /* SupportDataGenerator */, 9E0031A72A272BC8003DFCEB /* UserDefaults */, + 9E0031A92A276BC1003DFCEB /* URIParser */, + 9E0031AF2A276C5D003DFCEB /* UserPreferencesStorage */, + 9E0031B12A27723E003DFCEB /* WalletConfigProvider */, + 9E0031B32A27723E003DFCEB /* WalletStorage */, ); productName = secant; productReference = 0D4E7A0526B364170058B01E /* secant-testnet.app */; @@ -2007,18 +1923,14 @@ files = ( 0D26AE9B299E8196005260EE /* OnboardingFlowView.swift in Sources */, 0D26AE9C299E8196005260EE /* ZcashBadge.swift in Sources */, - 34F682F329A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */, 0D26AE9D299E8196005260EE /* CrashReporterTestKey.swift in Sources */, 0D26AEA0299E8196005260EE /* SandboxStore.swift in Sources */, - 0D26AEA3299E8196005260EE /* UserPreferencesStorage.swift in Sources */, 0D26AEA5299E8196005260EE /* TransactionSendingView.swift in Sources */, 0D26AEA6299E8196005260EE /* WalletEventsFlowView.swift in Sources */, 0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */, 0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */, - 34F682F029A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */, 0D26AEAF299E8196005260EE /* TransactionAmountTextFieldStore.swift in Sources */, 0D26AEB1299E8196005260EE /* AppDelegate.swift in Sources */, - 34F682F929A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */, 0D3016B929BFB2FB002371B3 /* PlainOnboardingView.swift in Sources */, 0D26AEB4299E8196005260EE /* Wedge.swift in Sources */, 0D26AEB5299E8196005260EE /* TransactionDetailView.swift in Sources */, @@ -2027,9 +1939,7 @@ 0D26AEBF299E8196005260EE /* TransactionFailedView.swift in Sources */, 0D26AEC2299E8196005260EE /* TransactionRowView.swift in Sources */, 0D26AEC4299E8196005260EE /* TCALogging.swift in Sources */, - 9E80C4672A25EAFB0049E6A7 /* URIParser.swift in Sources */, 9E486DFA29BA09C2003E6945 /* UIKit+Extensions.swift in Sources */, - 9E80C46A2A25EAFB0049E6A7 /* URIParserInterface.swift in Sources */, 9E33ECDA29D5E30700708DE4 /* OnChangeReducer.swift in Sources */, 0D26AEC6299E8196005260EE /* ImportWalletView.swift in Sources */, 0D26AEC7299E8196005260EE /* RootInitialization.swift in Sources */, @@ -2037,13 +1947,11 @@ 0D26AECF299E8196005260EE /* CurrencySelectionStore.swift in Sources */, 0D26AED2299E8196005260EE /* BalanceBreakdownStore.swift in Sources */, 0D26AED3299E8196005260EE /* SyncStatusSnapshot.swift in Sources */, - 0D26AED6299E8196005260EE /* UserPreferencesStorageInterface.swift in Sources */, 0D26AEDA299E8196005260EE /* ImportSeedEditor.swift in Sources */, 0D26AEDB299E8196005260EE /* ProfileStore.swift in Sources */, 9E486DE629B637AF003E6945 /* ImportBirthdayView.swift in Sources */, 0D26AEDC299E8196005260EE /* CheckCircle.swift in Sources */, 9E33ECD929D5E30200708DE4 /* AlertRequest.swift in Sources */, - 9E80C4692A25EAFB0049E6A7 /* URIParserLive.swift in Sources */, 0D26AEE4299E8196005260EE /* CurrencySelectionView.swift in Sources */, 0D26AEE7299E8196005260EE /* TransactionAddressTextFieldStore.swift in Sources */, 34C5658629B60C8B002F3A7C /* ExportLogsStore.swift in Sources */, @@ -2064,29 +1972,22 @@ 9E9075002A260FE400269308 /* WalletEvent+View.swift in Sources */, 0D3016B629BF94D1002371B3 /* Button+Disabling.swift in Sources */, 9E852D6229B098F400CF4AC1 /* RootDebug.swift in Sources */, - 34F682ED29A763FD0022C079 /* WalletConfigProvider.swift in Sources */, 0D26AF05299E8196005260EE /* ScanView.swift in Sources */, 0D26AF07299E8196005260EE /* RootView.swift in Sources */, 0D26AF0A299E8196005260EE /* OnboardingFooterView.swift in Sources */, 0D26AF0E299E8196005260EE /* MultiLineTextFieldStore.swift in Sources */, 0D26AF0F299E8196005260EE /* DebugFrame.swift in Sources */, 0D26AF11299E8196005260EE /* LottieAnimation.swift in Sources */, - 0D26AF12299E8196005260EE /* UserPreferencesStorageMocks.swift in Sources */, 0D26AF13299E8196005260EE /* RecoveryPhraseDisplayStore.swift in Sources */, 9E486DF129B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */, 0D573CB629C106E900B97379 /* About.swift in Sources */, 0D26AF18299E8196005260EE /* WalletEventsFlowStore.swift in Sources */, - 0D26AF19299E8196005260EE /* StoredWallet.swift in Sources */, - 34F682E629A75EB60022C079 /* WalletConfig.swift in Sources */, 0D26AF1B299E8196005260EE /* HomeStore.swift in Sources */, 0D26AF1E299E8196005260EE /* QRCodeGenerator.swift in Sources */, 0D26AF20299E8196005260EE /* UInt+SuperscriptText.swift in Sources */, 0D26AF23299E8196005260EE /* SendFlowStore.swift in Sources */, 0D26AF24299E8196005260EE /* SecantApp.swift in Sources */, - 0D26AF26299E8196005260EE /* WalletStorageLiveKey.swift in Sources */, - 0D26AF27299E8196005260EE /* WalletStorageInterface.swift in Sources */, 0D26AF2D299E8196005260EE /* DebugMenu.swift in Sources */, - 34F682F629A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */, 0D26AF37299E8196005260EE /* ScanUIView.swift in Sources */, 0D26AF3A299E8196005260EE /* OnboardingContentView.swift in Sources */, 0D26AF3B299E8196005260EE /* CircularProgress.swift in Sources */, @@ -2109,18 +2010,14 @@ 346731A329AE3A5100974482 /* UIMailDialog.swift in Sources */, 0D26AF55299E8196005260EE /* ProfileView.swift in Sources */, 0D26AF56299E8196005260EE /* ScanStore.swift in Sources */, - 0D26AF59299E8196005260EE /* WalletStorage.swift in Sources */, 0D26AF5C299E8196005260EE /* WelcomeStore.swift in Sources */, 0D26AF5F299E8196005260EE /* SendFlowView.swift in Sources */, - 0D26AF61299E8196005260EE /* WalletStorageTestKey.swift in Sources */, 0D26AF62299E8196005260EE /* WelcomeView.swift in Sources */, 9E33ECD729D5E30200708DE4 /* AlertReducer.swift in Sources */, 0D26AF64299E8196005260EE /* SettingsStore.swift in Sources */, 0D26AF65299E8196005260EE /* InitializationState.swift in Sources */, 0D26AF66299E8196005260EE /* ZcashSymbol.swift in Sources */, - 0D26AF67299E8196005260EE /* UserPreferencesStorageLive.swift in Sources */, 9E486DF429B9EEC4003E6945 /* UIResponder+Current.swift in Sources */, - 9E80C4682A25EAFB0049E6A7 /* URIParserTest.swift in Sources */, 0D26AF68299E8196005260EE /* TransactionAmountTextField.swift in Sources */, 0D26AF69299E8196005260EE /* AddressDetailsView.swift in Sources */, 0D26AF6A299E8196005260EE /* ClearBackgroundView.swift in Sources */, @@ -2135,20 +2032,16 @@ 9E33ECD629D5D99A00708DE4 /* AlertStates.swift in Sources */, 2EB660E02747EAB900A06A07 /* OnboardingFlowView.swift in Sources */, 9E7FE0DF282D2DD600C374E8 /* ZcashBadge.swift in Sources */, - 34F682F229A764120022C079 /* WalletConfigProviderLiveKey.swift in Sources */, 0D261040298C406F00CC9DE9 /* CrashReporterTestKey.swift in Sources */, 9EAFEB902808183D00199FC9 /* SandboxStore.swift in Sources */, - 9E39114A2848EEB90073DD9A /* UserPreferencesStorage.swift in Sources */, 34DA414728E4385800F8CC61 /* TransactionSendingView.swift in Sources */, F96B41E9273B501F0021B49A /* WalletEventsFlowView.swift in Sources */, 9E4AA4F829BF76BB00752BB3 /* About.swift in Sources */, 9E33ECD429D5D99000708DE4 /* AlertRequest.swift in Sources */, 0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */, 2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */, - 34F682EF29A7640A0022C079 /* WalletConfigProviderInterface.swift in Sources */, 2EB7758727FC67FD00269373 /* TransactionAmountTextFieldStore.swift in Sources */, 9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */, - 34F682F829A775C10022C079 /* UserDefaultsWalletConfigStorage.swift in Sources */, 0D3016B829BFB2FB002371B3 /* PlainOnboardingView.swift in Sources */, 34E0AF1128DEE5220034CF37 /* Wedge.swift in Sources */, F96B41E8273B501F0021B49A /* TransactionDetailView.swift in Sources */, @@ -2166,8 +2059,6 @@ 9E33ECD529D5D99700708DE4 /* AlertReducer.swift in Sources */, 9E6713F7289BC58C00A6796F /* BalanceBreakdownStore.swift in Sources */, 9E66122C2877188700C75B70 /* SyncStatusSnapshot.swift in Sources */, - 0D63170029919970007D873F /* UserPreferencesStorageInterface.swift in Sources */, - 9E0310CC2A24BB420021F995 /* URIParserInterface.swift in Sources */, 9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */, F9971A5327680DD000A2DB75 /* ProfileStore.swift in Sources */, 9E486DE529B637AF003E6945 /* ImportBirthdayView.swift in Sources */, @@ -2192,30 +2083,21 @@ 0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */, 0D3016B529BF94D1002371B3 /* Button+Disabling.swift in Sources */, 9E852D6129B098F400CF4AC1 /* RootDebug.swift in Sources */, - 34F682EC29A763FD0022C079 /* WalletConfigProvider.swift in Sources */, F9971A5F27680DF600A2DB75 /* ScanView.swift in Sources */, F9971A4E27680DC400A2DB75 /* RootView.swift in Sources */, 2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */, 9E7225F6288AC71A00DF7F17 /* MultiLineTextFieldStore.swift in Sources */, 2EDA07A427EDE2A900D6F09B /* DebugFrame.swift in Sources */, 9E6612332878338C00C75B70 /* LottieAnimation.swift in Sources */, - 9EB863C92923C953003D0F8B /* UserPreferencesStorageMocks.swift in Sources */, 0D3D040A2728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift in Sources */, 9E486DF029B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */, - 9E0310CD2A24BB420021F995 /* URIParser.swift in Sources */, F96B41E7273B501F0021B49A /* WalletEventsFlowStore.swift in Sources */, - 9E7FE0E6282E7B1100C374E8 /* StoredWallet.swift in Sources */, - 34F682E529A75EB60022C079 /* WalletConfig.swift in Sources */, 9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */, 9E7CB61A287310EC00A02233 /* QRCodeGenerator.swift in Sources */, 0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */, F9C165BF2740403600592F76 /* SendFlowStore.swift in Sources */, 0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */, - 9EB8639C2923935B003D0F8B /* WalletStorageLiveKey.swift in Sources */, - 9EB8639B2923935B003D0F8B /* WalletStorageInterface.swift in Sources */, 9E2F1C842809B606004E65FE /* DebugMenu.swift in Sources */, - 9E0310CE2A24BB420021F995 /* URIParserTest.swift in Sources */, - 34F682F529A7641B0022C079 /* WalletConfigProviderTestKey.swift in Sources */, 9E7FE0F628327F6F00C374E8 /* ScanUIView.swift in Sources */, 2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */, 9E7CB6152869E8C300A02233 /* CircularProgress.swift in Sources */, @@ -2237,16 +2119,12 @@ 346731A229AE3A5100974482 /* UIMailDialog.swift in Sources */, F9971A5427680DD000A2DB75 /* ProfileView.swift in Sources */, F9971A6027680DF600A2DB75 /* ScanStore.swift in Sources */, - 9EB8639D29239405003D0F8B /* WalletStorage.swift in Sources */, 9E69A24D27FB002800A55317 /* WelcomeStore.swift in Sources */, F9C165CB2741AB5D00592F76 /* SendFlowView.swift in Sources */, - 9EB8639A2923935B003D0F8B /* WalletStorageTestKey.swift in Sources */, 0D0781C4278750E30083ACD7 /* WelcomeView.swift in Sources */, F9971A6527680DFE00A2DB75 /* SettingsStore.swift in Sources */, 9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */, 0D0781C9278776D20083ACD7 /* ZcashSymbol.swift in Sources */, - 9EB863C72923C93B003D0F8B /* UserPreferencesStorageLive.swift in Sources */, - 9E0310CB2A24BB420021F995 /* URIParserLive.swift in Sources */, 9E486DF329B9EEC4003E6945 /* UIResponder+Current.swift in Sources */, 2E8719CB27FB09990082C926 /* TransactionAmountTextField.swift in Sources */, 9E7CB6212874143800A02233 /* AddressDetailsView.swift in Sources */, @@ -3017,6 +2895,38 @@ isa = XCSwiftPackageProductDependency; productName = UserDefaults; }; + 9E0031A92A276BC1003DFCEB /* URIParser */ = { + isa = XCSwiftPackageProductDependency; + productName = URIParser; + }; + 9E0031AB2A276BC6003DFCEB /* URIParser */ = { + isa = XCSwiftPackageProductDependency; + productName = URIParser; + }; + 9E0031AD2A276C56003DFCEB /* UserPreferencesStorage */ = { + isa = XCSwiftPackageProductDependency; + productName = UserPreferencesStorage; + }; + 9E0031AF2A276C5D003DFCEB /* UserPreferencesStorage */ = { + isa = XCSwiftPackageProductDependency; + productName = UserPreferencesStorage; + }; + 9E0031B12A27723E003DFCEB /* WalletConfigProvider */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConfigProvider; + }; + 9E0031B32A27723E003DFCEB /* WalletStorage */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletStorage; + }; + 9E0031B52A27724D003DFCEB /* WalletConfigProvider */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConfigProvider; + }; + 9E0031B72A27724D003DFCEB /* WalletStorage */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletStorage; + }; 9E0310B42A24A4CA0021F995 /* FileManager */ = { isa = XCSwiftPackageProductDependency; productName = FileManager; diff --git a/secant/Dependencies/URIParser/URIParser.swift b/secant/Dependencies/URIParser/URIParser.swift deleted file mode 100644 index cc3a1caf..00000000 --- a/secant/Dependencies/URIParser/URIParser.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// URIParser.swift -// secant-testnet -// -// Created by Lukáš Korba on 17.05.2022. -// - -import Foundation -import DerivationTool - -public struct URIParser { - enum URIParserError: Error { } - - private let derivationTool: DerivationToolClient - - init(derivationTool: DerivationToolClient) { - self.derivationTool = derivationTool - } - - func isValidURI(_ uri: String) -> Bool { - derivationTool.isZcashAddress(uri, TargetConstants.zcashNetwork.networkType) - } -} diff --git a/secant/Dependencies/URIParser/URIParserLive.swift b/secant/Dependencies/URIParser/URIParserLive.swift deleted file mode 100644 index ac5435a9..00000000 --- a/secant/Dependencies/URIParser/URIParserLive.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// URIParserLive.swift -// secant-testnet -// -// Created by Lukáš Korba on 15.11.2022. -// - -import ComposableArchitecture - -extension URIParserClient: DependencyKey { - static let liveValue = URIParserClient.live() - - static func live(uriParser: URIParser = URIParser(derivationTool: .live())) -> Self { - Self( - isValidURI: { uri in uriParser.isValidURI(uri) } - ) - } -} diff --git a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift b/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift deleted file mode 100644 index 2ebfb536..00000000 --- a/secant/Dependencies/UserPreferencesStorage/UserPreferencesStorageInterface.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// UserPreferencesStorageInterface.swift -// secant-testnet -// -// Created by Francisco Gindre on 2/6/23. -// - -import Foundation -import ComposableArchitecture - -extension DependencyValues { - var userStoredPreferences: UserPreferencesStorageClient { - get { self[UserPreferencesStorageClient.self] } - set { self[UserPreferencesStorageClient.self] = newValue } - } -} - -struct UserPreferencesStorageClient { - var activeAppSessionFrom: () -> TimeInterval - var setActiveAppSessionFrom: (TimeInterval) async -> Void - - var currency: () -> String - var setCurrenty: (String) async -> Void - - var isFiatConverted: () -> Bool - var setIsFiatConverted: (Bool) async -> Void - - var isRecoveryPhraseTestCompleted: () -> Bool - var setIsRecoveryPhraseTestCompleted: (Bool) async -> Void - - var isSessionAutoshielded: () -> Bool - var setIsSessionAutoshielded: (Bool) async -> Void - - var isUserOptedOutOfCrashReporting: () -> Bool - var setIsUserOptedOutOfCrashReporting: (Bool) async -> Void - - var removeAll: () async -> Void -} diff --git a/secant/Features/BalanceBreakdown/BalanceBreakdownStore.swift b/secant/Features/BalanceBreakdown/BalanceBreakdownStore.swift index ede5d564..df904ca8 100644 --- a/secant/Features/BalanceBreakdown/BalanceBreakdownStore.swift +++ b/secant/Features/BalanceBreakdown/BalanceBreakdownStore.swift @@ -13,6 +13,7 @@ import MnemonicClient import NumberFormatter import Utils import Generated +import WalletStorage typealias BalanceBreakdownStore = Store typealias BalanceBreakdownViewStore = ViewStore diff --git a/secant/Features/ImportWallet/ImportWalletStore.swift b/secant/Features/ImportWallet/ImportWalletStore.swift index a41a299c..27274f45 100644 --- a/secant/Features/ImportWallet/ImportWalletStore.swift +++ b/secant/Features/ImportWallet/ImportWalletStore.swift @@ -10,6 +10,7 @@ import ZcashLightClientKit import SwiftUI import Utils import Generated +import WalletStorage typealias ImportWalletStore = Store typealias ImportWalletViewStore = ViewStore diff --git a/secant/Features/OnboardingFlow/OnboardingFlowStore.swift b/secant/Features/OnboardingFlow/OnboardingFlowStore.swift index d0c979bf..805e9ce8 100644 --- a/secant/Features/OnboardingFlow/OnboardingFlowStore.swift +++ b/secant/Features/OnboardingFlow/OnboardingFlowStore.swift @@ -9,6 +9,7 @@ import Foundation import SwiftUI import ComposableArchitecture import Generated +import Models typealias OnboardingFlowStore = Store typealias OnboardingFlowViewStore = ViewStore diff --git a/secant/Features/OnboardingFlow/Views/OnboardingHeaderView.swift b/secant/Features/OnboardingFlow/Views/OnboardingHeaderView.swift index a0086fc7..4815bd59 100644 --- a/secant/Features/OnboardingFlow/Views/OnboardingHeaderView.swift +++ b/secant/Features/OnboardingFlow/Views/OnboardingHeaderView.swift @@ -8,6 +8,7 @@ import SwiftUI import ComposableArchitecture import Generated +import Models struct OnboardingHeaderView: View { struct ViewState: Equatable { diff --git a/secant/Features/Root/RootDebug.swift b/secant/Features/Root/RootDebug.swift index 9ff2687e..96429067 100644 --- a/secant/Features/Root/RootDebug.swift +++ b/secant/Features/Root/RootDebug.swift @@ -10,6 +10,7 @@ import ComposableArchitecture import Foundation import ZcashLightClientKit import Generated +import Models /// In this file is a collection of helpers that control all state and action related operations /// for the `RootReducer` with a connection to the UI navigation. diff --git a/secant/Features/Root/RootStore.swift b/secant/Features/Root/RootStore.swift index bf8943d3..c9c044f2 100644 --- a/secant/Features/Root/RootStore.swift +++ b/secant/Features/Root/RootStore.swift @@ -4,6 +4,10 @@ import DatabaseFiles import Deeplink import RecoveryPhraseValidationFlow import ZcashSDKEnvironment +import WalletStorage +import WalletConfigProvider +import UserPreferencesStorage +import Models typealias RootStore = Store typealias RootViewStore = ViewStore diff --git a/secant/Features/Root/RootView.swift b/secant/Features/Root/RootView.swift index a0eb0a64..4af8f74d 100644 --- a/secant/Features/Root/RootView.swift +++ b/secant/Features/Root/RootView.swift @@ -3,6 +3,7 @@ import StoreKit import ComposableArchitecture import Generated import RecoveryPhraseValidationFlow +import Models struct RootView: View { let store: RootStore diff --git a/secant/Features/Scan/ScanStore.swift b/secant/Features/Scan/ScanStore.swift index 4c756e71..65db35b7 100644 --- a/secant/Features/Scan/ScanStore.swift +++ b/secant/Features/Scan/ScanStore.swift @@ -9,6 +9,7 @@ import ComposableArchitecture import Foundation import CaptureDevice import Utils +import URIParser typealias ScanStore = Store typealias ScanViewStore = ViewStore @@ -90,7 +91,7 @@ struct ScanReducer: ReducerProtocol { if let prevCode = state.scannedValue, prevCode == code.data { return .none } - if uriParser.isValidURI(code.data) { + if uriParser.isValidURI(code.data, TargetConstants.zcashNetwork.networkType) { state.scanStatus = .value(code) // once valid URI is scanned we want to start the timer to deliver the code // any new code cancels the schedule and fires new one diff --git a/secant/Models/StoredWallet.swift b/secant/Models/StoredWallet.swift deleted file mode 100644 index 2b68bfa7..00000000 --- a/secant/Models/StoredWallet.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// StoredWallet.swift -// secant-testnet -// -// Created by Lukáš Korba on 13.05.2022. -// - -import Foundation -import ZcashLightClientKit -import MnemonicSwift -import Utils -import Models - -/// Representation of the wallet stored in the persistent storage (typically keychain, handled by `WalletStorage`). -struct StoredWallet: Codable, Equatable { - let language: MnemonicLanguageType - let seedPhrase: SeedPhrase - let version: Int - - var birthday: Birthday? - var hasUserPassedPhraseBackupTest: Bool -} - -extension StoredWallet { - static let placeholder = Self( - language: .english, - seedPhrase: SeedPhrase(RecoveryPhrase.testPhrase.joined(separator: " ")), - version: 0, - birthday: Birthday(0), - hasUserPassedPhraseBackupTest: false - ) -} diff --git a/secantTests/HomeTests/HomeFeatureFlagTests.swift b/secantTests/HomeTests/HomeFeatureFlagTests.swift index 69c5e7d5..cd7ed1b9 100644 --- a/secantTests/HomeTests/HomeFeatureFlagTests.swift +++ b/secantTests/HomeTests/HomeFeatureFlagTests.swift @@ -6,6 +6,8 @@ // import XCTest +import WalletConfigProvider +import Models @testable import secant_testnet class HomeFeatureFlagTests: XCTestCase { diff --git a/secantTests/OnboardingTests/OnboardingFlowFeatureFlagTests.swift b/secantTests/OnboardingTests/OnboardingFlowFeatureFlagTests.swift index db7db4d7..9b0d4065 100644 --- a/secantTests/OnboardingTests/OnboardingFlowFeatureFlagTests.swift +++ b/secantTests/OnboardingTests/OnboardingFlowFeatureFlagTests.swift @@ -6,8 +6,10 @@ // import XCTest -@testable import secant_testnet import ComposableArchitecture +import WalletConfigProvider +import Models +@testable import secant_testnet class OnboardingFlowFeatureFlagTests: XCTestCase { override func setUp() { diff --git a/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift b/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift index afe7d173..1af1dddc 100644 --- a/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift +++ b/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift @@ -12,6 +12,7 @@ import RecoveryPhraseValidationFlow import Models import UIComponents import Generated +import WalletConfigProvider @testable import secant_testnet // swiftlint:disable:next type_name diff --git a/secantTests/RootTests/RootTests.swift b/secantTests/RootTests/RootTests.swift index e619467c..abbc3de7 100644 --- a/secantTests/RootTests/RootTests.swift +++ b/secantTests/RootTests/RootTests.swift @@ -11,6 +11,7 @@ import ZcashLightClientKit import FileManager import DatabaseFiles import ZcashSDKEnvironment +import WalletStorage @testable import secant_testnet class RootTests: XCTestCase { diff --git a/secantTests/ScanTests/ScanTests.swift b/secantTests/ScanTests/ScanTests.swift index e097c7a8..938c935e 100644 --- a/secantTests/ScanTests/ScanTests.swift +++ b/secantTests/ScanTests/ScanTests.swift @@ -65,7 +65,7 @@ class ScanTests: XCTestCase { reducer: ScanReducer() ) - store.dependencies.uriParser.isValidURI = { _ in false } + store.dependencies.uriParser.isValidURI = { _, _ in false } let value = "test".redacted store.send(.scan(value)) { state in @@ -82,7 +82,7 @@ class ScanTests: XCTestCase { ) store.dependencies.mainQueue = testScheduler.eraseToAnyScheduler() - store.dependencies.uriParser.isValidURI = { _ in true } + store.dependencies.uriParser.isValidURI = { _, _ in true } let address = "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted store.send(.scan(address)) { state in diff --git a/secantTests/SendTests/SendTests.swift b/secantTests/SendTests/SendTests.swift index 0823d6de..6076b08f 100644 --- a/secantTests/SendTests/SendTests.swift +++ b/secantTests/SendTests/SendTests.swift @@ -10,6 +10,8 @@ import ComposableArchitecture import ZcashLightClientKit import AudioServices import NumberFormatter +import Models +import WalletStorage @testable import secant_testnet // swiftlint:disable type_body_length diff --git a/secantTests/SettingsTests/SettingsTests.swift b/secantTests/SettingsTests/SettingsTests.swift index 212aee73..30ef5f69 100644 --- a/secantTests/SettingsTests/SettingsTests.swift +++ b/secantTests/SettingsTests/SettingsTests.swift @@ -10,6 +10,7 @@ import Utils import ComposableArchitecture import LogsHandler import Models +import WalletStorage @testable import secant_testnet @MainActor diff --git a/secantTests/UtilTests/SecItemClientTests.swift b/secantTests/UtilTests/SecItemClientTests.swift index 129a8112..1ba2a8c9 100644 --- a/secantTests/UtilTests/SecItemClientTests.swift +++ b/secantTests/UtilTests/SecItemClientTests.swift @@ -7,6 +7,8 @@ import XCTest import SecItem +import Models +import WalletStorage @testable import secant_testnet extension WalletStorage.KeychainError { diff --git a/secantTests/UtilTests/UserPreferencesStorageTests.swift b/secantTests/UtilTests/UserPreferencesStorageTests.swift index b998d85b..ec2791ae 100644 --- a/secantTests/UtilTests/UserPreferencesStorageTests.swift +++ b/secantTests/UtilTests/UserPreferencesStorageTests.swift @@ -7,6 +7,7 @@ import XCTest import UserDefaults +import UserPreferencesStorage @testable import secant_testnet class UserPreferencesStorageTests: XCTestCase { diff --git a/secantTests/UtilTests/WalletStorageTests.swift b/secantTests/UtilTests/WalletStorageTests.swift index 38ad2cc8..2267fb45 100644 --- a/secantTests/UtilTests/WalletStorageTests.swift +++ b/secantTests/UtilTests/WalletStorageTests.swift @@ -9,6 +9,8 @@ import XCTest import MnemonicSwift import ZcashLightClientKit import Utils +import WalletStorage +import Models @testable import secant_testnet extension WalletStorage.WalletStorageError { diff --git a/secantTests/WalletConfigProviderTests/WalletConfigProviderTests.swift b/secantTests/WalletConfigProviderTests/WalletConfigProviderTests.swift index b89613f3..ec17cd86 100644 --- a/secantTests/WalletConfigProviderTests/WalletConfigProviderTests.swift +++ b/secantTests/WalletConfigProviderTests/WalletConfigProviderTests.swift @@ -7,8 +7,10 @@ import Combine import XCTest -@testable import secant_testnet import ComposableArchitecture +import WalletConfigProvider +import Models +@testable import secant_testnet class WalletConfigProviderTests: XCTestCase { var cancellables: [AnyCancellable] = []