Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-14 17:11:22 +03:00
parent 76209eb454
commit 64d429f642
15 changed files with 120 additions and 110 deletions

View file

@ -23,6 +23,7 @@ dependencies {
implementation(projects.domain.models) implementation(projects.domain.models)
implementation(projects.domain.wallets.models) implementation(projects.domain.wallets.models)
implementation(projects.domain.appCurrency.models) implementation(projects.domain.appCurrency.models)
implementation(projects.domain.tokens.models)
/** Project - Utils */ /** Project - Utils */
implementation(projects.core.utils) implementation(projects.core.utils)

View file

@ -43,11 +43,9 @@ internal class DefaultVisaRepository @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider, private val dispatchers: CoroutineDispatcherProvider,
private val visaApiRequestMaker: VisaApiRequestMaker, private val visaApiRequestMaker: VisaApiRequestMaker,
private val visaApi: TangemVisaApi, private val visaApi: TangemVisaApi,
private val visaCurrencyFactory: VisaCurrencyFactory,
) : VisaRepository { ) : VisaRepository {
private val currencyFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
VisaCurrencyFactory()
}
private val txDetailsFactory by lazy(mode = LazyThreadSafetyMode.NONE) { private val txDetailsFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
VisaTxDetailsFactory() VisaTxDetailsFactory()
} }
@ -79,20 +77,22 @@ internal class DefaultVisaRepository @Inject constructor(
private suspend fun fetchVisaCurrency(userWalletId: UserWalletId, address: String) { private suspend fun fetchVisaCurrency(userWalletId: UserWalletId, address: String) {
val contractInfoProvider = visaLibLoader.getOrCreateProvider() val contractInfoProvider = visaLibLoader.getOrCreateProvider()
val paymentAccountAddress = getPaymentAccountAddress(userWalletId)
val userWallet = findVisaUserWallet(userWalletId)
parZip( parZip(
dispatchers.io, dispatchers.io,
{ {
contractInfoProvider.getContractInfo( contractInfoProvider.getContractInfo(
walletAddress = address, walletAddress = address,
paymentAccountAddress = getPaymentAccountAddress(userWalletId), paymentAccountAddress = paymentAccountAddress,
) )
}, },
{ getFiatRate() }, { getFiatRate() },
{ contractInfo, fiatRate -> { contractInfo, fiatRate ->
fetchedCurrencies.update { value -> fetchedCurrencies.update { value ->
value.apply { value.apply {
put(address, currencyFactory.create(contractInfo, fiatRate)) put(address, visaCurrencyFactory.create(userWallet, contractInfo, fiatRate))
} }
} }
}, },
@ -157,7 +157,7 @@ internal class DefaultVisaRepository @Inject constructor(
) )
} }
// TODO select correct account when multiple accounts are available (will be implemented when backend is ready) // There will be only one payment account (backend has filtered for us), so we can take the first one
customerInfo.paymentAccounts.firstOrNull()?.paymentAccountAddress customerInfo.paymentAccounts.firstOrNull()?.paymentAccountAddress
}.getOrNull() }.getOrNull()
@ -187,14 +187,14 @@ internal class DefaultVisaRepository @Inject constructor(
} }
} }
private suspend fun getFiatRate(): BigDecimal? { private suspend fun getFiatRate(): BigDecimal {
val fiatCurrencyId = VisaConstants.fiatCurrency.code.lowercase() val fiatCurrencyId = VisaConstants.fiatCurrency.code.lowercase()
val quotes = tangemTechApi.getQuotes( val quotes = tangemTechApi.getQuotes(
currencyId = fiatCurrencyId, currencyId = fiatCurrencyId,
coinIds = VisaConstants.TOKEN_ID, coinIds = VisaConstants.TOKEN_ID,
).getOrThrow() ).getOrThrow()
return quotes.quotes[VisaConstants.TOKEN_ID]?.price return quotes.quotes[VisaConstants.TOKEN_ID]?.price ?: error("No price found")
} }
private fun makeWalletAddresses(userWallet: UserWallet): Set<Address> { private fun makeWalletAddresses(userWallet: UserWallet): Set<Address> {

View file

@ -1,16 +1,28 @@
package com.tangem.data.visa.utils package com.tangem.data.visa.utils
import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
import com.tangem.data.common.currency.CryptoCurrencyFactory
import com.tangem.data.common.currency.getNetwork
import com.tangem.domain.common.util.derivationStyleProvider
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.NetworkAddress
import com.tangem.domain.visa.model.VisaCurrency import com.tangem.domain.visa.model.VisaCurrency
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.lib.visa.model.VisaContractInfo import com.tangem.lib.visa.model.VisaContractInfo
import org.joda.time.DateTime import org.joda.time.DateTime
import org.joda.time.DateTimeZone import org.joda.time.DateTimeZone
import org.joda.time.Instant import org.joda.time.Instant
import java.math.BigDecimal import java.math.BigDecimal
import java.math.BigInteger import java.math.BigInteger
import javax.inject.Inject
internal class VisaCurrencyFactory { internal class VisaCurrencyFactory @Inject constructor(
private val cryptoCurrencyFactory: CryptoCurrencyFactory,
private val excludedBlockchains: ExcludedBlockchains,
) {
fun create(contractInfo: VisaContractInfo, fiatRate: BigDecimal?): VisaCurrency { fun create(userWallet: UserWallet, contractInfo: VisaContractInfo, fiatRate: BigDecimal): VisaCurrency {
val now = Instant.now() val now = Instant.now()
val currentLimit = if (contractInfo.limitsChangeDate > now) { val currentLimit = if (contractInfo.limitsChangeDate > now) {
contractInfo.oldLimits contractInfo.oldLimits
@ -19,11 +31,30 @@ internal class VisaCurrencyFactory {
} }
val remainingOtpLimit = getRemainingOtp(currentLimit, now) val remainingOtpLimit = getRemainingOtp(currentLimit, now)
val currencyNetwork = getNetwork(
blockchain = Blockchain.Polygon,
extraDerivationPath = null,
derivationStyleProvider = userWallet.scanResponse.derivationStyleProvider,
excludedBlockchains = excludedBlockchains,
canHandleTokens = true,
) ?: error("Unable to create network for Visa currency")
val cryptoCurrency = cryptoCurrencyFactory.createToken(
network = currencyNetwork,
rawId = CryptoCurrency.RawID(VisaConstants.TOKEN_ID),
name = contractInfo.token.name,
symbol = contractInfo.token.symbol,
decimals = contractInfo.token.decimals,
contractAddress = contractInfo.token.address,
)
return VisaCurrency( return VisaCurrency(
cryptoCurrency = cryptoCurrency,
symbol = contractInfo.token.symbol, symbol = contractInfo.token.symbol,
networkName = VisaConstants.NETWORK_NAME, networkName = VisaConstants.NETWORK_NAME,
decimals = contractInfo.token.decimals, decimals = contractInfo.token.decimals,
fiatRate = fiatRate, fiatRate = fiatRate,
priceChange = BigDecimal.ZERO, // [Second Visa Iteration] pass to create() params if needed
fiatCurrency = VisaConstants.fiatCurrency, fiatCurrency = VisaConstants.fiatCurrency,
balances = with(contractInfo) { balances = with(contractInfo) {
VisaCurrency.Balances( VisaCurrency.Balances(
@ -40,6 +71,12 @@ internal class VisaCurrencyFactory {
singleTransaction = currentLimit.singleTransactionLimit, singleTransaction = currentLimit.singleTransactionLimit,
expirationDate = getLimitsExpirationDate(currentLimit, now), expirationDate = getLimitsExpirationDate(currentLimit, now),
), ),
paymentAccountAddress = NetworkAddress.Single(
NetworkAddress.Address(
value = contractInfo.paymentAccountAddress,
type = NetworkAddress.Address.Type.Primary,
),
),
) )
} }

View file

@ -1,17 +1,22 @@
package com.tangem.domain.visa.model package com.tangem.domain.visa.model
import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.NetworkAddress
import org.joda.time.DateTime import org.joda.time.DateTime
import java.math.BigDecimal import java.math.BigDecimal
data class VisaCurrency( data class VisaCurrency(
val cryptoCurrency: CryptoCurrency,
val networkName: String, val networkName: String,
val symbol: String, val symbol: String,
val decimals: Int, val decimals: Int,
val fiatRate: BigDecimal?, val fiatRate: BigDecimal,
val priceChange: BigDecimal,
val fiatCurrency: AppCurrency, val fiatCurrency: AppCurrency,
val balances: Balances, val balances: Balances,
val limits: Limits, val limits: Limits,
val paymentAccountAddress: NetworkAddress,
) { ) {
data class Balances( data class Balances(

View file

@ -2,29 +2,19 @@ package com.tangem.feature.wallet.child.wallet.model.intents
import arrow.core.getOrElse import arrow.core.getOrElse
import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.tokenreceive.mapToAddressModels
import com.tangem.domain.tokens.GetCryptoCurrencyStatusSyncUseCase
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.visa.GetVisaCurrencyUseCase import com.tangem.domain.visa.GetVisaCurrencyUseCase
import com.tangem.domain.visa.GetVisaTxDetailsUseCase import com.tangem.domain.visa.GetVisaTxDetailsUseCase
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.BalancesAndLimitsBottomSheetConverter import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.BalancesAndLimitsBottomSheetConverter
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.VisaTxDetailsBottomSheetConverter import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.VisaTxDetailsBottomSheetConverter
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
internal interface VisaWalletIntents { internal interface VisaWalletIntents {
fun onDepositClick()
fun onBalancesAndLimitsClick() fun onBalancesAndLimitsClick()
fun onVisaTransactionClick(id: String) fun onVisaTransactionClick(id: String)
@ -36,7 +26,6 @@ internal interface VisaWalletIntents {
internal class VisaWalletIntentsImplementor @Inject constructor( internal class VisaWalletIntentsImplementor @Inject constructor(
private val stateController: WalletStateController, private val stateController: WalletStateController,
private val eventSender: WalletEventSender, private val eventSender: WalletEventSender,
private val getCurrencyStatusUseCase: GetCryptoCurrencyStatusSyncUseCase,
private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase, private val getVisaCurrencyUseCase: GetVisaCurrencyUseCase,
private val getVisaTxDetailsUseCase: GetVisaTxDetailsUseCase, private val getVisaTxDetailsUseCase: GetVisaTxDetailsUseCase,
private val dispatchers: CoroutineDispatcherProvider, private val dispatchers: CoroutineDispatcherProvider,
@ -46,38 +35,6 @@ internal class VisaWalletIntentsImplementor @Inject constructor(
BalancesAndLimitsBottomSheetConverter(eventSender) BalancesAndLimitsBottomSheetConverter(eventSender)
} }
override fun onDepositClick() {
val userWalletId = stateController.getSelectedWalletId()
modelScope.launch(dispatchers.main) {
val currencyStatus = getPrimaryCurrencyStatus(userWalletId) ?: return@launch
createReceiveBottomSheetContent(currencyStatus)?.let { content ->
stateController.showBottomSheet(content)
}
}
}
private fun createReceiveBottomSheetContent(currencyStatus: CryptoCurrencyStatus): TangemBottomSheetConfigContent? {
val currency = currencyStatus.currency
val addresses = currencyStatus.value.networkAddress?.availableAddresses
if (addresses == null) {
Timber.e("Addresses should not be null")
return null
}
return TokenReceiveBottomSheetConfig(
name = currency.name,
symbol = currency.symbol,
network = currency.network.name,
addresses = addresses.mapToAddressModels(currency).toImmutableList(),
showMemoDisclaimer = currency.network.transactionExtrasType != Network.TransactionExtrasType.NONE,
onCopyClick = { /* no-op */ },
onShareClick = { /* no-op */ },
)
}
override fun onBalancesAndLimitsClick() { override fun onBalancesAndLimitsClick() {
modelScope.launch(dispatchers.main) { modelScope.launch(dispatchers.main) {
val userWalletId = stateController.getSelectedWalletId() val userWalletId = stateController.getSelectedWalletId()
@ -95,14 +52,6 @@ internal class VisaWalletIntentsImplementor @Inject constructor(
} }
} }
private suspend fun getPrimaryCurrencyStatus(userWalletId: UserWalletId): CryptoCurrencyStatus? {
return getCurrencyStatusUseCase(userWalletId)
.getOrElse {
Timber.e("Failed to get primary currency $it")
null
}
}
override fun onVisaTransactionClick(id: String) { override fun onVisaTransactionClick(id: String) {
modelScope.launch(dispatchers.main) { modelScope.launch(dispatchers.main) {
val userWalletId = stateController.getSelectedWalletId() val userWalletId = stateController.getSelectedWalletId()

View file

@ -1,6 +0,0 @@
package com.tangem.feature.wallet.presentation.wallet.state.model
internal data class DepositButtonState(
val isEnabled: Boolean,
val onClick: () -> Unit,
)

View file

@ -96,7 +96,6 @@ internal sealed interface WalletState : WalletStateHolder {
override val bottomSheetConfig: TangemBottomSheetConfig?, override val bottomSheetConfig: TangemBottomSheetConfig?,
override val balancesAndLimitBlockState: BalancesAndLimitsBlockState, override val balancesAndLimitBlockState: BalancesAndLimitsBlockState,
override val txHistoryState: TxHistoryState, override val txHistoryState: TxHistoryState,
val depositButtonState: DepositButtonState,
) : Visa() ) : Visa()
data class Locked( data class Locked(

View file

@ -3,7 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.wallet.presentation.wallet.state.model.BalancesAndLimitsBlockState import com.tangem.feature.wallet.presentation.wallet.state.model.BalancesAndLimitsBlockState
import com.tangem.feature.wallet.presentation.wallet.state.model.DepositButtonState
import com.tangem.feature.wallet.presentation.wallet.state.model.* import com.tangem.feature.wallet.presentation.wallet.state.model.*
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.mutate import kotlinx.collections.immutable.mutate
@ -29,8 +28,8 @@ internal class SetRefreshStateTransformer(
} }
is WalletState.Visa.Content -> { is WalletState.Visa.Content -> {
prevState.copy( prevState.copy(
buttons = prevState.buttons.toUpdatedState(),
pullToRefreshConfig = prevState.pullToRefreshConfig.toUpdatedState(isRefreshing), pullToRefreshConfig = prevState.pullToRefreshConfig.toUpdatedState(isRefreshing),
depositButtonState = prevState.depositButtonState.toUpdatedState(isRefreshing),
balancesAndLimitBlockState = prevState.balancesAndLimitBlockState.toUpdatedState(isRefreshing), balancesAndLimitBlockState = prevState.balancesAndLimitBlockState.toUpdatedState(isRefreshing),
) )
} }
@ -75,10 +74,6 @@ internal class SetRefreshStateTransformer(
} }
} }
private fun DepositButtonState.toUpdatedState(isRefreshing: Boolean): DepositButtonState {
return copy(isEnabled = !isRefreshing)
}
private fun BalancesAndLimitsBlockState.toUpdatedState(isRefreshing: Boolean): BalancesAndLimitsBlockState { private fun BalancesAndLimitsBlockState.toUpdatedState(isRefreshing: Boolean): BalancesAndLimitsBlockState {
return when (this) { return when (this) {
is BalancesAndLimitsBlockState.Content -> copy(isEnabled = !isRefreshing) is BalancesAndLimitsBlockState.Content -> copy(isEnabled = !isRefreshing)

View file

@ -7,6 +7,7 @@ import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.common.util.getCardsCount import com.tangem.domain.common.util.getCardsCount
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.visa.exception.RefreshTokenExpiredException import com.tangem.domain.visa.exception.RefreshTokenExpiredException
import com.tangem.domain.visa.model.VisaCurrency import com.tangem.domain.visa.model.VisaCurrency
import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWallet
@ -15,11 +16,14 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAdditiona
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletManageButton
import com.tangem.utils.extensions.isZero import com.tangem.utils.extensions.isZero
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import org.joda.time.DateTime import org.joda.time.DateTime
import org.joda.time.Days import org.joda.time.Days
internal class SetBalancesAndLimitsTransformer( internal class SetVisaInfoTransformer(
private val userWallet: UserWallet, private val userWallet: UserWallet,
private val maybeVisaCurrency: Either<Throwable, VisaCurrency>, private val maybeVisaCurrency: Either<Throwable, VisaCurrency>,
private val clickIntents: WalletClickIntents, private val clickIntents: WalletClickIntents,
@ -35,15 +39,15 @@ internal class SetBalancesAndLimitsTransformer(
} }
return prevState.copy( return prevState.copy(
buttons = createVisaButtonsDimmed(),
walletCardState = getErrorWalletCardState(prevState.walletCardState), walletCardState = getErrorWalletCardState(prevState.walletCardState),
depositButtonState = prevState.depositButtonState.copy(isEnabled = false),
balancesAndLimitBlockState = BalancesAndLimitsBlockState.Error, balancesAndLimitBlockState = BalancesAndLimitsBlockState.Error,
) )
} }
return prevState.copy( return prevState.copy(
buttons = createVisaButtons(visaCurrency = visaCurrency),
walletCardState = getContentWalletCardState(prevState.walletCardState, visaCurrency), walletCardState = getContentWalletCardState(prevState.walletCardState, visaCurrency),
depositButtonState = prevState.depositButtonState.copy(isEnabled = true),
balancesAndLimitBlockState = getContentBlockState(visaCurrency), balancesAndLimitBlockState = getContentBlockState(visaCurrency),
) )
} }
@ -115,4 +119,43 @@ internal class SetBalancesAndLimitsTransformer(
onUnlockVisaAccessNotificationClick = clickIntents::onUnlockVisaAccessClick, onUnlockVisaAccessNotificationClick = clickIntents::onUnlockVisaAccessClick,
) )
} }
private fun createVisaButtonsDimmed(): PersistentList<WalletManageButton> {
return persistentListOf(
WalletManageButton.Receive(enabled = true, dimContent = true, onClick = {}, onLongClick = null),
WalletManageButton.Buy(enabled = true, dimContent = true, onClick = {}),
)
}
private fun createVisaButtons(visaCurrency: VisaCurrency): PersistentList<WalletManageButton> {
// [Second Visa Iteration] Make VisaCurrency contain CryptoCurrencyStatus
val cryptoCurrencyStatus = CryptoCurrencyStatus(
currency = visaCurrency.cryptoCurrency,
value = CryptoCurrencyStatus.Loaded(
amount = visaCurrency.balances.available,
fiatAmount = visaCurrency.balances.available.multiply(visaCurrency.fiatRate),
fiatRate = visaCurrency.fiatRate,
priceChange = visaCurrency.priceChange,
yieldBalance = null,
hasCurrentNetworkTransactions = false,
pendingTransactions = emptySet(),
networkAddress = visaCurrency.paymentAccountAddress,
sources = CryptoCurrencyStatus.Sources(),
),
)
return return persistentListOf(
WalletManageButton.Receive(
enabled = true,
dimContent = false,
onClick = { clickIntents.onReceiveClick(cryptoCurrencyStatus = cryptoCurrencyStatus) },
onLongClick = { clickIntents.onCopyAddressLongClick(cryptoCurrencyStatus = cryptoCurrencyStatus) },
),
WalletManageButton.Buy(
enabled = true,
dimContent = false,
onClick = { clickIntents.onMultiWalletBuyClick(userWalletId = userWallet.walletId) },
),
)
}
} }

View file

@ -67,7 +67,7 @@ internal class WalletLoadingStateFactory(
return WalletState.Visa.Content( return WalletState.Visa.Content(
pullToRefreshConfig = createPullToRefreshConfig(), pullToRefreshConfig = createPullToRefreshConfig(),
walletCardState = userWallet.toLoadingWalletCardState(), walletCardState = userWallet.toLoadingWalletCardState(),
buttons = createMultiWalletActions(userWallet), buttons = createVisaDimmedButtons(),
warnings = persistentListOf(), warnings = persistentListOf(),
bottomSheetConfig = null, bottomSheetConfig = null,
balancesAndLimitBlockState = BalancesAndLimitsBlockState.Loading, balancesAndLimitBlockState = BalancesAndLimitsBlockState.Loading,
@ -76,7 +76,6 @@ internal class WalletLoadingStateFactory(
value = TxHistoryState.getDefaultLoadingTransactions(clickIntents::onExploreClick), value = TxHistoryState.getDefaultLoadingTransactions(clickIntents::onExploreClick),
), ),
), ),
depositButtonState = DepositButtonState(isEnabled = false, clickIntents::onDepositClick),
) )
} }
@ -117,6 +116,13 @@ internal class WalletLoadingStateFactory(
) )
} }
private fun createVisaDimmedButtons(): PersistentList<WalletManageButton> {
return persistentListOf(
WalletManageButton.Receive(enabled = true, dimContent = true, onClick = {}, onLongClick = null),
WalletManageButton.Buy(enabled = true, dimContent = true, onClick = {}),
)
}
private fun createDimmedButtons(): PersistentList<WalletManageButton> { private fun createDimmedButtons(): PersistentList<WalletManageButton> {
return persistentListOf( return persistentListOf(
WalletManageButton.Receive(enabled = true, dimContent = true, onClick = {}, onLongClick = null), WalletManageButton.Receive(enabled = true, dimContent = true, onClick = {}, onLongClick = null),

View file

@ -13,7 +13,7 @@ import com.tangem.domain.visa.model.VisaTxHistoryItem
import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetBalancesAndLimitsTransformer import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetVisaInfoTransformer
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTxHistoryCountTransformer import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTxHistoryCountTransformer
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTxHistoryItemsErrorTransformer import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTxHistoryItemsErrorTransformer
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTxHistoryItemsTransformer import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetTxHistoryItemsTransformer
@ -62,7 +62,7 @@ internal class VisaWalletSubscriber(
private fun setLoadedCurrencyState(maybeCurrency: Either<Throwable, VisaCurrency>) { private fun setLoadedCurrencyState(maybeCurrency: Either<Throwable, VisaCurrency>) {
stateController.update( stateController.update(
SetBalancesAndLimitsTransformer( SetVisaInfoTransformer(
userWallet = userWallet, userWallet = userWallet,
maybeVisaCurrency = maybeCurrency, maybeVisaCurrency = maybeCurrency,
clickIntents = clickIntents, clickIntents = clickIntents,

View file

@ -85,7 +85,6 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrenc
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.BalancesAndLimitsBottomSheet import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.BalancesAndLimitsBottomSheet
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.VisaTxDetailsBottomSheet import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.VisaTxDetailsBottomSheet
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.balancesAndLimitsBlock import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.balancesAndLimitsBlock
import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.depositButton
import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimator import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimator
import com.tangem.features.markets.entry.BottomSheetState import com.tangem.features.markets.entry.BottomSheetState
import com.tangem.features.markets.entry.MarketsEntryComponent import com.tangem.features.markets.entry.MarketsEntryComponent
@ -230,11 +229,6 @@ private fun WalletContent(
} }
(selectedWallet as? WalletState.Visa.Content)?.let { (selectedWallet as? WalletState.Visa.Content)?.let {
depositButton(
modifier = itemModifier.fillMaxWidth(),
state = it.depositButtonState,
)
balancesAndLimitsBlock( balancesAndLimitsBlock(
modifier = itemModifier, modifier = itemModifier,
state = it.balancesAndLimitBlockState, state = it.balancesAndLimitBlockState,

View file

@ -1,21 +0,0 @@
package com.tangem.feature.wallet.presentation.wallet.ui.components.visa
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.PrimaryButtonIconStart
import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.DepositButtonState
private const val DEPOSIT_BUTTON_CONTENT_TYPE = "DepositButton"
internal fun LazyListScope.depositButton(state: DepositButtonState, modifier: Modifier = Modifier) {
item(key = DEPOSIT_BUTTON_CONTENT_TYPE, contentType = DEPOSIT_BUTTON_CONTENT_TYPE) {
PrimaryButtonIconStart(
modifier = modifier,
text = "Deposit",
iconResId = R.drawable.ic_arrow_down_24,
onClick = state.onClick,
enabled = state.isEnabled,
)
}
}

View file

@ -81,7 +81,14 @@ internal class DefaultVisaContractInfoProvider(
{ fetchBalances(paymentAccount, paymentToken) }, { fetchBalances(paymentAccount, paymentToken) },
{ fetchLimits(paymentAccount, paymentToken, walletAddress) }, { fetchLimits(paymentAccount, paymentToken, walletAddress) },
{ token, balances, (oldLimit, newLimit, changeDate) -> { token, balances, (oldLimit, newLimit, changeDate) ->
VisaContractInfo(token, balances, oldLimit, newLimit, changeDate) VisaContractInfo(
token = token,
balances = balances,
oldLimits = oldLimit,
newLimits = newLimit,
paymentAccountAddress = paymentAccount.contractAddress,
limitsChangeDate = changeDate,
)
}, },
) )

View file

@ -9,6 +9,7 @@ data class VisaContractInfo(
val balances: Balances, val balances: Balances,
val oldLimits: Limits, val oldLimits: Limits,
val newLimits: Limits, val newLimits: Limits,
val paymentAccountAddress: String,
val limitsChangeDate: Instant, val limitsChangeDate: Instant,
) { ) {