Updated on 2026-08-14
This commit is contained in:
parent
e1c819d421
commit
53b02cfb10
31 changed files with 286 additions and 346 deletions
|
|
@ -51,7 +51,7 @@ class MoshiModule {
|
|||
.withSubtype(PaymentAccountStatusValueDM.NotCreated::class.java, "not_created")
|
||||
.withSubtype(PaymentAccountStatusValueDM.UnderReview::class.java, "kyc_status")
|
||||
.withSubtype(PaymentAccountStatusValueDM.IssuingCard::class.java, "issuing_card")
|
||||
.withSubtype(PaymentAccountStatusValueDM.ActiveCard::class.java, "active_card")
|
||||
.withSubtype(PaymentAccountStatusValueDM.ActiveAccount::class.java, "active_account")
|
||||
.withSubtype(PaymentAccountStatusValueDM.CardIssueFailed::class.java, "card_issue_failed"),
|
||||
)
|
||||
.add(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.datasource.local.visa
|
||||
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.domain.models.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.pay.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
internal class DefaultTangemPayReissueCardStore(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.datasource.local.visa
|
||||
|
||||
import com.tangem.domain.models.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.pay.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface TangemPayReissueCardStore {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package com.tangem.datasource.local.visa.entity
|
|||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import dev.onenowy.moshipolymorphicadapter.PolymorphicAdapterType
|
||||
import dev.onenowy.moshipolymorphicadapter.annotations.NameLabel
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -32,18 +33,14 @@ sealed interface PaymentAccountStatusValueDM {
|
|||
@Json(name = "issuing_card") val marker: Boolean = true,
|
||||
) : PaymentAccountStatusValueDM
|
||||
|
||||
@NameLabel("active_card")
|
||||
data class ActiveCard(
|
||||
@Json(name = "active_card") val isLocked: Boolean,
|
||||
@NameLabel("active_account")
|
||||
data class ActiveAccount(
|
||||
@Json(name = "customer_id") val customerId: String,
|
||||
@Json(name = "card_id") val cardId: String,
|
||||
@Json(name = "last_four_digits") val lastFourDigits: String,
|
||||
@Json(name = "currency_code") val currencyCode: String,
|
||||
@Json(name = "deposit_address") val depositAddress: String?,
|
||||
@Json(name = "is_pin_set") val isPinSet: Boolean,
|
||||
@Json(name = "fiat_balance") val fiatBalance: FiatBalanceDM,
|
||||
@Json(name = "crypto_balance") val cryptoBalance: CryptoBalanceDM,
|
||||
@Json(name = "display_name") val displayName: String?,
|
||||
@Json(name = "cards") val cards: List<TangemPayCard>,
|
||||
) : PaymentAccountStatusValueDM
|
||||
|
||||
@NameLabel("card_issue_failed")
|
||||
|
|
@ -66,4 +63,15 @@ sealed interface PaymentAccountStatusValueDM {
|
|||
@Json(name = "token_contract_address") val tokenContractAddress: String,
|
||||
@Json(name = "balance") val balance: BigDecimal,
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class TangemPayCard(
|
||||
@Json(name = "id") val id: String,
|
||||
@Json(name = "has_pin_code") val hasPinCode: Boolean,
|
||||
@Json(name = "display_name") val displayName: String?,
|
||||
@Json(name = "actual_daily_limit") val actualDailyLimit: SerializedBigDecimal?,
|
||||
@Json(name = "admin_daily_limit") val adminDailyLimit: SerializedBigDecimal?,
|
||||
@Json(name = "is_frozen") val isFrozen: Boolean,
|
||||
@Json(name = "last_digits") val lastDigits: String,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.datasource.utils
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.Moshi
|
||||
|
|
@ -34,7 +35,11 @@ class MoshiDataStoreSerializer<T>(
|
|||
|
||||
override suspend fun readFrom(input: InputStream): T {
|
||||
return input.bufferedReader().use { reader ->
|
||||
adapter.fromJson(reader.readText()) ?: defaultValue
|
||||
try {
|
||||
adapter.fromJson(reader.readText()) ?: defaultValue
|
||||
} catch (e: Exception) {
|
||||
throw CorruptionException("Failed to deserialize data", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.data.pay
|
|||
|
||||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.TangemPayEligibilityType
|
||||
import com.tangem.domain.models.pay.TangemPayEligibilityType
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
package com.tangem.data.pay.converter
|
||||
|
||||
import com.tangem.data.pay.entity.TangemPayCurrencyFactory
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.data.pay.entity.TangemPayCurrencyFactory
|
||||
import com.tangem.datasource.local.visa.entity.PaymentAccountStatusValueDM
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimit
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimitData
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimitPeriod
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -31,29 +35,23 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
|
|||
customerId = value.customerId,
|
||||
)
|
||||
is PaymentAccountStatusValue.IssuingCard -> PaymentAccountStatusValueDM.IssuingCard()
|
||||
is PaymentAccountStatusValue.Locked -> PaymentAccountStatusValueDM.ActiveCard(
|
||||
isLocked = true,
|
||||
is PaymentAccountStatusValue.Loaded -> PaymentAccountStatusValueDM.ActiveAccount(
|
||||
customerId = value.customerId,
|
||||
cardId = value.cardId,
|
||||
lastFourDigits = value.lastFourDigits,
|
||||
currencyCode = value.currencyCode,
|
||||
depositAddress = value.depositAddress,
|
||||
isPinSet = value.isPinSet,
|
||||
fiatBalance = value.fiatBalance.toDM(),
|
||||
cryptoBalance = value.cryptoBalance.toDM(),
|
||||
displayName = value.displayName?.value,
|
||||
)
|
||||
is PaymentAccountStatusValue.Loaded -> PaymentAccountStatusValueDM.ActiveCard(
|
||||
isLocked = false,
|
||||
customerId = value.customerId,
|
||||
cardId = value.cardId,
|
||||
lastFourDigits = value.lastFourDigits,
|
||||
currencyCode = value.currencyCode,
|
||||
depositAddress = value.depositAddress,
|
||||
isPinSet = value.isPinSet,
|
||||
fiatBalance = value.fiatBalance.toDM(),
|
||||
cryptoBalance = value.cryptoBalance.toDM(),
|
||||
displayName = value.displayName?.value,
|
||||
cards = value.cards.map { card ->
|
||||
PaymentAccountStatusValueDM.TangemPayCard(
|
||||
id = card.id,
|
||||
hasPinCode = card.hasPinCode,
|
||||
displayName = card.displayName?.value,
|
||||
actualDailyLimit = card.limit?.actualCardLimit?.amount,
|
||||
adminDailyLimit = card.limit?.adminCardLimit?.amount,
|
||||
isFrozen = card.isFrozen,
|
||||
lastDigits = card.lastDigits,
|
||||
)
|
||||
},
|
||||
)
|
||||
is PaymentAccountStatusValue.Error.CardIssueFailed -> PaymentAccountStatusValueDM.CardIssueFailed(
|
||||
customerId = value.customerId,
|
||||
|
|
@ -76,35 +74,32 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
|
|||
is PaymentAccountStatusValueDM.IssuingCard -> PaymentAccountStatusValue.IssuingCard(
|
||||
source = StatusSource.CACHE,
|
||||
)
|
||||
is PaymentAccountStatusValueDM.ActiveCard -> if (value.isLocked) {
|
||||
PaymentAccountStatusValue.Locked(
|
||||
source = StatusSource.CACHE,
|
||||
customerId = value.customerId,
|
||||
cardId = value.cardId,
|
||||
lastFourDigits = value.lastFourDigits,
|
||||
currencyCode = value.currencyCode,
|
||||
depositAddress = value.depositAddress,
|
||||
isPinSet = value.isPinSet,
|
||||
fiatBalance = value.fiatBalance.toDomain(),
|
||||
cryptoBalance = value.cryptoBalance.toDomain(),
|
||||
cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId),
|
||||
displayName = value.displayName?.let { CardDisplayName(it).getOrElse { null } },
|
||||
)
|
||||
} else {
|
||||
PaymentAccountStatusValue.Loaded(
|
||||
source = StatusSource.CACHE,
|
||||
customerId = value.customerId,
|
||||
cardId = value.cardId,
|
||||
lastFourDigits = value.lastFourDigits,
|
||||
currencyCode = value.currencyCode,
|
||||
depositAddress = value.depositAddress,
|
||||
isPinSet = value.isPinSet,
|
||||
fiatBalance = value.fiatBalance.toDomain(),
|
||||
cryptoBalance = value.cryptoBalance.toDomain(),
|
||||
cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId),
|
||||
displayName = value.displayName?.let { CardDisplayName(it).getOrElse { null } },
|
||||
)
|
||||
}
|
||||
is PaymentAccountStatusValueDM.ActiveAccount -> PaymentAccountStatusValue.Loaded(
|
||||
source = StatusSource.CACHE,
|
||||
customerId = value.customerId,
|
||||
currencyCode = value.currencyCode,
|
||||
depositAddress = value.depositAddress,
|
||||
fiatBalance = value.fiatBalance.toDomain(),
|
||||
cryptoBalance = value.cryptoBalance.toDomain(),
|
||||
cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId),
|
||||
cards = value.cards.map { card ->
|
||||
TangemPayCard(
|
||||
id = card.id,
|
||||
hasPinCode = card.hasPinCode,
|
||||
displayName = card.displayName?.let { CardDisplayName(it).getOrElse { null } },
|
||||
limit = TangemPayCardLimitData(
|
||||
actualCardLimit = card.actualDailyLimit?.let { limit ->
|
||||
TangemPayCardLimit(limit, TangemPayCardLimitPeriod.DAY)
|
||||
},
|
||||
adminCardLimit = card.adminDailyLimit?.let { limit ->
|
||||
TangemPayCardLimit(limit, TangemPayCardLimitPeriod.DAY)
|
||||
},
|
||||
),
|
||||
isFrozen = card.isFrozen,
|
||||
lastDigits = card.lastDigits,
|
||||
)
|
||||
},
|
||||
)
|
||||
is PaymentAccountStatusValueDM.UnderReview -> PaymentAccountStatusValue.UnderReview(
|
||||
source = StatusSource.CACHE,
|
||||
kycStatus = value.kycStatus,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.data.pay.di
|
|||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
|
||||
import androidx.datastore.dataStoreFile
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.data.pay.DefaultTangemPayCryptoCurrencyFactory
|
||||
|
|
@ -129,6 +130,7 @@ internal interface TangemPayDataModule {
|
|||
types = mapWithStringKeyTypes<PaymentAccountStatusValueDM>(),
|
||||
defaultValue = emptyMap(),
|
||||
),
|
||||
corruptionHandler = ReplaceFileCorruptionHandler { emptyMap() },
|
||||
produceFile = { context.dataStoreFile(fileName = "payment_account_statuses") },
|
||||
scope = scope,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import com.tangem.domain.models.account.Account
|
|||
import com.tangem.domain.models.account.AccountStatus
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimitData
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.model.CustomerInfo
|
||||
|
|
@ -277,34 +279,28 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
|
|||
customerId: String,
|
||||
): PaymentAccountStatusValue {
|
||||
val cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId)
|
||||
return when (productInstance.frozenState) {
|
||||
TangemPayCardFrozenState.Frozen -> PaymentAccountStatusValue.Locked(
|
||||
source = StatusSource.ACTUAL,
|
||||
customerId = customerId,
|
||||
cardId = productInstance.cardId,
|
||||
lastFourDigits = cardInfo.lastFourDigits,
|
||||
currencyCode = cardInfo.currencyCode,
|
||||
depositAddress = cardInfo.depositAddress,
|
||||
isPinSet = cardInfo.isPinSet,
|
||||
fiatBalance = cardInfo.fiatBalance,
|
||||
cryptoBalance = cardInfo.cryptoBalance,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
displayName = productInstance.displayName,
|
||||
)
|
||||
else -> PaymentAccountStatusValue.Loaded(
|
||||
source = StatusSource.ACTUAL,
|
||||
customerId = customerId,
|
||||
cardId = productInstance.cardId,
|
||||
lastFourDigits = cardInfo.lastFourDigits,
|
||||
currencyCode = cardInfo.currencyCode,
|
||||
depositAddress = cardInfo.depositAddress,
|
||||
isPinSet = cardInfo.isPinSet,
|
||||
fiatBalance = cardInfo.fiatBalance,
|
||||
cryptoBalance = cardInfo.cryptoBalance,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
displayName = productInstance.displayName,
|
||||
)
|
||||
}
|
||||
return PaymentAccountStatusValue.Loaded(
|
||||
source = StatusSource.ACTUAL,
|
||||
customerId = customerId,
|
||||
currencyCode = cardInfo.currencyCode,
|
||||
depositAddress = cardInfo.depositAddress,
|
||||
fiatBalance = cardInfo.fiatBalance,
|
||||
cryptoBalance = cardInfo.cryptoBalance,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
cards = listOf(
|
||||
TangemPayCard(
|
||||
id = productInstance.cardId,
|
||||
hasPinCode = cardInfo.isPinSet,
|
||||
displayName = productInstance.displayName,
|
||||
limit = TangemPayCardLimitData(
|
||||
actualCardLimit = productInstance.actualCardLimit,
|
||||
adminCardLimit = productInstance.adminCardLimit,
|
||||
),
|
||||
isFrozen = productInstance.frozenState is TangemPayCardFrozenState.Frozen,
|
||||
lastDigits = cardInfo.lastFourDigits,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun VisaApiError.mapToPaymentAccountStatus(): PaymentAccountStatusValue {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.tangem.datasource.api.pay.models.response.OrderResponse
|
|||
import com.tangem.datasource.local.visa.TangemPayCardFrozenStateStore
|
||||
import com.tangem.datasource.local.visa.TangemPayStorage
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.TangemPayEligibilityType
|
||||
import com.tangem.domain.models.pay.TangemPayEligibilityType
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
|
|
@ -25,8 +25,8 @@ import com.tangem.domain.pay.datasource.TangemPayAuthDataSource
|
|||
import com.tangem.domain.pay.model.CustomerInfo
|
||||
import com.tangem.domain.pay.model.CustomerInfo.CardInfo
|
||||
import com.tangem.domain.pay.model.CustomerInfo.ProductInstance
|
||||
import com.tangem.domain.pay.model.TangemPayCardLimit
|
||||
import com.tangem.domain.pay.model.TangemPayCardLimitPeriod
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimit
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimitPeriod
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import com.tangem.datasource.api.pay.TangemPayApi
|
|||
import com.tangem.datasource.api.pay.models.request.ReissueCardRequest
|
||||
import com.tangem.datasource.api.pay.models.response.OrderResponse
|
||||
import com.tangem.datasource.local.visa.TangemPayReissueCardStore
|
||||
import com.tangem.domain.models.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.pay.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.model.OrderStatus
|
||||
import com.tangem.domain.pay.model.TangemPayReissueOrderInfo
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.tangem.domain.models.account.AccountStatus
|
|||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -45,6 +46,7 @@ internal class PaymentAccountStatusesStore(
|
|||
},
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
runSuspendCatching { persistenceDataStore.updateData { emptyMap() } }
|
||||
TangemLogger.e("Error while loading cached payment account statuses", e)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,18 +78,6 @@ class IsAccountsModeEnabledUseCaseTest {
|
|||
Truth.assertThat(actual).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns true when payment account is Locked`() = runTest {
|
||||
val statusList = createAccountStatusList(
|
||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Locked>())),
|
||||
)
|
||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
||||
|
||||
val actual = useCase.invoke().first()
|
||||
|
||||
Truth.assertThat(actual).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when payment account is NotCreated`() = runTest {
|
||||
val statusList = createAccountStatusList(
|
||||
|
|
@ -210,18 +198,6 @@ class IsAccountsModeEnabledUseCaseTest {
|
|||
Truth.assertThat(actual).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns true when payment account is Locked`() = runTest {
|
||||
val statusList = createAccountStatusList(
|
||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Locked>())),
|
||||
)
|
||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
||||
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
Truth.assertThat(actual).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when payment account is NotCreated`() = runTest {
|
||||
val statusList = createAccountStatusList(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -28,7 +29,6 @@ sealed class PaymentAccountStatusValue {
|
|||
is UnderReview,
|
||||
-> TotalFiatBalance.Loaded(amount = SerializedBigDecimal.ZERO, source = source)
|
||||
is Loading -> TotalFiatBalance.Loading
|
||||
is Locked -> TotalFiatBalance.Loaded(amount = fiatBalance.availableBalance, source = source)
|
||||
is Loaded -> TotalFiatBalance.Loaded(amount = fiatBalance.availableBalance, source = source)
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,6 @@ sealed class PaymentAccountStatusValue {
|
|||
return when (this) {
|
||||
is IssuingCard -> copy(source = source)
|
||||
is Loaded -> copy(source = source)
|
||||
is Locked -> copy(source = source)
|
||||
is UnderReview -> copy(source = source)
|
||||
is Loading,
|
||||
is NotCreated,
|
||||
|
|
@ -84,81 +83,27 @@ sealed class PaymentAccountStatusValue {
|
|||
@Serializable
|
||||
data class IssuingCard(override val source: StatusSource) : PaymentAccountStatusValue()
|
||||
|
||||
/**
|
||||
* Represents a state where the payment account is locked.
|
||||
*
|
||||
* @property source The source of the status information.
|
||||
* @property customerId The unique identifier of the customer.
|
||||
* @property cardId The unique identifier of the card.
|
||||
* @property lastFourDigits The last four digits of the card number.
|
||||
* @property currencyCode The code of the currency.
|
||||
* @property depositAddress The address for deposits, if available.
|
||||
* @property isPinSet Indicates if the PIN is set for the card.
|
||||
* @property fiatBalance The fiat balance details.
|
||||
* @property cryptoBalance The crypto balance details.
|
||||
*/
|
||||
@Serializable
|
||||
data class Locked(
|
||||
override val source: StatusSource,
|
||||
val customerId: String,
|
||||
val cardId: String,
|
||||
val lastFourDigits: String,
|
||||
val currencyCode: String,
|
||||
val depositAddress: String?,
|
||||
val isPinSet: Boolean,
|
||||
val fiatBalance: FiatBalance,
|
||||
val cryptoBalance: CryptoBalance,
|
||||
val cryptoCurrency: CryptoCurrency.Token,
|
||||
val displayName: CardDisplayName?,
|
||||
) : PaymentAccountStatusValue() {
|
||||
val cryptoCurrencyStatus: CryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
currency = cryptoCurrency,
|
||||
value = CryptoCurrencyStatus.Loaded(
|
||||
amount = cryptoBalance.balance,
|
||||
fiatAmount = fiatBalance.availableBalance,
|
||||
fiatRate = BigDecimal.ONE,
|
||||
priceChange = BigDecimal.ZERO,
|
||||
networkAddress = NetworkAddress.Single(
|
||||
defaultAddress = NetworkAddress.Address(
|
||||
type = NetworkAddress.Address.Type.Primary,
|
||||
value = cryptoBalance.depositAddress,
|
||||
),
|
||||
),
|
||||
sources = CryptoCurrencyStatus.Sources(),
|
||||
pendingTransactions = emptySet(),
|
||||
stakingBalance = null,
|
||||
yieldSupplyStatus = null,
|
||||
hasCurrentNetworkTransactions = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a state where the payment account is successfully loaded with complete information.
|
||||
*
|
||||
* @property source The source of the status information.
|
||||
* @property customerId The unique identifier of the customer.
|
||||
* @property cardId The unique identifier of the card.
|
||||
* @property lastFourDigits The last four digits of the card number.
|
||||
* @property currencyCode The code of the currency.
|
||||
* @property depositAddress The address for deposits, if available.
|
||||
* @property isPinSet Indicates if the PIN is set for the card.
|
||||
* @property fiatBalance The fiat balance details.
|
||||
* @property cryptoBalance The crypto balance details.
|
||||
* @property cards The list of user's cards.
|
||||
*/
|
||||
@Serializable
|
||||
data class Loaded(
|
||||
override val source: StatusSource,
|
||||
val customerId: String,
|
||||
val cardId: String,
|
||||
val lastFourDigits: String,
|
||||
val currencyCode: String,
|
||||
val depositAddress: String?,
|
||||
val isPinSet: Boolean,
|
||||
val fiatBalance: FiatBalance,
|
||||
val cryptoBalance: CryptoBalance,
|
||||
val cryptoCurrency: CryptoCurrency.Token,
|
||||
val displayName: CardDisplayName?,
|
||||
val cards: List<TangemPayCard>,
|
||||
) : PaymentAccountStatusValue() {
|
||||
val cryptoCurrencyStatus: CryptoCurrencyStatus = CryptoCurrencyStatus(
|
||||
currency = cryptoCurrency,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents a Tangem Pay card linked to a payment account.
|
||||
*
|
||||
* @property id unique card identifier assigned by the backend.
|
||||
* @property hasPinCode whether the card has a PIN code set.
|
||||
* @property displayName optional human-readable name assigned to the card; `null` if not set.
|
||||
* @property limit spending limit configuration for the card; `null` if not configured or not yet loaded.
|
||||
* @property isFrozen whether the card is currently frozen (blocked for payments).
|
||||
* @property lastDigits The last four digits of the card number.
|
||||
*/
|
||||
@Serializable
|
||||
data class TangemPayCard(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("has_pin_code") val hasPinCode: Boolean,
|
||||
@SerialName("display_name") val displayName: CardDisplayName?,
|
||||
@SerialName("limit") val limit: TangemPayCardLimitData?,
|
||||
@SerialName("is_frozen") val isFrozen: Boolean,
|
||||
@SerialName("last_digits") val lastDigits: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import com.tangem.domain.models.serialization.SerializedBigDecimal
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.Locale
|
||||
|
||||
@Serializable
|
||||
data class TangemPayCardLimit(
|
||||
@SerialName("amount") val amount: SerializedBigDecimal,
|
||||
@SerialName("period") val period: TangemPayCardLimitPeriod,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
enum class TangemPayCardLimitPeriod {
|
||||
@SerialName("DAY")
|
||||
DAY,
|
||||
|
||||
@SerialName("WEEK")
|
||||
WEEK,
|
||||
|
||||
@SerialName("MONTH")
|
||||
MONTH,
|
||||
|
||||
@SerialName("YEAR")
|
||||
YEAR,
|
||||
|
||||
@SerialName("ALL_TIME")
|
||||
ALL_TIME,
|
||||
|
||||
@SerialName("AUTHORIZATION")
|
||||
AUTHORIZATION,
|
||||
|
||||
@SerialName("UNKNOWN")
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = when (value.uppercase(Locale.US)) {
|
||||
"DAY" -> DAY
|
||||
"WEEK" -> WEEK
|
||||
"MONTH" -> MONTH
|
||||
"YEAR" -> YEAR
|
||||
"ALL_TIME" -> ALL_TIME
|
||||
"AUTHORIZATION" -> AUTHORIZATION
|
||||
else -> UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.models.pay
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class TangemPayCardLimitData(
|
||||
@SerialName("actual_card_limit") val actualCardLimit: TangemPayCardLimit?,
|
||||
@SerialName("admin_card_limit") val adminCardLimit: TangemPayCardLimit?,
|
||||
)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.domain.models
|
||||
package com.tangem.domain.models.pay
|
||||
|
||||
enum class TangemPayEligibilityType {
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.domain.models
|
||||
package com.tangem.domain.models.pay
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.pay.model
|
||||
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimit
|
||||
import com.tangem.domain.models.account.CardDisplayName
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.kyc.KycStatus
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
package com.tangem.domain.pay.model
|
||||
|
||||
import java.math.BigDecimal
|
||||
import java.util.Locale
|
||||
|
||||
data class TangemPayCardLimit(
|
||||
val amount: BigDecimal,
|
||||
val period: TangemPayCardLimitPeriod,
|
||||
)
|
||||
|
||||
enum class TangemPayCardLimitPeriod {
|
||||
DAY,
|
||||
WEEK,
|
||||
MONTH,
|
||||
YEAR,
|
||||
ALL_TIME,
|
||||
AUTHORIZATION,
|
||||
UNKNOWN,
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = when (value.uppercase(Locale.US)) {
|
||||
"DAY" -> DAY
|
||||
"WEEK" -> WEEK
|
||||
"MONTH" -> MONTH
|
||||
"YEAR" -> YEAR
|
||||
"ALL_TIME" -> ALL_TIME
|
||||
"AUTHORIZATION" -> AUTHORIZATION
|
||||
else -> UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package com.tangem.domain.pay.repository
|
|||
|
||||
import arrow.core.Either
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.domain.models.TangemPayEligibilityType
|
||||
import com.tangem.domain.models.pay.TangemPayEligibilityType
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.model.CustomerInfo
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.tangem.domain.pay.repository
|
|||
import arrow.core.Either
|
||||
import com.tangem.core.error.UniversalError
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.pay.TangemPayReissueCardFee
|
||||
import com.tangem.domain.pay.model.TangemPayReissueOrderInfo
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class GetPaymentAccountCryptoCurrencyStatusUseCase(
|
|||
val accountStatus = paymentAccountStatusSupplier.invoke(userWalletId).firstOrNull() ?: return none()
|
||||
val cryptoCurrencyStatus = when (val statusValue = accountStatus.value) {
|
||||
is PaymentAccountStatusValue.Loaded -> statusValue.cryptoCurrencyStatus
|
||||
is PaymentAccountStatusValue.Locked -> statusValue.cryptoCurrencyStatus
|
||||
else -> return none()
|
||||
}
|
||||
return if (cryptoCurrencyStatus.currency == cryptoCurrency) {
|
||||
|
|
|
|||
|
|
@ -262,7 +262,6 @@ internal class SendDestinationModel @Inject constructor(
|
|||
val contractAddress = (cryptoCurrency as? CryptoCurrency.Token)?.contractAddress ?: return null
|
||||
val (paymentAccountAddress, currency) = when (val status = this.value) {
|
||||
is PaymentAccountStatusValue.Loaded -> status.cryptoBalance.depositAddress to status.cryptoCurrency
|
||||
is PaymentAccountStatusValue.Locked -> status.cryptoBalance.depositAddress to status.cryptoCurrency
|
||||
else -> return null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ internal class SwapInteractorImpl @AssistedInject constructor(
|
|||
private fun getPaymentAccountCurrencies(accountStatus: AccountStatus.Payment): List<CryptoCurrencyStatus> {
|
||||
val currencyStatus = when (val statusValue = accountStatus.value) {
|
||||
is PaymentAccountStatusValue.Loaded -> statusValue.cryptoCurrencyStatus
|
||||
is PaymentAccountStatusValue.Locked -> statusValue.cryptoCurrencyStatus
|
||||
else -> return emptyList()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -188,7 +188,6 @@ internal class ChooseTokenListItemConverter(
|
|||
PaymentAccountStatusValue.Loading,
|
||||
-> return null
|
||||
is PaymentAccountStatusValue.Loaded -> status.cryptoCurrencyStatus
|
||||
is PaymentAccountStatusValue.Locked -> status.cryptoCurrencyStatus
|
||||
}
|
||||
val account = this.account
|
||||
val tokensCount = 1
|
||||
|
|
|
|||
|
|
@ -18,12 +18,15 @@ import com.tangem.core.ui.format.bigdecimal.fiat
|
|||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.format.bigdecimal.getJavaCurrencyByCode
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.TokenReceiveConfig
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.pay.TangemPayCard
|
||||
import com.tangem.domain.models.pay.TangemPayCardLimitPeriod
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.model.OrderStatus
|
||||
import com.tangem.domain.pay.model.TangemPayCardLimitPeriod
|
||||
import com.tangem.domain.pay.model.TangemPayReissueOrderInfo
|
||||
import com.tangem.domain.pay.model.TangemPayTopUpData
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.pay.repository.TangemPayReissueCardRepository
|
||||
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
|
||||
|
|
@ -33,22 +36,15 @@ import com.tangem.features.tangempay.components.ReissueCardListener
|
|||
import com.tangem.features.tangempay.components.TangemPayCardPageComponent
|
||||
import com.tangem.features.tangempay.components.ViewPinListener
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.AddToWalletBlockState
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardPageSetting
|
||||
import com.tangem.features.tangempay.entity.TangemPayCardPageUM
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation
|
||||
import com.tangem.features.tangempay.entity.*
|
||||
import com.tangem.features.tangempay.navigation.TangemPayDetailsInnerRoute
|
||||
import com.tangem.features.tangempay.entity.TangemPayDailyLimitBlockState
|
||||
import com.tangem.features.tangempay.utils.TangemPayMessagesFactory
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -57,19 +53,17 @@ import javax.inject.Inject
|
|||
@ModelScoped
|
||||
internal class TangemPayCardPageModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val analytics: AnalyticsEventHandler,
|
||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
private val onboardingRepository: OnboardingRepository,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val reissueCardRepository: TangemPayReissueCardRepository,
|
||||
) : Model(), ViewPinListener, ReissueCardListener, AddFundsListener {
|
||||
|
||||
private val params: TangemPayCardPageComponent.Params = paramsContainer.require()
|
||||
|
||||
private var currentFrozenState: TangemPayCardFrozenState = params.config.cardFrozenState
|
||||
|
||||
private val addToWalletBannerJobHolder = JobHolder()
|
||||
private val addFundsJobHolder = JobHolder()
|
||||
|
||||
|
|
@ -78,34 +72,63 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
TangemPayCardPageUM(
|
||||
onBackClick = router::pop,
|
||||
dailyLimitState = TangemPayDailyLimitBlockState.Loading,
|
||||
settings = persistentListOf(
|
||||
TangemPayCardPageSetting(
|
||||
title = TextReference.Res(R.string.tangempay_card_details_change_pin),
|
||||
onSettingClick = ::onClickChangePIN,
|
||||
),
|
||||
TangemPayCardPageSetting(
|
||||
title = TextReference.Res(R.string.tangempay_card_details_freeze_card),
|
||||
onSettingClick = ::onClickFreezeOrUnfreezeCard,
|
||||
),
|
||||
TangemPayCardPageSetting(
|
||||
title = TextReference.Res(R.string.tangempay_card_details_reissue_card),
|
||||
onSettingClick = ::onClickReissueCard,
|
||||
),
|
||||
),
|
||||
settings = persistentListOf(),
|
||||
),
|
||||
)
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
|
||||
|
||||
// TODO v_rodionov: #[REDACTED_TASK_KEY] check reissue order state before card details are showed
|
||||
init {
|
||||
// TODO v_rodionov: #[REDACTED_TASK_KEY] check reissue order state before card details are showed
|
||||
fetchAddToWalletBanner()
|
||||
fetchCardLimit()
|
||||
subscribeToCardFrozenState()
|
||||
|
||||
paymentAccountStatusSupplier.invoke(params.userWalletId)
|
||||
.onEach { state ->
|
||||
val status = state.value
|
||||
if (status is PaymentAccountStatusValue.Loaded &&
|
||||
status.source == StatusSource.ACTUAL &&
|
||||
status.cards.isNotEmpty()
|
||||
) {
|
||||
val card = status.cards.first()
|
||||
val limit = card.limit?.actualCardLimit?.takeIf { it.period == TangemPayCardLimitPeriod.DAY }
|
||||
val dailyLimitState = if (limit != null) {
|
||||
TangemPayDailyLimitBlockState.Content(
|
||||
limit = limit.amount.format {
|
||||
val symbol = getJavaCurrencyByCode(status.currencyCode).symbol
|
||||
fiat(status.currencyCode, symbol)
|
||||
},
|
||||
onChangeClick = {}, // TODO v_rodionov: #[REDACTED_TASK_KEY]
|
||||
)
|
||||
} else {
|
||||
TangemPayDailyLimitBlockState.Error
|
||||
}
|
||||
uiState.update { it.copy(dailyLimitState = dailyLimitState, settings = buildSettings(card)) }
|
||||
} else {
|
||||
// TODO v_rodionov: #[REDACTED_TASK_KEY] show error state
|
||||
}
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun onClickChangePIN() {
|
||||
if (!params.config.isPinSet) {
|
||||
private fun buildSettings(card: TangemPayCard): ImmutableList<TangemPayCardPageSetting> {
|
||||
return persistentListOf(
|
||||
TangemPayCardPageSetting(
|
||||
title = TextReference.Res(R.string.tangempay_card_details_change_pin),
|
||||
onSettingClick = { onClickChangePIN(card.hasPinCode) },
|
||||
),
|
||||
TangemPayCardPageSetting(
|
||||
title = TextReference.Res(R.string.tangempay_card_details_freeze_card),
|
||||
onSettingClick = { onClickFreezeOrUnfreezeCard(card.isFrozen) },
|
||||
),
|
||||
TangemPayCardPageSetting(
|
||||
title = TextReference.Res(R.string.tangempay_card_details_reissue_card),
|
||||
onSettingClick = ::onClickReissueCard,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onClickChangePIN(isPinSet: Boolean) {
|
||||
if (!isPinSet) {
|
||||
router.push(TangemPayDetailsInnerRoute.ChangePIN)
|
||||
} else {
|
||||
bottomSheetNavigation.activate(
|
||||
|
|
@ -117,15 +140,13 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onClickFreezeOrUnfreezeCard() {
|
||||
when (currentFrozenState) {
|
||||
TangemPayCardFrozenState.Frozen -> uiMessageSender.send(
|
||||
TangemPayMessagesFactory.createUnfreezeCardMessage(onUnfreezeClicked = ::unfreezeCard),
|
||||
)
|
||||
else -> uiMessageSender.send(
|
||||
TangemPayMessagesFactory.createFreezeCardMessage(onFreezeClicked = ::freezeCard),
|
||||
)
|
||||
private fun onClickFreezeOrUnfreezeCard(isFrozen: Boolean) {
|
||||
val message = if (isFrozen) {
|
||||
TangemPayMessagesFactory.createUnfreezeCardMessage(onUnfreezeClicked = ::unfreezeCard)
|
||||
} else {
|
||||
TangemPayMessagesFactory.createFreezeCardMessage(onFreezeClicked = ::freezeCard)
|
||||
}
|
||||
uiMessageSender.send(message)
|
||||
}
|
||||
|
||||
private fun onClickReissueCard() {
|
||||
|
|
@ -242,13 +263,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun subscribeToCardFrozenState() {
|
||||
cardDetailsRepository
|
||||
.cardFrozenState(params.config.cardId)
|
||||
.onEach { state -> currentFrozenState = state }
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun fetchAddToWalletBanner() {
|
||||
modelScope.launch {
|
||||
val isDone = cardDetailsRepository.isAddToWalletDone(params.userWalletId).getOrNull() == true
|
||||
|
|
@ -265,39 +279,6 @@ internal class TangemPayCardPageModel @Inject constructor(
|
|||
}.saveIn(addToWalletBannerJobHolder)
|
||||
}
|
||||
|
||||
private fun fetchCardLimit() {
|
||||
modelScope.launch {
|
||||
onboardingRepository.getCustomerInfo(params.userWalletId)
|
||||
.onRight { info ->
|
||||
val productInstance = info.productInstance
|
||||
val cardInfo = info.cardInfo
|
||||
val actualCardLimit = productInstance?.actualCardLimit
|
||||
val dailyLimitState = if (
|
||||
productInstance != null &&
|
||||
cardInfo != null &&
|
||||
actualCardLimit?.period == TangemPayCardLimitPeriod.DAY
|
||||
) {
|
||||
val limit = actualCardLimit.amount.format {
|
||||
val symbol = getJavaCurrencyByCode(cardInfo.currencyCode).symbol
|
||||
fiat(cardInfo.currencyCode, symbol)
|
||||
}
|
||||
TangemPayDailyLimitBlockState.Content(
|
||||
limit = limit,
|
||||
onChangeClick = {}, // TODO v_rodionov: #[REDACTED_TASK_KEY]
|
||||
)
|
||||
} else {
|
||||
TangemPayDailyLimitBlockState.Error
|
||||
}
|
||||
uiState.update { it.copy(dailyLimitState = dailyLimitState) }
|
||||
}
|
||||
.onLeft {
|
||||
uiState.update { state ->
|
||||
state.copy(dailyLimitState = TangemPayDailyLimitBlockState.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onClickAddToWallet() {
|
||||
router.push(TangemPayDetailsInnerRoute.AddToWallet)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
is PaymentAccountStatusValue.IssuingCard,
|
||||
is PaymentAccountStatusValue.Loaded,
|
||||
is PaymentAccountStatusValue.Loading,
|
||||
is PaymentAccountStatusValue.Locked,
|
||||
is PaymentAccountStatusValue.UnderReview,
|
||||
-> null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,7 +237,6 @@ internal class GetWalletNotificationsFactory @Inject constructor(
|
|||
is PaymentAccountStatusValue.IssuingCard,
|
||||
is PaymentAccountStatusValue.Loaded,
|
||||
is PaymentAccountStatusValue.Loading,
|
||||
is PaymentAccountStatusValue.Locked,
|
||||
is PaymentAccountStatusValue.UnderReview,
|
||||
-> null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,54 +55,37 @@ internal class TangemPayMainBlockConverter(
|
|||
)
|
||||
is PaymentAccountStatusValue.NotCreated -> TangemPayMainUM.Empty
|
||||
is PaymentAccountStatusValue.Loading -> TangemPayMainUM.Loading
|
||||
is PaymentAccountStatusValue.Locked -> TangemPayMainUM.Content(
|
||||
subtitle = stringReference("*${statusValue.lastFourDigits}"),
|
||||
isBalanceFlickering = statusValue.source == StatusSource.CACHE,
|
||||
balance = getBalanceText(
|
||||
currencyCode = statusValue.currencyCode,
|
||||
balance = statusValue.fiatBalance.availableBalance,
|
||||
),
|
||||
balanceSubtitle = stringReference("USDC"), // TODO hardcode for now
|
||||
shouldShowOnlyCacheWarning = statusValue.source == StatusSource.ONLY_CACHE,
|
||||
onClick = {
|
||||
tangemPayClickIntents.openDetails(
|
||||
value.account.userWalletId,
|
||||
TangemPayDetailsConfig(
|
||||
customerId = statusValue.customerId,
|
||||
cardId = statusValue.cardId,
|
||||
isPinSet = statusValue.isPinSet,
|
||||
cardFrozenState = TangemPayCardFrozenState.Frozen,
|
||||
cardNumberEnd = statusValue.lastFourDigits,
|
||||
chainId = POLYGON_CHAIN_ID,
|
||||
displayName = statusValue.displayName,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
is PaymentAccountStatusValue.Loaded -> TangemPayMainUM.Content(
|
||||
subtitle = stringReference("*${statusValue.lastFourDigits}"),
|
||||
isBalanceFlickering = statusValue.source == StatusSource.CACHE,
|
||||
balance = getBalanceText(
|
||||
currencyCode = statusValue.currencyCode,
|
||||
balance = statusValue.fiatBalance.availableBalance,
|
||||
),
|
||||
balanceSubtitle = stringReference("USDC"), // TODO hardcode for now
|
||||
shouldShowOnlyCacheWarning = statusValue.source == StatusSource.ONLY_CACHE,
|
||||
onClick = {
|
||||
tangemPayClickIntents.openDetails(
|
||||
value.account.userWalletId,
|
||||
TangemPayDetailsConfig(
|
||||
customerId = statusValue.customerId,
|
||||
cardId = statusValue.cardId,
|
||||
isPinSet = statusValue.isPinSet,
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
cardNumberEnd = statusValue.lastFourDigits,
|
||||
chainId = POLYGON_CHAIN_ID,
|
||||
displayName = statusValue.displayName,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
is PaymentAccountStatusValue.Loaded -> {
|
||||
val card = statusValue.cards.firstOrNull() ?: return TangemPayMainUM.TemporaryUnavailable
|
||||
TangemPayMainUM.Content(
|
||||
subtitle = stringReference("*${card.lastDigits}"),
|
||||
isBalanceFlickering = statusValue.source == StatusSource.CACHE,
|
||||
balance = getBalanceText(
|
||||
currencyCode = statusValue.currencyCode,
|
||||
balance = statusValue.fiatBalance.availableBalance,
|
||||
),
|
||||
balanceSubtitle = stringReference("USDC"), // TODO hardcode for now
|
||||
shouldShowOnlyCacheWarning = statusValue.source == StatusSource.ONLY_CACHE,
|
||||
onClick = {
|
||||
tangemPayClickIntents.openDetails(
|
||||
value.account.userWalletId,
|
||||
TangemPayDetailsConfig(
|
||||
customerId = statusValue.customerId,
|
||||
cardId = card.id,
|
||||
isPinSet = card.hasPinCode,
|
||||
cardFrozenState = if (card.isFrozen) {
|
||||
TangemPayCardFrozenState.Frozen
|
||||
} else {
|
||||
TangemPayCardFrozenState.Unfrozen
|
||||
},
|
||||
cardNumberEnd = card.lastDigits,
|
||||
chainId = POLYGON_CHAIN_ID,
|
||||
displayName = card.displayName,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue