Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-08 12:37:31 +03:00
parent e6b4d2ae7b
commit c2625a0de7
7 changed files with 29 additions and 12 deletions

View file

@ -9,7 +9,6 @@ import com.tangem.core.error.UniversalError
import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.data.common.network.NetworkFactory
import com.tangem.data.pay.util.TangemPayErrorConverter
import com.tangem.data.pay.util.TangemPayWalletsManager
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.domain.models.ReceiveAddressModel
import com.tangem.domain.models.ReceiveAddressModel.NameService
@ -32,7 +31,6 @@ private const val TOKEN_DECIMALS = 6
internal class DefaultTangemPaySwapDataFactory @Inject constructor(
@NetworkMoshi moshi: Moshi,
private val tangemPayWalletsManager: TangemPayWalletsManager,
excludedBlockchains: ExcludedBlockchains,
) : TangemPaySwapDataFactory {
@ -63,17 +61,17 @@ internal class DefaultTangemPaySwapDataFactory @Inject constructor(
}
override fun create(
userWallet: UserWallet,
depositAddress: String,
chainId: Int,
cryptoBalance: BigDecimal,
fiatBalance: BigDecimal,
): Either<UniversalError, TangemPayTopUpData> {
return catch {
val wallet = tangemPayWalletsManager.getDefaultWalletForTangemPayBlocking()
val currency = getCurrency(wallet, chainId)
val currency = getCurrency(userWallet, chainId)
TangemPayTopUpData(
currency = currency,
walletId = wallet.walletId,
walletId = userWallet.walletId,
cryptoBalance = cryptoBalance,
fiatBalance = fiatBalance,
depositAddress = depositAddress,

View file

@ -21,11 +21,11 @@ import com.tangem.domain.visa.model.TangemPayAuthTokens
import com.tangem.domain.visa.model.getAuthHeader
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Singleton
@ -40,7 +40,7 @@ internal class TangemPayRequestPerformer @Inject constructor(
private val tangemPayStorage: TangemPayStorage,
) {
private val customerWalletAddress = MutableStateFlow<String?>(null)
private val customerWalletAddresses = ConcurrentHashMap<UserWalletId, String>()
private val tokensMutex = Mutex()
private val errorConverter = TangemPayErrorConverter(moshi)
@ -110,7 +110,7 @@ internal class TangemPayRequestPerformer @Inject constructor(
}
suspend fun getCustomerWalletAddress(userWalletId: UserWalletId): String {
val existingAddress = customerWalletAddress.value
val existingAddress = customerWalletAddresses[userWalletId]
if (existingAddress != null) {
return existingAddress
}
@ -118,7 +118,7 @@ internal class TangemPayRequestPerformer @Inject constructor(
userWalletId = userWalletId,
) ?: error("Can not find customer address")
customerWalletAddress.value = storedAddress
customerWalletAddresses[userWalletId] = storedAddress
return storedAddress
}

View file

@ -15,12 +15,14 @@ class TangemPayWalletsManager @Inject constructor(
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
) {
@Deprecated("Don't use and put userWallet in features that need it")
suspend fun getDefaultWalletForTangemPay(): UserWallet.Cold {
val userWalletsFlow = if (useNewRepository()) repository.userWallets else manager.userWallets
val userWallets = userWalletsFlow.filter { !it.isNullOrEmpty() }.first()
return findColdWallet(userWallets)
}
@Deprecated("Don't use and put userWallet in features that need it")
fun getDefaultWalletForTangemPayBlocking(): UserWallet.Cold {
val userWallets = if (useNewRepository()) repository.userWallets.value else manager.userWalletsSync
return findColdWallet(userWallets)
@ -29,7 +31,9 @@ class TangemPayWalletsManager @Inject constructor(
private fun useNewRepository(): Boolean = hotWalletFeatureToggles.isHotWalletEnabled
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")
}
}

View file

@ -4,12 +4,14 @@ import arrow.core.Either
import com.tangem.core.error.UniversalError
import com.tangem.domain.models.ReceiveAddressModel
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import java.math.BigDecimal
interface TangemPaySwapDataFactory {
fun create(
userWallet: UserWallet,
depositAddress: String,
chainId: Int,
cryptoBalance: BigDecimal,

View file

@ -5,6 +5,7 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
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.entity.TangemPayAddFundsUM
import com.tangem.features.tangempay.model.transformers.TangemPayAddFundsUMConverter
@ -17,6 +18,7 @@ internal class TangemPayAddFundsModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
private val tangemPaySwapDataFactory: TangemPaySwapDataFactory,
private val getUserWalletUseCase: GetUserWalletUseCase,
) : Model() {
private val params = paramsContainer.require<TangemPayAddFundsComponent.Params>()
@ -24,7 +26,11 @@ internal class TangemPayAddFundsModel @Inject constructor(
val uiState: TangemPayAddFundsUM = getInitialState()
private fun getInitialState(): TangemPayAddFundsUM {
val userWallet = requireNotNull(
getUserWalletUseCase(params.walletId).getOrNull(),
) { "User wallet not found for id: ${params.walletId}" }
val data = tangemPaySwapDataFactory.create(
userWallet = userWallet,
depositAddress = params.depositAddress,
chainId = params.chainId,
cryptoBalance = params.cryptoBalance,

View file

@ -18,14 +18,15 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.models.TokenReceiveConfig
import com.tangem.domain.pay.TangemPayTopUpData
import com.tangem.domain.pay.TangemPaySwapDataFactory
import com.tangem.domain.pay.TangemPayTopUpData
import com.tangem.domain.pay.model.TangemPayCardBalance
import com.tangem.domain.pay.repository.CustomerOrderRepository
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
import com.tangem.domain.visa.model.TangemPayCardFrozenState
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.components.AddFundsListener
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
@ -55,7 +56,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@Suppress("LongParameterList", "LargeClass")
@Stable
@ModelScoped
internal class TangemPayDetailsModel @Inject constructor(
@ -71,6 +72,7 @@ internal class TangemPayDetailsModel @Inject constructor(
private val txHistoryUpdateListener: TangemPayTxHistoryUpdateListener,
private val tangemPaySwapDataFactory: TangemPaySwapDataFactory,
private val orderRepository: CustomerOrderRepository,
private val getUserWalletUseCase: GetUserWalletUseCase,
) : Model(), TangemPayTxHistoryUiActions, TangemPayDetailIntents, AddFundsListener {
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
@ -234,7 +236,11 @@ internal class TangemPayDetailsModel @Inject constructor(
if (hasActiveWithdrawal) {
showBottomSheetError(TangemPayDetailsErrorType.WithdrawInProgress)
} else {
val userWallet = requireNotNull(
getUserWalletUseCase(params.userWalletId).getOrNull(),
) { "User wallet not found: ${params.userWalletId}" }
val data = tangemPaySwapDataFactory.create(
userWallet = userWallet,
depositAddress = depositAddress,
chainId = params.config.chainId,
cryptoBalance = currentBalance.cryptoBalance,

View file

@ -46,6 +46,7 @@ internal class TangemPayMainSubscriber @AssistedInject constructor(
.distinctUntilChanged()
.onEach { data ->
val userWalletId = userWallet.walletId
Timber.tag("scan===").e("onEach $userWalletId $data")
val mainInfoData = data[userWalletId] ?: return@onEach
mainInfoData.onLeft { tangemPayError ->
when (tangemPayError) {