Updated on 2026-08-14

This commit is contained in:
Tangem 2026-01-18 13:56:25 +03:00
parent c024ba2836
commit 96784ebd43
8 changed files with 53 additions and 21 deletions

View file

@ -98,6 +98,7 @@ fun FeeExtendedSelectorContent(state: FeeExtendedSelectorUM, modifier: Modifier
},
ellipsizeOffset = fee.amount.currencySymbol.length,
showSelectorIcon = isChooseSpeedAvailable,
isNotEnoughFunds = state.parent.feeExtraInfo.isNotEnoughFunds,
isLoading = state.fee.isLoading(),
)
}
@ -168,6 +169,7 @@ private fun Preview() {
isFeeConvertibleToFiat = true,
isTronToken = false,
feeCryptoCurrencyStatus = cryptoCurrencyStatus,
isNotEnoughFunds = true,
),
feeNonce = FeeNonce.None,
feeFiatRateUM = FeeFiatRateUM(

View file

@ -328,6 +328,7 @@ internal fun RegularFeeItemContent(
ellipsizeOffset: Int? = null,
showSelectorIcon: Boolean = false,
isLoading: Boolean = false,
isNotEnoughFunds: Boolean = false,
) {
Column(modifier = modifier) {
Row(
@ -353,6 +354,7 @@ internal fun RegularFeeItemContent(
postDot = postDot,
ellipsizeOffset = ellipsizeOffset,
isLoading = isLoading,
isNotEnoughFunds = isNotEnoughFunds,
)
if (showSelectorIcon) {
@ -376,6 +378,7 @@ private fun FeeDescription(
postDot: TextReference? = null,
ellipsizeOffset: Int? = null,
isLoading: Boolean = false,
isNotEnoughFunds: Boolean = false,
) {
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(2.dp)) {
Text(
@ -385,6 +388,11 @@ private fun FeeDescription(
modifier = Modifier.testTag(SendSelectNetworkFeeBottomSheetTestTags.REGULAR_ITEM_TITLE),
)
when {
isNotEnoughFunds -> Text(
text = stringResourceSafe(R.string.gasless_not_enough_funds_to_cover_token_fee),
color = TangemTheme.colors.text.warning,
style = TangemTheme.typography.caption1,
)
isLoading -> TextShimmer(
modifier = Modifier.width(122.dp),
style = TangemTheme.typography.caption1,

View file

@ -3,6 +3,7 @@ package com.tangem.features.send.v2.feeselector.model
import arrow.core.Either
import arrow.core.flatMap
import arrow.core.getOrElse
import arrow.core.left
import arrow.core.raise.either
import com.tangem.blockchain.common.AmountType
import com.tangem.blockchain.common.transaction.TransactionFee
@ -228,10 +229,13 @@ internal class FeeSelectorLogic @AssistedInject constructor(
return extended(selectedTokenOrNull).fold(
ifLeft = { error ->
if (error is GetFeeError.GaslessError) {
params.onLoadFee().map { LoadedFeeResult.Basic(it) }
} else {
Either.Left(error)
when (error) {
is GetFeeError.GaslessError.NotEnoughFunds -> error.left()
is GetFeeError.GaslessError -> {
// Something wrong with gasless fee, fallback to basic fee
params.onLoadFee().map { LoadedFeeResult.Basic(it) }
}
else -> error.left()
}
},
ifRight = { fee ->
@ -243,32 +247,38 @@ internal class FeeSelectorLogic @AssistedInject constructor(
private suspend fun populateExtendedFee(
fee: TransactionFeeExtended,
): Either<GetFeeError, LoadedFeeResult.Extended> = either {
val selectedToken = if (params.feeCryptoCurrencyStatus.currency.id != fee.feeTokenId) {
getSingleCryptoCurrencyStatusUseCase
.invokeMultiWalletSync(
userWalletId = params.userWalletId,
cryptoCurrencyId = fee.feeTokenId,
).getOrElse {
raise(GetFeeError.DataError(IllegalStateException("No token found for id: ${fee.feeTokenId}")))
}
} else {
params.feeCryptoCurrencyStatus
LoadedFeeResult.Extended(
fee = fee,
selectedToken = getSelectedTokenStatus(fee.feeTokenId).bind(),
availableTokens = getAvailableFeeTokens().bind(),
)
}
private suspend fun getSelectedTokenStatus(tokenId: CryptoCurrency.ID): Either<GetFeeError, CryptoCurrencyStatus> =
either {
val feeTokenId = tokenId
if (params.feeCryptoCurrencyStatus.currency.id != feeTokenId) {
getSingleCryptoCurrencyStatusUseCase
.invokeMultiWalletSync(
userWalletId = params.userWalletId,
cryptoCurrencyId = feeTokenId,
).getOrElse {
raise(GetFeeError.DataError(IllegalStateException("No token found for id: $tokenId")))
}
} else {
params.feeCryptoCurrencyStatus
}
}
private suspend fun getAvailableFeeTokens(): Either<GetFeeError, List<CryptoCurrencyStatus>> = either {
val userWallet = getUserWalletUseCase(params.userWalletId).mapLeft {
GetFeeError.DataError(IllegalStateException("No wallet found for id: ${params.userWalletId}"))
}.bind()
val availableTokens = getAvailableFeeTokensUseCase.invoke(
getAvailableFeeTokensUseCase.invoke(
userWallet = userWallet,
network = params.cryptoCurrencyStatus.currency.network,
).bind()
LoadedFeeResult.Extended(
fee = fee,
selectedToken = selectedToken,
availableTokens = availableTokens,
)
}
sealed class LoadedFeeResult {

View file

@ -7,6 +7,13 @@ import com.tangem.utils.transformer.Transformer
internal class FeeSelectorErrorTransformer(private val error: GetFeeError) : Transformer<FeeSelectorUM> {
override fun transform(prevState: FeeSelectorUM): FeeSelectorUM {
if (prevState is FeeSelectorUM.Content && error is GetFeeError.GaslessError.NotEnoughFunds) {
return prevState.copy(
isPrimaryButtonEnabled = false,
feeExtraInfo = prevState.feeExtraInfo.copy(isNotEnoughFunds = true),
)
}
return FeeSelectorUM.Error(error = error)
}
}

View file

@ -18,6 +18,7 @@ class FeeSelectorTokenSelectedTransformer(
feeItems = persistentListOf(FeeItem.Loading),
feeExtraInfo = prevState.feeExtraInfo.copy(
feeCryptoCurrencyStatus = selectedToken,
isNotEnoughFunds = false,
),
)
} else {