diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml
index 6ac1337a55..5197f96905 100644
--- a/core/res/src/main/res/values-ja/strings.xml
+++ b/core/res/src/main/res/values-ja/strings.xml
@@ -552,6 +552,7 @@
Tangemへのフィードバック
取引を送信できません
コインの説明エラー
+ ガス代不要の取引手数料
エラーが発生しました
エラーが発生しました。コード: %s 。
メモが必要
@@ -973,6 +974,7 @@
アクセスコードの復元
同一のカード
アクセスコード
+ 同時に利用できるのは、モバイルウォレットまたはハードウェアウォレットのいずれか一方のみです。Tangemのコールドウォレットを使用するには、ウォレットをアップグレードするか、アプリから削除してください。
すべてのオファー
%sで利用可能
プロバイダーが取引を促進します
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 128a5d68c7..a5e90a215a 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -560,6 +560,7 @@
Tangem feedback
Can\'t send a transaction
Coin description error
+ Not enough funds
Gasless transaction fee
An error occurred
An error occurred. Code: %s.
diff --git a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt
index 3706fa2f92..9d92d11e1c 100644
--- a/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt
+++ b/features/send-v2/api/src/main/java/com/tangem/features/send/v2/api/entity/FeeSelectorUM.kt
@@ -68,6 +68,7 @@ data class FeeExtraInfo(
val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
val availableFeeCurrencies: ImmutableList? = null,
val transactionFeeExtended: TransactionFeeExtended? = null,
+ val isNotEnoughFunds: Boolean = false,
)
sealed class FeeNonce {
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/extended/ui/FeeExtendedSelectorContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/extended/ui/FeeExtendedSelectorContent.kt
index eef8cc085a..e084555a7b 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/extended/ui/FeeExtendedSelectorContent.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/extended/ui/FeeExtendedSelectorContent.kt
@@ -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(
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/speed/ui/FeeSpeedSelectorContent.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/speed/ui/FeeSpeedSelectorContent.kt
index 89a8ed3660..ef604613c9 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/speed/ui/FeeSpeedSelectorContent.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/component/speed/ui/FeeSpeedSelectorContent.kt
@@ -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,
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt
index 8afabe494a..100d288151 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/FeeSelectorLogic.kt
@@ -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 = 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 =
+ 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> = 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 {
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorErrorTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorErrorTransformer.kt
index 80386d5c77..7cac2f632f 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorErrorTransformer.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorErrorTransformer.kt
@@ -7,6 +7,13 @@ import com.tangem.utils.transformer.Transformer
internal class FeeSelectorErrorTransformer(private val error: GetFeeError) : Transformer {
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)
}
}
\ No newline at end of file
diff --git a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorTokenSelectedTransformer.kt b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorTokenSelectedTransformer.kt
index f11d9c8dd9..c054119f3d 100644
--- a/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorTokenSelectedTransformer.kt
+++ b/features/send-v2/impl/src/main/java/com/tangem/features/send/v2/feeselector/model/transformers/FeeSelectorTokenSelectedTransformer.kt
@@ -18,6 +18,7 @@ class FeeSelectorTokenSelectedTransformer(
feeItems = persistentListOf(FeeItem.Loading),
feeExtraInfo = prevState.feeExtraInfo.copy(
feeCryptoCurrencyStatus = selectedToken,
+ isNotEnoughFunds = false,
),
)
} else {