Updated on 2026-08-14
This commit is contained in:
parent
e6b4d2ae7b
commit
c2625a0de7
7 changed files with 29 additions and 12 deletions
|
|
@ -9,7 +9,6 @@ import com.tangem.core.error.UniversalError
|
||||||
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
import com.tangem.data.common.currency.CryptoCurrencyFactory
|
||||||
import com.tangem.data.common.network.NetworkFactory
|
import com.tangem.data.common.network.NetworkFactory
|
||||||
import com.tangem.data.pay.util.TangemPayErrorConverter
|
import com.tangem.data.pay.util.TangemPayErrorConverter
|
||||||
import com.tangem.data.pay.util.TangemPayWalletsManager
|
|
||||||
import com.tangem.datasource.di.NetworkMoshi
|
import com.tangem.datasource.di.NetworkMoshi
|
||||||
import com.tangem.domain.models.ReceiveAddressModel
|
import com.tangem.domain.models.ReceiveAddressModel
|
||||||
import com.tangem.domain.models.ReceiveAddressModel.NameService
|
import com.tangem.domain.models.ReceiveAddressModel.NameService
|
||||||
|
|
@ -32,7 +31,6 @@ private const val TOKEN_DECIMALS = 6
|
||||||
|
|
||||||
internal class DefaultTangemPaySwapDataFactory @Inject constructor(
|
internal class DefaultTangemPaySwapDataFactory @Inject constructor(
|
||||||
@NetworkMoshi moshi: Moshi,
|
@NetworkMoshi moshi: Moshi,
|
||||||
private val tangemPayWalletsManager: TangemPayWalletsManager,
|
|
||||||
excludedBlockchains: ExcludedBlockchains,
|
excludedBlockchains: ExcludedBlockchains,
|
||||||
) : TangemPaySwapDataFactory {
|
) : TangemPaySwapDataFactory {
|
||||||
|
|
||||||
|
|
@ -63,17 +61,17 @@ internal class DefaultTangemPaySwapDataFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun create(
|
override fun create(
|
||||||
|
userWallet: UserWallet,
|
||||||
depositAddress: String,
|
depositAddress: String,
|
||||||
chainId: Int,
|
chainId: Int,
|
||||||
cryptoBalance: BigDecimal,
|
cryptoBalance: BigDecimal,
|
||||||
fiatBalance: BigDecimal,
|
fiatBalance: BigDecimal,
|
||||||
): Either<UniversalError, TangemPayTopUpData> {
|
): Either<UniversalError, TangemPayTopUpData> {
|
||||||
return catch {
|
return catch {
|
||||||
val wallet = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking()
|
val currency = getCurrency(userWallet, chainId)
|
||||||
val currency = getCurrency(wallet, chainId)
|
|
||||||
TangemPayTopUpData(
|
TangemPayTopUpData(
|
||||||
currency = currency,
|
currency = currency,
|
||||||
walletId = wallet.walletId,
|
walletId = userWallet.walletId,
|
||||||
cryptoBalance = cryptoBalance,
|
cryptoBalance = cryptoBalance,
|
||||||
fiatBalance = fiatBalance,
|
fiatBalance = fiatBalance,
|
||||||
depositAddress = depositAddress,
|
depositAddress = depositAddress,
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ import com.tangem.domain.visa.model.TangemPayAuthTokens
|
||||||
import com.tangem.domain.visa.model.getAuthHeader
|
import com.tangem.domain.visa.model.getAuthHeader
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ internal class TangemPayRequestPerformer @Inject constructor(
|
||||||
private val tangemPayStorage: TangemPayStorage,
|
private val tangemPayStorage: TangemPayStorage,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val customerWalletAddress = MutableStateFlow<String?>(null)
|
private val customerWalletAddresses = ConcurrentHashMap<UserWalletId, String>()
|
||||||
private val tokensMutex = Mutex()
|
private val tokensMutex = Mutex()
|
||||||
private val errorConverter = TangemPayErrorConverter(moshi)
|
private val errorConverter = TangemPayErrorConverter(moshi)
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ internal class TangemPayRequestPerformer @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getCustomerWalletAddress(userWalletId: UserWalletId): String {
|
suspend fun getCustomerWalletAddress(userWalletId: UserWalletId): String {
|
||||||
val existingAddress = customerWalletAddress.value
|
val existingAddress = customerWalletAddresses[userWalletId]
|
||||||
if (existingAddress != null) {
|
if (existingAddress != null) {
|
||||||
return existingAddress
|
return existingAddress
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ internal class TangemPayRequestPerformer @Inject constructor(
|
||||||
userWalletId = userWalletId,
|
userWalletId = userWalletId,
|
||||||
) ?: error("Can not find customer address")
|
) ?: error("Can not find customer address")
|
||||||
|
|
||||||
customerWalletAddress.value = storedAddress
|
customerWalletAddresses[userWalletId] = storedAddress
|
||||||
return storedAddress
|
return storedAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,14 @@ class TangemPayWalletsManager @Inject constructor(
|
||||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@Deprecated("Don't use and put userWallet in features that need it")
|
||||||
suspend fun getDefaultWalletForTangemPay(): UserWallet.Cold {
|
suspend fun getDefaultWalletForTangemPay(): UserWallet.Cold {
|
||||||
val userWalletsFlow = if (useNewRepository()) repository.userWallets else manager.userWallets
|
val userWalletsFlow = if (useNewRepository()) repository.userWallets else manager.userWallets
|
||||||
val userWallets = userWalletsFlow.filter { !it.isNullOrEmpty() }.first()
|
val userWallets = userWalletsFlow.filter { !it.isNullOrEmpty() }.first()
|
||||||
return findColdWallet(userWallets)
|
return findColdWallet(userWallets)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Don't use and put userWallet in features that need it")
|
||||||
fun getDefaultWalletForTangemPayBlocking(): UserWallet.Cold {
|
fun getDefaultWalletForTangemPayBlocking(): UserWallet.Cold {
|
||||||
val userWallets = if (useNewRepository()) repository.userWallets.value else manager.userWalletsSync
|
val userWallets = if (useNewRepository()) repository.userWallets.value else manager.userWalletsSync
|
||||||
return findColdWallet(userWallets)
|
return findColdWallet(userWallets)
|
||||||
|
|
@ -29,7 +31,9 @@ class TangemPayWalletsManager @Inject constructor(
|
||||||
private fun useNewRepository(): Boolean = hotWalletFeatureToggles.isHotWalletEnabled
|
private fun useNewRepository(): Boolean = hotWalletFeatureToggles.isHotWalletEnabled
|
||||||
|
|
||||||
private fun findColdWallet(userWallets: List<UserWallet>?): UserWallet.Cold {
|
private fun findColdWallet(userWallets: List<UserWallet>?): UserWallet.Cold {
|
||||||
return userWallets?.find { it is UserWallet.Cold } as? UserWallet.Cold
|
return userWallets?.find {
|
||||||
|
it is UserWallet.Cold && it.isMultiCurrency
|
||||||
|
} as? UserWallet.Cold
|
||||||
?: error("Cannot find cold user wallet")
|
?: error("Cannot find cold user wallet")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,12 +4,14 @@ import arrow.core.Either
|
||||||
import com.tangem.core.error.UniversalError
|
import com.tangem.core.error.UniversalError
|
||||||
import com.tangem.domain.models.ReceiveAddressModel
|
import com.tangem.domain.models.ReceiveAddressModel
|
||||||
import com.tangem.domain.models.currency.CryptoCurrency
|
import com.tangem.domain.models.currency.CryptoCurrency
|
||||||
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
import com.tangem.domain.models.wallet.UserWalletId
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
|
|
||||||
interface TangemPaySwapDataFactory {
|
interface TangemPaySwapDataFactory {
|
||||||
|
|
||||||
fun create(
|
fun create(
|
||||||
|
userWallet: UserWallet,
|
||||||
depositAddress: String,
|
depositAddress: String,
|
||||||
chainId: Int,
|
chainId: Int,
|
||||||
cryptoBalance: BigDecimal,
|
cryptoBalance: BigDecimal,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.tangem.core.decompose.di.ModelScoped
|
||||||
import com.tangem.core.decompose.model.Model
|
import com.tangem.core.decompose.model.Model
|
||||||
import com.tangem.core.decompose.model.ParamsContainer
|
import com.tangem.core.decompose.model.ParamsContainer
|
||||||
import com.tangem.domain.pay.TangemPaySwapDataFactory
|
import com.tangem.domain.pay.TangemPaySwapDataFactory
|
||||||
|
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||||
import com.tangem.features.tangempay.components.TangemPayAddFundsComponent
|
import com.tangem.features.tangempay.components.TangemPayAddFundsComponent
|
||||||
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
import com.tangem.features.tangempay.entity.TangemPayAddFundsUM
|
||||||
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
|
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
|
||||||
|
|
@ -17,6 +18,7 @@ internal class TangemPayAddFundsModel @Inject constructor(
|
||||||
paramsContainer: ParamsContainer,
|
paramsContainer: ParamsContainer,
|
||||||
override val dispatchers: CoroutineDispatcherProvider,
|
override val dispatchers: CoroutineDispatcherProvider,
|
||||||
private val tangemPaySwapDataFactory: TangemPaySwapDataFactory,
|
private val tangemPaySwapDataFactory: TangemPaySwapDataFactory,
|
||||||
|
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||||
) : Model() {
|
) : Model() {
|
||||||
|
|
||||||
private val params = paramsContainer.require<TangemPayAddFundsComponent.Params>()
|
private val params = paramsContainer.require<TangemPayAddFundsComponent.Params>()
|
||||||
|
|
@ -24,7 +26,11 @@ internal class TangemPayAddFundsModel @Inject constructor(
|
||||||
val uiState: TangemPayAddFundsUM = getInitialState()
|
val uiState: TangemPayAddFundsUM = getInitialState()
|
||||||
|
|
||||||
private fun getInitialState(): TangemPayAddFundsUM {
|
private fun getInitialState(): TangemPayAddFundsUM {
|
||||||
|
val userWallet = requireNotNull(
|
||||||
|
getUserWalletUseCase(params.walletId).getOrNull(),
|
||||||
|
) { "User wallet not found for id: ${params.walletId}" }
|
||||||
val data = tangemPaySwapDataFactory.create(
|
val data = tangemPaySwapDataFactory.create(
|
||||||
|
userWallet = userWallet,
|
||||||
depositAddress = params.depositAddress,
|
depositAddress = params.depositAddress,
|
||||||
chainId = params.chainId,
|
chainId = params.chainId,
|
||||||
cryptoBalance = params.cryptoBalance,
|
cryptoBalance = params.cryptoBalance,
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,15 @@ import com.tangem.core.ui.extensions.resourceReference
|
||||||
import com.tangem.core.ui.message.SnackbarMessage
|
import com.tangem.core.ui.message.SnackbarMessage
|
||||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||||
import com.tangem.domain.models.TokenReceiveConfig
|
import com.tangem.domain.models.TokenReceiveConfig
|
||||||
import com.tangem.domain.pay.TangemPayTopUpData
|
|
||||||
import com.tangem.domain.pay.TangemPaySwapDataFactory
|
import com.tangem.domain.pay.TangemPaySwapDataFactory
|
||||||
|
import com.tangem.domain.pay.TangemPayTopUpData
|
||||||
import com.tangem.domain.pay.model.TangemPayCardBalance
|
import com.tangem.domain.pay.model.TangemPayCardBalance
|
||||||
import com.tangem.domain.pay.repository.CustomerOrderRepository
|
import com.tangem.domain.pay.repository.CustomerOrderRepository
|
||||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||||
import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
||||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||||
|
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||||
import com.tangem.features.tangempay.TangemPayConstants
|
import com.tangem.features.tangempay.TangemPayConstants
|
||||||
import com.tangem.features.tangempay.components.AddFundsListener
|
import com.tangem.features.tangempay.components.AddFundsListener
|
||||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||||
|
|
@ -55,7 +56,7 @@ import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList", "LargeClass")
|
||||||
@Stable
|
@Stable
|
||||||
@ModelScoped
|
@ModelScoped
|
||||||
internal class TangemPayDetailsModel @Inject constructor(
|
internal class TangemPayDetailsModel @Inject constructor(
|
||||||
|
|
@ -71,6 +72,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
||||||
private val txHistoryUpdateListener: TangemPayTxHistoryUpdateListener,
|
private val txHistoryUpdateListener: TangemPayTxHistoryUpdateListener,
|
||||||
private val tangemPaySwapDataFactory: TangemPaySwapDataFactory,
|
private val tangemPaySwapDataFactory: TangemPaySwapDataFactory,
|
||||||
private val orderRepository: CustomerOrderRepository,
|
private val orderRepository: CustomerOrderRepository,
|
||||||
|
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||||
) : Model(), TangemPayTxHistoryUiActions, TangemPayDetailIntents, AddFundsListener {
|
) : Model(), TangemPayTxHistoryUiActions, TangemPayDetailIntents, AddFundsListener {
|
||||||
|
|
||||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||||
|
|
@ -234,7 +236,11 @@ internal class TangemPayDetailsModel @Inject constructor(
|
||||||
if (hasActiveWithdrawal) {
|
if (hasActiveWithdrawal) {
|
||||||
showBottomSheetError(TangemPayDetailsErrorType.WithdrawInProgress)
|
showBottomSheetError(TangemPayDetailsErrorType.WithdrawInProgress)
|
||||||
} else {
|
} else {
|
||||||
|
val userWallet = requireNotNull(
|
||||||
|
getUserWalletUseCase(params.userWalletId).getOrNull(),
|
||||||
|
) { "User wallet not found: ${params.userWalletId}" }
|
||||||
val data = tangemPaySwapDataFactory.create(
|
val data = tangemPaySwapDataFactory.create(
|
||||||
|
userWallet = userWallet,
|
||||||
depositAddress = depositAddress,
|
depositAddress = depositAddress,
|
||||||
chainId = params.config.chainId,
|
chainId = params.config.chainId,
|
||||||
cryptoBalance = currentBalance.cryptoBalance,
|
cryptoBalance = currentBalance.cryptoBalance,
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ internal class TangemPayMainSubscriber @AssistedInject constructor(
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.onEach { data ->
|
.onEach { data ->
|
||||||
val userWalletId = userWallet.walletId
|
val userWalletId = userWallet.walletId
|
||||||
|
Timber.tag("scan===").e("onEach $userWalletId $data")
|
||||||
val mainInfoData = data[userWalletId] ?: return@onEach
|
val mainInfoData = data[userWalletId] ?: return@onEach
|
||||||
mainInfoData.onLeft { tangemPayError ->
|
mainInfoData.onLeft { tangemPayError ->
|
||||||
when (tangemPayError) {
|
when (tangemPayError) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue