diff --git a/Aux/Config/Common.xcconfig b/Aux/Config/Common.xcconfig index 6a48d0ac1b..fa81b01bb3 100644 --- a/Aux/Config/Common.xcconfig +++ b/Aux/Config/Common.xcconfig @@ -1,7 +1,7 @@ // MARK: - Custom flags /// Application version shared across all targets and flavours -APP_VERSION = 1.11.0 +APP_VERSION = 1.11.1 /// App Icon base name APP_ICON = AppIcon diff --git a/RadixWallet/Clients/AccountPortfoliosClient/AccountPortfoliosClient+State.swift b/RadixWallet/Clients/AccountPortfoliosClient/AccountPortfoliosClient+State.swift index d35d495a95..30f5883b02 100644 --- a/RadixWallet/Clients/AccountPortfoliosClient/AccountPortfoliosClient+State.swift +++ b/RadixWallet/Clients/AccountPortfoliosClient/AccountPortfoliosClient+State.swift @@ -51,6 +51,11 @@ extension AccountPortfoliosClient { return modified } + + /// Returns if the original account (which doesn't remove the hidden resources) contains any asset + var containsAnyAsset: Bool { + originalAccount.containsAnyAsset + } } /// Internal state that holds all loaded portfolios. diff --git a/RadixWallet/Features/AccountPreferencesFeature/Children/DeleteAccount/DeleteAccountConfirmation+Reducer.swift b/RadixWallet/Features/AccountPreferencesFeature/Children/DeleteAccount/DeleteAccountConfirmation+Reducer.swift index fed075409c..0c8746376a 100644 --- a/RadixWallet/Features/AccountPreferencesFeature/Children/DeleteAccount/DeleteAccountConfirmation+Reducer.swift +++ b/RadixWallet/Features/AccountPreferencesFeature/Children/DeleteAccount/DeleteAccountConfirmation+Reducer.swift @@ -16,7 +16,7 @@ struct DeleteAccountConfirmation: Sendable, FeatureReducer { @CasePathable enum InternalAction: Sendable, Equatable { - case fetchAccountPortfolioResult(TaskResult) + case fetchAccountPortfolioResult(TaskResult) case fetchReceivingAccounts case fetchReceivingAccountsResult(TaskResult<[State.ReceivingAccountCandidate]>) } @@ -44,7 +44,7 @@ struct DeleteAccountConfirmation: Sendable, FeatureReducer { state.footerButtonState = .loading(.local) return .run { [address = state.account.address] send in let result = await TaskResult { - try await accountPortfoliosClient.fetchAccountPortfolio(address, true).account + try await accountPortfoliosClient.fetchAccountPortfolio(address, true) } await send(.internal(.fetchAccountPortfolioResult(result))) } @@ -53,9 +53,9 @@ struct DeleteAccountConfirmation: Sendable, FeatureReducer { func reduce(into state: inout State, internalAction: InternalAction) -> Effect { switch internalAction { - case let .fetchAccountPortfolioResult(.success(account)): + case let .fetchAccountPortfolioResult(.success(portfolio)): state.footerButtonState = .enabled - return account.containsAnyAsset ? .send(.internal(.fetchReceivingAccounts)) : .send(.delegate(.deleteAccount)) + return portfolio.containsAnyAsset ? .send(.internal(.fetchReceivingAccounts)) : .send(.delegate(.deleteAccount)) case .fetchReceivingAccounts: return .run { send in diff --git a/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Models.swift b/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Models.swift index 4af2d69827..a0ba0d028f 100644 --- a/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Models.swift +++ b/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Models.swift @@ -5,15 +5,18 @@ import SwiftUI struct CreateAccountConfig: Sendable, Hashable { let specificNetworkID: NetworkID? let isFirstAccount: Bool + let isNewProfile: Bool let navigationButtonCTA: CreateAccountNavigationButtonCTA fileprivate init( isFirstAccount: Bool, + isNewProfile: Bool = false, navigationButtonCTA: CreateAccountNavigationButtonCTA, specificNetworkID: NetworkID? = nil ) { self.specificNetworkID = specificNetworkID self.isFirstAccount = isFirstAccount + self.isNewProfile = isNewProfile self.navigationButtonCTA = navigationButtonCTA } } @@ -31,6 +34,7 @@ extension CreateAccountConfig { case .firstAccountForNewProfile: self.init( isFirstAccount: true, + isNewProfile: true, navigationButtonCTA: .goHome ) case let .firstAccountOnNewNetwork(specificNetworkID): diff --git a/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Reducer.swift b/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Reducer.swift index 19fbb10274..4ebb7629be 100644 --- a/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Reducer.swift +++ b/RadixWallet/Features/CreateAccount/Coordinator/CreateAccountCoordinator+Reducer.swift @@ -14,6 +14,8 @@ struct CreateAccountCoordinator: Sendable, FeatureReducer { let config: CreateAccountConfig var name: NonEmptyString? + fileprivate var createdProfile = false + init( root: Path.State? = nil, config: CreateAccountConfig @@ -92,6 +94,7 @@ struct CreateAccountCoordinator: Sendable, FeatureReducer { enum InternalAction: Sendable, Equatable { case createAccountResult(TaskResult) case handleAccountCreated(TaskResult) + case handleProfileCreated(factorSourceOption: DerivePublicKeys.State.FactorSourceOption) } enum DelegateAction: Sendable, Equatable { @@ -103,6 +106,7 @@ struct CreateAccountCoordinator: Sendable, FeatureReducer { @Dependency(\.factorSourcesClient) var factorSourcesClient @Dependency(\.accountsClient) var accountsClient @Dependency(\.onLedgerEntitiesClient) var onLedgerEntitiesClient + @Dependency(\.onboardingClient) var onboardingClient @Dependency(\.errorQueue) var errorQueue @Dependency(\.isPresented) var isPresented @Dependency(\.dismiss) var dismiss @@ -146,11 +150,11 @@ extension CreateAccountCoordinator { state.path.append(.selectLedger(.init(context: .createHardwareAccount))) return .none } else { - return derivePublicKey(state: &state, factorSourceOption: .device) + return createProfileIfNecessaryThenDerivePublicKey(state: &state, factorSourceOption: .device) } case let .path(.element(_, action: .selectLedger(.delegate(.choseLedger(ledger))))): - return derivePublicKey( + return createProfileIfNecessaryThenDerivePublicKey( state: &state, factorSourceOption: .specific( ledger.asGeneral @@ -194,6 +198,10 @@ extension CreateAccountCoordinator { config: state.config ))) return .send(.delegate(.accountCreated)) + + case let .handleProfileCreated(factorSourceOption): + state.createdProfile = true + return derivePublicKey(state: &state, factorSourceOption: factorSourceOption) } } @@ -253,6 +261,21 @@ extension CreateAccountCoordinator { } } + private func createProfileIfNecessaryThenDerivePublicKey(state: inout State, factorSourceOption: DerivePublicKeys.State.FactorSourceOption) -> Effect { + if state.config.isNewProfile, !state.createdProfile { + // We need to create the Profile before deriving the public key + .run { send in + try await onboardingClient.createNewProfile() + await send(.internal(.handleProfileCreated(factorSourceOption: factorSourceOption))) + } catch: { error, _ in + errorQueue.schedule(error) + } + } else { + // We can derive the public key since the Profile has been created already + derivePublicKey(state: &state, factorSourceOption: factorSourceOption) + } + } + private func derivePublicKey(state: inout State, factorSourceOption: DerivePublicKeys.State.FactorSourceOption) -> Effect { state.destination = .derivePublicKey( .init( diff --git a/RadixWallet/Features/OnboardingFeature/Coordinator/OnboardingCoordinator+Reducer.swift b/RadixWallet/Features/OnboardingFeature/Coordinator/OnboardingCoordinator+Reducer.swift index 17f2c9fd9c..fe2078d673 100644 --- a/RadixWallet/Features/OnboardingFeature/Coordinator/OnboardingCoordinator+Reducer.swift +++ b/RadixWallet/Features/OnboardingFeature/Coordinator/OnboardingCoordinator+Reducer.swift @@ -14,10 +14,6 @@ struct OnboardingCoordinator: Sendable, FeatureReducer { } } - public enum InternalAction: Sendable, Equatable { - case newProfileCreated - } - @CasePathable enum ChildAction: Sendable, Equatable { case startup(OnboardingStartup.Action) @@ -45,7 +41,6 @@ struct OnboardingCoordinator: Sendable, FeatureReducer { } } - @Dependency(\.onboardingClient) var onboardingClient @Dependency(\.radixConnectClient) var radixConnectClient @Dependency(\.appEventsClient) var appEventsClient @Dependency(\.errorQueue) var errorQueue @@ -65,27 +60,15 @@ struct OnboardingCoordinator: Sendable, FeatureReducer { private let destinationPath: WritableKeyPath> = \.$destination - func reduce(into state: inout State, internalAction: InternalAction) -> Effect { - switch internalAction { - case .newProfileCreated: + func reduce(into state: inout State, childAction: ChildAction) -> Effect { + switch childAction { + case .startup(.delegate(.setupNewUser)): state.destination = .createAccount( .init( config: .init(purpose: .firstAccountForNewProfile) ) ) return .none - } - } - - func reduce(into state: inout State, childAction: ChildAction) -> Effect { - switch childAction { - case .startup(.delegate(.setupNewUser)): - return .run { send in - try await onboardingClient.createNewProfile() - await send(.internal(.newProfileCreated)) - } catch: { error, _ in - errorQueue.schedule(error) - } case .startup(.delegate(.profileCreatedFromImportedBDFS)): appEventsClient.handleEvent(.walletRestored)