Skip to content

Commit

Permalink
IOS-8268 [Onramp] Repository for user preference (#4110)
Browse files Browse the repository at this point in the history
  • Loading branch information
Balashov152 authored Oct 29, 2024
1 parent 09989d1 commit 9836302
Show file tree
Hide file tree
Showing 38 changed files with 616 additions and 188 deletions.
31 changes: 31 additions & 0 deletions Tangem/App/Services/Onramp/CommonOnrampStorage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// CommonOnrampStorage.swift
// TangemApp
//
// Created by Sergey Balashov on 21.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

import TangemExpress
import TangemFoundation

struct CommonOnrampStorage: OnrampStorage {
@Injected(\.persistentStorage) private var storage: PersistentStorageProtocol

func save(preference: OnrampUserPreference) {
do {
try storage.store(value: preference, for: .onrampPreference)
} catch {
AppLog.shared.debug("[CommonOnrampStorage] Failed to save changes in storage. Reason: \(error)")
}
}

func preference() -> OnrampUserPreference? {
do {
return try storage.value(for: .onrampPreference)
} catch {
AppLog.shared.debug("[CommonOnrampStorage] Couldn't get the staking transactions list from the storage with error \(error)")
return nil
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum PersistentStorageKey {
case walletConnectSessions(userWalletId: String)
case pendingExpressTransactions
case pendingStakingTransactions
case onrampPreference

var path: String {
switch self {
Expand All @@ -30,6 +31,8 @@ enum PersistentStorageKey {
return "express_pending_transactions"
case .pendingStakingTransactions:
return "staking_pending_transactions"
case .onrampPreference:
return "onramp_preference"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ extension SendDecimalNumberTextField: Setupable {
map { $0.toolbarType = toolbarType }
}

func prefixSuffixOptions(_ prefixSuffixOptions: PrefixSuffixOptions) -> Self {
func prefixSuffixOptions(_ prefixSuffixOptions: PrefixSuffixOptions?) -> Self {
map { $0.prefixSuffixOptions = prefixSuffixOptions }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,13 @@ extension SendDecimalNumberTextField {

extension SendDecimalNumberTextField {
struct PrefixSuffixOptionsFactory {
private let cryptoCurrencyCode: String
private let fiatCurrencyCode: String
private let locale: Locale

init(cryptoCurrencyCode: String, fiatCurrencyCode: String, locale: Locale = .current) {
self.cryptoCurrencyCode = cryptoCurrencyCode
self.fiatCurrencyCode = fiatCurrencyCode
init(locale: Locale = .current) {
self.locale = locale
}

func makeCryptoOptions() -> PrefixSuffixOptions {
func makeCryptoOptions(cryptoCurrencyCode: String) -> PrefixSuffixOptions {
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .currency
numberFormatter.currencySymbol = cryptoCurrencyCode
Expand All @@ -36,7 +32,7 @@ extension SendDecimalNumberTextField {
return options(from: numberFormatter, currency: cryptoCurrencyCode, forceSpace: true)
}

func makeFiatOptions() -> PrefixSuffixOptions {
func makeFiatOptions(fiatCurrencyCode: String) -> PrefixSuffixOptions {
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .currency
numberFormatter.currencyCode = fiatCurrencyCode
Expand Down
2 changes: 0 additions & 2 deletions Tangem/Modules/Main/MainCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,6 @@ extension MainCoordinator: SingleTokenBaseRoutable {
}

func openOnramp(walletModel: WalletModel, userWalletModel: UserWalletModel) {
mainBottomSheetUIManager.hide()

let dismissAction: Action<(walletModel: WalletModel, userWalletModel: UserWalletModel)?> = { [weak self] navigationInfo in
self?.sendCoordinator = nil

Expand Down
1 change: 1 addition & 0 deletions Tangem/Modules/OnrampCountry/OnrampCountryViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ final class OnrampCountryViewModel: ObservableObject, Identifiable {
func didTapMainButton() {
switch style {
case .info:
repository.saveChanges()
coordinator?.dismissConfirmCountryView()
case .notSupport:
coordinator?.dismiss()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@ struct OnrampFlowBaseBuilder {
let sendFinishStepBuilder: SendFinishStepBuilder
let builder: SendDependenciesBuilder

func makeSendViewModel(onrampManager: some OnrampManager, router: SendRoutable) -> SendViewModel {
func makeSendViewModel(router: SendRoutable) -> SendViewModel {
let expressAPIProvider = ExpressAPIProviderFactory().makeExpressAPIProvider(userId: userWalletModel.userWalletId.stringValue, logger: AppLog.shared)
let onrampRepository = builder.makeOnrampRepository()

let onrampManager = TangemExpressFactory().makeOnrampManager(
expressAPIProvider: expressAPIProvider,
onrampRepository: onrampRepository,
logger: AppLog.shared
)

let onrampModel = builder.makeOnrampModel(onrampManager: onrampManager)

let onrampAmountViewModel = sendAmountStepBuilder.makeOnrampAmountViewModel(
io: (input: onrampModel, output: onrampModel),
sendAmountValidator: builder.makeOnrampAmountValidator(),
amountModifier: .none
repository: onrampRepository,
sendAmountValidator: builder.makeOnrampAmountValidator()
)

let sendAmountCompactViewModel = sendAmountStepBuilder.makeSendAmountCompactViewModel(
Expand All @@ -47,24 +56,29 @@ struct OnrampFlowBaseBuilder {

let stepsManager = CommonOnrampStepsManager(
onrampStep: onramp.step,
finishStep: finish
finishStep: finish,
// If user already has saved country in the repository then the bottom sheet will not show
// And we can show keyboard safely
shouldActivateKeyboard: onrampRepository.savedCountry != nil
)

let interactor = CommonSendBaseInteractor(input: onrampModel, output: onrampModel)
let dataBuilder = builder.makeOnrampBaseDataBuilder(input: onrampModel, onrampRepository: onrampRepository)

let viewModel = SendViewModel(
interactor: interactor,
stepsManager: stepsManager,
userWalletModel: userWalletModel,
alertBuilder: builder.makeSendAlertBuilder(),
dataBuilder: builder.makeSendBaseDataBuilder(input: onrampModel),
dataBuilder: dataBuilder,
tokenItem: walletModel.tokenItem,
feeTokenItem: walletModel.feeTokenItem,
coordinator: router
)

stepsManager.set(output: viewModel)
onrampModel.router = viewModel
onrampModel.alertPresenter = viewModel

return viewModel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct RestakingFlowBaseBuilder {
stepsManager: stepsManager,
userWalletModel: userWalletModel,
alertBuilder: builder.makeStakingAlertBuilder(),
dataBuilder: builder.makeSendBaseDataBuilder(input: restakingModel),
dataBuilder: builder.makeStakingBaseDataBuilder(input: restakingModel),
tokenItem: walletModel.tokenItem,
feeTokenItem: walletModel.feeTokenItem,
coordinator: router
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct StakingFlowBaseBuilder {
stepsManager: stepsManager,
userWalletModel: userWalletModel,
alertBuilder: builder.makeStakingAlertBuilder(),
dataBuilder: builder.makeSendBaseDataBuilder(input: stakingModel),
dataBuilder: builder.makeStakingBaseDataBuilder(input: stakingModel),
tokenItem: walletModel.tokenItem,
feeTokenItem: walletModel.feeTokenItem,
coordinator: router
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct StakingSingleActionFlowBaseBuilder {
stepsManager: stepsManager,
userWalletModel: userWalletModel,
alertBuilder: builder.makeStakingAlertBuilder(),
dataBuilder: builder.makeSendBaseDataBuilder(input: actionModel),
dataBuilder: builder.makeStakingBaseDataBuilder(input: actionModel),
tokenItem: walletModel.tokenItem,
feeTokenItem: walletModel.feeTokenItem,
coordinator: router
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct UnstakingFlowBaseBuilder {
stepsManager: stepsManager,
userWalletModel: userWalletModel,
alertBuilder: builder.makeStakingAlertBuilder(),
dataBuilder: builder.makeSendBaseDataBuilder(input: unstakingModel),
dataBuilder: builder.makeStakingBaseDataBuilder(input: unstakingModel),
tokenItem: walletModel.tokenItem,
feeTokenItem: walletModel.feeTokenItem,
coordinator: router
Expand Down
32 changes: 25 additions & 7 deletions Tangem/Modules/Send/Factories/SendDependenciesBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,6 @@ struct SendDependenciesBuilder {
CommonFeeIncludedCalculator(validator: walletModel.transactionValidator)
}

func makeSendBaseDataBuilder(input: SendBaseDataBuilderInput) -> SendBaseDataBuilder {
SendBaseDataBuilder(input: input, walletModel: walletModel, emailDataProvider: userWalletModel)
}

// MARK: - Send, Sell

func makeSendModel(
Expand Down Expand Up @@ -224,6 +220,10 @@ struct SendDependenciesBuilder {
CommonSendAlertBuilder()
}

func makeSendBaseDataBuilder(input: SendBaseDataBuilderInput) -> SendBaseDataBuilder {
CommonSendBaseDataBuilder(input: input, walletModel: walletModel, emailDataProvider: userWalletModel)
}

// MARK: - Staking

func makeStakingModel(stakingManager: some StakingManager) -> StakingModel {
Expand Down Expand Up @@ -323,18 +323,36 @@ struct SendDependenciesBuilder {
StakingAmountModifier(tokenItem: walletModel.tokenItem)
}

func makeStakingBaseDataBuilder(input: StakingBaseDataBuilderInput) -> StakingBaseDataBuilder {
CommonStakingBaseDataBuilder(input: input, walletModel: walletModel, emailDataProvider: userWalletModel)
}

// MARK: - Onramp

func makeOnrampModel(onrampManager: some OnrampManager) -> OnrampModel {
OnrampModel(onrampManager: onrampManager)
}

func makeOnrampManager(userWalletId: String) -> OnrampManager {
let expressAPIProvider = ExpressAPIProviderFactory().makeExpressAPIProvider(userId: userWalletId, logger: AppLog.shared)
return TangemExpressFactory().makeOnrampManager(expressAPIProvider: expressAPIProvider, logger: AppLog.shared)
func makeOnrampManager(userWalletId: String, onrampRepository: OnrampRepository) -> OnrampManager {
let expressAPIProvider = ExpressAPIProviderFactory()
.makeExpressAPIProvider(userId: userWalletId, logger: AppLog.shared)

return TangemExpressFactory().makeOnrampManager(
expressAPIProvider: expressAPIProvider,
onrampRepository: onrampRepository,
logger: AppLog.shared
)
}

func makeOnrampAmountValidator() -> SendAmountValidator {
OnrampAmountValidator()
}

func makeOnrampBaseDataBuilder(input: OnrampBaseDataBuilderInput, onrampRepository: OnrampRepository) -> OnrampBaseDataBuilder {
CommonOnrampBaseDataBuilder(input: input, walletModel: walletModel, onrampRepository: onrampRepository)
}

func makeOnrampRepository() -> OnrampRepository {
TangemExpressFactory().makeOnrampRepository(storage: CommonOnrampStorage())
}
}
3 changes: 1 addition & 2 deletions Tangem/Modules/Send/Factories/SendFlowFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ struct SendFlowFactory {
let sendAmountStepBuilder = SendAmountStepBuilder(walletModel: walletModel, builder: builder)
let onrampStepBuilder = OnrampStepBuilder()
let sendFinishStepBuilder = SendFinishStepBuilder(walletModel: walletModel)
let onrampManager = builder.makeOnrampManager(userWalletId: userWalletModel.userWalletId.stringValue)

let baseBuilder = OnrampFlowBaseBuilder(
userWalletModel: userWalletModel,
Expand All @@ -162,6 +161,6 @@ struct SendFlowFactory {
builder: builder
)

return baseBuilder.makeSendViewModel(onrampManager: onrampManager, router: router)
return baseBuilder.makeSendViewModel(router: router)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Foundation
import TangemExpress

struct SendAmountStepBuilder {
typealias IO = (input: SendAmountInput, output: SendAmountOutput)
Expand Down Expand Up @@ -57,20 +58,17 @@ struct SendAmountStepBuilder {

func makeOnrampAmountViewModel(
io: IO,
sendAmountValidator: SendAmountValidator,
amountModifier: SendAmountModifier?
repository: OnrampRepository,
sendAmountValidator: SendAmountValidator
) -> OnrampAmountViewModel {
let interactor = makeSendAmountInteractor(
io: io,
sendAmountValidator: sendAmountValidator,
amountModifier: amountModifier,
amountModifier: nil,
type: .fiat
)

return OnrampAmountViewModel(
settings: .init(tokenIconInfo: builder.makeTokenIconInfo(), tokenItem: walletModel.tokenItem),
interactor: interactor
)
return OnrampAmountViewModel(tokenItem: walletModel.tokenItem, repository: repository, interactor: interactor)
}
}

Expand Down
29 changes: 21 additions & 8 deletions Tangem/Modules/Send/Services/ManagmentModels/OnrampModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import TangemExpress
import Combine

protocol OnrampModelRoutable: AnyObject {
func openOnrampCountriesSelector()
func openOnrampCountryBottomSheet(country: OnrampCountry)
}

Expand All @@ -24,24 +25,42 @@ class OnrampModel {
// MARK: - Dependencies

weak var router: OnrampModelRoutable?
weak var alertPresenter: SendViewAlertPresenter?

// MARK: - Private injections

private let onrampManager: OnrampManager

private var task: Task<Void, Never>?
private var bag: Set<AnyCancellable> = []

init(onrampManager: OnrampManager) {
self.onrampManager = onrampManager

bind()
updateCountry()
}
}

// MARK: - Bind

private extension OnrampModel {
func bind() {}

func updateCountry() {
task = runTask(in: self) { model in
do {
let country = try await model.onrampManager.getCountry()
await runOnMain {
model.router?.openOnrampCountryBottomSheet(country: country)
}
} catch {
await runOnMain {
model.alertPresenter?.showAlert(error.alertBinder)
}
}
}
}
}

// MARK: - Buy
Expand Down Expand Up @@ -132,12 +151,6 @@ extension OnrampModel: SendBaseOutput {
}
}

// MARK: - SendBaseDataBuilderInput
// MARK: - OnrampBaseDataBuilderInput

extension OnrampModel: SendBaseDataBuilderInput {
var bsdkAmount: BSDKAmount? { nil }

var bsdkFee: BSDKFee? { nil }

var isFeeIncluded: Bool { false }
}
extension OnrampModel: OnrampBaseDataBuilderInput {}
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,21 @@ extension RestakingModel: NotificationTapDelegate {
}
}

// MARK: - SendBaseDataBuilderInput
// MARK: - StakingBaseDataBuilderInput

extension RestakingModel: SendBaseDataBuilderInput {
extension RestakingModel: StakingBaseDataBuilderInput {
var bsdkAmount: BSDKAmount? { makeAmount(value: action.amount) }

var bsdkFee: BlockchainSdk.Fee? { selectedFee.value.value }

var isFeeIncluded: Bool { false }

var stakingActionType: TangemStaking.StakingAction.ActionType? { stakingAction.type }

var selectedPolicy: ApprovePolicy? { nil }

var approveViewModelInput: (any ApproveViewModelInput)? { nil }

var validator: ValidatorInfo? { action.validatorInfo }
}

Expand Down
Loading

0 comments on commit 9836302

Please sign in to comment.