[#766] Modularize batch of leaf features Vol III (#768)

Following features have been modularized:
- OnboardingFlow
- ImportWallet
- SendFlow
- Sandbox
- crashReporter TODO added
This commit is contained in:
Lukas Korba 2023-06-08 14:13:36 +02:00 committed by GitHub
parent 0d5904e30c
commit 896f4532a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 727 additions and 693 deletions

View File

@ -23,19 +23,23 @@ let package = Package(
.library(name: "FeedbackGenerator", targets: ["FeedbackGenerator"]),
.library(name: "FileManager", targets: ["FileManager"]),
.library(name: "Generated", targets: ["Generated"]),
.library(name: "ImportWallet", targets: ["ImportWallet"]),
.library(name: "LocalAuthenticationHandler", targets: ["LocalAuthenticationHandler"]),
.library(name: "LogsHandler", targets: ["LogsHandler"]),
.library(name: "MnemonicClient", targets: ["MnemonicClient"]),
.library(name: "Models", targets: ["Models"]),
.library(name: "NumberFormatter", targets: ["NumberFormatter"]),
.library(name: "OnboardingFlow", targets: ["OnboardingFlow"]),
.library(name: "Pasteboard", targets: ["Pasteboard"]),
.library(name: "Profile", targets: ["Profile"]),
.library(name: "RecoveryPhraseDisplay", targets: ["RecoveryPhraseDisplay"]),
.library(name: "RecoveryPhraseValidationFlow", targets: ["RecoveryPhraseValidationFlow"]),
.library(name: "ReviewRequest", targets: ["ReviewRequest"]),
.library(name: "Sandbox", targets: ["Sandbox"]),
.library(name: "Scan", targets: ["Scan"]),
.library(name: "SDKSynchronizer", targets: ["SDKSynchronizer"]),
.library(name: "SecItem", targets: ["SecItem"]),
.library(name: "SendFlow", targets: ["SendFlow"]),
.library(name: "Settings", targets: ["Settings"]),
.library(name: "SupportDataGenerator", targets: ["SupportDataGenerator"]),
.library(name: "UIComponents", targets: ["UIComponents"]),
@ -186,6 +190,20 @@ let package = Package(
],
path: "Sources/Dependencies/LocalAuthenticationHandler"
),
.target(
name: "ImportWallet",
dependencies: [
"Generated",
"MnemonicClient",
"UIComponents",
"Utils",
"WalletStorage",
"ZcashSDKEnvironment",
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
.product(name: "ZcashLightClientKit", package: "ZcashLightClientKit")
],
path: "Sources/Features/ImportWallet"
),
.target(
name: "LogsHandler",
dependencies: [
@ -218,6 +236,18 @@ let package = Package(
],
path: "Sources/Dependencies/NumberFormatter"
),
.target(
name: "OnboardingFlow",
dependencies: [
"Generated",
"ImportWallet",
"Models",
"UIComponents",
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
.product(name: "ZcashLightClientKit", package: "ZcashLightClientKit")
],
path: "Sources/Features/OnboardingFlow"
),
.target(
name: "Pasteboard",
dependencies: [
@ -276,6 +306,19 @@ let package = Package(
],
path: "Sources/Dependencies/ReviewRequest"
),
.target(
name: "Sandbox",
dependencies: [
"Profile",
"RecoveryPhraseDisplay",
"Scan",
"SendFlow",
"WalletEventsFlow",
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
.product(name: "ZcashLightClientKit", package: "ZcashLightClientKit")
],
path: "Sources/Features/Sandbox"
),
.target(
name: "Scan",
dependencies: [
@ -307,6 +350,24 @@ let package = Package(
],
path: "Sources/Dependencies/SecItem"
),
.target(
name: "SendFlow",
dependencies: [
"AudioServices",
"Generated",
"DerivationTool",
"MnemonicClient",
"Scan",
"SDKSynchronizer",
"UIComponents",
"Utils",
"WalletStorage",
"ZcashSDKEnvironment",
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
.product(name: "ZcashLightClientKit", package: "ZcashLightClientKit")
],
path: "Sources/Features/SendFlow"
),
.target(
name: "Settings",
dependencies: [
@ -340,8 +401,10 @@ let package = Package(
.target(
name: "UIComponents",
dependencies: [
"DerivationTool",
"Generated",
"Utils"
"Utils",
"ZcashSDKEnvironment"
],
path: "Sources/UIComponents"
),

View File

@ -38,10 +38,8 @@ extension ZcashSDKEnvironment {
public struct ZcashSDKEnvironment {
public var latestCheckpoint: (ZcashNetwork) -> BlockHeight //{ BlockHeight.ofLatestCheckpoint(network: network()) }
public let endpoint: (ZcashNetwork) -> LightWalletEndpoint
//public var isMainnet: Bool { network().networkType == .mainnet }
public let memoCharLimit: Int
public let mnemonicWordsMaxCount: Int
//public let network: () -> ZcashNetwork
public let requiredTransactionConfirmations: Int
public let sdkVersion: String
}

View File

@ -21,7 +21,6 @@ extension ZcashSDKEnvironment: DependencyKey {
},
memoCharLimit: MemoBytes.capacity,
mnemonicWordsMaxCount: ZcashSDKConstants.mnemonicWordsMaxCount,
//network: { TargetConstants.zcashNetwork },
requiredTransactionConfirmations: ZcashSDKConstants.requiredTransactionConfirmations,
sdkVersion: "0.18.1-beta"
)

View File

@ -24,7 +24,6 @@ extension ZcashSDKEnvironment: TestDependencyKey {
},
memoCharLimit: MemoBytes.capacity,
mnemonicWordsMaxCount: ZcashSDKConstants.mnemonicWordsMaxCount,
//network: { ZcashNetworkBuilder.network(for: .testnet) },
requiredTransactionConfirmations: ZcashSDKConstants.requiredTransactionConfirmations,
sdkVersion: "0.18.1-beta"
)

View File

@ -8,11 +8,16 @@
import SwiftUI
import ComposableArchitecture
import Generated
import UIComponents
struct ImportBirthdayView: View {
public struct ImportBirthdayView: View {
var store: ImportWalletStore
var body: some View {
public init(store: ImportWalletStore) {
self.store = store
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
Text(L10n.ImportWallet.Birthday.description)

View File

@ -11,27 +11,31 @@ import SwiftUI
import Utils
import Generated
import WalletStorage
import MnemonicClient
import ZcashSDKEnvironment
typealias ImportWalletStore = Store<ImportWalletReducer.State, ImportWalletReducer.Action>
typealias ImportWalletViewStore = ViewStore<ImportWalletReducer.State, ImportWalletReducer.Action>
public typealias ImportWalletStore = Store<ImportWalletReducer.State, ImportWalletReducer.Action>
public typealias ImportWalletViewStore = ViewStore<ImportWalletReducer.State, ImportWalletReducer.Action>
struct ImportWalletReducer: ReducerProtocol {
struct State: Equatable {
enum Destination: Equatable {
public struct ImportWalletReducer: ReducerProtocol {
let saplingActivationHeight: BlockHeight
public struct State: Equatable {
public enum Destination: Equatable {
case birthday
}
@PresentationState var alert: AlertState<Action>?
var birthdayHeight = "".redacted
var birthdayHeightValue: RedactableBlockHeight?
var destination: Destination?
var importedSeedPhrase = "".redacted
var isValidMnemonic = false
var isValidNumberOfWords = false
var maxWordsCount = 0
var wordsCount = 0
@PresentationState public var alert: AlertState<Action>?
public var birthdayHeight = "".redacted
public var birthdayHeightValue: RedactableBlockHeight?
public var destination: Destination?
public var importedSeedPhrase = "".redacted
public var isValidMnemonic = false
public var isValidNumberOfWords = false
public var maxWordsCount = 0
public var wordsCount = 0
var mnemonicStatus: String {
public var mnemonicStatus: String {
if isValidMnemonic {
return L10n.ImportWallet.Seed.valid
} else {
@ -39,14 +43,35 @@ struct ImportWalletReducer: ReducerProtocol {
}
}
var isValidForm: Bool {
public var isValidForm: Bool {
isValidMnemonic &&
(birthdayHeight.data.isEmpty ||
(!birthdayHeight.data.isEmpty && birthdayHeightValue != nil))
}
public init(
birthdayHeight: RedactableString = "".redacted,
birthdayHeightValue: RedactableBlockHeight? = nil,
destination: Destination? = nil,
importedSeedPhrase: RedactableString = "".redacted,
isValidMnemonic: Bool = false,
isValidNumberOfWords: Bool = false,
maxWordsCount: Int = 0,
wordsCount: Int = 0
) {
self.alert = alert
self.birthdayHeight = birthdayHeight
self.birthdayHeightValue = birthdayHeightValue
self.destination = destination
self.importedSeedPhrase = importedSeedPhrase
self.isValidMnemonic = isValidMnemonic
self.isValidNumberOfWords = isValidNumberOfWords
self.maxWordsCount = maxWordsCount
self.wordsCount = wordsCount
}
}
enum Action: Equatable {
public enum Action: Equatable {
case alert(PresentationAction<Action>)
case birthdayInputChanged(RedactableString)
case dismissAlert
@ -63,7 +88,11 @@ struct ImportWalletReducer: ReducerProtocol {
@Dependency(\.walletStorage) var walletStorage
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
var body: some ReducerProtocol<State, Action> {
public init(saplingActivationHeight: BlockHeight) {
self.saplingActivationHeight = saplingActivationHeight
}
public var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
switch action {
case .onAppear:
@ -85,7 +114,7 @@ struct ImportWalletReducer: ReducerProtocol {
return .none
case .birthdayInputChanged(let redactedBirthday):
let saplingActivation = TargetConstants.zcashNetwork.constants.saplingActivationHeight
let saplingActivation = saplingActivationHeight
state.birthdayHeight = redactedBirthday
@ -106,7 +135,7 @@ struct ImportWalletReducer: ReducerProtocol {
// store it to the keychain, if the user did not input a height,
// fall back to sapling activation
let birthday = state.birthdayHeightValue ?? TargetConstants.zcashNetwork.constants.saplingActivationHeight.redacted
let birthday = state.birthdayHeightValue ?? saplingActivationHeight.redacted
try walletStorage.importWallet(state.importedSeedPhrase.data, birthday.data, .english, false)
@ -172,7 +201,7 @@ extension ImportWalletViewStore {
// MARK: Alerts
extension AlertState where Action == ImportWalletReducer.Action {
static func succeed() -> AlertState {
public static func succeed() -> AlertState {
AlertState {
TextState(L10n.General.success)
} actions: {
@ -184,7 +213,7 @@ extension AlertState where Action == ImportWalletReducer.Action {
}
}
static func failed(_ error: ZcashError) -> AlertState {
public static func failed(_ error: ZcashError) -> AlertState {
AlertState {
TextState(L10n.ImportWallet.Alert.Failed.title)
} actions: {
@ -200,14 +229,14 @@ extension AlertState where Action == ImportWalletReducer.Action {
// MARK: - Placeholders
extension ImportWalletReducer.State {
static let placeholder = ImportWalletReducer.State()
public static let placeholder = ImportWalletReducer.State()
static let live = ImportWalletReducer.State()
public static let live = ImportWalletReducer.State()
}
extension ImportWalletStore {
static let demo = Store(
public static let demo = Store(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
}

View File

@ -8,11 +8,16 @@
import SwiftUI
import ComposableArchitecture
import Generated
import UIComponents
struct ImportWalletView: View {
public struct ImportWalletView: View {
var store: ImportWalletStore
var body: some View {
public init(store: ImportWalletStore) {
self.store = store
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
Text(L10n.ImportWallet.description)

View File

@ -9,16 +9,16 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct ImportSeedEditor: View {
public struct ImportSeedEditor: View {
var store: ImportWalletStore
/// Clearance of the black color for the TextEditor under the text (.dark colorScheme)
init(store: ImportWalletStore) {
public init(store: ImportWalletStore) {
self.store = store
UITextView.appearance().backgroundColor = .clear
}
var body: some View {
public var body: some View {
WithViewStore(store) { viewStore in
TextEditor(text: viewStore.bindingForRedactableSeedPhrase(viewStore.importedSeedPhrase))
.autocapitalization(.none)

View File

@ -10,44 +10,65 @@ import SwiftUI
import ComposableArchitecture
import Generated
import Models
import ImportWallet
import ZcashLightClientKit
typealias OnboardingFlowStore = Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
typealias OnboardingFlowViewStore = ViewStore<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
public typealias OnboardingFlowStore = Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
public typealias OnboardingFlowViewStore = ViewStore<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
struct OnboardingFlowReducer: ReducerProtocol {
struct State: Equatable {
enum Destination: Equatable, CaseIterable {
public struct OnboardingFlowReducer: ReducerProtocol {
let saplingActivationHeight: BlockHeight
public struct State: Equatable {
public enum Destination: Equatable, CaseIterable {
case createNewWallet
case importExistingWallet
}
struct Step: Equatable, Identifiable {
let id: UUID
let title: String
let description: String
let background: Image
public struct Step: Equatable, Identifiable {
public let id: UUID
public let title: String
public let description: String
public let background: Image
}
var destination: Destination?
var walletConfig: WalletConfig
var importWalletState: ImportWalletReducer.State
var index = 0
var skippedAtindex: Int?
var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
public var destination: Destination?
public var walletConfig: WalletConfig
public var importWalletState: ImportWalletReducer.State
public var index = 0
public var skippedAtindex: Int?
public var steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
var currentStep: Step { steps[index] }
var isFinalStep: Bool { steps.count == index + 1 }
var isInitialStep: Bool { index == 0 }
var progress: Int { ((index + 1) * 100) / (steps.count) }
var offset: CGFloat {
public var currentStep: Step { steps[index] }
public var isFinalStep: Bool { steps.count == index + 1 }
public var isInitialStep: Bool { index == 0 }
public var progress: Int { ((index + 1) * 100) / (steps.count) }
public var offset: CGFloat {
let maxOffset = CGFloat(-60)
let stepOffset = CGFloat(maxOffset / CGFloat(steps.count - 1))
guard index != 0 else { return .zero }
return stepOffset * CGFloat(index)
}
public init(
destination: Destination? = nil,
walletConfig: WalletConfig,
importWalletState: ImportWalletReducer.State,
index: Int = 0,
skippedAtindex: Int? = nil,
steps: IdentifiedArrayOf<Step> = Self.onboardingSteps
) {
self.destination = destination
self.walletConfig = walletConfig
self.importWalletState = importWalletState
self.index = index
self.skippedAtindex = skippedAtindex
self.steps = steps
}
}
enum Action: Equatable {
public enum Action: Equatable {
case back
case createNewWallet
case importExistingWallet
@ -58,9 +79,13 @@ struct OnboardingFlowReducer: ReducerProtocol {
case updateDestination(OnboardingFlowReducer.State.Destination?)
}
var body: some ReducerProtocol<State, Action> {
public init(saplingActivationHeight: BlockHeight) {
self.saplingActivationHeight = saplingActivationHeight
}
public var body: some ReducerProtocol<State, Action> {
Scope(state: \.importWalletState, action: /Action.importWallet) {
ImportWalletReducer()
ImportWalletReducer(saplingActivationHeight: saplingActivationHeight)
}
Reduce { state, action in
@ -112,7 +137,7 @@ struct OnboardingFlowReducer: ReducerProtocol {
}
extension OnboardingFlowReducer.State {
static let onboardingSteps = IdentifiedArray(
public static let onboardingSteps = IdentifiedArray(
uniqueElements: [
Step(
id: UUID(),

View File

@ -7,11 +7,16 @@
import SwiftUI
import ComposableArchitecture
import UIComponents
struct OnboardingScreen: View {
public struct OnboardingScreen: View {
let store: OnboardingFlowStore
var body: some View {
public init(store: OnboardingFlowStore) {
self.store = store
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
ZStack {
@ -60,7 +65,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
)
.preferredColorScheme(.light)
@ -72,7 +77,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
)
.preferredColorScheme(.light)
@ -84,7 +89,7 @@ struct OnboardingScreen_Previews: PreviewProvider {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
)
.preferredColorScheme(.light)

View File

@ -8,12 +8,17 @@
import SwiftUI
import ComposableArchitecture
import Generated
import ImportWallet
struct PlainOnboardingView: View {
public struct PlainOnboardingView: View {
let store: OnboardingFlowStore
let animationDuration: CGFloat = 0.8
var body: some View {
public init(store: OnboardingFlowStore) {
self.store = store
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
VStack(alignment: .leading, spacing: 80) {
@ -65,7 +70,7 @@ struct PlainOnboardingView_Previews: PreviewProvider {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
)
}

View File

@ -8,10 +8,14 @@
import SwiftUI
import ComposableArchitecture
struct OnboardingContentView: View {
let store: Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
public struct OnboardingContentView: View {
let store: OnboardingFlowStore
var body: some View {
public init(store: OnboardingFlowStore) {
self.store = store
}
public var body: some View {
WithViewStore(self.store) { viewStore in
let image = viewStore.steps[viewStore.index].background
.resizable()
@ -63,7 +67,7 @@ struct OnboardingContentView_Previews: PreviewProvider {
importWalletState: .placeholder,
index: 0
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
OnboardingContentView_Previews.example(store)

View File

@ -8,12 +8,17 @@
import SwiftUI
import ComposableArchitecture
import Generated
import ImportWallet
struct OnboardingFooterView: View {
let store: Store<OnboardingFlowReducer.State, OnboardingFlowReducer.Action>
public struct OnboardingFooterView: View {
let store: OnboardingFlowStore
let animationDuration: CGFloat = 0.8
var body: some View {
public init(store: OnboardingFlowStore) {
self.store = store
}
public var body: some View {
WithViewStore(self.store) { viewStore in
VStack(spacing: 5) {
if viewStore.isFinalStep {
@ -88,7 +93,7 @@ struct OnboardingFooterView_Previews: PreviewProvider {
importWalletState: .placeholder,
index: 3
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
Group {

View File

@ -10,14 +10,14 @@ import ComposableArchitecture
import Generated
import Models
struct OnboardingHeaderView: View {
struct ViewState: Equatable {
let walletConfig: WalletConfig
let isInitialStep: Bool
let isFinalStep: Bool
public struct OnboardingHeaderView: View {
public struct ViewState: Equatable {
public let walletConfig: WalletConfig
public let isInitialStep: Bool
public let isFinalStep: Bool
}
enum ViewAction {
public enum ViewAction {
case back
case skip
}
@ -25,7 +25,11 @@ struct OnboardingHeaderView: View {
let store: Store<ViewState, ViewAction>
let animationDuration: CGFloat = 0.8
var body: some View {
public init(store: Store<ViewState, ViewAction>) {
self.store = store
}
public var body: some View {
WithViewStore(self.store) { viewStore in
VStack {
HStack {
@ -70,7 +74,7 @@ struct OnboardingHeaderView_Previews: PreviewProvider {
importWalletState: .placeholder,
index: 0
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 0)
)
OnboardingHeaderView(

View File

@ -62,7 +62,7 @@ struct OnboardingProgressStyle: ProgressViewStyle {
// MARK: - ProgressView : onboardingProgressStyle
extension ProgressView {
var onboardingProgressStyle: some View {
public var onboardingProgressStyle: some View {
progressViewStyle(OnboardingProgressStyle())
}
}

View File

@ -3,31 +3,33 @@ import SwiftUI
import Profile
import WalletEventsFlow
typealias SandboxStore = Store<SandboxReducer.State, SandboxReducer.Action>
typealias SandboxViewStore = ViewStore<SandboxReducer.State, SandboxReducer.Action>
public typealias SandboxStore = Store<SandboxReducer.State, SandboxReducer.Action>
public typealias SandboxViewStore = ViewStore<SandboxReducer.State, SandboxReducer.Action>
struct SandboxReducer: ReducerProtocol {
struct State: Equatable {
enum Destination: Equatable, CaseIterable {
public struct SandboxReducer: ReducerProtocol {
public struct State: Equatable {
public enum Destination: Equatable, CaseIterable {
case history
case send
case recoveryPhraseDisplay
case profile
case scan
}
var walletEventsState: WalletEventsFlowReducer.State
var profileState: ProfileReducer.State
var destination: Destination?
public var walletEventsState: WalletEventsFlowReducer.State
public var profileState: ProfileReducer.State
public var destination: Destination?
}
enum Action: Equatable {
public enum Action: Equatable {
case updateDestination(SandboxReducer.State.Destination?)
case walletEvents(WalletEventsFlowReducer.Action)
case profile(ProfileReducer.Action)
case reset
}
func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
public init() {}
public func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
switch action {
case let .updateDestination(destination):
state.destination = destination
@ -98,7 +100,7 @@ extension SandboxViewStore {
// MARK: - PlaceHolders
extension SandboxReducer.State {
static var placeholder: Self {
public static var placeholder: Self {
.init(
walletEventsState: .placeHolder,
profileState: .placeholder,
@ -108,7 +110,7 @@ extension SandboxReducer.State {
}
extension SandboxStore {
static var placeholder: SandboxStore {
public static var placeholder: SandboxStore {
SandboxStore(
initialState: SandboxReducer.State(
walletEventsState: .placeHolder,

View File

@ -4,14 +4,18 @@ import RecoveryPhraseDisplay
import Profile
import WalletEventsFlow
import Scan
import SendFlow
import ZcashLightClientKit
struct SandboxView: View {
public struct SandboxView: View {
struct SandboxDestinationValue: Identifiable {
let id: Int
let destination: SandboxReducer.State.Destination
}
let store: SandboxStore
let tokenName: String
let networkType: NetworkType
var navigationDestinationValues: [SandboxDestinationValue] = SandboxReducer.State.Destination.allCases
.enumerated()
@ -26,13 +30,14 @@ struct SandboxView: View {
@ViewBuilder func view(for destination: SandboxReducer.State.Destination) -> some View {
switch destination {
case .history:
WalletEventsFlowView(store: store.historyStore(), tokenName: TargetConstants.tokenName)
WalletEventsFlowView(store: store.historyStore(), tokenName: tokenName)
case .send:
SendFlowView(
store: .init(
initialState: .placeholder,
reducer: SendFlowReducer()
)
reducer: SendFlowReducer(networkType: networkType)
),
tokenName: tokenName
)
case .recoveryPhraseDisplay:
RecoveryPhraseDisplayView(store: .demo)
@ -43,7 +48,13 @@ struct SandboxView: View {
}
}
var body: some View {
public init(store: SandboxStore, tokenName: String, networkType: NetworkType) {
self.store = store
self.tokenName = tokenName
self.networkType = networkType
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
List {
@ -85,7 +96,7 @@ struct SandboxView: View {
isPresented: viewStore.bindingForDestination(.history),
content: {
NavigationView {
WalletEventsFlowView(store: store.historyStore(), tokenName: TargetConstants.tokenName)
WalletEventsFlowView(store: store.historyStore(), tokenName: tokenName)
.toolbar {
ToolbarItem {
Button("Done") { viewStore.send(.updateDestination(nil)) }
@ -104,7 +115,7 @@ struct SandboxView: View {
struct SandboxView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
SandboxView(store: .placeholder)
SandboxView(store: .placeholder, tokenName: "ZEC", networkType: .testnet)
}
}
}

View File

@ -11,15 +11,21 @@ import ZcashLightClientKit
import AudioServices
import Utils
import Scan
import MnemonicClient
import SDKSynchronizer
import WalletStorage
import ZcashSDKEnvironment
import UIComponents
typealias SendFlowStore = Store<SendFlowReducer.State, SendFlowReducer.Action>
typealias SendFlowViewStore = ViewStore<SendFlowReducer.State, SendFlowReducer.Action>
public typealias SendFlowStore = Store<SendFlowReducer.State, SendFlowReducer.Action>
public typealias SendFlowViewStore = ViewStore<SendFlowReducer.State, SendFlowReducer.Action>
struct SendFlowReducer: ReducerProtocol {
public struct SendFlowReducer: ReducerProtocol {
private enum SyncStatusUpdatesID { case timer }
let networkType: NetworkType
struct State: Equatable {
enum Destination: Equatable {
public struct State: Equatable {
public enum Destination: Equatable {
case done
case failure
case inProgress
@ -28,21 +34,21 @@ struct SendFlowReducer: ReducerProtocol {
case success
}
var addMemoState: Bool
var destination: Destination?
var isSendingTransaction = false
var memoState: MultiLineTextFieldReducer.State
var scanState: ScanReducer.State
var shieldedBalance = Balance.zero
var transactionAddressInputState: TransactionAddressTextFieldReducer.State
var transactionAmountInputState: TransactionAmountTextFieldReducer.State
public var addMemoState: Bool
public var destination: Destination?
public var isSendingTransaction = false
public var memoState: MultiLineTextFieldReducer.State
public var scanState: ScanReducer.State
public var shieldedBalance = Balance.zero
public var transactionAddressInputState: TransactionAddressTextFieldReducer.State
public var transactionAmountInputState: TransactionAmountTextFieldReducer.State
var address: String {
public var address: String {
get { transactionAddressInputState.textFieldState.text.data }
set { transactionAddressInputState.textFieldState.text = newValue.redacted }
}
var amount: Zatoshi {
public var amount: Zatoshi {
get { Zatoshi(transactionAmountInputState.amount.data) }
set {
transactionAmountInputState.amount = newValue.amount.redacted
@ -52,38 +58,57 @@ struct SendFlowReducer: ReducerProtocol {
}
}
var isInvalidAddressFormat: Bool {
public var isInvalidAddressFormat: Bool {
!transactionAddressInputState.isValidAddress
&& !transactionAddressInputState.textFieldState.text.data.isEmpty
}
var isInvalidAmountFormat: Bool {
public var isInvalidAmountFormat: Bool {
!transactionAmountInputState.textFieldState.valid
&& !transactionAmountInputState.textFieldState.text.data.isEmpty
}
var isValidForm: Bool {
public var isValidForm: Bool {
transactionAmountInputState.amount.data > 0
&& transactionAddressInputState.isValidAddress
&& !isInsufficientFunds
&& memoState.isValid
}
var isInsufficientFunds: Bool {
public var isInsufficientFunds: Bool {
transactionAmountInputState.amount.data > transactionAmountInputState.maxValue.data
}
var isMemoInputEnabled: Bool {
public var isMemoInputEnabled: Bool {
transactionAddressInputState.isValidAddress && !transactionAddressInputState.isValidTransparentAddress
}
var totalCurrencyBalance: Zatoshi {
public var totalCurrencyBalance: Zatoshi {
Zatoshi.from(decimal: shieldedBalance.data.verified.decimalValue.decimalValue * transactionAmountInputState.zecPrice)
}
public init(
addMemoState: Bool,
destination: Destination? = nil,
isSendingTransaction: Bool = false,
memoState: MultiLineTextFieldReducer.State,
scanState: ScanReducer.State,
shieldedBalance: Balance = Balance.zero,
transactionAddressInputState: TransactionAddressTextFieldReducer.State,
transactionAmountInputState: TransactionAmountTextFieldReducer.State
) {
self.addMemoState = addMemoState
self.destination = destination
self.isSendingTransaction = isSendingTransaction
self.memoState = memoState
self.scanState = scanState
self.shieldedBalance = shieldedBalance
self.transactionAddressInputState = transactionAddressInputState
self.transactionAmountInputState = transactionAmountInputState
}
}
enum Action: Equatable {
case addMemo(CheckCircleReducer.Action)
public enum Action: Equatable {
case memo(MultiLineTextFieldReducer.Action)
case onAppear
case onDisappear
@ -105,17 +130,17 @@ struct SendFlowReducer: ReducerProtocol {
@Dependency(\.walletStorage) var walletStorage
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
var body: some ReducerProtocol<State, Action> {
Scope(state: \.addMemoState, action: /Action.addMemo) {
CheckCircleReducer()
}
public init(networkType: NetworkType) {
self.networkType = networkType
}
public var body: some ReducerProtocol<State, Action> {
Scope(state: \.memoState, action: /Action.memo) {
MultiLineTextFieldReducer()
}
Scope(state: \.transactionAddressInputState, action: /Action.transactionAddressInput) {
TransactionAddressTextFieldReducer()
TransactionAddressTextFieldReducer(networkType: networkType)
}
Scope(state: \.transactionAmountInputState, action: /Action.transactionAmountInput) {
@ -123,14 +148,11 @@ struct SendFlowReducer: ReducerProtocol {
}
Scope(state: \.scanState, action: /Action.scan) {
ScanReducer(networkType: TargetConstants.zcashNetwork.networkType)
ScanReducer(networkType: networkType)
}
Reduce { state, action in
switch action {
case .addMemo:
return .none
case .updateDestination(.done):
state.destination = nil
state.memoState.text = "".redacted
@ -158,7 +180,7 @@ struct SendFlowReducer: ReducerProtocol {
do {
let storedWallet = try walletStorage.exportWallet()
let seedBytes = try mnemonic.toSeed(storedWallet.seedPhrase.value())
let spendingKey = try derivationTool.deriveSpendingKey(seedBytes, 0, TargetConstants.zcashNetwork.networkType)
let spendingKey = try derivationTool.deriveSpendingKey(seedBytes, 0, networkType)
state.isSendingTransaction = true
@ -171,7 +193,7 @@ struct SendFlowReducer: ReducerProtocol {
memo = nil
}
let recipient = try Recipient(state.address, network: TargetConstants.zcashNetwork.networkType)
let recipient = try Recipient(state.address, network: networkType)
return .run { [state] send in
do {
await send(SendFlowReducer.Action.updateDestination(.inProgress))
@ -229,7 +251,7 @@ struct SendFlowReducer: ReducerProtocol {
state.transactionAddressInputState.isValidAddress = true
state.transactionAddressInputState.isValidTransparentAddress = derivationTool.isTransparentAddress(
address.data,
TargetConstants.zcashNetwork.networkType
networkType
)
audioServices.systemSoundVibrate()
return EffectTask(value: .updateDestination(nil))
@ -244,13 +266,6 @@ struct SendFlowReducer: ReducerProtocol {
// MARK: - Store
extension SendFlowStore {
func addMemoStore() -> CheckCircleStore {
self.scope(
state: \.addMemoState,
action: SendFlowReducer.Action.addMemo
)
}
func memoStore() -> MultiLineTextFieldStore {
self.scope(
state: \.memoState,
@ -321,7 +336,7 @@ extension SendFlowViewStore {
// MARK: Placeholders
extension SendFlowReducer.State {
static var placeholder: Self {
public static var placeholder: Self {
.init(
addMemoState: true,
destination: nil,
@ -332,7 +347,7 @@ extension SendFlowReducer.State {
)
}
static var emptyPlaceholder: Self {
public static var emptyPlaceholder: Self {
.init(
addMemoState: true,
destination: nil,
@ -346,10 +361,10 @@ extension SendFlowReducer.State {
// #if DEBUG // FIX: Issue #306 - Release build is broken
extension SendFlowStore {
static var placeholder: SendFlowStore {
public static var placeholder: SendFlowStore {
return SendFlowStore(
initialState: .emptyPlaceholder,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
}
}

View File

@ -9,16 +9,23 @@ import SwiftUI
import ComposableArchitecture
import Generated
import Scan
import UIComponents
struct SendFlowView: View {
public struct SendFlowView: View {
let store: SendFlowStore
let tokenName: String
@FocusState private var isFocused: Bool
var body: some View {
public init(store: SendFlowStore, tokenName: String) {
self.store = store
self.tokenName = tokenName
}
public var body: some View {
isFocused = true
return WithViewStore(store) { viewStore in
CreateTransaction(store: store)
CreateTransaction(store: store, tokenName: tokenName)
.onAppear { viewStore.send(.onAppear) }
.onDisappear { viewStore.send(.onDisappear) }
.sheet(
@ -28,10 +35,10 @@ struct SendFlowView: View {
},
content: {
VStack {
MultipleLineTextField(
MultipleLineTextField<EmptyView>(
store: store.memoStore(),
title: L10n.Send.memoPlaceholder,
titleAccessoryView: {},
titleAccessoryView: { EmptyView() }(),
isFocused: _isFocused
)
.frame(height: 200)
@ -44,7 +51,7 @@ struct SendFlowView: View {
.applyScreenBackground()
.navigationLinkEmpty(
isActive: viewStore.bindingForInProgress,
destination: { TransactionSendingView(viewStore: viewStore) }
destination: { TransactionSendingView(viewStore: viewStore, tokenName: tokenName) }
)
.navigationLinkEmpty(
isActive: viewStore.bindingForScanQR,
@ -71,8 +78,9 @@ struct SendFLowView_Previews: PreviewProvider {
transactionAddressInputState: .placeholder,
transactionAmountInputState: .placeholder
),
reducer: SendFlowReducer()
)
reducer: SendFlowReducer(networkType: .testnet)
),
tokenName: "ZEC"
)
.navigationBarTitleDisplayMode(.inline)
.navigationViewStyle(.stack)

View File

@ -1,17 +1,25 @@
import SwiftUI
import ComposableArchitecture
import Generated
import UIComponents
import Utils
struct CreateTransaction: View {
public struct CreateTransaction: View {
let store: SendFlowStore
let tokenName: String
var body: some View {
public init(store: SendFlowStore, tokenName: String) {
self.store = store
self.tokenName = tokenName
}
public var body: some View {
UITextView.appearance().backgroundColor = .clear
return WithViewStore(store) { viewStore in
VStack(spacing: 5) {
VStack(spacing: 0) {
Text(L10n.Balance.available(viewStore.shieldedBalance.data.verified.decimalString(), TargetConstants.tokenName))
Text(L10n.Balance.available(viewStore.shieldedBalance.data.verified.decimalString(), tokenName))
.font(.system(size: 26))
.fontWeight(.bold)
.multilineTextAlignment(.center)
@ -35,7 +43,8 @@ struct CreateTransaction: View {
store: store.scope(
state: \.transactionAmountInputState,
action: SendFlowReducer.Action.transactionAmountInput
)
),
tokenName: tokenName
)
.padding(.horizontal)
@ -78,7 +87,7 @@ struct Create_Previews: PreviewProvider {
StateContainer(
initialState: ( false )
) { _ in
CreateTransaction(store: .placeholder)
CreateTransaction(store: .placeholder, tokenName: "ZEC")
}
.navigationBarTitleDisplayMode(.inline)
.preferredColorScheme(.light)

View File

@ -1,11 +1,16 @@
import SwiftUI
import ComposableArchitecture
import Generated
import UIComponents
struct TransactionFailed: View {
public struct TransactionFailed: View {
let viewStore: SendFlowViewStore
var body: some View {
public init(viewStore: SendFlowViewStore) {
self.viewStore = viewStore
}
public var body: some View {
VStack {
Text(L10n.Send.failed)

View File

@ -9,15 +9,22 @@ import ComposableArchitecture
import Foundation
import SwiftUI
import Generated
import UIComponents
struct TransactionSendingView: View {
public struct TransactionSendingView: View {
let viewStore: SendFlowViewStore
let tokenName: String
var body: some View {
public init(viewStore: SendFlowViewStore, tokenName: String) {
self.viewStore = viewStore
self.tokenName = tokenName
}
public var body: some View {
ZStack {
VStack(alignment: .center, spacing: 40) {
Spacer()
Text(L10n.Send.sendingTo(viewStore.amount.decimalString(), TargetConstants.tokenName))
Text(L10n.Send.sendingTo(viewStore.amount.decimalString(), tokenName))
.foregroundColor(Asset.Colors.Mfp.fontDark.color)
Text(viewStore.address)
@ -45,6 +52,6 @@ struct TransactionSendingView: View {
struct TransactionSendingView_Previews: PreviewProvider {
static var previews: some View {
TransactionSendingView(viewStore: ViewStore(SendFlowStore.placeholder))
TransactionSendingView(viewStore: ViewStore(SendFlowStore.placeholder), tokenName: "ZEC")
}
}

View File

@ -1,11 +1,16 @@
import SwiftUI
import ComposableArchitecture
import Generated
import UIComponents
struct TransactionSent: View {
public struct TransactionSent: View {
let viewStore: SendFlowViewStore
var body: some View {
public init(viewStore: SendFlowViewStore) {
self.viewStore = viewStore
}
public var body: some View {
VStack {
Text(L10n.Send.succeeded)

View File

@ -9,15 +9,15 @@ import ComposableArchitecture
// TODO: [#315] Reimplement this into multicurrency supporter (https://github.com/zcash/secant-ios-wallet/issues/315)
typealias CurrencySelectionStore = Store<CurrencySelectionReducer.State, CurrencySelectionReducer.Action>
public typealias CurrencySelectionStore = Store<CurrencySelectionReducer.State, CurrencySelectionReducer.Action>
struct CurrencySelectionReducer: ReducerProtocol {
struct State: Equatable {
enum Currency: Equatable {
public struct CurrencySelectionReducer: ReducerProtocol {
public struct State: Equatable {
public enum Currency: Equatable {
case usd
case zec
var acronym: String {
public var acronym: String {
switch self {
case .usd: return "USD"
case .zec: return "ZEC"
@ -25,14 +25,20 @@ struct CurrencySelectionReducer: ReducerProtocol {
}
}
var currencyType: Currency = .zec
public var currencyType: Currency = .zec
public init(currencyType: Currency = .zec) {
self.currencyType = currencyType
}
}
enum Action: Equatable {
public enum Action: Equatable {
case swapCurrencyType
}
func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
public init() {}
public func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
switch action {
case .swapCurrencyType:
switch state.currencyType {

View File

@ -8,10 +8,10 @@
import SwiftUI
import ComposableArchitecture
struct CurrencySelectionView: View {
public struct CurrencySelectionView: View {
let store: CurrencySelectionStore
var body: some View {
public var body: some View {
WithViewStore(store) { viewStore in
Button(
action: { viewStore.send(.swapCurrencyType) },

View File

@ -9,8 +9,8 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct TextFieldFooter: View {
var body: some View {
public struct TextFieldFooter: View {
public var body: some View {
HStack(spacing: 0) {
Rectangle()
.frame(height: 1.5)

View File

@ -24,7 +24,7 @@ struct TextFieldTitleAccessoryButtonStyle: ButtonStyle {
}
extension Button {
var textFieldTitleAccessoryButtonStyle: some View {
public var textFieldTitleAccessoryButtonStyle: some View {
buttonStyle(TextFieldTitleAccessoryButtonStyle())
}
}

View File

@ -11,43 +11,50 @@ import SwiftUI
import Utils
import Generated
typealias MultiLineTextFieldStore = Store<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action>
typealias MultiLineTextFieldViewStore = ViewStore<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action>
public typealias MultiLineTextFieldStore = Store<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action>
public typealias MultiLineTextFieldViewStore = ViewStore<MultiLineTextFieldReducer.State, MultiLineTextFieldReducer.Action>
struct MultiLineTextFieldReducer: ReducerProtocol {
struct State: Equatable {
public struct MultiLineTextFieldReducer: ReducerProtocol {
public struct State: Equatable {
/// default 0, no char limit
var charLimit = 0
var text = "".redacted
public var charLimit = 0
public var text = "".redacted
var isCharLimited: Bool {
public var isCharLimited: Bool {
charLimit > 0
}
var textLength: Int {
public var textLength: Int {
text.data.count
}
var isValid: Bool {
public var isValid: Bool {
charLimit > 0
? textLength <= charLimit
: true
}
var charLimitText: String {
public var charLimitText: String {
charLimit > 0
? isValid
? "\(textLength)/\(charLimit)"
: "\(L10n.Field.Multiline.charLimitExceeded) \(textLength)/\(charLimit)"
: ""
}
public init(charLimit: Int = 0, text: RedactableString = "".redacted) {
self.charLimit = charLimit
self.text = text
}
}
enum Action: Equatable {
public enum Action: Equatable {
case memoInputChanged(RedactableString)
}
var body: some ReducerProtocol<State, Action> {
public init() {}
public var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
switch action {
case .memoInputChanged(let text):
@ -72,7 +79,7 @@ extension MultiLineTextFieldViewStore {
// MARK: - Store
extension MultiLineTextFieldStore {
static let placeholder = MultiLineTextFieldStore(
public static let placeholder = MultiLineTextFieldStore(
initialState: .placeholder,
reducer: MultiLineTextFieldReducer()
)
@ -81,7 +88,7 @@ extension MultiLineTextFieldStore {
// MARK: - Placeholders
extension MultiLineTextFieldReducer.State {
static let placeholder: MultiLineTextFieldReducer.State = {
public static let placeholder: MultiLineTextFieldReducer.State = {
var state = MultiLineTextFieldReducer.State()
state.text = "".redacted
return state

View File

@ -9,7 +9,7 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct MultipleLineTextField<TitleAccessoryContent>: View
public struct MultipleLineTextField<TitleAccessoryContent>: View
where TitleAccessoryContent: View {
let store: MultiLineTextFieldStore
let title: String
@ -17,7 +17,19 @@ struct MultipleLineTextField<TitleAccessoryContent>: View
@ViewBuilder let titleAccessoryView: TitleAccessoryContent
@FocusState public var isFocused: Bool
var body: some View {
public init(
store: MultiLineTextFieldStore,
title: String,
titleAccessoryView: TitleAccessoryContent,
isFocused: FocusState<Bool>
) {
self.store = store
self.title = title
self.titleAccessoryView = titleAccessoryView
self.isFocused = isFocused.wrappedValue
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
HStack {
@ -67,7 +79,7 @@ struct MultilineTextEditorModifier: ViewModifier {
}
extension View {
func multilineTextEditorModifier(
public func multilineTextEditorModifier(
_ backgroundColor: Color = .white,
_ outlineColor: Color = .black
) -> some View {
@ -82,13 +94,16 @@ extension View {
struct MultipleLineTextField_Previews: PreviewProvider {
static var previews: some View {
MultipleLineTextField(
@FocusState var isFocused
return MultipleLineTextField<Text>(
store: .placeholder,
title: "Memo",
titleAccessoryView: {
Text("accessory")
.font(.custom(FontFamily.Rubik.regular.name, size: 13))
}
}(),
isFocused: _isFocused
)
.frame(height: 200)
.padding()

View File

@ -9,7 +9,7 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct SingleLineTextField<TitleAccessoryContent, InputPrefixContent, InputAccessoryContent>: View
public struct SingleLineTextField<TitleAccessoryContent, InputPrefixContent, InputAccessoryContent>: View
where TitleAccessoryContent: View, InputPrefixContent: View, InputAccessoryContent: View {
let placeholderText: String
let title: String
@ -19,7 +19,7 @@ struct SingleLineTextField<TitleAccessoryContent, InputPrefixContent, InputAcces
@ViewBuilder let inputPrefixView: InputPrefixContent
@ViewBuilder let inputAccessoryView: InputAccessoryContent
var body: some View {
public var body: some View {
VStack(spacing: 0) {
HStack {
Text(title)

View File

@ -9,11 +9,16 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct TCATextField: View {
public struct TCATextField: View {
let placeholder: String
let store: TCATextFieldStore
var body: some View {
public init(placeholder: String, store: TCATextFieldStore) {
self.placeholder = placeholder
self.store = store
}
public var body: some View {
WithViewStore(store) { viewStore in
TextField(
placeholder,

View File

@ -8,25 +8,25 @@
import ComposableArchitecture
import Utils
typealias TCATextFieldStore = Store<TCATextFieldReducer.State, TCATextFieldReducer.Action>
public typealias TCATextFieldStore = Store<TCATextFieldReducer.State, TCATextFieldReducer.Action>
struct TCATextFieldReducer: ReducerProtocol {
struct State: Equatable {
var validationType: String.ValidationType?
var text = "".redacted
var valid = false
public struct TCATextFieldReducer: ReducerProtocol {
public struct State: Equatable {
public var validationType: String.ValidationType?
public var text = "".redacted
public var valid = false
init(validationType: String.ValidationType?, text: RedactableString) {
public init(validationType: String.ValidationType?, text: RedactableString) {
self.validationType = validationType
self.text = text
}
}
enum Action: Equatable {
public enum Action: Equatable {
case set(RedactableString)
}
func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
public func reduce(into state: inout State, action: Action) -> ComposableArchitecture.EffectTask<Action> {
switch action {
case .set(let text):
state.text = text
@ -39,14 +39,14 @@ struct TCATextFieldReducer: ReducerProtocol {
// MARK: - Store
extension TCATextFieldStore {
static var transaction: Self {
public static var transaction: Self {
.init(
initialState: .init(validationType: .customFloatingPoint(.zcashNumberFormatter), text: "".redacted),
reducer: TCATextFieldReducer()
)
}
static var address: Self {
public static var address: Self {
.init(
initialState: .init(validationType: .email, text: "".redacted),
reducer: TCATextFieldReducer()
@ -57,12 +57,12 @@ extension TCATextFieldStore {
// MARK: - Placeholders
extension TCATextFieldReducer.State {
static let placeholder = TCATextFieldReducer.State(
public static let placeholder = TCATextFieldReducer.State(
validationType: nil,
text: "".redacted
)
static let amount = TCATextFieldReducer.State(
public static let amount = TCATextFieldReducer.State(
validationType: .floatingPoint,
text: "".redacted
)

View File

@ -9,10 +9,14 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct TransactionAddressTextField: View {
public struct TransactionAddressTextField: View {
let store: TransactionAddressTextFieldStore
var body: some View {
public init(store: TransactionAddressTextFieldStore) {
self.store = store
}
public var body: some View {
WithViewStore(store) { viewStore in
VStack {
SingleLineTextField(
@ -50,7 +54,7 @@ struct TransactionAddressTextField_Previews: PreviewProvider {
text: "".redacted
)
),
reducer: TransactionAddressTextFieldReducer()
reducer: TransactionAddressTextFieldReducer(networkType: .testnet)
)
)
.preferredColorScheme(.light)

View File

@ -0,0 +1,80 @@
//
// TransactionAddressTextFieldStore.swift
// secant-testnet
//
// Created by Lukáš Korba on 05/05/22.
//
import ComposableArchitecture
import SwiftUI
import ZcashLightClientKit
import DerivationTool
import ZcashSDKEnvironment
public typealias TransactionAddressTextFieldStore = Store<TransactionAddressTextFieldReducer.State, TransactionAddressTextFieldReducer.Action>
public struct TransactionAddressTextFieldReducer: ReducerProtocol {
let networkType: NetworkType
public struct State: Equatable {
public var isValidAddress = false
public var isValidTransparentAddress = false
public var textFieldState: TCATextFieldReducer.State
public init(isValidAddress: Bool = false, isValidTransparentAddress: Bool = false, textFieldState: TCATextFieldReducer.State) {
self.isValidAddress = isValidAddress
self.isValidTransparentAddress = isValidTransparentAddress
self.textFieldState = textFieldState
}
}
public enum Action: Equatable {
case clearAddress
case scanQR
case textField(TCATextFieldReducer.Action)
}
@Dependency(\.derivationTool) var derivationTool
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
public init(networkType: NetworkType) {
self.networkType = networkType
}
public var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
switch action {
case .clearAddress:
state.textFieldState.text = "".redacted
return .none
case .scanQR:
return .none
case .textField(.set(let address)):
state.isValidAddress = derivationTool.isZcashAddress(address.data, networkType)
state.isValidTransparentAddress = derivationTool.isTransparentAddress(address.data, networkType)
return .none
}
}
Scope(state: \.textFieldState, action: /Action.textField) {
TCATextFieldReducer()
}
}
}
// MARK: - Placeholders
extension TransactionAddressTextFieldReducer.State {
public static let placeholder = TransactionAddressTextFieldReducer.State(
textFieldState: .placeholder
)
}
extension TransactionAddressTextFieldStore {
public static let placeholder = TransactionAddressTextFieldStore(
initialState: .placeholder,
reducer: TransactionAddressTextFieldReducer(networkType: .testnet)
)
}

View File

@ -9,13 +9,19 @@ import SwiftUI
import ComposableArchitecture
import Generated
struct TransactionAmountTextField: View {
public struct TransactionAmountTextField: View {
let store: TransactionAmountTextFieldStore
let tokenName: String
var body: some View {
public init(store: TransactionAmountTextFieldStore, tokenName: String) {
self.store = store
self.tokenName = tokenName
}
public var body: some View {
VStack {
SingleLineTextField(
placeholderText: L10n.Field.TransactionAmount.zecAmount(TargetConstants.tokenName),
placeholderText: L10n.Field.TransactionAmount.zecAmount(tokenName),
title: L10n.Field.TransactionAmount.amount,
store: store.scope(
state: \.textFieldState,
@ -41,7 +47,8 @@ struct TransactionAmountTextField_Previews: PreviewProvider {
)
),
reducer: TransactionAmountTextFieldReducer()
)
),
tokenName: "ZEC"
)
.preferredColorScheme(.light)
.padding(.horizontal, 50)

View File

@ -11,23 +11,37 @@ import Foundation
import Utils
import NumberFormatter
typealias TransactionAmountTextFieldStore = Store<TransactionAmountTextFieldReducer.State, TransactionAmountTextFieldReducer.Action>
public typealias TransactionAmountTextFieldStore = Store<TransactionAmountTextFieldReducer.State, TransactionAmountTextFieldReducer.Action>
struct TransactionAmountTextFieldReducer: ReducerProtocol {
struct State: Equatable {
var amount = RedactableInt64(0)
var currencySelectionState: CurrencySelectionReducer.State
var maxValue = RedactableInt64(0)
var textFieldState: TCATextFieldReducer.State
public struct TransactionAmountTextFieldReducer: ReducerProtocol {
public struct State: Equatable {
public var amount = RedactableInt64(0)
public var currencySelectionState: CurrencySelectionReducer.State
public var maxValue = RedactableInt64(0)
public var textFieldState: TCATextFieldReducer.State
// TODO: [#311] - Get the ZEC price from the SDK, https://github.com/zcash/secant-ios-wallet/issues/311
var zecPrice = Decimal(140.0)
public var zecPrice = Decimal(140.0)
var isMax: Bool {
public var isMax: Bool {
return amount == maxValue
}
public init(
amount: RedactableInt64 = RedactableInt64(0),
currencySelectionState: CurrencySelectionReducer.State,
maxValue: RedactableInt64 = RedactableInt64(0),
textFieldState: TCATextFieldReducer.State,
zecPrice: Decimal = Decimal(140.0)
) {
self.amount = amount
self.currencySelectionState = currencySelectionState
self.maxValue = maxValue
self.textFieldState = textFieldState
self.zecPrice = zecPrice
}
}
enum Action: Equatable {
public enum Action: Equatable {
case clearValue
case currencySelection(CurrencySelectionReducer.Action)
case setMax
@ -37,7 +51,9 @@ struct TransactionAmountTextFieldReducer: ReducerProtocol {
@Dependency(\.numberFormatter) var numberFormatter
var body: some ReducerProtocol<State, Action> {
public init() {}
public var body: some ReducerProtocol<State, Action> {
Scope(state: \.currencySelectionState, action: /Action.currencySelection) {
CurrencySelectionReducer()
}
@ -106,19 +122,19 @@ struct TransactionAmountTextFieldReducer: ReducerProtocol {
// MARK: - Placeholders
extension TransactionAmountTextFieldReducer.State {
static let placeholder = TransactionAmountTextFieldReducer.State(
public static let placeholder = TransactionAmountTextFieldReducer.State(
currencySelectionState: CurrencySelectionReducer.State(),
textFieldState: .placeholder
)
static let amount = TransactionAmountTextFieldReducer.State(
public static let amount = TransactionAmountTextFieldReducer.State(
currencySelectionState: CurrencySelectionReducer.State(),
textFieldState: .amount
)
}
extension TransactionAmountTextFieldStore {
static let placeholder = TransactionAmountTextFieldStore(
public static let placeholder = TransactionAmountTextFieldStore(
initialState: .placeholder,
reducer: TransactionAmountTextFieldReducer()
)

View File

@ -1,16 +1,16 @@
import SwiftUI
// TODO: [#695] This should have a #DEBUG tag, but if so, it's not possible to compile this on release mode and submit it to testflight https://github.com/zcash/ZcashLightClientKit/issues/695
struct StateContainer<T, Content: View>: View {
public struct StateContainer<T, Content: View>: View {
@State private var state: T
private var content: (Binding<T>) -> Content
init(initialState: T, content: @escaping (Binding<T>) -> Content) {
public init(initialState: T, content: @escaping (Binding<T>) -> Content) {
self._state = State(initialValue: initialState)
self.content = content
}
var body: some View {
public var body: some View {
content($state)
}
}

View File

@ -10,64 +10,33 @@
0D26103C298C3E4800CC9DE9 /* CrashReporterInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103B298C3E4800CC9DE9 /* CrashReporterInterface.swift */; };
0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103D298C3FA600CC9DE9 /* CrashReporterLiveKey.swift */; };
0D261040298C406F00CC9DE9 /* CrashReporterTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103F298C406F00CC9DE9 /* CrashReporterTestKey.swift */; };
0D26AE9B299E8196005260EE /* OnboardingFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E5C03802738C570008BFFD3 /* OnboardingFlowView.swift */; };
0D26AE9D299E8196005260EE /* CrashReporterTestKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103F298C406F00CC9DE9 /* CrashReporterTestKey.swift */; };
0D26AEA0299E8196005260EE /* SandboxStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */; };
0D26AEA5299E8196005260EE /* TransactionSendingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DA414628E4385800F8CC61 /* TransactionSendingView.swift */; };
0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103D298C3FA600CC9DE9 /* CrashReporterLiveKey.swift */; };
0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA079F27EDE18C00D6F09B /* TCATextField.swift */; };
0D26AEAF299E8196005260EE /* TransactionAmountTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB7758627FC67FD00269373 /* TransactionAmountTextFieldStore.swift */; };
0D26AEB1299E8196005260EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8135F27F043CC0075AF48 /* AppDelegate.swift */; };
0D26AEBC299E8196005260EE /* TCATextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB1C5E727D77F6100BC43D7 /* TCATextFieldStore.swift */; };
0D26AEBF299E8196005260EE /* TransactionFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */; };
0D26AEC4299E8196005260EE /* TCALogging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5740297E7F1C005304FA /* TCALogging.swift */; };
0D26AEC6299E8196005260EE /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99B27CF704D00649636 /* ImportWalletView.swift */; };
0D26AEC7299E8196005260EE /* RootInitialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ADA7C2938F4C00071767B /* RootInitialization.swift */; };
0D26AECC299E8196005260EE /* OnboardingFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C73D2715A41300901167 /* OnboardingFlowStore.swift */; };
0D26AECF299E8196005260EE /* CurrencySelectionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */; };
0D26AED3299E8196005260EE /* SyncStatusSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */; };
0D26AEDA299E8196005260EE /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; };
0D26AEDC299E8196005260EE /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
0D26AEE4299E8196005260EE /* CurrencySelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CC27FB0D3B0082C926 /* CurrencySelectionView.swift */; };
0D26AEE7299E8196005260EE /* TransactionAddressTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF64E2823E94900BA3F17 /* TransactionAddressTextFieldStore.swift */; };
0D26AEE9299E8196005260EE /* WithStateBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */; };
0D26AEEB299E8196005260EE /* Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93673D52742CB840099C6AF /* Previews.swift */; };
0D26AEF0299E8196005260EE /* TCALoggerReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E0F5742297EB96C005304FA /* TCALoggerReducer.swift */; };
0D26AEF2299E8196005260EE /* MultipleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */; };
0D26AEF3299E8196005260EE /* NotEnoughFreeSpaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */; };
0D26AEF7299E8196005260EE /* Drawer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8E280EDE09004E65FE /* Drawer.swift */; };
0D26AEFA299E8196005260EE /* DesignGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */; };
0D26AEFC299E8196005260EE /* RootStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4A27680DC400A2DB75 /* RootStore.swift */; };
0D26AEFD299E8196005260EE /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874EF273C4DE200F0E875 /* HomeView.swift */; };
0D26AEFF299E8196005260EE /* SandboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8D2808183D00199FC9 /* SandboxView.swift */; };
0D26AF07299E8196005260EE /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4C27680DC400A2DB75 /* RootView.swift */; };
0D26AF0A299E8196005260EE /* OnboardingFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */; };
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 */; };
0D26AF1B299E8196005260EE /* HomeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F93874ED273C4DE200F0E875 /* HomeStore.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 */; };
0D26AF3A299E8196005260EE /* OnboardingContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5C27467F7700709571 /* OnboardingContentView.swift */; };
0D26AF3B299E8196005260EE /* CircularProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6142869E8C300A02233 /* CircularProgress.swift */; };
0D26AF3C299E8196005260EE /* OnboardingHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */; };
0D26AF3D299E8196005260EE /* TransactionAddressTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF64D2823E94900BA3F17 /* TransactionAddressTextField.swift */; };
0D26AF3E299E8196005260EE /* SingleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */; };
0D26AF40299E8196005260EE /* RootDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ADA7E2938F5EC0071767B /* RootDestination.swift */; };
0D26AF41299E8196005260EE /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
0D26AF44299E8196005260EE /* Memo+toString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BF09082927C98000222134 /* Memo+toString.swift */; };
0D26AF46299E8196005260EE /* CheckCircleStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A428E2027D0035F7C4 /* CheckCircleStore.swift */; };
0D26AF47299E8196005260EE /* CreateTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BB2740403600592F76 /* CreateTransactionView.swift */; };
0D26AF4B299E8196005260EE /* TextFieldTitleAccessoryButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */; };
0D26AF4D299E8196005260EE /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99827CF704D00649636 /* ImportWalletStore.swift */; };
0D26AF53299E8196005260EE /* TextFieldFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */; };
0D26AF54299E8196005260EE /* CrashReporterInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D26103B298C3E4800CC9DE9 /* CrashReporterInterface.swift */; };
0D26AF5F299E8196005260EE /* SendFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165CA2741AB5D00592F76 /* SendFlowView.swift */; };
0D26AF65299E8196005260EE /* InitializationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EF8139B27F47AED0075AF48 /* InitializationState.swift */; };
0D26AF68299E8196005260EE /* TransactionAmountTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CA27FB09990082C926 /* TransactionAmountTextField.swift */; };
0D26AF6A299E8196005260EE /* ClearBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */; };
0D26AF6C299E8196005260EE /* TransactionSentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BD2740403600592F76 /* TransactionSentView.swift */; };
0D26AF71299E8196005260EE /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 0D26AE8F299E8196005260EE /* Lottie */; };
0D26AF72299E8196005260EE /* URLRouting in Frameworks */ = {isa = PBXBuildFile; productRef = 0D26AE93299E8196005260EE /* URLRouting */; };
0D26AF73299E8196005260EE /* ZcashLightClientKit in Frameworks */ = {isa = PBXBuildFile; productRef = 0D26AE91299E8196005260EE /* ZcashLightClientKit */; };
@ -80,38 +49,20 @@
0D26AF84299E8196005260EE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0F26B364180058B01E /* Preview Assets.xcassets */; };
0D26AF88299E8196005260EE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8B280ED6A7004E65FE /* LaunchScreen.storyboard */; };
0D26AF8C299E8196005260EE /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0D3B01EB298DAF89007EBCDA /* GoogleService-Info.plist */; };
0D3016B829BFB2FB002371B3 /* PlainOnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D3016B729BFB2FB002371B3 /* PlainOnboardingView.swift */; };
0D3016B929BFB2FB002371B3 /* PlainOnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D3016B729BFB2FB002371B3 /* PlainOnboardingView.swift */; };
0D3B01EC298DAF89007EBCDA /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0D3B01EB298DAF89007EBCDA /* GoogleService-Info.plist */; };
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0826B364170058B01E /* SecantApp.swift */; };
0D4E7A1026B364180058B01E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D4E7A0F26B364180058B01E /* Preview Assets.xcassets */; };
0D5D9B8F2914620700DBD03F /* URLRouting in Frameworks */ = {isa = PBXBuildFile; productRef = 0D5D9B8E2914620700DBD03F /* URLRouting */; };
0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */; };
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB8AA80271DC7520035BC9D /* DesignGuide.swift */; };
2E35F99227B28E7600EB79CD /* SingleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */; };
2E35F99A27B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */; };
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */; };
2E6CF8DD27D78319004DCD7A /* CurrencySelectionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */; };
2E8719CB27FB09990082C926 /* TransactionAmountTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CA27FB09990082C926 /* TransactionAmountTextField.swift */; };
2E8719CD27FB0D3B0082C926 /* CurrencySelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8719CC27FB0D3B0082C926 /* CurrencySelectionView.swift */; };
2EA11F5B27467EF800709571 /* OnboardingFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */; };
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA11F5C27467F7700709571 /* OnboardingContentView.swift */; };
2EB1C5E827D77F6100BC43D7 /* TCATextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB1C5E727D77F6100BC43D7 /* TCATextFieldStore.swift */; };
2EB660E02747EAB900A06A07 /* OnboardingFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E5C03802738C570008BFFD3 /* OnboardingFlowView.swift */; };
2EB7758727FC67FD00269373 /* TransactionAmountTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB7758627FC67FD00269373 /* TransactionAmountTextFieldStore.swift */; };
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA079F27EDE18C00D6F09B /* TCATextField.swift */; };
2EDA07A227EDE1AE00D6F09B /* TextFieldFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */; };
2EDA07A427EDE2A900D6F09B /* DebugFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */; };
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448CB3128E47666006ADEDB /* NotEnoughFreeSpaceView.swift */; };
346715A528E2027D0035F7C4 /* CheckCircleStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346715A428E2027D0035F7C4 /* CheckCircleStore.swift */; };
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346D41E328DF0B8600963F36 /* CheckCircle.swift */; };
34BF09092927C98000222134 /* Memo+toString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BF09082927C98000222134 /* Memo+toString.swift */; };
34CE032B29C0938600A6626B /* ZcashLightClientKit in Frameworks */ = {isa = PBXBuildFile; productRef = 34CE032A29C0938600A6626B /* ZcashLightClientKit */; };
34DA414728E4385800F8CC61 /* TransactionSendingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DA414628E4385800F8CC61 /* TransactionSendingView.swift */; };
34DA414928E439CD00F8CC61 /* sendingTransaction.json in Resources */ = {isa = PBXBuildFile; fileRef = 34DA414828E439CD00F8CC61 /* sendingTransaction.json */; };
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 */; };
9E0031602A272736003DFCEB /* AppVersion in Frameworks */ = {isa = PBXBuildFile; productRef = 9E00315F2A272736003DFCEB /* AppVersion */; };
9E0031622A272736003DFCEB /* AudioServices in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031612A272736003DFCEB /* AudioServices */; };
9E0031642A272736003DFCEB /* CaptureDevice in Frameworks */ = {isa = PBXBuildFile; productRef = 9E0031632A272736003DFCEB /* CaptureDevice */; };
@ -164,9 +115,6 @@
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 */; };
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99827CF704D00649636 /* ImportWalletStore.swift */; };
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; };
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99B27CF704D00649636 /* ImportWalletView.swift */; };
9E2F1C8C280ED6A7004E65FE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8B280ED6A7004E65FE /* LaunchScreen.storyboard */; };
9E2F1C8F280EDE09004E65FE /* Drawer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2F1C8E280EDE09004E65FE /* Drawer.swift */; };
9E33ECDA29D5E30700708DE4 /* OnChangeReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9CEA3D29D47BE000599DF5 /* OnChangeReducer.swift */; };
@ -219,8 +167,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 */; };
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 */; };
9E486DF129B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DEF29B9EE84003E6945 /* KeyboardAdaptive.swift */; };
9E486DF329B9EEC4003E6945 /* UIResponder+Current.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E486DF229B9EEC4003E6945 /* UIResponder+Current.swift */; };
@ -231,16 +177,11 @@
9E54526A2A28D5570098B887 /* Welcome in Frameworks */ = {isa = PBXBuildFile; productRef = 9E5452692A28D5570098B887 /* Welcome */; };
9E54526C2A28DA4B0098B887 /* Profile in Frameworks */ = {isa = PBXBuildFile; productRef = 9E54526B2A28DA4B0098B887 /* Profile */; };
9E54526E2A28DA510098B887 /* Profile in Frameworks */ = {isa = PBXBuildFile; productRef = 9E54526D2A28DA510098B887 /* Profile */; };
9E5BF641281FD7B600BA3F17 /* TransactionFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */; };
9E5BF64F2823E94900BA3F17 /* TransactionAddressTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF64D2823E94900BA3F17 /* TransactionAddressTextField.swift */; };
9E5BF6502823E94900BA3F17 /* TransactionAddressTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF64E2823E94900BA3F17 /* TransactionAddressTextFieldStore.swift */; };
9E66122C2877188700C75B70 /* SyncStatusSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */; };
9E6612312878337F00C75B70 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 9E6612302878337F00C75B70 /* Lottie */; };
9E6612332878338C00C75B70 /* LottieAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6612322878338C00C75B70 /* LottieAnimation.swift */; };
9E6612362878345000C75B70 /* endlessCircleProgress.json in Resources */ = {isa = PBXBuildFile; fileRef = 9E6612352878345000C75B70 /* endlessCircleProgress.json */; };
9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */; };
9E7225F3288AB6DD00DF7F17 /* MultipleLineTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */; };
9E7225F6288AC71A00DF7F17 /* MultiLineTextFieldStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */; };
9E74CCD029DC0628003D6E32 /* ReviewRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E74CCCF29DC0628003D6E32 /* ReviewRequestTests.swift */; };
9E7CB6152869E8C300A02233 /* CircularProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E7CB6142869E8C300A02233 /* CircularProgress.swift */; };
9E80C44C2A25E8EC0049E6A7 /* MnemonicClient in Frameworks */ = {isa = PBXBuildFile; productRef = 9E80C44B2A25E8EC0049E6A7 /* MnemonicClient */; };
@ -261,10 +202,16 @@
9E9ADA7F2938F5EC0071767B /* RootDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9ADA7E2938F5EC0071767B /* RootDestination.swift */; };
9E9CEA3E29D47BE000599DF5 /* OnChangeReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E9CEA3D29D47BE000599DF5 /* OnChangeReducer.swift */; };
9EAB466D285A0468002904A0 /* Parsing in Frameworks */ = {isa = PBXBuildFile; productRef = 9EAB466C285A0468002904A0 /* Parsing */; };
9EAFEB8F2808183D00199FC9 /* SandboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB8D2808183D00199FC9 /* SandboxView.swift */; };
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 */; };
9EB35D442A2F5F2A00A2149B /* ImportWallet in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D432A2F5F2A00A2149B /* ImportWallet */; };
9EB35D462A2F5F2F00A2149B /* ImportWallet in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D452A2F5F2F00A2149B /* ImportWallet */; };
9EB35D482A2F6B8700A2149B /* OnboardingFlow in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D472A2F6B8700A2149B /* OnboardingFlow */; };
9EB35D4A2A2F6B8B00A2149B /* OnboardingFlow in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D492A2F6B8B00A2149B /* OnboardingFlow */; };
9EB35D552A30656400A2149B /* SendFlow in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D542A30656400A2149B /* SendFlow */; };
9EB35D572A30656900A2149B /* SendFlow in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D562A30656900A2149B /* SendFlow */; };
9EB35D592A306C3E00A2149B /* Sandbox in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D582A306C3E00A2149B /* Sandbox */; };
9EB35D5B2A306C4300A2149B /* Sandbox in Frameworks */ = {isa = PBXBuildFile; productRef = 9EB35D5A2A306C4300A2149B /* Sandbox */; };
9EE5926D2A2DDF94007147CD /* BalanceBreakdown in Frameworks */ = {isa = PBXBuildFile; productRef = 9EE5926C2A2DDF94007147CD /* BalanceBreakdown */; };
9EE5926F2A2DDF98007147CD /* BalanceBreakdown in Frameworks */ = {isa = PBXBuildFile; productRef = 9EE5926E2A2DDF98007147CD /* BalanceBreakdown */; };
9EE592712A2DF202007147CD /* WalletEventsFlow in Frameworks */ = {isa = PBXBuildFile; productRef = 9EE592702A2DF202007147CD /* WalletEventsFlow */; };
@ -277,13 +224,8 @@
9EE5927F2A2E028D007147CD /* Settings in Frameworks */ = {isa = PBXBuildFile; productRef = 9EE5927E2A2E028D007147CD /* Settings */; };
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 */; };
F9971A4D27680DC400A2DB75 /* RootStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4A27680DC400A2DB75 /* RootStore.swift */; };
F9971A4E27680DC400A2DB75 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9971A4C27680DC400A2DB75 /* RootView.swift */; };
F9C165BF2740403600592F76 /* SendFlowStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165B72740403600592F76 /* SendFlowStore.swift */; };
F9C165C22740403600592F76 /* CreateTransactionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BB2740403600592F76 /* CreateTransactionView.swift */; };
F9C165C42740403600592F76 /* TransactionSentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165BD2740403600592F76 /* TransactionSentView.swift */; };
F9C165CB2741AB5D00592F76 /* SendFlowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C165CA2741AB5D00592F76 /* SendFlowView.swift */; };
F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */; };
/* End PBXBuildFile section */
@ -310,7 +252,6 @@
0D26103D298C3FA600CC9DE9 /* CrashReporterLiveKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporterLiveKey.swift; sourceTree = "<group>"; };
0D26103F298C406F00CC9DE9 /* CrashReporterTestKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporterTestKey.swift; sourceTree = "<group>"; };
0D26AF94299E8196005260EE /* secant-mainnet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "secant-mainnet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
0D3016B729BFB2FB002371B3 /* PlainOnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlainOnboardingView.swift; sourceTree = "<group>"; };
0D3B01EB298DAF89007EBCDA /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
0D4E7A0526B364170058B01E /* secant-testnet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "secant-testnet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
0D4E7A0826B364170058B01E /* SecantApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecantApp.swift; sourceTree = "<group>"; };
@ -328,19 +269,6 @@
0DEF4766299EA5920032708B /* secant-mainnet-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "secant-mainnet-Info.plist"; sourceTree = "<group>"; };
0DFE93DE272C6D4B000FCCA5 /* RecoveryPhraseBackupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseBackupTests.swift; sourceTree = "<group>"; };
0DFE93E5272CB6F7000FCCA5 /* RecoveryPhraseValidationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseValidationTests.swift; sourceTree = "<group>"; };
2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleLineTextField.swift; sourceTree = "<group>"; };
2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTitleAccessoryButtonStyle.swift; sourceTree = "<group>"; };
2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingHeaderView.swift; sourceTree = "<group>"; };
2E5C03802738C570008BFFD3 /* OnboardingFlowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFlowView.swift; sourceTree = "<group>"; };
2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencySelectionStore.swift; sourceTree = "<group>"; };
2E8719CA27FB09990082C926 /* TransactionAmountTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionAmountTextField.swift; sourceTree = "<group>"; };
2E8719CC27FB0D3B0082C926 /* CurrencySelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrencySelectionView.swift; sourceTree = "<group>"; };
2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFooterView.swift; sourceTree = "<group>"; };
2EA11F5C27467F7700709571 /* OnboardingContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingContentView.swift; sourceTree = "<group>"; };
2EB1C5E727D77F6100BC43D7 /* TCATextFieldStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCATextFieldStore.swift; sourceTree = "<group>"; };
2EB7758627FC67FD00269373 /* TransactionAmountTextFieldStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionAmountTextFieldStore.swift; sourceTree = "<group>"; };
2EDA079F27EDE18C00D6F09B /* TCATextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCATextField.swift; sourceTree = "<group>"; };
2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldFooter.swift; sourceTree = "<group>"; };
2EDA07A327EDE2A900D6F09B /* DebugFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugFrame.swift; sourceTree = "<group>"; };
341B30BA29B78D1000697081 /* HomeFeatureFlagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeFeatureFlagTests.swift; sourceTree = "<group>"; };
34429C6D28E703CD00F2B929 /* TransactionSendingSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionSendingSnapshotTests.swift; sourceTree = "<group>"; };
@ -350,12 +278,9 @@
3469F18129ACD70500A07146 /* OnboardingFlowFeatureFlagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFlowFeatureFlagTests.swift; sourceTree = "<group>"; };
346D41E328DF0B8600963F36 /* CheckCircle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckCircle.swift; sourceTree = "<group>"; };
34BF09082927C98000222134 /* Memo+toString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Memo+toString.swift"; sourceTree = "<group>"; };
34DA414628E4385800F8CC61 /* TransactionSendingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionSendingView.swift; sourceTree = "<group>"; };
34DA414828E439CD00F8CC61 /* sendingTransaction.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = sendingTransaction.json; sourceTree = "<group>"; };
34F039B229ABCE8500CF0053 /* WalletConfigProviderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletConfigProviderTests.swift; sourceTree = "<group>"; };
6654C73D2715A41300901167 /* OnboardingFlowStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingFlowStore.swift; sourceTree = "<group>"; };
6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingStoreTests.swift; sourceTree = "<group>"; };
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = "<group>"; };
9E01F8272833CDA0000EFC57 /* ScanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanTests.swift; sourceTree = "<group>"; };
9E02B56B27FED475005B809B /* DatabaseFilesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseFilesTests.swift; sourceTree = "<group>"; };
9E0F5740297E7F1C005304FA /* TCALogging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCALogging.swift; sourceTree = "<group>"; };
@ -363,24 +288,17 @@
9E0F574A2980260D005304FA /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = "<group>"; };
9E207C352966EC77003E2C9B /* AddressDetailsSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressDetailsSnapshotTests.swift; sourceTree = "<group>"; };
9E207C382966EF87003E2C9B /* AddressDetailsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressDetailsTests.swift; sourceTree = "<group>"; };
9E2DF99827CF704D00649636 /* ImportWalletStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = "<group>"; };
9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = "<group>"; };
9E2DF99B27CF704D00649636 /* ImportWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = "<group>"; };
9E2F1C8B280ED6A7004E65FE /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
9E2F1C8E280EDE09004E65FE /* Drawer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Drawer.swift; sourceTree = "<group>"; };
9E391123283E4CAC0073DD9A /* ImportWalletTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportWalletTests.swift; sourceTree = "<group>"; };
9E39112D283F91600073DD9A /* ZatoshiTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZatoshiTests.swift; sourceTree = "<group>"; };
9E391131284644580073DD9A /* AppInitializationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInitializationTests.swift; sourceTree = "<group>"; };
9E3911382848AD500073DD9A /* HomeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTests.swift; sourceTree = "<group>"; };
9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportBirthdayView.swift; sourceTree = "<group>"; };
9E486DEF29B9EE84003E6945 /* KeyboardAdaptive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyboardAdaptive.swift; sourceTree = "<group>"; };
9E486DF229B9EEC4003E6945 /* UIResponder+Current.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Current.swift"; sourceTree = "<group>"; };
9E486DF829BA09C2003E6945 /* UIKit+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+Extensions.swift"; sourceTree = "<group>"; };
9E5BF63E2819542C00BA3F17 /* WalletEventsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletEventsTests.swift; sourceTree = "<group>"; };
9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionFailedView.swift; sourceTree = "<group>"; };
9E5BF643281FEC9900BA3F17 /* SendTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTests.swift; sourceTree = "<group>"; };
9E5BF64D2823E94900BA3F17 /* TransactionAddressTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAddressTextField.swift; sourceTree = "<group>"; };
9E5BF64E2823E94900BA3F17 /* TransactionAddressTextFieldStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAddressTextFieldStore.swift; sourceTree = "<group>"; };
9E612C7829913F3600D09B09 /* SensitiveDataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SensitiveDataTests.swift; sourceTree = "<group>"; };
9E66122B2877188700C75B70 /* SyncStatusSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncStatusSnapshot.swift; sourceTree = "<group>"; };
9E6612322878338C00C75B70 /* LottieAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LottieAnimation.swift; sourceTree = "<group>"; };
@ -389,8 +307,6 @@
9E6713F02897F81B00A6796F /* MultiLineTextFieldTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiLineTextFieldTests.swift; sourceTree = "<group>"; };
9E6713F9289BE0E100A6796F /* ClearBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearBackgroundView.swift; sourceTree = "<group>"; };
9E7225F02889539300DF7F17 /* SettingsSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSnapshotTests.swift; sourceTree = "<group>"; };
9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleLineTextField.swift; sourceTree = "<group>"; };
9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiLineTextFieldStore.swift; sourceTree = "<group>"; };
9E74CCCF29DC0628003D6E32 /* ReviewRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewRequestTests.swift; sourceTree = "<group>"; };
9E7CB6112869882D00A02233 /* WalletEventsSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletEventsSnapshotTests.swift; sourceTree = "<group>"; };
9E7CB6142869E8C300A02233 /* CircularProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularProgress.swift; sourceTree = "<group>"; };
@ -415,8 +331,6 @@
9EAB4675285B5C7C002904A0 /* DeeplinkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeeplinkTests.swift; sourceTree = "<group>"; };
9EAFEB812805793200199FC9 /* RootTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootTests.swift; sourceTree = "<group>"; };
9EAFEB852805A23100199FC9 /* SecItemClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecItemClientTests.swift; sourceTree = "<group>"; };
9EAFEB8D2808183D00199FC9 /* SandboxView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxView.swift; sourceTree = "<group>"; };
9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxStore.swift; sourceTree = "<group>"; };
9EB7D14A2A20C6BC00F35E03 /* modules */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = modules; sourceTree = "<group>"; };
9EDDEA9F2829610D00B4100C /* CurrencySelectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrencySelectionTests.swift; sourceTree = "<group>"; };
9EDDEAA02829610D00B4100C /* TransactionAmountInputTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionAmountInputTests.swift; sourceTree = "<group>"; };
@ -425,15 +339,10 @@
9EF8135B27ECC25E0075AF48 /* UserPreferencesStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorageTests.swift; sourceTree = "<group>"; };
9EF8135F27F043CC0075AF48 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
9EF8139B27F47AED0075AF48 /* InitializationState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitializationState.swift; sourceTree = "<group>"; };
F93673D52742CB840099C6AF /* Previews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Previews.swift; sourceTree = "<group>"; };
F93874ED273C4DE200F0E875 /* HomeStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeStore.swift; sourceTree = "<group>"; };
F93874EF273C4DE200F0E875 /* HomeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
F9971A4A27680DC400A2DB75 /* RootStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootStore.swift; sourceTree = "<group>"; };
F9971A4C27680DC400A2DB75 /* RootView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
F9C165B72740403600592F76 /* SendFlowStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendFlowStore.swift; sourceTree = "<group>"; };
F9C165BB2740403600592F76 /* CreateTransactionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateTransactionView.swift; sourceTree = "<group>"; };
F9C165BD2740403600592F76 /* TransactionSentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionSentView.swift; sourceTree = "<group>"; };
F9C165CA2741AB5D00592F76 /* SendFlowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendFlowView.swift; sourceTree = "<group>"; };
F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WithStateBinding.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -446,10 +355,12 @@
9E0031902A272A61003DFCEB /* LogsHandler in Frameworks */,
0D26AF71299E8196005260EE /* Lottie in Frameworks */,
9EE5927F2A2E028D007147CD /* Settings in Frameworks */,
9EB35D4A2A2F6B8B00A2149B /* OnboardingFlow in Frameworks */,
9EE5927D2A2E0288007147CD /* ExportLogs in Frameworks */,
9EE592752A2DF7D8007147CD /* Scan in Frameworks */,
0D26AF72299E8196005260EE /* URLRouting in Frameworks */,
9EE5926F2A2DDF98007147CD /* BalanceBreakdown in Frameworks */,
9EB35D442A2F5F2A00A2149B /* ImportWallet in Frameworks */,
0D26AF73299E8196005260EE /* ZcashLightClientKit in Frameworks */,
9EE592732A2DF207007147CD /* WalletEventsFlow in Frameworks */,
9E0031BA2A2878EE003DFCEB /* AddressDetails in Frameworks */,
@ -462,6 +373,7 @@
9E0031AC2A276BC6003DFCEB /* URIParser in Frameworks */,
9E0031942A272A61003DFCEB /* Pasteboard in Frameworks */,
9E9075142A2691B700269308 /* ZcashSDKEnvironment in Frameworks */,
9EB35D552A30656400A2149B /* SendFlow in Frameworks */,
9E00319E2A272BB6003DFCEB /* SupportDataGenerator in Frameworks */,
9E0031822A27299A003DFCEB /* DiskSpaceChecker in Frameworks */,
9E0310C52A24A4E60021F995 /* FileManager in Frameworks */,
@ -473,6 +385,7 @@
0D26AF75299E8196005260EE /* MnemonicSwift in Frameworks */,
0D26AF76299E8196005260EE /* ComposableArchitecture in Frameworks */,
9E5452682A28D5500098B887 /* Welcome in Frameworks */,
9EB35D5B2A306C4300A2149B /* Sandbox in Frameworks */,
9E00319C2A272BB6003DFCEB /* SDKSynchronizer in Frameworks */,
9E9075062A2689D600269308 /* RecoveryPhraseValidationFlow in Frameworks */,
9E0031B82A27724D003DFCEB /* WalletStorage in Frameworks */,
@ -496,10 +409,12 @@
9E0031882A272A52003DFCEB /* LogsHandler in Frameworks */,
9E6612312878337F00C75B70 /* Lottie in Frameworks */,
9EE5927B2A2E0284007147CD /* Settings in Frameworks */,
9EB35D482A2F6B8700A2149B /* OnboardingFlow in Frameworks */,
9EE592792A2E027F007147CD /* ExportLogs in Frameworks */,
9EE592772A2DF7DD007147CD /* Scan in Frameworks */,
0D5D9B8F2914620700DBD03F /* URLRouting in Frameworks */,
9EE5926D2A2DDF94007147CD /* BalanceBreakdown in Frameworks */,
9EB35D462A2F5F2F00A2149B /* ImportWallet in Frameworks */,
34CE032B29C0938600A6626B /* ZcashLightClientKit in Frameworks */,
9EE592712A2DF202007147CD /* WalletEventsFlow in Frameworks */,
9E0031BC2A2878F3003DFCEB /* AddressDetails in Frameworks */,
@ -512,6 +427,7 @@
9E0031AA2A276BC1003DFCEB /* URIParser in Frameworks */,
9E00318C2A272A52003DFCEB /* Pasteboard in Frameworks */,
9E0310B52A24A4CA0021F995 /* FileManager in Frameworks */,
9EB35D572A30656900A2149B /* SendFlow in Frameworks */,
9E0031A62A272BC8003DFCEB /* SupportDataGenerator in Frameworks */,
9E00317E2A272991003DFCEB /* DiskSpaceChecker in Frameworks */,
9E0031682A272736003DFCEB /* Date in Frameworks */,
@ -523,6 +439,7 @@
9E80C44C2A25E8EC0049E6A7 /* MnemonicClient in Frameworks */,
6654C73A2715A38000901167 /* ComposableArchitecture in Frameworks */,
9E54526A2A28D5570098B887 /* Welcome in Frameworks */,
9EB35D592A306C3E00A2149B /* Sandbox in Frameworks */,
9E0031A42A272BC7003DFCEB /* SDKSynchronizer in Frameworks */,
9E9075082A2689DB00269308 /* RecoveryPhraseValidationFlow in Frameworks */,
9E0031B42A27723E003DFCEB /* WalletStorage in Frameworks */,
@ -662,13 +579,6 @@
path = Models;
sourceTree = "<group>";
};
0DF2DC5227235E1F00FA31E2 /* Extensions */ = {
isa = PBXGroup;
children = (
);
path = Extensions;
sourceTree = "<group>";
};
0DFE93DD272C6D4B000FCCA5 /* BackupFlowTests */ = {
isa = PBXGroup;
children = (
@ -687,29 +597,6 @@
path = RecoveryPhraseValidationTests;
sourceTree = "<group>";
};
2E35F99027B28E6800EB79CD /* TextFields */ = {
isa = PBXGroup;
children = (
2E35F99127B28E7600EB79CD /* SingleLineTextField.swift */,
2EDA07A527EDE31100D6F09B /* Components */,
9E7225F4288AC6F300DF7F17 /* MultiLineTextField */,
9E7FE0F0282E80C100C374E8 /* TCATextField */,
9E5BF64C2823E84300BA3F17 /* TransactionAddress */,
9E5BF64B2823C91200BA3F17 /* TransactionAmount */,
);
path = TextFields;
sourceTree = "<group>";
};
2EDA07A527EDE31100D6F09B /* Components */ = {
isa = PBXGroup;
children = (
9E7FE0EF282E7FA900C374E8 /* CurrencySelection */,
2EDA07A127EDE1AE00D6F09B /* TextFieldFooter.swift */,
2E35F99927B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift */,
);
path = Components;
sourceTree = "<group>";
};
343CF3F429BB5A14009E44DF /* Frameworks */ = {
isa = PBXGroup;
children = (
@ -754,37 +641,12 @@
isa = PBXGroup;
children = (
F93874EC273C4DE200F0E875 /* Home */,
9E2DF99727CF704D00649636 /* ImportWallet */,
3448CB3028E4764E006ADEDB /* NotEnoughFreeSpace */,
6654C73C2715A3FA00901167 /* OnboardingFlow */,
F9971A4927680DC400A2DB75 /* Root */,
9EAFEB8B2808174900199FC9 /* Sandbox */,
F9C165B62740403600592F76 /* SendFlow */,
);
path = Features;
sourceTree = "<group>";
};
6654C73C2715A3FA00901167 /* OnboardingFlow */ = {
isa = PBXGroup;
children = (
6654C73D2715A41300901167 /* OnboardingFlowStore.swift */,
2E5C03802738C570008BFFD3 /* OnboardingFlowView.swift */,
6654C73F2715A45900901167 /* Views */,
0D3016B729BFB2FB002371B3 /* PlainOnboardingView.swift */,
);
path = OnboardingFlow;
sourceTree = "<group>";
};
6654C73F2715A45900901167 /* Views */ = {
isa = PBXGroup;
children = (
2E58E73A274679F000B2B84B /* OnboardingHeaderView.swift */,
2EA11F5C27467F7700709571 /* OnboardingContentView.swift */,
2EA11F5A27467EF800709571 /* OnboardingFooterView.swift */,
);
path = Views;
sourceTree = "<group>";
};
6654C7422715A48E00901167 /* OnboardingTests */ = {
isa = PBXGroup;
children = (
@ -794,14 +656,6 @@
path = OnboardingTests;
sourceTree = "<group>";
};
669FDAE5272C2371007B9422 /* ProgressIndicators */ = {
isa = PBXGroup;
children = (
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */,
);
path = ProgressIndicators;
sourceTree = "<group>";
};
9E01F8262833CD84000EFC57 /* ScanTests */ = {
isa = PBXGroup;
children = (
@ -835,16 +689,6 @@
path = AddressDetailsTests;
sourceTree = "<group>";
};
9E2DF99727CF704D00649636 /* ImportWallet */ = {
isa = PBXGroup;
children = (
9E2DF99827CF704D00649636 /* ImportWalletStore.swift */,
9E2DF99B27CF704D00649636 /* ImportWalletView.swift */,
9E486DE429B637AF003E6945 /* ImportBirthdayView.swift */,
);
path = ImportWallet;
sourceTree = "<group>";
};
9E2F1C8D280EDDEF004E65FE /* Drawer */ = {
isa = PBXGroup;
children = (
@ -909,24 +753,6 @@
path = SendTests;
sourceTree = "<group>";
};
9E5BF64B2823C91200BA3F17 /* TransactionAmount */ = {
isa = PBXGroup;
children = (
2EB7758627FC67FD00269373 /* TransactionAmountTextFieldStore.swift */,
2E8719CA27FB09990082C926 /* TransactionAmountTextField.swift */,
);
path = TransactionAmount;
sourceTree = "<group>";
};
9E5BF64C2823E84300BA3F17 /* TransactionAddress */ = {
isa = PBXGroup;
children = (
9E5BF64E2823E94900BA3F17 /* TransactionAddressTextFieldStore.swift */,
9E5BF64D2823E94900BA3F17 /* TransactionAddressTextField.swift */,
);
path = TransactionAddress;
sourceTree = "<group>";
};
9E612C7729913F2300D09B09 /* SensitiveDataTests */ = {
isa = PBXGroup;
children = (
@ -968,15 +794,6 @@
path = SettingsSnapshotTests;
sourceTree = "<group>";
};
9E7225F4288AC6F300DF7F17 /* MultiLineTextField */ = {
isa = PBXGroup;
children = (
9E7225F5288AC71A00DF7F17 /* MultiLineTextFieldStore.swift */,
9E7225F2288AB6DD00DF7F17 /* MultipleLineTextField.swift */,
);
path = MultiLineTextField;
sourceTree = "<group>";
};
9E74CCCE29DC060B003D6E32 /* ReviewRequestTests */ = {
isa = PBXGroup;
children = (
@ -1036,7 +853,6 @@
9E486DEF29B9EE84003E6945 /* KeyboardAdaptive.swift */,
9E6612322878338C00C75B70 /* LottieAnimation.swift */,
34BF09082927C98000222134 /* Memo+toString.swift */,
F93673D52742CB840099C6AF /* Previews.swift */,
0DACFA8027208D940039EEA5 /* UInt+SuperscriptText.swift */,
9E486DF829BA09C2003E6945 /* UIKit+Extensions.swift */,
9E486DF229B9EEC4003E6945 /* UIResponder+Current.swift */,
@ -1059,42 +875,12 @@
children = (
346D41E228DF0B0900963F36 /* CheckCircle */,
9E7CB6132869E8A700A02233 /* CircularProgress */,
0DF2DC5227235E1F00FA31E2 /* Extensions */,
0DB8AA80271DC7520035BC9D /* DesignGuide.swift */,
9E7FE0E9282E7CF800C374E8 /* ImportSeedEditor */,
9E2F1C8D280EDDEF004E65FE /* Drawer */,
2E35F99027B28E6800EB79CD /* TextFields */,
669FDAE5272C2371007B9422 /* ProgressIndicators */,
);
path = "UI Components";
sourceTree = "<group>";
};
9E7FE0E9282E7CF800C374E8 /* ImportSeedEditor */ = {
isa = PBXGroup;
children = (
9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */,
);
path = ImportSeedEditor;
sourceTree = "<group>";
};
9E7FE0EF282E7FA900C374E8 /* CurrencySelection */ = {
isa = PBXGroup;
children = (
2E6CF8DC27D78319004DCD7A /* CurrencySelectionStore.swift */,
2E8719CC27FB0D3B0082C926 /* CurrencySelectionView.swift */,
);
path = CurrencySelection;
sourceTree = "<group>";
};
9E7FE0F0282E80C100C374E8 /* TCATextField */ = {
isa = PBXGroup;
children = (
2EB1C5E727D77F6100BC43D7 /* TCATextFieldStore.swift */,
2EDA079F27EDE18C00D6F09B /* TCATextField.swift */,
);
path = TCATextField;
sourceTree = "<group>";
};
9E94C61E28AA7DD5008256E9 /* BalanceBreakdownTests */ = {
isa = PBXGroup;
children = (
@ -1186,15 +972,6 @@
path = RootTests;
sourceTree = "<group>";
};
9EAFEB8B2808174900199FC9 /* Sandbox */ = {
isa = PBXGroup;
children = (
9EAFEB8E2808183D00199FC9 /* SandboxStore.swift */,
9EAFEB8D2808183D00199FC9 /* SandboxView.swift */,
);
path = Sandbox;
sourceTree = "<group>";
};
9EF8135927ECC25E0075AF48 /* UtilTests */ = {
isa = PBXGroup;
children = (
@ -1230,27 +1007,6 @@
path = Root;
sourceTree = "<group>";
};
F9C165B62740403600592F76 /* SendFlow */ = {
isa = PBXGroup;
children = (
F9C165B72740403600592F76 /* SendFlowStore.swift */,
F9C165CA2741AB5D00592F76 /* SendFlowView.swift */,
F9C165B82740403600592F76 /* Views */,
);
path = SendFlow;
sourceTree = "<group>";
};
F9C165B82740403600592F76 /* Views */ = {
isa = PBXGroup;
children = (
F9C165BB2740403600592F76 /* CreateTransactionView.swift */,
9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */,
34DA414628E4385800F8CC61 /* TransactionSendingView.swift */,
F9C165BD2740403600592F76 /* TransactionSentView.swift */,
);
path = Views;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -1315,6 +1071,10 @@
9EE592742A2DF7D8007147CD /* Scan */,
9EE5927C2A2E0288007147CD /* ExportLogs */,
9EE5927E2A2E028D007147CD /* Settings */,
9EB35D432A2F5F2A00A2149B /* ImportWallet */,
9EB35D492A2F6B8B00A2149B /* OnboardingFlow */,
9EB35D542A30656400A2149B /* SendFlow */,
9EB35D5A2A306C4300A2149B /* Sandbox */,
);
productName = secant;
productReference = 0D26AF94299E8196005260EE /* secant-mainnet.app */;
@ -1381,6 +1141,10 @@
9EE592762A2DF7DD007147CD /* Scan */,
9EE592782A2E027F007147CD /* ExportLogs */,
9EE5927A2A2E0284007147CD /* Settings */,
9EB35D452A2F5F2F00A2149B /* ImportWallet */,
9EB35D472A2F6B8700A2149B /* OnboardingFlow */,
9EB35D562A30656900A2149B /* SendFlow */,
9EB35D582A306C3E00A2149B /* Sandbox */,
);
productName = secant;
productReference = 0D4E7A0526B364170058B01E /* secant-testnet.app */;
@ -1695,71 +1459,38 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0D26AE9B299E8196005260EE /* OnboardingFlowView.swift in Sources */,
0D26AE9D299E8196005260EE /* CrashReporterTestKey.swift in Sources */,
0D26AEA0299E8196005260EE /* SandboxStore.swift in Sources */,
0D26AEA5299E8196005260EE /* TransactionSendingView.swift in Sources */,
0D26AEAA299E8196005260EE /* CrashReporterLiveKey.swift in Sources */,
0D26AEAC299E8196005260EE /* TCATextField.swift in Sources */,
0D26AEAF299E8196005260EE /* TransactionAmountTextFieldStore.swift in Sources */,
0D26AEB1299E8196005260EE /* AppDelegate.swift in Sources */,
0D3016B929BFB2FB002371B3 /* PlainOnboardingView.swift in Sources */,
0D26AEBC299E8196005260EE /* TCATextFieldStore.swift in Sources */,
0D26AEBF299E8196005260EE /* TransactionFailedView.swift in Sources */,
0D26AEC4299E8196005260EE /* TCALogging.swift in Sources */,
9E486DFA29BA09C2003E6945 /* UIKit+Extensions.swift in Sources */,
9E33ECDA29D5E30700708DE4 /* OnChangeReducer.swift in Sources */,
0D26AEC6299E8196005260EE /* ImportWalletView.swift in Sources */,
0D26AEC7299E8196005260EE /* RootInitialization.swift in Sources */,
0D26AECC299E8196005260EE /* OnboardingFlowStore.swift in Sources */,
0D26AECF299E8196005260EE /* CurrencySelectionStore.swift in Sources */,
0D26AED3299E8196005260EE /* SyncStatusSnapshot.swift in Sources */,
0D26AEDA299E8196005260EE /* ImportSeedEditor.swift in Sources */,
9E486DE629B637AF003E6945 /* ImportBirthdayView.swift in Sources */,
0D26AEDC299E8196005260EE /* CheckCircle.swift in Sources */,
0D26AEE4299E8196005260EE /* CurrencySelectionView.swift in Sources */,
0D26AEE7299E8196005260EE /* TransactionAddressTextFieldStore.swift in Sources */,
0D26AEE9299E8196005260EE /* WithStateBinding.swift in Sources */,
0D26AEEB299E8196005260EE /* Previews.swift in Sources */,
0D26AEF0299E8196005260EE /* TCALoggerReducer.swift in Sources */,
0D26AEF2299E8196005260EE /* MultipleLineTextField.swift in Sources */,
0D26AEF3299E8196005260EE /* NotEnoughFreeSpaceView.swift in Sources */,
0D26AEF7299E8196005260EE /* Drawer.swift in Sources */,
0D26AEFA299E8196005260EE /* DesignGuide.swift in Sources */,
0D26AEFC299E8196005260EE /* RootStore.swift in Sources */,
0D26AEFD299E8196005260EE /* HomeView.swift in Sources */,
0D26AEFF299E8196005260EE /* SandboxView.swift in Sources */,
9E852D6229B098F400CF4AC1 /* RootDebug.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 */,
9E486DF129B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */,
0D26AF1B299E8196005260EE /* HomeStore.swift in Sources */,
0D26AF20299E8196005260EE /* UInt+SuperscriptText.swift in Sources */,
0D26AF23299E8196005260EE /* SendFlowStore.swift in Sources */,
0D26AF24299E8196005260EE /* SecantApp.swift in Sources */,
0D26AF3A299E8196005260EE /* OnboardingContentView.swift in Sources */,
0D26AF3B299E8196005260EE /* CircularProgress.swift in Sources */,
0D26AF3C299E8196005260EE /* OnboardingHeaderView.swift in Sources */,
0D26AF3D299E8196005260EE /* TransactionAddressTextField.swift in Sources */,
0D26AF3E299E8196005260EE /* SingleLineTextField.swift in Sources */,
0D26AF40299E8196005260EE /* RootDestination.swift in Sources */,
0D26AF41299E8196005260EE /* OnboardingProgressIndicator.swift in Sources */,
0D26AF44299E8196005260EE /* Memo+toString.swift in Sources */,
0D26AF46299E8196005260EE /* CheckCircleStore.swift in Sources */,
0D26AF47299E8196005260EE /* CreateTransactionView.swift in Sources */,
0D26AF4B299E8196005260EE /* TextFieldTitleAccessoryButtonStyle.swift in Sources */,
0D26AF4D299E8196005260EE /* ImportWalletStore.swift in Sources */,
0D26AF53299E8196005260EE /* TextFieldFooter.swift in Sources */,
0D26AF54299E8196005260EE /* CrashReporterInterface.swift in Sources */,
0D26AF5F299E8196005260EE /* SendFlowView.swift in Sources */,
0D26AF65299E8196005260EE /* InitializationState.swift in Sources */,
9E486DF429B9EEC4003E6945 /* UIResponder+Current.swift in Sources */,
0D26AF68299E8196005260EE /* TransactionAmountTextField.swift in Sources */,
0D26AF6A299E8196005260EE /* ClearBackgroundView.swift in Sources */,
0D26AF6C299E8196005260EE /* TransactionSentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1767,71 +1498,38 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2EB660E02747EAB900A06A07 /* OnboardingFlowView.swift in Sources */,
0D261040298C406F00CC9DE9 /* CrashReporterTestKey.swift in Sources */,
9EAFEB902808183D00199FC9 /* SandboxStore.swift in Sources */,
34DA414728E4385800F8CC61 /* TransactionSendingView.swift in Sources */,
0D26103E298C3FA600CC9DE9 /* CrashReporterLiveKey.swift in Sources */,
2EDA07A027EDE18C00D6F09B /* TCATextField.swift in Sources */,
2EB7758727FC67FD00269373 /* TransactionAmountTextFieldStore.swift in Sources */,
9EF8136027F043CC0075AF48 /* AppDelegate.swift in Sources */,
0D3016B829BFB2FB002371B3 /* PlainOnboardingView.swift in Sources */,
2EB1C5E827D77F6100BC43D7 /* TCATextFieldStore.swift in Sources */,
9E5BF641281FD7B600BA3F17 /* TransactionFailedView.swift in Sources */,
9E0F5741297E7F1D005304FA /* TCALogging.swift in Sources */,
9E9CEA3E29D47BE000599DF5 /* OnChangeReducer.swift in Sources */,
9E486DF929BA09C2003E6945 /* UIKit+Extensions.swift in Sources */,
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */,
9E9ADA7D2938F4C00071767B /* RootInitialization.swift in Sources */,
6654C73E2715A41300901167 /* OnboardingFlowStore.swift in Sources */,
2E6CF8DD27D78319004DCD7A /* CurrencySelectionStore.swift in Sources */,
9E66122C2877188700C75B70 /* SyncStatusSnapshot.swift in Sources */,
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */,
9E486DE529B637AF003E6945 /* ImportBirthdayView.swift in Sources */,
346D41E428DF0B8600963F36 /* CheckCircle.swift in Sources */,
2E8719CD27FB0D3B0082C926 /* CurrencySelectionView.swift in Sources */,
9E5BF6502823E94900BA3F17 /* TransactionAddressTextFieldStore.swift in Sources */,
F9EEB8162742C2210032EEB8 /* WithStateBinding.swift in Sources */,
F93673D62742CB840099C6AF /* Previews.swift in Sources */,
9E0F5743297EB96C005304FA /* TCALoggerReducer.swift in Sources */,
9E7225F3288AB6DD00DF7F17 /* MultipleLineTextField.swift in Sources */,
3448CB3228E47666006ADEDB /* NotEnoughFreeSpaceView.swift in Sources */,
9E2F1C8F280EDE09004E65FE /* Drawer.swift in Sources */,
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */,
F9971A4D27680DC400A2DB75 /* RootStore.swift in Sources */,
9EAFEB9228081E9400199FC9 /* HomeView.swift in Sources */,
9EAFEB8F2808183D00199FC9 /* SandboxView.swift in Sources */,
9E852D6129B098F400CF4AC1 /* RootDebug.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 */,
9E486DF029B9EE84003E6945 /* KeyboardAdaptive.swift in Sources */,
9EAFEB9128081E9400199FC9 /* HomeStore.swift in Sources */,
0DACFA8127208D940039EEA5 /* UInt+SuperscriptText.swift in Sources */,
F9C165BF2740403600592F76 /* SendFlowStore.swift in Sources */,
0D4E7A0926B364170058B01E /* SecantApp.swift in Sources */,
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */,
9E7CB6152869E8C300A02233 /* CircularProgress.swift in Sources */,
2E58E73B274679F000B2B84B /* OnboardingHeaderView.swift in Sources */,
9E5BF64F2823E94900BA3F17 /* TransactionAddressTextField.swift in Sources */,
2E35F99227B28E7600EB79CD /* SingleLineTextField.swift in Sources */,
9E9ADA7F2938F5EC0071767B /* RootDestination.swift in Sources */,
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */,
34BF09092927C98000222134 /* Memo+toString.swift in Sources */,
346715A528E2027D0035F7C4 /* CheckCircleStore.swift in Sources */,
F9C165C22740403600592F76 /* CreateTransactionView.swift in Sources */,
2E35F99A27B3E99C00EB79CD /* TextFieldTitleAccessoryButtonStyle.swift in Sources */,
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */,
2EDA07A227EDE1AE00D6F09B /* TextFieldFooter.swift in Sources */,
0D26103C298C3E4800CC9DE9 /* CrashReporterInterface.swift in Sources */,
F9C165CB2741AB5D00592F76 /* SendFlowView.swift in Sources */,
9EF8139C27F47AED0075AF48 /* InitializationState.swift in Sources */,
9E486DF329B9EEC4003E6945 /* UIResponder+Current.swift in Sources */,
2E8719CB27FB09990082C926 /* TransactionAmountTextField.swift in Sources */,
9E6713FA289BE0E100A6796F /* ClearBackgroundView.swift in Sources */,
F9C165C42740403600592F76 /* TransactionSentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2724,6 +2422,38 @@
package = 9EAB466B285A0468002904A0 /* XCRemoteSwiftPackageReference "swift-parsing" */;
productName = Parsing;
};
9EB35D432A2F5F2A00A2149B /* ImportWallet */ = {
isa = XCSwiftPackageProductDependency;
productName = ImportWallet;
};
9EB35D452A2F5F2F00A2149B /* ImportWallet */ = {
isa = XCSwiftPackageProductDependency;
productName = ImportWallet;
};
9EB35D472A2F6B8700A2149B /* OnboardingFlow */ = {
isa = XCSwiftPackageProductDependency;
productName = OnboardingFlow;
};
9EB35D492A2F6B8B00A2149B /* OnboardingFlow */ = {
isa = XCSwiftPackageProductDependency;
productName = OnboardingFlow;
};
9EB35D542A30656400A2149B /* SendFlow */ = {
isa = XCSwiftPackageProductDependency;
productName = SendFlow;
};
9EB35D562A30656900A2149B /* SendFlow */ = {
isa = XCSwiftPackageProductDependency;
productName = SendFlow;
};
9EB35D582A306C3E00A2149B /* Sandbox */ = {
isa = XCSwiftPackageProductDependency;
productName = Sandbox;
};
9EB35D5A2A306C4300A2149B /* Sandbox */ = {
isa = XCSwiftPackageProductDependency;
productName = Sandbox;
};
9EE5926C2A2DDF94007147CD /* BalanceBreakdown */ = {
isa = XCSwiftPackageProductDependency;
productName = BalanceBreakdown;

View File

@ -14,6 +14,7 @@ import BalanceBreakdown
import WalletEventsFlow
import Scan
import Settings
import SendFlow
typealias HomeStore = Store<HomeReducer.State, HomeReducer.Action>
typealias HomeViewStore = ViewStore<HomeReducer.State, HomeReducer.Action>
@ -107,7 +108,7 @@ struct HomeReducer: ReducerProtocol {
}
Scope(state: \.sendState, action: /Action.send) {
SendFlowReducer()
SendFlowReducer(networkType: TargetConstants.zcashNetwork.networkType)
}
Scope(state: \.settingsState, action: /Action.settings) {

View File

@ -6,6 +6,7 @@ import Profile
import BalanceBreakdown
import WalletEventsFlow
import Settings
import SendFlow
struct HomeView: View {
let store: Store<HomeReducer.State, HomeReducer.Action>
@ -68,7 +69,7 @@ struct HomeView: View {
)
.navigationLinkEmpty(
isActive: viewStore.bindingForDestination(.send),
destination: { SendFlowView(store: store.sendStore()) }
destination: { SendFlowView(store: store.sendStore(), tokenName: TargetConstants.tokenName) }
)
.navigationLinkEmpty(
isActive: viewStore.bindingForDestination(.profile),

View File

@ -13,6 +13,8 @@ import Welcome
import Generated
import Foundation
import ExportLogs
import OnboardingFlow
import Sandbox
typealias RootStore = Store<RootReducer.State, RootReducer.Action>
typealias RootViewStore = ViewStore<RootReducer.State, RootReducer.Action>
@ -82,7 +84,7 @@ struct RootReducer: ReducerProtocol {
}
Scope(state: \.onboardingState, action: /Action.onboarding) {
OnboardingFlowReducer()
OnboardingFlowReducer(saplingActivationHeight: TargetConstants.zcashNetwork.constants.saplingActivationHeight)
}
Scope(state: \.phraseValidationState, action: /Action.phraseValidation) {

View File

@ -7,6 +7,8 @@ import Models
import RecoveryPhraseDisplay
import Welcome
import ExportLogs
import OnboardingFlow
import Sandbox
struct RootView: View {
let store: RootStore
@ -52,7 +54,9 @@ private extension RootView {
store: store.scope(
state: \.sandboxState,
action: RootReducer.Action.sandbox
)
),
tokenName: TargetConstants.tokenName,
networkType: TargetConstants.zcashNetwork.networkType
)
}
.navigationViewStyle(.stack)

View File

@ -1,66 +0,0 @@
//
// TransactionAddressTextFieldStore.swift
// secant-testnet
//
// Created by Lukáš Korba on 05/05/22.
//
import ComposableArchitecture
import SwiftUI
import ZcashLightClientKit
typealias TransactionAddressTextFieldStore = Store<TransactionAddressTextFieldReducer.State, TransactionAddressTextFieldReducer.Action>
struct TransactionAddressTextFieldReducer: ReducerProtocol {
struct State: Equatable {
var isValidAddress = false
var isValidTransparentAddress = false
var textFieldState: TCATextFieldReducer.State
}
enum Action: Equatable {
case clearAddress
case scanQR
case textField(TCATextFieldReducer.Action)
}
@Dependency(\.derivationTool) var derivationTool
@Dependency(\.zcashSDKEnvironment) var zcashSDKEnvironment
var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
switch action {
case .clearAddress:
state.textFieldState.text = "".redacted
return .none
case .scanQR:
return .none
case .textField(.set(let address)):
state.isValidAddress = derivationTool.isZcashAddress(address.data, TargetConstants.zcashNetwork.networkType)
state.isValidTransparentAddress = derivationTool.isTransparentAddress(address.data, TargetConstants.zcashNetwork.networkType)
return .none
}
}
Scope(state: \.textFieldState, action: /Action.textField) {
TCATextFieldReducer()
}
}
}
// MARK: - Placeholders
extension TransactionAddressTextFieldReducer.State {
static let placeholder = TransactionAddressTextFieldReducer.State(
textFieldState: .placeholder
)
}
extension TransactionAddressTextFieldStore {
static let placeholder = TransactionAddressTextFieldStore(
initialState: .placeholder,
reducer: TransactionAddressTextFieldReducer()
)
}

View File

@ -1,5 +1,6 @@
import SwiftUI
import ComposableArchitecture
import Utils
struct WithStateBinding<T: Equatable, Content: View>: View {
@State var localState: T

View File

@ -8,6 +8,7 @@
import XCTest
import ComposableArchitecture
import Utils
import ImportWallet
@testable import secant_testnet
// swiftlint:disable type_body_length
@ -15,7 +16,7 @@ class ImportWalletTests: XCTestCase {
func testOnAppear() throws {
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.send(.onAppear) { state in
@ -26,7 +27,7 @@ class ImportWalletTests: XCTestCase {
func testWordsCount() throws {
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp
@ -43,7 +44,7 @@ class ImportWalletTests: XCTestCase {
func testMaxWordsInvalidMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp
@ -61,7 +62,7 @@ class ImportWalletTests: XCTestCase {
func testValidMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp
@ -84,7 +85,7 @@ class ImportWalletTests: XCTestCase {
func testInvalidBirthdayHeight_lessThanSaplingActivation() throws {
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 280_000)
)
let birthday = "200000".redacted
@ -96,7 +97,7 @@ class ImportWalletTests: XCTestCase {
func testInvalidBirthdayHeight_invalidInput() throws {
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
let birthday = "abc".redacted
@ -108,7 +109,7 @@ class ImportWalletTests: XCTestCase {
func testInvalidBirthdayHeight_validInput() throws {
let store = TestStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
let birthday = "1700000".redacted
@ -121,7 +122,7 @@ class ImportWalletTests: XCTestCase {
func testFormValidity_validBirthday_invalidMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp
@ -149,7 +150,7 @@ class ImportWalletTests: XCTestCase {
func testFormValidity_invalidBirthday_invalidMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 280_000)
)
store.dependencies.mnemonic = .noOp
@ -176,7 +177,7 @@ class ImportWalletTests: XCTestCase {
func testFormValidity_invalidBirthday_validMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 280_000)
)
store.dependencies.mnemonic = .noOp
@ -208,7 +209,7 @@ class ImportWalletTests: XCTestCase {
func testFormValidity_validBirthday_validMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp
@ -241,7 +242,7 @@ class ImportWalletTests: XCTestCase {
func testFormValidity_noBirthday_validMnemonic() throws {
let store = TestStore(
initialState: ImportWalletReducer.State(maxWordsCount: 24),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp
@ -281,7 +282,7 @@ class ImportWalletTests: XCTestCase {
maxWordsCount: 24,
wordsCount: 24
),
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
store.dependencies.mnemonic = .noOp

View File

@ -6,8 +6,9 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import UIComponents
@testable import secant_testnet
class MultiLineTextFieldTests: XCTestCase {
func testIsCharLimited() throws {

View File

@ -9,6 +9,7 @@ import XCTest
import ComposableArchitecture
import WalletConfigProvider
import Models
import OnboardingFlow
@testable import secant_testnet
class OnboardingFlowFeatureFlagTests: XCTestCase {
@ -30,7 +31,7 @@ class OnboardingFlowFeatureFlagTests: XCTestCase {
let store = TestStore(
initialState: initialState,
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.onAppear)
@ -53,7 +54,7 @@ class OnboardingFlowFeatureFlagTests: XCTestCase {
let store = TestStore(
initialState: initialState,
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.onAppear)

View File

@ -7,6 +7,7 @@
import XCTest
import ComposableArchitecture
import OnboardingFlow
@testable import secant_testnet
class OnboardingStoreTests: XCTestCase {
@ -16,7 +17,7 @@ class OnboardingStoreTests: XCTestCase {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.next) { state in
@ -57,7 +58,7 @@ class OnboardingStoreTests: XCTestCase {
importWalletState: .placeholder,
index: 3
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.next)
@ -71,7 +72,7 @@ class OnboardingStoreTests: XCTestCase {
importWalletState: .placeholder,
index: 2
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.back) { state in
@ -101,7 +102,7 @@ class OnboardingStoreTests: XCTestCase {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.back)
@ -117,7 +118,7 @@ class OnboardingStoreTests: XCTestCase {
importWalletState: .placeholder,
index: initialIndex
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
store.send(.skip) { state in

View File

@ -6,8 +6,9 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import UIComponents
@testable import secant_testnet
class CurrencySelectionTests: XCTestCase {
func testCurrencySwapUsdToZec() throws {

View File

@ -12,6 +12,8 @@ import AudioServices
import NumberFormatter
import Models
import WalletStorage
import SendFlow
import UIComponents
@testable import secant_testnet
// swiftlint:disable type_body_length
@ -49,7 +51,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: initialState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .liveValue
@ -104,7 +106,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: state,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .liveValue
@ -158,7 +160,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: initialState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .liveValue
@ -200,7 +202,7 @@ class SendTests: XCTestCase {
func testAddressValidation_Invalid() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -223,7 +225,7 @@ class SendTests: XCTestCase {
func testAddressValidation_Valid() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -246,7 +248,7 @@ class SendTests: XCTestCase {
func testInvalidAmountFormatEmptyInput() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.numberFormatter = .noOp
@ -261,7 +263,7 @@ class SendTests: XCTestCase {
func testInvalidAddressFormatEmptyInput() throws {
let store = TestStore(
initialState: .placeholder,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -300,7 +302,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.numberFormatter = .noOp
@ -341,7 +343,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.numberFormatter = .noOp
@ -402,7 +404,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -442,7 +444,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -482,7 +484,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -521,7 +523,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.derivationTool = .noOp
@ -573,7 +575,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
let value = "test".redacted
@ -606,7 +608,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.mainQueue = .immediate
@ -632,7 +634,7 @@ class SendTests: XCTestCase {
let store = TestStore(
initialState: sendState,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
)
store.dependencies.audioServices = AudioServicesClient(systemSoundVibrate: { })

View File

@ -6,8 +6,9 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import UIComponents
@testable import secant_testnet
class TransactionAddressTextFieldTests: XCTestCase {
func testClearValue() throws {
@ -20,7 +21,7 @@ class TransactionAddressTextFieldTests: XCTestCase {
text: "t1gXqfSSQt6WfpwyuCU3Wi7sSVZ66DYQ3Po".redacted
)
),
reducer: TransactionAddressTextFieldReducer()
reducer: TransactionAddressTextFieldReducer(networkType: .testnet)
)
store.send(.clearAddress) { state in

View File

@ -6,8 +6,9 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import UIComponents
@testable import secant_testnet
class TransactionAmountTextFieldTests: XCTestCase {
let usNumberFormatter = NumberFormatter()

View File

@ -6,14 +6,15 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import ImportWallet
@testable import secant_testnet
class ImportWalletSnapshotTests: XCTestCase {
func testImportWalletSnapshot() throws {
let store = ImportWalletStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
addAttachments(ImportWalletView(store: store))
@ -22,7 +23,7 @@ class ImportWalletSnapshotTests: XCTestCase {
func testImportBirthdaySnapshot() throws {
let store = ImportWalletStore(
initialState: .placeholder,
reducer: ImportWalletReducer()
reducer: ImportWalletReducer(saplingActivationHeight: 0)
)
addAttachments(ImportBirthdayView(store: store))

View File

@ -6,8 +6,9 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import OnboardingFlow
@testable import secant_testnet
class OnboardingSnapshotTests: XCTestCase {
func testOnboardingFlowSnapshot() throws {
@ -16,7 +17,7 @@ class OnboardingSnapshotTests: XCTestCase {
walletConfig: .default,
importWalletState: .placeholder
),
reducer: OnboardingFlowReducer()
reducer: OnboardingFlowReducer(saplingActivationHeight: 280_000)
)
let viewStore = ViewStore(store)

View File

@ -6,10 +6,12 @@
//
import XCTest
@testable import secant_testnet
import ComposableArchitecture
import SwiftUI
import ZcashLightClientKit
import SendFlow
import UIComponents
@testable import secant_testnet
class TransactionSendingTests: XCTestCase {
func testTransactionSendingSnapshot() throws {
@ -31,7 +33,7 @@ class TransactionSendingTests: XCTestCase {
let store = Store(
initialState: state,
reducer: SendFlowReducer()
reducer: SendFlowReducer(networkType: .testnet)
.dependency(\.derivationTool, .live())
.dependency(\.mainQueue, DispatchQueue.main.eraseToAnyScheduler())
.dependency(\.numberFormatter, .live())
@ -40,6 +42,6 @@ class TransactionSendingTests: XCTestCase {
)
ViewStore(store).send(.onAppear)
addAttachments(TransactionSendingView(viewStore: ViewStore(store)))
addAttachments(TransactionSendingView(viewStore: ViewStore(store), tokenName: "ZEC"))
}
}