- added alert view asking if nuke is triggered or canceled - wipe of the keychain - wipe publisher properly used - functional wipe accessible through debug menu
This commit is contained in:
parent
148ca941f1
commit
75150da3a4
|
@ -3517,8 +3517,8 @@
|
|||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/zcash/ZcashLightClientKit/";
|
||||
requirement = {
|
||||
branch = main;
|
||||
kind = branch;
|
||||
kind = revision;
|
||||
revision = 3b2d972b2dd0c51e36d76e49fcf58273bf585c1b;
|
||||
};
|
||||
};
|
||||
6654C7382715A38000901167 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */ = {
|
||||
|
|
|
@ -338,8 +338,7 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/zcash/ZcashLightClientKit/",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "27b99013f7dda11caee0a261361c155490966e7f"
|
||||
"revision" : "3b2d972b2dd0c51e36d76e49fcf58273bf585c1b"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -18,24 +18,11 @@ extension DependencyValues {
|
|||
}
|
||||
|
||||
enum SDKSynchronizerState: Equatable {
|
||||
case unknown
|
||||
case transactionsUpdated
|
||||
case started
|
||||
case progressUpdated
|
||||
case statusWillUpdate
|
||||
case synced
|
||||
case started
|
||||
case stopped
|
||||
case disconnected
|
||||
case syncing
|
||||
case downloading
|
||||
case validating
|
||||
case scanning
|
||||
case enhancing
|
||||
case fetching
|
||||
case minedTransaction
|
||||
case foundTransactions
|
||||
case failed
|
||||
case connectionStateChanged
|
||||
case synced
|
||||
case unknown
|
||||
}
|
||||
|
||||
enum SDKSynchronizerClientError: Error {
|
||||
|
@ -54,6 +41,8 @@ protocol SDKSynchronizerClient {
|
|||
func stop()
|
||||
func synchronizerSynced(_ synchronizerState: SDKSynchronizer.SynchronizerState?)
|
||||
func statusSnapshot() -> SyncStatusSnapshot
|
||||
func isSyncing() -> Bool
|
||||
func isInitialized() -> Bool
|
||||
|
||||
func rewind(_ policy: RewindPolicy) async throws
|
||||
|
||||
|
@ -75,6 +64,8 @@ protocol SDKSynchronizerClient {
|
|||
to recipientAddress: Recipient,
|
||||
memo: Memo?
|
||||
) -> EffectTask<Result<TransactionState, NSError>>
|
||||
|
||||
func wipe() -> AnyPublisher<Void, Error>?
|
||||
}
|
||||
|
||||
extension SDKSynchronizerClient {
|
||||
|
|
|
@ -76,6 +76,14 @@ class LiveSDKSynchronizerClient: SDKSynchronizerClient {
|
|||
synchronizer?.stop()
|
||||
}
|
||||
|
||||
func isSyncing() -> Bool {
|
||||
latestScannedSynchronizerState?.syncStatus.isSyncing ?? false
|
||||
}
|
||||
|
||||
func isInitialized() -> Bool {
|
||||
synchronizer != nil
|
||||
}
|
||||
|
||||
func synchronizerStarted() {
|
||||
stateChanged.send(.started)
|
||||
}
|
||||
|
@ -229,4 +237,8 @@ class LiveSDKSynchronizerClient: SDKSynchronizerClient {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func wipe() -> AnyPublisher<Void, Error>? {
|
||||
synchronizer?.wipe()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,10 @@ class MockSDKSynchronizerClient: SDKSynchronizerClient {
|
|||
|
||||
func stop() { }
|
||||
|
||||
func isSyncing() -> Bool { false }
|
||||
|
||||
func isInitialized() -> Bool { false }
|
||||
|
||||
func synchronizerSynced(_ synchronizerState: SDKSynchronizer.SynchronizerState?) { }
|
||||
|
||||
func statusSnapshot() -> SyncStatusSnapshot { .default }
|
||||
|
@ -200,4 +204,6 @@ class MockSDKSynchronizerClient: SDKSynchronizerClient {
|
|||
|
||||
return EffectTask(value: Result.success(transactionState))
|
||||
}
|
||||
|
||||
func wipe() -> AnyPublisher<Void, Error>? { nil }
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ class NoopSDKSynchronizer: SDKSynchronizerClient {
|
|||
|
||||
func stop() { }
|
||||
|
||||
func isSyncing() -> Bool { false }
|
||||
|
||||
func isInitialized() -> Bool { false }
|
||||
|
||||
func synchronizerSynced(_ synchronizerState: SDKSynchronizer.SynchronizerState?) { }
|
||||
|
||||
func statusSnapshot() -> SyncStatusSnapshot { .default }
|
||||
|
@ -70,6 +74,8 @@ class NoopSDKSynchronizer: SDKSynchronizerClient {
|
|||
func updateStateChanged(_ newState: SDKSynchronizerState) {
|
||||
stateChanged = CurrentValueSubject<SDKSynchronizerState, Never>(newState)
|
||||
}
|
||||
|
||||
func wipe() -> AnyPublisher<Void, Error>? { nil }
|
||||
}
|
||||
|
||||
class TestSDKSynchronizerClient: SDKSynchronizerClient {
|
||||
|
@ -90,6 +96,10 @@ class TestSDKSynchronizerClient: SDKSynchronizerClient {
|
|||
|
||||
func stop() { }
|
||||
|
||||
func isSyncing() -> Bool { false }
|
||||
|
||||
func isInitialized() -> Bool { false }
|
||||
|
||||
func synchronizerSynced(_ synchronizerState: SDKSynchronizer.SynchronizerState?) { }
|
||||
|
||||
func statusSnapshot() -> SyncStatusSnapshot { .default }
|
||||
|
@ -235,4 +245,6 @@ class TestSDKSynchronizerClient: SDKSynchronizerClient {
|
|||
func updateStateChanged(_ newState: SDKSynchronizerState) {
|
||||
stateChanged = CurrentValueSubject<SDKSynchronizerState, Never>(newState)
|
||||
}
|
||||
|
||||
func wipe() -> AnyPublisher<Void, Error>? { nil }
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ extension RootReducer {
|
|||
case welcome
|
||||
}
|
||||
|
||||
@BindingState var alert: AlertState<RootReducer.Action>?
|
||||
var internalDestination: Destination = .welcome
|
||||
var previousDestination: Destination?
|
||||
|
||||
|
@ -39,6 +40,7 @@ extension RootReducer {
|
|||
case deeplink(URL)
|
||||
case deeplinkHome
|
||||
case deeplinkSend(Zatoshi, String, String)
|
||||
case dismissAlert
|
||||
case updateDestination(RootReducer.DestinationState.Destination)
|
||||
}
|
||||
|
||||
|
@ -112,7 +114,12 @@ extension RootReducer {
|
|||
}
|
||||
return EffectTask(value: .destination(.deeplink(url)))
|
||||
|
||||
case .home, .initialization, .onboarding, .phraseDisplay, .phraseValidation, .sandbox, .welcome, .debug:
|
||||
case .destination(.dismissAlert):
|
||||
state.destinationState.alert = nil
|
||||
return .none
|
||||
|
||||
case .home, .initialization, .onboarding, .phraseDisplay, .phraseValidation,
|
||||
.sandbox, .welcome, .binding, .nukeWalletFailed, .nukeWalletSucceeded, .debug:
|
||||
return .none
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ extension RootReducer {
|
|||
case initializeSDK
|
||||
case initialSetups
|
||||
case nukeWallet
|
||||
case nukeWalletRequest
|
||||
case respondToWalletInitializationState(InitializationState)
|
||||
case walletConfigChanged(WalletConfig)
|
||||
}
|
||||
|
@ -128,7 +129,6 @@ extension RootReducer {
|
|||
|
||||
try sdkSynchronizer.prepareWith(initializer: initializer, seedBytes: seedBytes)
|
||||
try sdkSynchronizer.start()
|
||||
|
||||
return .none
|
||||
} catch {
|
||||
// TODO: [#221] error we need to handle (https://github.com/zcash/secant-ios-wallet/issues/221)
|
||||
|
@ -199,15 +199,58 @@ extension RootReducer {
|
|||
}
|
||||
return .none
|
||||
|
||||
case .initialization(.nukeWallet):
|
||||
walletStorage.nukeWallet()
|
||||
do {
|
||||
try databaseFiles.nukeDbFilesFor(zcashSDKEnvironment.network)
|
||||
} catch {
|
||||
// TODO: [#221] error we need to handle, issue #221 (https://github.com/zcash/secant-ios-wallet/issues/221)
|
||||
}
|
||||
case .initialization(.nukeWalletRequest):
|
||||
state.destinationState.alert = AlertState(
|
||||
title: TextState("Wipe of the wallet"),
|
||||
message: TextState("Are you sure?"),
|
||||
buttons: [
|
||||
.destructive(
|
||||
TextState("Yes"),
|
||||
action: .send(.initialization(.nukeWallet))
|
||||
),
|
||||
.cancel(
|
||||
TextState("No"),
|
||||
action: .send(.destination(.dismissAlert))
|
||||
)
|
||||
]
|
||||
)
|
||||
return .none
|
||||
|
||||
case .initialization(.nukeWallet):
|
||||
guard let wipePublisher = sdkSynchronizer.wipe() else {
|
||||
return EffectTask(value: .nukeWalletFailed)
|
||||
}
|
||||
return wipePublisher
|
||||
.catchToEffect()
|
||||
.receive(on: mainQueue)
|
||||
.replaceEmpty(with: .success(Void()))
|
||||
.map { _ in return RootReducer.Action.nukeWalletSucceeded }
|
||||
.replaceError(with: RootReducer.Action.nukeWalletFailed)
|
||||
.eraseToEffect()
|
||||
.cancellable(id: SynchronizerCancelId.self, cancelInFlight: true)
|
||||
|
||||
case .nukeWalletSucceeded:
|
||||
walletStorage.nukeWallet()
|
||||
state.onboardingState.destination = nil
|
||||
state.onboardingState.index = 0
|
||||
return .concatenate(
|
||||
.cancel(id: SynchronizerCancelId.self),
|
||||
EffectTask(value: .initialization(.checkWalletInitialization))
|
||||
)
|
||||
|
||||
case .nukeWalletFailed:
|
||||
// TODO: [#221] error we need to handle, issue #221 (https://github.com/zcash/secant-ios-wallet/issues/221)
|
||||
let backDestination: EffectTask<RootReducer.Action>
|
||||
if let previousDestination = state.destinationState.previousDestination {
|
||||
backDestination = EffectTask(value: .destination(.updateDestination(previousDestination)))
|
||||
} else {
|
||||
backDestination = EffectTask(value: .destination(.updateDestination(state.destinationState.destination)))
|
||||
}
|
||||
return .concatenate(
|
||||
.cancel(id: SynchronizerCancelId.self),
|
||||
backDestination
|
||||
)
|
||||
|
||||
case .welcome(.debugMenuStartup), .home(.debugMenuStartup):
|
||||
return .concatenate(
|
||||
EffectTask.cancel(id: CancelId.self),
|
||||
|
@ -223,7 +266,7 @@ extension RootReducer {
|
|||
case .onboarding(.createNewWallet):
|
||||
return EffectTask(value: .initialization(.createNewWallet))
|
||||
|
||||
case .home, .destination, .onboarding, .phraseDisplay, .phraseValidation, .sandbox, .welcome:
|
||||
case .home, .destination, .onboarding, .phraseDisplay, .phraseValidation, .sandbox, .welcome, .binding:
|
||||
return .none
|
||||
|
||||
case .initialization(.configureCrashReporter):
|
||||
|
|
|
@ -6,6 +6,7 @@ typealias RootViewStore = ViewStore<RootReducer.State, RootReducer.Action>
|
|||
|
||||
struct RootReducer: ReducerProtocol {
|
||||
enum CancelId {}
|
||||
enum SynchronizerCancelId {}
|
||||
|
||||
struct State: Equatable {
|
||||
var appInitializationState: InitializationState = .uninitialized
|
||||
|
@ -20,10 +21,13 @@ struct RootReducer: ReducerProtocol {
|
|||
var welcomeState: WelcomeReducer.State
|
||||
}
|
||||
|
||||
enum Action: Equatable {
|
||||
enum Action: Equatable, BindableAction {
|
||||
case binding(BindingAction<RootReducer.State>)
|
||||
case destination(DestinationAction)
|
||||
case home(HomeReducer.Action)
|
||||
case initialization(InitializationAction)
|
||||
case nukeWalletFailed
|
||||
case nukeWalletSucceeded
|
||||
case onboarding(OnboardingFlowReducer.Action)
|
||||
case phraseDisplay(RecoveryPhraseDisplayReducer.Action)
|
||||
case phraseValidation(RecoveryPhraseValidationFlowReducer.Action)
|
||||
|
@ -46,6 +50,8 @@ struct RootReducer: ReducerProtocol {
|
|||
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
|
||||
|
||||
var body: some ReducerProtocol<State, Action> {
|
||||
BindingReducer()
|
||||
|
||||
Scope(state: \.homeState, action: /Action.home) {
|
||||
HomeReducer()
|
||||
}
|
||||
|
@ -144,6 +150,7 @@ extension RootReducer {
|
|||
network: zcashSDKEnvironment.network,
|
||||
spendParamsURL: try databaseFiles.spendParamsURLFor(network),
|
||||
outputParamsURL: try databaseFiles.outputParamsURLFor(network),
|
||||
saplingParamsSourceURL: SaplingParamsSourceURL.default,
|
||||
viewingKeys: [viewingKey],
|
||||
walletBirthday: birthday,
|
||||
loggerProxy: OSLogger_(logLevel: .debug, category: LoggerConstants.sdkLogs)
|
||||
|
|
|
@ -126,7 +126,7 @@ private extension RootView {
|
|||
}
|
||||
|
||||
Button("[Be careful] Nuke Wallet") {
|
||||
viewStore.send(.initialization(.nukeWallet))
|
||||
viewStore.send(.initialization(.nukeWalletRequest))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,7 @@ private extension RootView {
|
|||
}
|
||||
}
|
||||
}
|
||||
.alert(self.store.scope(state: \.destinationState.alert), dismiss: .destination(.dismissAlert))
|
||||
}
|
||||
.navigationBarTitle("Startup")
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class HomeTests: XCTestCase {
|
|||
reducer: HomeReducer()
|
||||
)
|
||||
|
||||
store.send(.synchronizerStateChanged(.downloading))
|
||||
store.send(.synchronizerStateChanged(.progressUpdated))
|
||||
|
||||
store.receive(.updateSynchronizerStatus)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue