Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-18 20:02:54 +05:00
parent ec59339d51
commit 9be5646b78
6 changed files with 36 additions and 68 deletions

View file

@ -6,9 +6,9 @@ import java.math.BigDecimal
@JsonClass(generateAdapter = true)
data class BalanceResponse(
@Json(name = "fiat") val fiat: FiatBalance,
@Json(name = "crypto") val crypto: CryptoBalance,
@Json(name = "available_for_withdrawal") val availableForWithdrawal: AvailableForWithdrawal,
@Json(name = "fiat") val fiat: FiatBalance?,
@Json(name = "crypto") val crypto: CryptoBalance?,
@Json(name = "available_for_withdrawal") val availableForWithdrawal: AvailableForWithdrawal?,
)
@JsonClass(generateAdapter = true)

View file

@ -139,13 +139,13 @@ internal class DefaultOnboardingRepository @Inject constructor(
response: CustomerMeResponse.Result?,
): CustomerInfo {
val card = response?.card
val balance = response?.balance
val fiatBalance = response?.balance?.fiat
val paymentAccount = response?.paymentAccount
val cardInfo = if (paymentAccount != null && card != null && balance != null) {
val cardInfo = if (paymentAccount != null && card != null && fiatBalance != null) {
CardInfo(
lastFourDigits = card.cardNumberEnd,
balance = balance.fiat.availableBalance,
currencyCode = balance.fiat.currency,
balance = fiatBalance.availableBalance,
currencyCode = fiatBalance.currency,
customerWalletAddress = paymentAccount.customerWalletAddress,
depositAddress = response.depositAddress,
)

View file

@ -52,20 +52,29 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
private val storePollingMutex = Mutex()
override suspend fun getCardBalance(userWalletId: UserWalletId): Either<UniversalError, TangemPayCardBalance> {
return requestHelper.runWithErrorLogs(TAG) {
val result = requestHelper.request(userWalletId) { authHeader ->
tangemPayApi.getCardBalance(authHeader)
}.result ?: error("Cannot get card balance")
TangemPayCardBalance(
fiatBalance = result.fiat.availableBalance,
currencyCode = result.fiat.currency,
cryptoBalance = result.crypto.balance,
availableForWithdrawal = result.availableForWithdrawal.amount,
chainId = result.crypto.chainId,
depositAddress = result.crypto.depositAddress,
contractAddress = result.crypto.tokenContractAddress,
)
}
return catch(
block = {
val response = requestHelper.performRequest(userWalletId) { authHeader ->
tangemPayApi.getCardBalance(authHeader)
}.getOrNull()
val fiatBalance = requireNotNull(response?.result?.fiat) { "Cannot get card balance fiat" }
val cryptoBalance = requireNotNull(response.result?.crypto) { "Cannot get card balance crypto" }
val withdrawalAmount = requireNotNull(response.result?.availableForWithdrawal) {
"Cannot get card balance availableForWithdrawal"
}
TangemPayCardBalance(
fiatBalance = fiatBalance.availableBalance,
currencyCode = fiatBalance.currency,
cryptoBalance = cryptoBalance.balance,
availableForWithdrawal = withdrawalAmount.amount,
chainId = cryptoBalance.chainId,
depositAddress = cryptoBalance.depositAddress,
contractAddress = cryptoBalance.tokenContractAddress,
).right()
},
catch = ::catchException,
)
}
override suspend fun revealCardDetails(userWalletId: UserWalletId): Either<UniversalError, TangemPayCardDetails> {
@ -100,7 +109,7 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
expirationMonth = result.expirationMonth,
).right()
},
catch = { errorConverter.convert(it).left() },
catch = ::catchException,
)
}
@ -285,6 +294,11 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
}
}
private fun <T> catchException(throwable: Throwable): Either<UniversalError, T> {
Timber.tag(TAG).e(throwable)
return errorConverter.convert(throwable).left()
}
private companion object {
const val MAX_POLLING_RETRIES = 3
}

View file

@ -41,7 +41,6 @@ internal sealed class TangemPayDetailsBalanceBlockState {
data class Content(
override val actionButtons: ImmutableList<ActionButtonConfig>,
val cryptoBalance: String,
val fiatBalance: String,
val isBalanceFlickering: Boolean,
) : TangemPayDetailsBalanceBlockState()

View file

@ -2,10 +2,8 @@ package com.tangem.features.tangempay.model.transformers
import arrow.core.Either
import com.tangem.core.error.UniversalError
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.fiat
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory
import com.tangem.domain.pay.model.TangemPayCardBalance
@ -13,7 +11,6 @@ import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.persistentListOf
import java.math.BigDecimal
import java.util.Currency
internal class DetailsBalanceTransformer(
@ -37,7 +34,6 @@ internal class DetailsBalanceTransformer(
TangemPayDetailsBalanceBlockState.Content(
isBalanceFlickering = false,
fiatBalance = getFiatBalanceText(balance.value),
cryptoBalance = getCryptoBalanceText(balance.value.cryptoBalance, cryptoCurrency),
actionButtons = prevState.balanceBlockState.actionButtons,
)
}
@ -52,8 +48,4 @@ internal class DetailsBalanceTransformer(
fiat(fiatCurrencyCode = currency.currencyCode, fiatCurrencySymbol = currency.symbol)
}
}
private fun getCryptoBalanceText(cryptoBalance: BigDecimal, cryptoCurrency: CryptoCurrency): String {
return cryptoBalance.format { crypto(cryptoCurrency = cryptoCurrency) }
}
}

View file

@ -175,11 +175,6 @@ private fun TangemPayDetailsBalanceBlock(
state = state,
isBalanceHidden = isBalanceHidden,
)
CryptoBalance(
modifier = Modifier.padding(start = 12.dp, top = 4.dp),
state = state,
isBalanceHidden = isBalanceHidden,
)
if (state.actionButtons.isNotEmpty()) {
HorizontalActionChips(
modifier = Modifier.padding(top = 12.dp),
@ -220,37 +215,6 @@ private fun FiatBalance(
)
}
}
@Suppress("UnusedPrivateMember")
@Composable
private fun CryptoBalance(
state: TangemPayDetailsBalanceBlockState,
isBalanceHidden: Boolean,
modifier: Modifier = Modifier,
) {
when (state) {
is TangemPayDetailsBalanceBlockState.Loading -> RectangleShimmer(
modifier = modifier.size(
width = TangemTheme.dimens.size70,
height = TangemTheme.dimens.size16,
),
)
is TangemPayDetailsBalanceBlockState.Content -> Text(
modifier = modifier,
text = state.cryptoBalance.orMaskWithStars(isBalanceHidden),
style = TangemTheme.typography.caption2.applyBladeBrush(
isEnabled = state.isBalanceFlickering,
textColor = TangemTheme.colors.text.tertiary,
),
)
is TangemPayDetailsBalanceBlockState.Error -> Text(
modifier = modifier,
text = DASH_SIGN.orMaskWithStars(isBalanceHidden),
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
}
// endregion
@OptIn(ExperimentalMaterial3Api::class)
@ -345,7 +309,6 @@ private class TangemPayDetailsUMProvider : CollectionPreviewParameterProvider<Ta
onClick = {},
),
),
cryptoBalance = "1234.56 USDT",
fiatBalance = "$1234.56",
isBalanceFlickering = false,
),