diff --git a/modules/Package.swift b/modules/Package.swift index b93610b..254b6d6 100644 --- a/modules/Package.swift +++ b/modules/Package.swift @@ -62,7 +62,7 @@ let package = Package( .package(url: "https://github.com/pointfreeco/swift-url-routing", from: "0.5.0"), .package(url: "https://github.com/SwiftGen/SwiftGenPlugin", from: "6.6.0"), .package(url: "https://github.com/zcash-hackworks/MnemonicSwift", from: "2.2.4"), - .package(url: "https://github.com/zcash/ZcashLightClientKit", revision: "9a82acbd5e33495a3ac7353bde77cfd741a75244"), + .package(url: "https://github.com/zcash/ZcashLightClientKit", from: "2.0.0-rc.1"), .package(url: "https://github.com/firebase/firebase-ios-sdk", from: "10.11.0") ], targets: [ diff --git a/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerInterface.swift b/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerInterface.swift index 2e9fad8..47711a4 100644 --- a/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerInterface.swift +++ b/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerInterface.swift @@ -22,9 +22,8 @@ public struct SDKSynchronizerClient { public let stateStream: () -> AnyPublisher public let eventStream: () -> AnyPublisher public let latestState: () -> SynchronizerState - public let latestScannedHeight: () -> BlockHeight - public let prepareWith: ([UInt8], UnifiedFullViewingKey, BlockHeight) async throws -> Void + public let prepareWith: ([UInt8], BlockHeight, WalletInitMode) async throws -> Void public let start: (_ retry: Bool) async throws -> Void public let stop: () -> Void public let isSyncing: () -> Bool diff --git a/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerLive.swift b/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerLive.swift index 2a6ac7c..f8e3195 100644 --- a/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerLive.swift +++ b/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerLive.swift @@ -38,9 +38,8 @@ extension SDKSynchronizerClient { stateStream: { synchronizer.stateStream }, eventStream: { synchronizer.eventStream }, latestState: { synchronizer.latestState }, - latestScannedHeight: { synchronizer.latestState.latestScannedHeight }, - prepareWith: { seedBytes, viewingKey, walletBirtday in - let result = try await synchronizer.prepare(with: seedBytes, viewingKeys: [viewingKey], walletBirthday: walletBirtday) + prepareWith: { seedBytes, walletBirtday, walletMode in + let result = try await synchronizer.prepare(with: seedBytes, walletBirthday: walletBirtday, for: walletMode) if result != .success { throw ZcashError.synchronizerNotPrepared } }, start: { retry in try await synchronizer.start(retry: retry) }, @@ -58,7 +57,7 @@ extension SDKSynchronizerClient { var transaction = TransactionState.init( transaction: clearedTransaction, memos: clearedTransaction.memoCount > 0 ? try await synchronizer.getMemos(for: clearedTransaction) : nil, - latestBlockHeight: synchronizer.latestState.latestScannedHeight + latestBlockHeight: synchronizer.latestState.latestBlockHeight ) let recipients = await synchronizer.getRecipients(for: clearedTransaction) diff --git a/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerTest.swift b/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerTest.swift index b5ee0a1..8dadcd3 100644 --- a/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerTest.swift +++ b/modules/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerTest.swift @@ -17,7 +17,6 @@ extension SDKSynchronizerClient: TestDependencyKey { stateStream: XCTUnimplemented("\(Self.self).stateStream", placeholder: Empty().eraseToAnyPublisher()), eventStream: XCTUnimplemented("\(Self.self).eventStream", placeholder: Empty().eraseToAnyPublisher()), latestState: XCTUnimplemented("\(Self.self).latestState", placeholder: .zero), - latestScannedHeight: XCTUnimplemented("\(Self.self).latestScannedHeight", placeholder: 0), prepareWith: XCTUnimplemented("\(Self.self).prepareWith"), start: XCTUnimplemented("\(Self.self).start"), stop: XCTUnimplemented("\(Self.self).stop"), @@ -41,7 +40,6 @@ extension SDKSynchronizerClient { stateStream: { Empty().eraseToAnyPublisher() }, eventStream: { Empty().eraseToAnyPublisher() }, latestState: { .zero }, - latestScannedHeight: { 0 }, prepareWith: { _, _, _ in }, start: { _ in }, stop: { }, @@ -68,7 +66,7 @@ extension SDKSynchronizerClient { eventStream: @escaping () -> AnyPublisher = { Empty().eraseToAnyPublisher() }, latestState: @escaping () -> SynchronizerState = { .zero }, latestScannedHeight: @escaping () -> BlockHeight = { 0 }, - prepareWith: @escaping ([UInt8], UnifiedFullViewingKey, BlockHeight) throws -> Void = { _, _, _ in }, + prepareWith: @escaping ([UInt8], BlockHeight, WalletInitMode) throws -> Void = { _, _, _ in }, start: @escaping (_ retry: Bool) throws -> Void = { _ in }, stop: @escaping () -> Void = { }, isSyncing: @escaping () -> Bool = { false }, @@ -183,7 +181,6 @@ extension SDKSynchronizerClient { stateStream: stateStream, eventStream: eventStream, latestState: latestState, - latestScannedHeight: latestScannedHeight, prepareWith: prepareWith, start: start, stop: stop, diff --git a/modules/Sources/Features/BalanceBreakdown/BalanceBreakdownStore.swift b/modules/Sources/Features/BalanceBreakdown/BalanceBreakdownStore.swift index 8a596a4..c589554 100644 --- a/modules/Sources/Features/BalanceBreakdown/BalanceBreakdownStore.swift +++ b/modules/Sources/Features/BalanceBreakdown/BalanceBreakdownStore.swift @@ -135,7 +135,7 @@ public struct BalanceBreakdownReducer: ReducerProtocol { return EffectTask(value: .updateLatestBlock) case .updateLatestBlock: - let latestBlockNumber = sdkSynchronizer.latestScannedHeight() + let latestBlockNumber = sdkSynchronizer.latestState().latestBlockHeight let latestBlock = numberFormatter.string(NSDecimalNumber(value: latestBlockNumber)) state.latestBlock = "\(String(describing: latestBlock ?? ""))" return .none diff --git a/modules/Sources/Features/Root/RootInitialization.swift b/modules/Sources/Features/Root/RootInitialization.swift index 896e9ac..78713d6 100644 --- a/modules/Sources/Features/Root/RootInitialization.swift +++ b/modules/Sources/Features/Root/RootInitialization.swift @@ -21,7 +21,7 @@ extension RootReducer { case configureCrashReporter case createNewWallet case checkWalletConfig - case initializeSDK + case initializeSDK(WalletInitMode) case initialSetups case initializationFailed(ZcashError) case nukeWallet @@ -97,7 +97,7 @@ extension RootReducer { state.appInitializationState = .filesMissing } return .concatenate( - EffectTask(value: .initialization(.initializeSDK)), + EffectTask(value: .initialization(.initializeSDK(.existingWallet))), EffectTask(value: .initialization(.checkBackupPhraseValidation)) ) case .uninitialized: @@ -110,7 +110,7 @@ extension RootReducer { /// Stored wallet is present, database files may or may not be present, trying to initialize app state variables and environments. /// When initialization succeeds user is taken to the home screen. - case .initialization(.initializeSDK): + case .initialization(.initializeSDK(let walletMode)): do { state.storedWallet = try walletStorage.exportWallet() @@ -124,12 +124,10 @@ extension RootReducer { try mnemonic.isValid(storedWallet.seedPhrase.value()) let seedBytes = try mnemonic.toSeed(storedWallet.seedPhrase.value()) - let spendingKey = try derivationTool.deriveSpendingKey(seedBytes, 0, zcashNetwork.networkType) - let viewingKey = try derivationTool.deriveUnifiedFullViewingKey(spendingKey, zcashNetwork.networkType) return .run { send in do { - try await sdkSynchronizer.prepareWith(seedBytes, viewingKey, birthday) + try await sdkSynchronizer.prepareWith(seedBytes, birthday, walletMode) try await sdkSynchronizer.start(false) } catch { await send(.initialization(.initializationFailed(error.toZcashError()))) @@ -180,7 +178,7 @@ extension RootReducer { state.phraseValidationState = randomRecoveryPhrase.random(recoveryPhrase) return .concatenate( - EffectTask(value: .initialization(.initializeSDK)), + EffectTask(value: .initialization(.initializeSDK(.newWallet))), EffectTask(value: .phraseValidation(.displayBackedUpPhrase)) ) } catch { @@ -244,7 +242,7 @@ extension RootReducer { return EffectTask(value: .destination(.updateDestination(.home))) case .onboarding(.importWallet(.initializeSDK)): - return EffectTask(value: .initialization(.initializeSDK)) + return EffectTask(value: .initialization(.initializeSDK(.restoreWallet))) case .onboarding(.createNewWallet): return EffectTask(value: .initialization(.createNewWallet)) diff --git a/modules/Sources/Features/WalletEventsFlow/Views/TransactionDetailView.swift b/modules/Sources/Features/WalletEventsFlow/Views/TransactionDetailView.swift index 0fa14b9..7f01b6b 100644 --- a/modules/Sources/Features/WalletEventsFlow/Views/TransactionDetailView.swift +++ b/modules/Sources/Features/WalletEventsFlow/Views/TransactionDetailView.swift @@ -109,7 +109,7 @@ extension TransactionDetailView { mark: RowMark = .neutral ) -> some View { Group { - if let memoText = transaction.memos?.first?.toString() { + if let memoText = transaction.textMemo?.toString() { VStack(alignment: .leading) { Text(L10n.Transaction.withMemo) .padding(.leading) diff --git a/modules/Sources/Features/WalletEventsFlow/WalletEventsFlowStore.swift b/modules/Sources/Features/WalletEventsFlow/WalletEventsFlowStore.swift index 3b6c9e3..0d27d8c 100644 --- a/modules/Sources/Features/WalletEventsFlow/WalletEventsFlowStore.swift +++ b/modules/Sources/Features/WalletEventsFlow/WalletEventsFlowStore.swift @@ -81,7 +81,7 @@ public struct WalletEventsFlowReducer: ReducerProtocol { return .cancel(id: CancelId.timer) case .synchronizerStateChanged(.upToDate): - state.latestMinedHeight = sdkSynchronizer.latestScannedHeight() + state.latestMinedHeight = sdkSynchronizer.latestState().latestBlockHeight return .task { return .updateWalletEvents(try await sdkSynchronizer.getAllTransactions()) } diff --git a/modules/Sources/Models/TransactionState.swift b/modules/Sources/Models/TransactionState.swift index 70b7960..3fc95ff 100644 --- a/modules/Sources/Models/TransactionState.swift +++ b/modules/Sources/Models/TransactionState.swift @@ -60,6 +60,18 @@ public struct TransactionState: Equatable, Identifiable { URL(string: "https://zcashblockexplorer.com/transactions/\(id)") } + public var textMemo: Memo? { + guard let memos else { return nil } + + for memo in memos { + if case .text = memo { + return memo + } + } + + return nil + } + public init( errorMessage: String? = nil, expiryHeight: BlockHeight? = nil, diff --git a/secant.xcodeproj/project.pbxproj b/secant.xcodeproj/project.pbxproj index 6b22386..32272b4 100644 --- a/secant.xcodeproj/project.pbxproj +++ b/secant.xcodeproj/project.pbxproj @@ -969,10 +969,10 @@ 0D26AF92299E8196005260EE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-testnet"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 59; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; @@ -998,10 +998,10 @@ 0D26AF93299E8196005260EE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-testnet"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 59; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; ENABLE_BITCODE = NO; @@ -1144,10 +1144,10 @@ 0D4E7A2B26B364180058B01E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-testnet"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 59; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; @@ -1173,10 +1173,10 @@ 0D4E7A2C26B364180058B01E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-testnet"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 53; + CURRENT_PROJECT_VERSION = 59; DEVELOPMENT_ASSET_PATHS = "\"secant/Preview Content\""; DEVELOPMENT_TEAM = RLPRR8CPQG; ENABLE_BITCODE = NO; diff --git a/secant.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/secant.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index c22b611..4b6057a 100644 --- a/secant.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/secant.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -329,7 +329,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/zcash-hackworks/zcash-light-client-ffi", "state" : { - "revision" : "c3b5f4ebee758b619aa81e844d791aa1fd35b918" + "revision" : "8607dc26a637697e53e0be1fb09b81cba9d8475a", + "version" : "0.4.0-rc.2" } }, { @@ -337,7 +338,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/zcash/ZcashLightClientKit", "state" : { - "revision" : "9a82acbd5e33495a3ac7353bde77cfd741a75244" + "revision" : "552d31eb649bbce7ecddcbab976138a8472929ab", + "version" : "2.0.0-rc.1" } } ], diff --git a/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift b/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift index e2b95a5..0223d5a 100644 --- a/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift +++ b/secantTests/RecoveryPhraseValidationTests/RecoveryPhraseValidationFlowFeatureFlagTests.swift @@ -227,7 +227,7 @@ class RecoveryPhraseValidationFlowFeatureFlagTests: XCTestCase { await testQueue.advance(by: 3.00) - await store.receive(.initialization(.initializeSDK)) { state in + await store.receive(.initialization(.initializeSDK(.existingWallet))) { state in state.storedWallet = .placeholder } diff --git a/secantTests/RootTests/AppInitializationTests.swift b/secantTests/RootTests/AppInitializationTests.swift index 3a0c80e..92e4fb0 100644 --- a/secantTests/RootTests/AppInitializationTests.swift +++ b/secantTests/RootTests/AppInitializationTests.swift @@ -133,7 +133,7 @@ class AppInitializationTests: XCTestCase { await testQueue.advance(by: 3.00) - await store.receive(.initialization(.initializeSDK)) { state in + await store.receive(.initialization(.initializeSDK(.existingWallet))) { state in state.storedWallet = .placeholder } diff --git a/secantTests/RootTests/RootTests.swift b/secantTests/RootTests/RootTests.swift index 995224d..becc3a7 100644 --- a/secantTests/RootTests/RootTests.swift +++ b/secantTests/RootTests/RootTests.swift @@ -144,7 +144,7 @@ class RootTests: XCTestCase { state.appInitializationState = .filesMissing } - store.receive(.initialization(.initializeSDK)) + store.receive(.initialization(.initializeSDK(.existingWallet))) store.receive(.initialization(.checkBackupPhraseValidation)) { state in // failed is expected because environment is throwing errors @@ -171,7 +171,7 @@ class RootTests: XCTestCase { store.send(.initialization(.respondToWalletInitializationState(.initialized))) - store.receive(.initialization(.initializeSDK)) + store.receive(.initialization(.initializeSDK(.existingWallet))) store.receive(.initialization(.checkBackupPhraseValidation)) { state in // failed is expected because environment is throwing errors