Skip to content

Commit

Permalink
Merge branch 'develop' into bugfix/IOS-7062_hide_dash_if_no_balance
Browse files Browse the repository at this point in the history
  • Loading branch information
amuraveinik authored Oct 15, 2024
2 parents c69a4df + bb119d7 commit 76f028f
Show file tree
Hide file tree
Showing 36 changed files with 454 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,46 +28,6 @@ struct CommonExpressDestinationService {
// MARK: - ExpressDestinationService

extension CommonExpressDestinationService: ExpressDestinationService {
func canBeSwapped(wallet: WalletModel) async -> Bool {
let isAvailable = swapAvailabilityProvider.canSwap(tokenItem: wallet.tokenItem)

guard isAvailable, !wallet.isCustom else {
AppLog.shared.debug("[Express] \(self) has checked that wallet: \(wallet.name) can not be swapped")
return false
}

do {
try await expressRepository.updatePairs(for: wallet)
} catch {
return false
}

let hasBalance = (wallet.balanceValue ?? 0) > 0
let pairsFrom = await expressRepository.getPairs(from: wallet)

// If we can swap as source
if hasBalance, !pairsFrom.isEmpty {
AppLog.shared.debug("[Express] \(self) has checked that wallet: \(wallet.name) can be swapped as source")
return true
}

// Otherwise we try to find a source wallet with balance and swap on `wallet` as destination
let pairsTo = await expressRepository.getPairs(to: wallet)
let walletModelsWithPositiveBalance = walletModelsManager.walletModels.filter { !$0.isZeroAmount }

let hasSourceWithBalance = walletModelsWithPositiveBalance.contains { wallet in
pairsTo.contains(where: { $0.source == wallet.expressCurrency })
}

if hasSourceWithBalance {
AppLog.shared.debug("[Express] \(self) has checked that wallet: \(wallet.name) can be swapped as destination")
return true
}

AppLog.shared.debug("[Express] \(self) has checked that wallet: \(wallet.name) can not be swapped")
return false
}

func getDestination(source: WalletModel) async throws -> WalletModel {
let availablePairs = await expressRepository.getPairs(from: source)
let searchableWalletModels = walletModelsManager.walletModels.filter { wallet in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import Foundation

protocol ExpressDestinationService {
func canBeSwapped(wallet: WalletModel) async -> Bool
func getDestination(source: WalletModel) async throws -> WalletModel
}

Expand Down
150 changes: 128 additions & 22 deletions TangemApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions TangemExpress/Factory/TangemExpressFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ public struct TangemExpressFactory {
)
}

public func makeOnrampManager(
expressAPIProvider: ExpressAPIProvider,
allowanceProvider: ExpressAllowanceProvider,
feeProvider: FeeProvider,
expressRepository: ExpressRepository,
logger: Logger? = nil,
analyticsLogger: ExpressAnalyticsLogger? = nil
) -> OnrampManager {
let logger: Logger = logger ?? CommonLogger()
let repository = CommonOnrampRepository(provider: expressAPIProvider)

return CommonOnrampManager(
provider: expressAPIProvider,
onrampRepository: repository,
logger: logger
)
}

public func makeExpressAPIProvider(
credential: ExpressAPICredential,
deviceInfo: ExpressDeviceInfo,
Expand Down
62 changes: 62 additions & 0 deletions TangemExpress/Manager/OnrampManager/CommonOnrampManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// CommonOnrampManager.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public actor CommonOnrampManager {
private let provider: ExpressAPIProvider
private let onrampRepository: OnrampRepository
private let logger: Logger

private var _providers: [OnrampProvider] = []

public init(
provider: ExpressAPIProvider,
onrampRepository: OnrampRepository,
logger: Logger
) {
self.provider = provider
self.onrampRepository = onrampRepository
self.logger = logger
}
}

// MARK: - OnrampManager

extension CommonOnrampManager: OnrampManager {
public func updateCountry() async throws -> OnrampCountry {
// Define country by ip or get from repository
// https://tangem.atlassian.net/browse/IOS-8267

throw OnrampManagerError.notImplement
}

public func updatePaymentMethod() async throws -> OnrampPaymentMethod {
// Load payment methods
// Or get it from repository (?)
throw OnrampManagerError.notImplement
}

public func update(pair: OnrampPair) async throws -> [OnrampProvider] {
// Load providers from API
// Make provides
// Save providers
throw OnrampManagerError.notImplement
}

public func update(amount: Decimal) async throws -> [OnrampProvider] {
for provider in _providers {
_ = await provider.manager.update(amount: amount)
}

return _providers
}

public func loadOnrampData(request: OnrampQuotesRequest) async throws -> OnrampRedirectData {
// Load data from API
throw OnrampManagerError.notImplement
}
}
28 changes: 28 additions & 0 deletions TangemExpress/Manager/OnrampManager/OnrampManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// OnrampManager.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public protocol OnrampManager {
// Load country by IP or get from repository
func updateCountry() async throws -> OnrampCountry

// Load methods
func updatePaymentMethod() async throws -> OnrampPaymentMethod

// User did choose country. We prepare providers
func update(pair: OnrampPair) async throws -> [OnrampProvider]

// User did change amount. We load quotes providers
func update(amount: Decimal) async throws -> [OnrampProvider]

// load data to make onramp
func loadOnrampData(request: OnrampQuotesRequest) async throws -> OnrampRedirectData
}

public enum OnrampManagerError: LocalizedError {
case notImplement
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// OnrampProviderManager.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

// For every onramp provider
public protocol OnrampProviderManager: Actor {
// Update quotes for amount
func update(amount: Decimal) async -> OnrampProviderManagerState

// Get actual state
func state() -> OnrampProviderManagerState
}

public enum OnrampProviderManagerState: Hashable {
case created
case loading
case failed(error: String)
case loaded(quote: OnrampQuote)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// CommonOnrampRepository.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

class CommonOnrampRepository {
let provider: ExpressAPIProvider

init(provider: ExpressAPIProvider) {
self.provider = provider
}
}

// MARK: - OnrampRepository

// TODO: https://tangem.atlassian.net/browse/IOS-8268
// Add method to save values which user chose
extension CommonOnrampRepository: OnrampRepository {
var savedCountry: OnrampCountry? { nil }
var savedPaymentMethod: OnrampPaymentMethod? { nil }

func save(country: OnrampCountry) throws {}

func save(paymentMethod: OnrampPaymentMethod) throws {}
}
15 changes: 15 additions & 0 deletions TangemExpress/Manager/OnrampRepository/OnrampRepository.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// OnrampRepository.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public protocol OnrampRepository {
var savedCountry: OnrampCountry? { get }
var savedPaymentMethod: OnrampPaymentMethod? { get }

func save(country: OnrampCountry) throws
func save(paymentMethod: OnrampPaymentMethod) throws
}
19 changes: 19 additions & 0 deletions TangemExpress/Models/Onramp/OnrampCountry.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// OnrampCountry.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampCountry: Hashable {
public let identity: OnrampIdentity
public let currency: OnrampCurrency
public let onrampAvailable: Bool

public init(identity: OnrampIdentity, currency: OnrampCurrency, onrampAvailable: Bool) {
self.identity = identity
self.currency = currency
self.onrampAvailable = onrampAvailable
}
}
15 changes: 15 additions & 0 deletions TangemExpress/Models/Onramp/OnrampCurrency.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// OnrampCurrency.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampCurrency: Hashable {
public let identity: OnrampIdentity

public init(identity: OnrampIdentity) {
self.identity = identity
}
}
19 changes: 19 additions & 0 deletions TangemExpress/Models/Onramp/OnrampIdentity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// OnrampIdentity.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampIdentity: Hashable {
public let name: String
public let code: String
public let image: URL

public init(name: String, code: String, image: URL) {
self.name = name
self.code = code
self.image = image
}
}
30 changes: 30 additions & 0 deletions TangemExpress/Models/Onramp/OnrampPair.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// OnrampPair.swift
// TangemApp
//
// Created by Sergey Balashov on 02.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampPair {
public let item: ExpressWallet
public let currency: OnrampCurrency

public init(item: ExpressWallet, currency: OnrampCurrency) {
self.item = item
self.currency = currency
}
}

// MARK: - Hashable

extension OnrampPair: Hashable {
public static func == (lhs: OnrampPair, rhs: OnrampPair) -> Bool {
lhs.hashValue == rhs.hashValue
}

public func hash(into hasher: inout Hasher) {
hasher.combine(item.expressCurrency)
hasher.combine(currency)
}
}
9 changes: 9 additions & 0 deletions TangemExpress/Models/Onramp/OnrampPaymentMethod.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// OnrampPaymentMethod.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampPaymentMethod: Hashable {}
11 changes: 11 additions & 0 deletions TangemExpress/Models/Onramp/OnrampProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// OnrampProvider.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampProvider {
public let manager: OnrampProviderManager
}
9 changes: 9 additions & 0 deletions TangemExpress/Models/Onramp/OnrampQuote.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// OnrampQuote.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampQuote: Hashable {}
26 changes: 26 additions & 0 deletions TangemExpress/Models/Onramp/OnrampQuotesRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// OnrampQuotesRequest.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampQuotesRequest: Hashable {
public let pair: OnrampPair
public let providerId: String
public let paymentMethod: OnrampPaymentMethod
public let amount: Decimal

public init(
pair: OnrampPair,
providerId: String,
paymentMethod: OnrampPaymentMethod,
amount: Decimal
) {
self.pair = pair
self.providerId = providerId
self.paymentMethod = paymentMethod
self.amount = amount
}
}
11 changes: 11 additions & 0 deletions TangemExpress/Models/Onramp/OnrampRedirectData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//
// OnrampRedirectData.swift
// TangemApp
//
// Created by Sergey Balashov on 14.10.2024.
// Copyright © 2024 Tangem AG. All rights reserved.
//

public struct OnrampRedirectData: Hashable {
let successURL: URL
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 76f028f

Please sign in to comment.