diff --git a/Features/FiatConnect/Package.swift b/Features/FiatConnect/Package.swift index 5723d48d8..c2a71c0b1 100644 --- a/Features/FiatConnect/Package.swift +++ b/Features/FiatConnect/Package.swift @@ -38,6 +38,7 @@ let package = Package( "Store", "PrimitivesComponents", .product(name: "FiatService", package: "FeatureServices"), + .product(name: "BalanceService", package: "FeatureServices"), ], path: "Sources" ), @@ -47,6 +48,7 @@ let package = Package( "FiatConnect", .product(name: "PrimitivesTestKit", package: "Primitives"), .product(name: "FiatServiceTestKit", package: "FeatureServices"), + .product(name: "BalanceServiceTestKit", package: "FeatureServices"), ], path: "Tests" ), diff --git a/Features/FiatConnect/Sources/ViewModels/FiatSceneViewModel.swift b/Features/FiatConnect/Sources/ViewModels/FiatSceneViewModel.swift index e36a4939e..5d54822fd 100644 --- a/Features/FiatConnect/Sources/ViewModels/FiatSceneViewModel.swift +++ b/Features/FiatConnect/Sources/ViewModels/FiatSceneViewModel.swift @@ -12,6 +12,7 @@ import Formatters import Validators import BigInt import FiatService +import BalanceService @MainActor @Observable @@ -22,8 +23,9 @@ public final class FiatSceneViewModel { static let suggestedAmounts: [Int] = [100, 250] } - let walletId: WalletId let fiatService: FiatService + private let wallet: Wallet + private let assetsEnabler: any AssetsEnabler private let assetAddress: AssetAddress private let currencyFormatter: CurrencyFormatter private let valueFormatter = ValueFormatter(locale: .US, style: .medium) @@ -43,28 +45,30 @@ public final class FiatSceneViewModel { fiatService: FiatService, currencyFormatter: CurrencyFormatter = CurrencyFormatter(currencyCode: Currency.usd.rawValue), assetAddress: AssetAddress, - walletId: WalletId, + wallet: Wallet, + assetsEnabler: any AssetsEnabler, type: FiatQuoteType = .buy, amount: Int? = nil ) { self.fiatService = fiatService self.currencyFormatter = currencyFormatter self.assetAddress = assetAddress - self.walletId = walletId + self.wallet = wallet + self.assetsEnabler = assetsEnabler self.type = type - self.assetQuery = ObservableQuery(AssetRequest(walletId: walletId, assetId: assetAddress.asset.id), initialValue: .with(asset: assetAddress.asset)) + self.assetQuery = ObservableQuery(AssetRequest(walletId: wallet.walletId, assetId: assetAddress.asset.id), initialValue: .with(asset: assetAddress.asset)) let buyOperation = BuyOperation( service: fiatService, asset: assetAddress.asset, currencyFormatter: currencyFormatter, - walletId: walletId + walletId: wallet.walletId ) let sellOperation = SellOperation( service: fiatService, asset: assetAddress.asset, currencyFormatter: currencyFormatter, - walletId: walletId + walletId: wallet.walletId ) self.buyViewModel = FiatOperationViewModel( @@ -185,12 +189,13 @@ extension FiatSceneViewModel { urlState = .loading do { - guard let url = try await fiatService.getQuoteUrl(walletId: walletId.id, quoteId: selectedQuote.id).redirectUrl.asURL else { + guard let url = try await fiatService.getQuoteUrl(walletId: wallet.walletId.id, quoteId: selectedQuote.id).redirectUrl.asURL else { urlState = .noData return } urlState = .data(()) + Task { await enableAsset() } await UIApplication.shared.open(url, options: [:]) } catch { urlState = .error(error) @@ -239,6 +244,16 @@ extension FiatSceneViewModel { // MARK: - Private extension FiatSceneViewModel { + private func enableAsset() async { + do { + try await assetsEnabler.enableAssets(wallet: wallet, assetIds: [asset.id], enabled: true) + } catch { + debugLog("FiatSceneViewModel enableAsset error: \(error)") + } + } + + var walletId: WalletId { wallet.walletId } + private var balanceModel: BalanceViewModel { BalanceViewModel(asset: asset, balance: assetData.balance, formatter: valueFormatter) } diff --git a/Features/FiatConnect/Tests/FiatSceneViewModelTests.swift b/Features/FiatConnect/Tests/FiatSceneViewModelTests.swift index 32f7ddcf7..4f39fe168 100644 --- a/Features/FiatConnect/Tests/FiatSceneViewModelTests.swift +++ b/Features/FiatConnect/Tests/FiatSceneViewModelTests.swift @@ -8,6 +8,7 @@ import Formatters import FiatService import FiatServiceTestKit import BigInt +import BalanceServiceTestKit @testable import FiatConnect @@ -17,13 +18,14 @@ final class FiatSceneViewModelTests { fiatService: FiatService = .mock(), currencyFormatter: CurrencyFormatter = .init(locale: Locale.US, currencyCode: Currency.usd.rawValue), assetAddress: AssetAddress = .mock(), - walletId: WalletId = .mock() + wallet: Wallet = .mock() ) -> FiatSceneViewModel { FiatSceneViewModel( fiatService: fiatService, currencyFormatter: currencyFormatter, assetAddress: assetAddress, - walletId: walletId + wallet: wallet, + assetsEnabler: .mock() ) } diff --git a/Features/Transfer/Package.swift b/Features/Transfer/Package.swift index 30d1f4d46..4c309e04a 100644 --- a/Features/Transfer/Package.swift +++ b/Features/Transfer/Package.swift @@ -34,7 +34,6 @@ let package = Package( .package(name: "Stake", path: "../Stake"), .package(name: "WalletConnector", path: "../WalletConnector"), .package(name: "InfoSheet", path: "../InfoSheet"), - .package(name: "FiatConnect", path: "../FiatConnect"), .package(name: "Swap", path: "../Swap"), .package(name: "Perpetuals", path: "../Perpetuals"), .package(name: "EventPresenterService", path: "../EventPresenterService"), @@ -63,7 +62,6 @@ let package = Package( "Stake", "WalletConnector", "InfoSheet", - "FiatConnect", "Swap", "Perpetuals", "EventPresenterService", diff --git a/Features/Transfer/Sources/Scenes/AmountScene.swift b/Features/Transfer/Sources/Scenes/AmountScene.swift index c69d8fb00..6f7db247f 100644 --- a/Features/Transfer/Sources/Scenes/AmountScene.swift +++ b/Features/Transfer/Sources/Scenes/AmountScene.swift @@ -8,16 +8,16 @@ import SwiftUI import struct Stake.ValidatorViewModel import struct Stake.ValidatorView -struct AmountScene: View { +public struct AmountScene: View { @FocusState private var focusedField: Bool private var model: AmountSceneViewModel - init(model: AmountSceneViewModel) { + public init(model: AmountSceneViewModel) { self.model = model } - var body: some View { + public var body: some View { @Bindable var model = model List { CurrencyInputValidationView( diff --git a/Features/Transfer/Sources/Scenes/ConfirmTransferScene.swift b/Features/Transfer/Sources/Scenes/ConfirmTransferScene.swift index 9afe97aa5..ffa57a98d 100644 --- a/Features/Transfer/Sources/Scenes/ConfirmTransferScene.swift +++ b/Features/Transfer/Sources/Scenes/ConfirmTransferScene.swift @@ -4,18 +4,15 @@ import SwiftUI import Components import Style import Localization -import InfoSheet import PrimitivesComponents -import FiatConnect import Swap -import Preferences import Primitives public struct ConfirmTransferScene: View { - @State private var model: ConfirmTransferSceneViewModel + @Bindable var model: ConfirmTransferSceneViewModel public init(model: ConfirmTransferSceneViewModel) { - _model = State(initialValue: model) + self.model = model } public var body: some View { @@ -36,56 +33,8 @@ public struct ConfirmTransferScene: View { ) .taskOnce { model.fetch() } .navigationTitle(model.title) - // TODO: - move to navigation view .navigationBarTitleDisplayMode(.inline) .activityIndicator(isLoading: model.confirmingState.isLoading, message: model.progressMessage) - .sheet(item: $model.isPresentingSheet) { - switch $0 { - case .info(let type): - InfoSheetScene(type: type) - case .url(let url): - SFSafariView(url: url) - case .networkFeeSelector: - NetworkFeeSheet(model: model.feeModel) - case .payloadDetails: - NavigationStack { - SimulationPayloadDetailsScene( - primaryFields: model.primaryPayloadFields, - secondaryFields: model.secondaryPayloadFields, - fieldViewModel: model.payloadFieldViewModel(for:), - contextMenuItems: model.contextMenuItems(for:) - ) - .presentationDetents([.large]) - .presentationBackground(Colors.grayBackground) - } - case .fiatConnect(let assetAddress, let walletId): - NavigationStack { - FiatConnectNavigationView( - model: FiatSceneViewModel( - fiatService: model.fiatService, - assetAddress: assetAddress, - walletId: walletId - ) - ) - .navigationBarTitleDisplayMode(.inline) - .toolbarDismissItem(type: .close, placement: .topBarLeading) - } - case .swapDetails: - if case let .swapDetails(model) = model.detailsViewModel.itemModel { - NavigationStack { - SwapDetailsView(model: Bindable(model)) - .presentationDetentsForCurrentDeviceSize(expandable: true) - .presentationBackground(Colors.grayBackground) - } - } - case .perpetualDetails(let model): - NavigationStack { - PerpetualDetailsView(model: model) - .presentationDetentsForCurrentDeviceSize(expandable: true) - .presentationBackground(Colors.grayBackground) - } - } - } .alertSheet($model.isPresentingAlertMessage) } } diff --git a/Features/Transfer/Sources/Types/AmountDataProvider.swift b/Features/Transfer/Sources/Types/AmountDataProvider.swift index e9108d646..56f240938 100644 --- a/Features/Transfer/Sources/Types/AmountDataProvider.swift +++ b/Features/Transfer/Sources/Types/AmountDataProvider.swift @@ -3,7 +3,7 @@ import BigInt import Primitives -enum AmountDataProvider: AmountDataProvidable, @unchecked Sendable { +public enum AmountDataProvider: AmountDataProvidable, @unchecked Sendable { case transfer(AmountTransferViewModel) case stake(AmountStakeViewModel) case freeze(AmountFreezeViewModel) diff --git a/Features/Transfer/Sources/Types/AmountSheetType.swift b/Features/Transfer/Sources/Types/AmountSheetType.swift index ee95a1e6a..73337dd7d 100644 --- a/Features/Transfer/Sources/Types/AmountSheetType.swift +++ b/Features/Transfer/Sources/Types/AmountSheetType.swift @@ -7,13 +7,13 @@ import Components import Perpetuals import PrimitivesComponents -enum AmountSheetType: Identifiable { +public enum AmountSheetType: Identifiable { case infoAction(InfoSheetType) - case fiatConnect(assetAddress: AssetAddress, walletId: WalletId) + case fiatConnect(assetAddress: AssetAddress, wallet: Wallet) case leverageSelector(selection: SelectionState) case autoclose(AutocloseOpenData) - var id: String { + public var id: String { switch self { case let .infoAction(type): "info-action-\(type.id)" case .fiatConnect: "fiat-connect" diff --git a/Features/Transfer/Sources/Types/ConfirmTransferSheetType.swift b/Features/Transfer/Sources/Types/ConfirmTransferSheetType.swift index 2dd7e5d23..f7ccaec67 100644 --- a/Features/Transfer/Sources/Types/ConfirmTransferSheetType.swift +++ b/Features/Transfer/Sources/Types/ConfirmTransferSheetType.swift @@ -6,16 +6,16 @@ import Primitives import Components import PrimitivesComponents -enum ConfirmTransferSheetType: Identifiable, Sendable { +public enum ConfirmTransferSheetType: Identifiable, Sendable { case info(InfoSheetType) case networkFeeSelector case payloadDetails case url(URL) - case fiatConnect(assetAddress: AssetAddress, walletId: WalletId) + case fiatConnect(assetAddress: AssetAddress, wallet: Wallet) case swapDetails case perpetualDetails(PerpetualDetailsViewModel) - var id: String { + public var id: String { switch self { case let .info(type): "info-\(type.id)" case let .url(url): "url-\(url)" diff --git a/Features/Transfer/Sources/Types/SelectionState.swift b/Features/Transfer/Sources/Types/SelectionState.swift index 4703fd772..c94bcb2b6 100644 --- a/Features/Transfer/Sources/Types/SelectionState.swift +++ b/Features/Transfer/Sources/Types/SelectionState.swift @@ -3,13 +3,13 @@ import Foundation @Observable -final class SelectionState { - let options: [T] - var selected: T - let isEnabled: Bool - let title: String +public final class SelectionState { + public let options: [T] + public var selected: T + public let isEnabled: Bool + public let title: String - init( + public init( options: [T], selected: T, isEnabled: Bool, diff --git a/Features/Transfer/Sources/ViewModels/AmountEarnViewModel.swift b/Features/Transfer/Sources/ViewModels/AmountEarnViewModel.swift index 70806c94a..f9d74330c 100644 --- a/Features/Transfer/Sources/ViewModels/AmountEarnViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/AmountEarnViewModel.swift @@ -6,7 +6,7 @@ import Foundation import Localization import Primitives -final class AmountEarnViewModel: AmountDataProvidable { +public final class AmountEarnViewModel: AmountDataProvidable { let asset: Asset let action: EarnType private let earnService: any EarnDataProvidable diff --git a/Features/Transfer/Sources/ViewModels/AmountFreezeViewModel.swift b/Features/Transfer/Sources/ViewModels/AmountFreezeViewModel.swift index c88e55b66..4f84d8fed 100644 --- a/Features/Transfer/Sources/ViewModels/AmountFreezeViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/AmountFreezeViewModel.swift @@ -8,7 +8,7 @@ import Primitives import PrimitivesComponents import Stake -final class AmountFreezeViewModel: AmountDataProvidable { +public final class AmountFreezeViewModel: AmountDataProvidable { enum Action { case freeze case unfreeze diff --git a/Features/Transfer/Sources/ViewModels/AmountPerpetualViewModel.swift b/Features/Transfer/Sources/ViewModels/AmountPerpetualViewModel.swift index e64bc4488..dbda12029 100644 --- a/Features/Transfer/Sources/ViewModels/AmountPerpetualViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/AmountPerpetualViewModel.swift @@ -18,7 +18,7 @@ struct AmountPerpetualLimits { } @Observable -final class AmountPerpetualViewModel: AmountDataProvidable { +public final class AmountPerpetualViewModel: AmountDataProvidable { let asset: Asset let data: PerpetualRecipientData let leverageSelection: SelectionState? diff --git a/Features/Transfer/Sources/ViewModels/AmountSceneViewModel.swift b/Features/Transfer/Sources/ViewModels/AmountSceneViewModel.swift index 27c105c8e..d164f6d52 100644 --- a/Features/Transfer/Sources/ViewModels/AmountSceneViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/AmountSceneViewModel.swift @@ -26,13 +26,13 @@ public final class AmountSceneViewModel { private let valueConverter = ValueConverter() let currencyFormatter: CurrencyFormatter - let provider: AmountDataProvider + public let provider: AmountDataProvider public let assetQuery: ObservableQuery var assetData: AssetData { assetQuery.value } - var transferState: StateViewType = .noData + public var transferState: StateViewType = .noData var amountInputModel: InputValidationViewModel - var isPresentingSheet: AmountSheetType? + public var isPresentingSheet: AmountSheetType? private var amountInputType: AmountInputType = .asset { didSet { amountInputModel.update(validators: inputValidators) } @@ -60,7 +60,7 @@ public final class AmountSceneViewModel { } } - var asset: Asset { provider.asset } + public var asset: Asset { provider.asset } var title: String { provider.title } var canChangeValue: Bool { provider.canChangeValue } var isInputDisabled: Bool { !canChangeValue } @@ -88,8 +88,8 @@ public final class AmountSceneViewModel { } var maxTitle: String { Localized.Transfer.max } - var continueTitle: String { Localized.Common.continue } - var isNextEnabled: Bool { actionButtonState == .normal } + public var continueTitle: String { Localized.Common.continue } + public var isNextEnabled: Bool { actionButtonState == .normal } var inputConfig: any CurrencyInputConfigurable { AmountInputConfig( @@ -113,11 +113,11 @@ extension AmountSceneViewModel { } } - func onChangeAssetBalance(_: AssetData, _: AssetData) { + public func onChangeAssetBalance(_: AssetData, _: AssetData) { amountInputModel.update(validators: inputValidators) } - func onSelectNextButton() { + public func onSelectNextButton() { Task { await fetch() } @@ -148,7 +148,7 @@ extension AmountSceneViewModel { isPresentingSheet = .autoclose(perpetual.makeAutocloseData(size: amount)) } - func onAutocloseComplete(takeProfit: InputValidationViewModel, stopLoss: InputValidationViewModel) { + public func onAutocloseComplete(takeProfit: InputValidationViewModel, stopLoss: InputValidationViewModel) { if case let .perpetual(perpetual) = provider { perpetual.takeProfit = takeProfit.text.isEmpty ? nil : takeProfit.text perpetual.stopLoss = stopLoss.text.isEmpty ? nil : stopLoss.text @@ -160,11 +160,11 @@ extension AmountSceneViewModel { cleanInput() } - func onChangeLeverage(_: LeverageOption, _: LeverageOption) { + public func onChangeLeverage(_: LeverageOption, _: LeverageOption) { amountInputModel.update(validators: inputValidators) } - func onValidatorSelected(_ validator: DelegationValidator) { + public func onValidatorSelected(_ validator: DelegationValidator) { if case let .stake(stake) = provider { stake.validatorSelection.selected = validator } @@ -214,7 +214,7 @@ private extension AmountSceneViewModel { func onSelectBuy() { let senderAddress = (try? wallet.account(for: asset.chain).address) ?? "" let assetAddress = AssetAddress(asset: asset, address: senderAddress) - isPresentingSheet = .fiatConnect(assetAddress: assetAddress, walletId: wallet.walletId) + isPresentingSheet = .fiatConnect(assetAddress: assetAddress, wallet: wallet) } var inputValidators: [any TextValidator] { diff --git a/Features/Transfer/Sources/ViewModels/AmountStakeViewModel.swift b/Features/Transfer/Sources/ViewModels/AmountStakeViewModel.swift index d4d94eba1..07d5e0be3 100644 --- a/Features/Transfer/Sources/ViewModels/AmountStakeViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/AmountStakeViewModel.swift @@ -11,10 +11,10 @@ import PrimitivesComponents import Stake import Validators -final class AmountStakeViewModel: AmountDataProvidable { +public final class AmountStakeViewModel: AmountDataProvidable { let asset: Asset let action: StakeAmountType - let validatorSelection: SelectionState + public let validatorSelection: SelectionState init(asset: Asset, action: StakeAmountType) { self.asset = asset @@ -35,7 +35,7 @@ final class AmountStakeViewModel: AmountDataProvidable { } } - var validatorSelectType: ValidatorSelectType { + public var validatorSelectType: ValidatorSelectType { switch action { case .stake, .redelegate: .stake case .unstake, .withdraw: .unstake diff --git a/Features/Transfer/Sources/ViewModels/AmountTransferViewModel.swift b/Features/Transfer/Sources/ViewModels/AmountTransferViewModel.swift index eb792a1c2..7aa780fc6 100644 --- a/Features/Transfer/Sources/ViewModels/AmountTransferViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/AmountTransferViewModel.swift @@ -18,7 +18,7 @@ enum TransferAction { } } -final class AmountTransferViewModel: AmountDataProvidable { +public final class AmountTransferViewModel: AmountDataProvidable { let asset: Asset let action: TransferAction diff --git a/Features/Transfer/Sources/ViewModels/ConfirmDetailsViewModel.swift b/Features/Transfer/Sources/ViewModels/ConfirmDetailsViewModel.swift index d5e352187..76993a242 100644 --- a/Features/Transfer/Sources/ViewModels/ConfirmDetailsViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/ConfirmDetailsViewModel.swift @@ -5,7 +5,7 @@ import PrimitivesComponents import Components import Swap -struct ConfirmDetailsViewModel { +public struct ConfirmDetailsViewModel { private let type: TransferDataType private let metadata: TransferDataMetadata? @@ -18,7 +18,7 @@ struct ConfirmDetailsViewModel { // MARK: - ItemModelProvidable extension ConfirmDetailsViewModel: ItemModelProvidable { - var itemModel: ConfirmTransferItemModel { + public var itemModel: ConfirmTransferItemModel { switch type { case let .swap(fromAsset, toAsset, swapData): .swapDetails( diff --git a/Features/Transfer/Sources/ViewModels/ConfirmTransferSceneViewModel.swift b/Features/Transfer/Sources/ViewModels/ConfirmTransferSceneViewModel.swift index 18d6322ca..0b0ccb7d3 100644 --- a/Features/Transfer/Sources/ViewModels/ConfirmTransferSceneViewModel.swift +++ b/Features/Transfer/Sources/ViewModels/ConfirmTransferSceneViewModel.swift @@ -18,7 +18,7 @@ import Swap @MainActor public final class ConfirmTransferSceneViewModel { let fiatService: FiatService - var feeModel: NetworkFeeSceneViewModel + public var feeModel: NetworkFeeSceneViewModel var state: StateViewType = .loading { didSet { onStateChange(state: state) @@ -38,8 +38,8 @@ public final class ConfirmTransferSceneViewModel { } } - var isPresentingSheet: ConfirmTransferSheetType? - var isPresentingAlertMessage: AlertMessage? + public var isPresentingSheet: ConfirmTransferSheetType? + public var isPresentingAlertMessage: AlertMessage? private let confirmService: ConfirmService private let simulationService: ConfirmSimulationService @@ -97,11 +97,11 @@ public final class ConfirmTransferSceneViewModel { simulationState.warnings } - var primaryPayloadFields: [SimulationPayloadField] { + public var primaryPayloadFields: [SimulationPayloadField] { simulationState.primaryFields } - var secondaryPayloadFields: [SimulationPayloadField] { + public var secondaryPayloadFields: [SimulationPayloadField] { simulationState.secondaryFields } @@ -129,7 +129,7 @@ public final class ConfirmTransferSceneViewModel { ) } - var detailsViewModel: ConfirmDetailsViewModel { + public var detailsViewModel: ConfirmDetailsViewModel { ConfirmDetailsViewModel(type: transferData.type, metadata: metadata) } @@ -267,7 +267,7 @@ extension ConfirmTransferSceneViewModel { isPresentingSheet = .info(.networkFee(dataModel.chain)) } - func contextMenuItems(for field: SimulationPayloadField) -> [ContextMenuItemType] { + public func contextMenuItems(for field: SimulationPayloadField) -> [ContextMenuItemType] { var items = payloadFieldViewModel(for: field).contextMenuItems if field.fieldType == .address { let link = confirmService.getExplorerLink(chain: transferData.chain, address: field.value) @@ -280,7 +280,7 @@ extension ConfirmTransferSceneViewModel { return items } - func payloadFieldViewModel(for field: SimulationPayloadField) -> SimulationPayloadFieldViewModel { + public func payloadFieldViewModel(for field: SimulationPayloadField) -> SimulationPayloadFieldViewModel { SimulationPayloadFieldViewModel( field: field, chain: transferData.chain, @@ -382,7 +382,7 @@ extension ConfirmTransferSceneViewModel { private func onSelectBuy() { isPresentingSheet = .fiatConnect( assetAddress: feeAssetAddress, - walletId: wallet.walletId + wallet: wallet ) } private func onSelectConfirmTransfer() { diff --git a/Gem.xcodeproj/project.pbxproj b/Gem.xcodeproj/project.pbxproj index 1d5b5af93..ba89c45a9 100644 --- a/Gem.xcodeproj/project.pbxproj +++ b/Gem.xcodeproj/project.pbxproj @@ -120,6 +120,8 @@ D8C4A3772C8CF957006FABE8 /* EarnNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C4A3782C8CF957006FABE8 /* EarnNavigationView.swift */; }; D8C4A3A52C9696FE006FABE8 /* AssetNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C4A3992C9696FE006FABE8 /* AssetNavigationView.swift */; }; D8C4A3B22EA6B00000C26819 /* RecipientNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C4A3B12EA6B00000C26819 /* RecipientNavigationView.swift */; }; + 67AEE2D03EB6F99C6ECF9527 /* AmountNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032FCD1308A93D4A9B370F35 /* AmountNavigationView.swift */; }; + BACBF787C9F698E54FE79F82 /* ConfirmTransferNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA467CA776E4FE56A659D9C /* ConfirmTransferNavigationView.swift */; }; D8CF19E32CC747370025D6B4 /* Transfer in Frameworks */ = {isa = PBXBuildFile; productRef = D8CF19E22CC747370025D6B4 /* Transfer */; }; D8CFDE9E2E37FC2500D27283 /* Style in Frameworks */ = {isa = PBXBuildFile; productRef = D8CFDE9D2E37FC2500D27283 /* Style */; }; D8CFDEA02E37FC3B00D27283 /* Primitives in Frameworks */ = {isa = PBXBuildFile; productRef = D8CFDE9F2E37FC3B00D27283 /* Primitives */; }; @@ -284,6 +286,8 @@ D8C4A3782C8CF957006FABE8 /* EarnNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EarnNavigationView.swift; sourceTree = ""; }; D8C4A3992C9696FE006FABE8 /* AssetNavigationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetNavigationView.swift; sourceTree = ""; }; D8C4A3B12EA6B00000C26819 /* RecipientNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipientNavigationView.swift; sourceTree = ""; }; + 032FCD1308A93D4A9B370F35 /* AmountNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmountNavigationView.swift; sourceTree = ""; }; + DBA467CA776E4FE56A659D9C /* ConfirmTransferNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmTransferNavigationView.swift; sourceTree = ""; }; D8CF19E12CC745ED0025D6B4 /* Transfer */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Transfer; sourceTree = ""; }; D8D203D12AE0813E00261CA2 /* SwiftHTTPClient */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = SwiftHTTPClient; sourceTree = ""; }; D8D5C1D02E6CAC16007628A1 /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; @@ -519,6 +523,8 @@ 83A35C612DF2054B00360060 /* Transfer */ = { isa = PBXGroup; children = ( + 032FCD1308A93D4A9B370F35 /* AmountNavigationView.swift */, + DBA467CA776E4FE56A659D9C /* ConfirmTransferNavigationView.swift */, D8C4A3B12EA6B00000C26819 /* RecipientNavigationView.swift */, D89BB5ED2D1A085C00C7E510 /* ConfirmTransferNavigationStack.swift */, ); @@ -1127,6 +1133,8 @@ B6B86A102D702E7C00D31D65 /* SwapNavigationView.swift in Sources */, D89CD7A92CC70C7C007A2BAC /* SelectedAssetNavigationStack.swift in Sources */, D8C4A3B22EA6B00000C26819 /* RecipientNavigationView.swift in Sources */, + 67AEE2D03EB6F99C6ECF9527 /* AmountNavigationView.swift in Sources */, + BACBF787C9F698E54FE79F82 /* ConfirmTransferNavigationView.swift in Sources */, D89BB5EE2D1A085C00C7E510 /* ConfirmTransferNavigationStack.swift in Sources */, 83E041582D0AFCB10031D4BC /* RootScene.swift in Sources */, D852CAFD2C9C9837004121D3 /* AddAssetPriceAlertNavigationStack.swift in Sources */, diff --git a/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift b/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift index fb0071b35..62acf13c3 100644 --- a/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift +++ b/Gem/Navigation/Assets/SelectAssetSceneNavigationStack.swift @@ -84,7 +84,7 @@ struct SelectAssetSceneNavigationStack: View { FiatConnectNavigationView( model: viewModelFactory.fiatScene( assetAddress: input.assetAddress, - walletId: model.wallet.walletId + wallet: model.wallet ) ) case .deposit: @@ -135,7 +135,7 @@ struct SelectAssetSceneNavigationStack: View { } .navigationBarTitleDisplayMode(.inline) .navigationDestination(for: TransferData.self) { data in - ConfirmTransferScene( + ConfirmTransferNavigationView( model: viewModelFactory.confirmTransferScene( wallet: model.wallet, data: data, diff --git a/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift b/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift index e9d8cbdfb..ce0e14207 100644 --- a/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift +++ b/Gem/Navigation/Assets/SelectedAssetNavigationStack.swift @@ -59,7 +59,7 @@ struct SelectedAssetNavigationStack: View { FiatConnectNavigationView( model: viewModelFactory.fiatScene( assetAddress: input.assetAddress, - walletId: wallet.walletId, + wallet: wallet, type: .buy, amount: amount ) @@ -68,7 +68,7 @@ struct SelectedAssetNavigationStack: View { FiatConnectNavigationView( model: viewModelFactory.fiatScene( assetAddress: input.assetAddress, - walletId: wallet.walletId, + wallet: wallet, type: .sell, amount: amount ) @@ -112,7 +112,7 @@ struct SelectedAssetNavigationStack: View { .toolbarDismissItem(type: .close, placement: .topBarLeading) .navigationBarTitleDisplayMode(.inline) .navigationDestination(for: TransferData.self) { data in - ConfirmTransferScene( + ConfirmTransferNavigationView( model: viewModelFactory.confirmTransferScene( wallet: wallet, data: data, diff --git a/Gem/Navigation/Perpetuals/AutocloseNavigationStack.swift b/Gem/Navigation/Perpetuals/AutocloseNavigationStack.swift index 38935b3f5..f851bc1a7 100644 --- a/Gem/Navigation/Perpetuals/AutocloseNavigationStack.swift +++ b/Gem/Navigation/Perpetuals/AutocloseNavigationStack.swift @@ -27,7 +27,7 @@ struct AutocloseNavigationStack: View { .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarDismissItem(type: .close, placement: .topBarLeading) } .navigationDestination(for: TransferData.self) { - ConfirmTransferScene( + ConfirmTransferNavigationView( model: viewModelFactory.confirmTransferScene( wallet: wallet, data: $0, diff --git a/Gem/Navigation/Perpetuals/PerpetualPositionNavigationStack.swift b/Gem/Navigation/Perpetuals/PerpetualPositionNavigationStack.swift index 5f06a12db..156bac13d 100644 --- a/Gem/Navigation/Perpetuals/PerpetualPositionNavigationStack.swift +++ b/Gem/Navigation/Perpetuals/PerpetualPositionNavigationStack.swift @@ -46,7 +46,7 @@ struct PerpetualPositionNavigationStack: View { ) } .navigationDestination(for: TransferData.self) { - ConfirmTransferScene( + ConfirmTransferNavigationView( model: viewModelFactory.confirmTransferScene( wallet: wallet, data: $0, diff --git a/Features/Transfer/Sources/Navigation/AmountNavigationView.swift b/Gem/Navigation/Transfer/AmountNavigationView.swift similarity index 88% rename from Features/Transfer/Sources/Navigation/AmountNavigationView.swift rename to Gem/Navigation/Transfer/AmountNavigationView.swift index 9f5fb42a4..cb49ca07d 100644 --- a/Features/Transfer/Sources/Navigation/AmountNavigationView.swift +++ b/Gem/Navigation/Transfer/AmountNavigationView.swift @@ -1,6 +1,5 @@ // Copyright (c). Gem Wallet. All rights reserved. -import Foundation import SwiftUI import Primitives import Stake @@ -8,28 +7,28 @@ import InfoSheet import Components import FiatConnect import PrimitivesComponents -import Store import Perpetuals -import Preferences +import Transfer -public struct AmountNavigationView: View { +struct AmountNavigationView: View { + @Environment(\.viewModelFactory) private var viewModelFactory @State private var model: AmountSceneViewModel - public init(model: AmountSceneViewModel) { + init(model: AmountSceneViewModel) { _model = State(initialValue: model) } - public var body: some View { + var body: some View { AmountScene(model: model) .onChangeBindQuery(model.assetQuery, action: model.onChangeAssetBalance) .sheet(item: $model.isPresentingSheet) { switch $0 { case let .infoAction(type): InfoSheetScene(type: type) - case let .fiatConnect(assetAddress, walletId): + case let .fiatConnect(assetAddress, wallet): NavigationStack { FiatConnectNavigationView( - model: FiatSceneViewModel(fiatService: model.fiatService, assetAddress: assetAddress, walletId: walletId) + model: viewModelFactory.fiatScene(assetAddress: assetAddress, wallet: wallet) ) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarDismissItem(type: .close, placement: .topBarLeading) } diff --git a/Gem/Navigation/Transfer/ConfirmTransferNavigationStack.swift b/Gem/Navigation/Transfer/ConfirmTransferNavigationStack.swift index f4c6d94e6..696c10fa5 100644 --- a/Gem/Navigation/Transfer/ConfirmTransferNavigationStack.swift +++ b/Gem/Navigation/Transfer/ConfirmTransferNavigationStack.swift @@ -28,7 +28,7 @@ struct ConfirmTransferNavigationStack: View { var body: some View { NavigationStack { - ConfirmTransferScene( + ConfirmTransferNavigationView( model: viewModelFactory.confirmTransferScene( wallet: wallet, data: transferData, diff --git a/Gem/Navigation/Transfer/ConfirmTransferNavigationView.swift b/Gem/Navigation/Transfer/ConfirmTransferNavigationView.swift new file mode 100644 index 000000000..057a01b15 --- /dev/null +++ b/Gem/Navigation/Transfer/ConfirmTransferNavigationView.swift @@ -0,0 +1,64 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import SwiftUI +import Components +import Style +import InfoSheet +import PrimitivesComponents +import FiatConnect +import Swap +import Perpetuals +import Transfer + +struct ConfirmTransferNavigationView: View { + @Environment(\.viewModelFactory) private var viewModelFactory + + @Bindable var model: ConfirmTransferSceneViewModel + + var body: some View { + ConfirmTransferScene(model: model) + .sheet(item: $model.isPresentingSheet) { + switch $0 { + case .info(let type): + InfoSheetScene(type: type) + case .url(let url): + SFSafariView(url: url) + case .networkFeeSelector: + NetworkFeeSheet(model: model.feeModel) + case .payloadDetails: + NavigationStack { + SimulationPayloadDetailsScene( + primaryFields: model.primaryPayloadFields, + secondaryFields: model.secondaryPayloadFields, + fieldViewModel: model.payloadFieldViewModel(for:), + contextMenuItems: model.contextMenuItems(for:) + ) + .presentationDetents([.large]) + .presentationBackground(Colors.grayBackground) + } + case .fiatConnect(let assetAddress, let wallet): + NavigationStack { + FiatConnectNavigationView( + model: viewModelFactory.fiatScene(assetAddress: assetAddress, wallet: wallet) + ) + .navigationBarTitleDisplayMode(.inline) + .toolbarDismissItem(type: .close, placement: .topBarLeading) + } + case .swapDetails: + if case let .swapDetails(model) = model.detailsViewModel.itemModel { + NavigationStack { + SwapDetailsView(model: Bindable(model)) + .presentationDetentsForCurrentDeviceSize(expandable: true) + .presentationBackground(Colors.grayBackground) + } + } + case .perpetualDetails(let model): + NavigationStack { + PerpetualDetailsView(model: model) + .presentationDetentsForCurrentDeviceSize(expandable: true) + .presentationBackground(Colors.grayBackground) + } + } + } + } +} diff --git a/Gem/Navigation/WalletConnector/WalletConnectorNavigationStack.swift b/Gem/Navigation/WalletConnector/WalletConnectorNavigationStack.swift index 21a6c96b1..160d14d16 100644 --- a/Gem/Navigation/WalletConnector/WalletConnectorNavigationStack.swift +++ b/Gem/Navigation/WalletConnector/WalletConnectorNavigationStack.swift @@ -28,7 +28,7 @@ struct WalletConnectorNavigationStack: View { Group { switch type { case .transferData(let data): - ConfirmTransferScene( + ConfirmTransferNavigationView( model: viewModelFactory.confirmTransferScene( wallet: data.payload.wallet, data: data.payload.tranferData, diff --git a/Gem/Services/ViewModelFactory.swift b/Gem/Services/ViewModelFactory.swift index f0d573e88..0699b63ee 100644 --- a/Gem/Services/ViewModelFactory.swift +++ b/Gem/Services/ViewModelFactory.swift @@ -168,14 +168,15 @@ public struct ViewModelFactory: Sendable { @MainActor public func fiatScene( assetAddress: AssetAddress, - walletId: WalletId, + wallet: Wallet, type: FiatQuoteType = .buy, amount: Int? = nil ) -> FiatSceneViewModel { FiatSceneViewModel( fiatService: fiatService, assetAddress: assetAddress, - walletId: walletId, + wallet: wallet, + assetsEnabler: assetsEnabler, type: type, amount: amount ) diff --git a/Gem/Types/Environment.swift b/Gem/Types/Environment.swift index 87abdda8e..13314450a 100644 --- a/Gem/Types/Environment.swift +++ b/Gem/Types/Environment.swift @@ -9,7 +9,6 @@ import BannerService import NotificationService import DeviceService import PriceAlertService -import GemAPI import ChainService import StakeService import NodeService