Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-28 17:31:47 +05:00
commit 68282ea495
11 changed files with 72 additions and 44 deletions

View file

@ -14,7 +14,7 @@ sealed class FeeSelectorParams {
abstract val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>
abstract val cryptoCurrencyStatus: CryptoCurrencyStatus
abstract val feeCryptoCurrencyStatus: CryptoCurrencyStatus
abstract val suggestedFeeState: SuggestedFeeState
abstract val feeStateConfiguration: FeeStateConfiguration
abstract val feeDisplaySource: FeeDisplaySource
data class FeeSelectorBlockParams(
@ -22,7 +22,7 @@ sealed class FeeSelectorParams {
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
override val suggestedFeeState: SuggestedFeeState,
override val feeStateConfiguration: FeeStateConfiguration,
override val feeDisplaySource: FeeDisplaySource,
) : FeeSelectorParams()
@ -31,14 +31,16 @@ sealed class FeeSelectorParams {
override val onLoadFee: suspend () -> Either<GetFeeError, TransactionFee>,
override val cryptoCurrencyStatus: CryptoCurrencyStatus,
override val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
override val suggestedFeeState: SuggestedFeeState,
override val feeStateConfiguration: FeeStateConfiguration,
override val feeDisplaySource: FeeDisplaySource,
val callback: FeeSelectorModelCallback,
) : FeeSelectorParams()
sealed class SuggestedFeeState {
data object None : SuggestedFeeState()
data class Suggestion(val title: TextReference, val fee: Fee) : SuggestedFeeState()
sealed class FeeStateConfiguration {
data object None : FeeStateConfiguration()
data class Suggestion(val title: TextReference, val fee: Fee) : FeeStateConfiguration()
data object ExcludeLow : FeeStateConfiguration()
}
enum class FeeDisplaySource {

View file

@ -48,7 +48,7 @@ internal class DefaultFeeSelectorBlockComponent @AssistedInject constructor(
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
callback = model,
suggestedFeeState = FeeSelectorParams.SuggestedFeeState.None,
feeStateConfiguration = params.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,
),
onDismiss = {

View file

@ -96,7 +96,7 @@ internal class FeeSelectorModel @Inject constructor(
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
appCurrency = appCurrency,
fees = fee,
suggestedFeeState = params.suggestedFeeState,
feeStateConfiguration = params.feeStateConfiguration,
isFeeApproximate = isFeeApproximate(fee.normal.amount.type),
feeSelectorIntents = this@FeeSelectorModel,
),

View file

@ -12,7 +12,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
internal class FeeItemConverter(
private val suggestedFeeState: FeeSelectorParams.SuggestedFeeState,
private val feeStateConfiguration: FeeSelectorParams.FeeStateConfiguration,
private val normalFee: Fee,
private val feeSelectorIntents: FeeSelectorIntents,
private val appCurrency: AppCurrency,
@ -29,32 +29,58 @@ internal class FeeItemConverter(
override fun convert(value: Input): ImmutableList<FeeItem> {
val fees = mutableListOf<FeeItem>()
when (suggestedFeeState) {
FeeSelectorParams.SuggestedFeeState.None -> Unit
is FeeSelectorParams.SuggestedFeeState.Suggestion -> fees.add(
FeeItem.Suggested(
title = suggestedFeeState.title,
fee = suggestedFeeState.fee,
),
)
}
when (value.transactionFee) {
is TransactionFee.Choosable -> {
fees.add(FeeItem.Slow(fee = value.transactionFee.minimum))
fees.add(FeeItem.Market(fee = value.transactionFee.normal))
fees.add(FeeItem.Fast(fee = value.transactionFee.priority))
when (feeStateConfiguration) {
FeeSelectorParams.FeeStateConfiguration.None -> fees.addFeeItemsFull(value = value)
is FeeSelectorParams.FeeStateConfiguration.Suggestion -> {
fees.addFeeItemSuggested(feeStateConfiguration)
fees.addFeeItemsFull(value = value)
}
is TransactionFee.Single -> {
fees.add(FeeItem.Market(fee = value.transactionFee.normal))
FeeSelectorParams.FeeStateConfiguration.ExcludeLow -> {
fees.addFeeItemsLimited(value = value)
}
}
val customFee = value.customFee ?: constructCustomFee()
customFee?.let(fees::add)
return fees.toImmutableList()
}
private fun MutableList<FeeItem>.addFeeItemsFull(value: Input) {
when (value.transactionFee) {
is TransactionFee.Choosable -> {
add(FeeItem.Slow(fee = value.transactionFee.minimum))
add(FeeItem.Market(fee = value.transactionFee.normal))
add(FeeItem.Fast(fee = value.transactionFee.priority))
}
is TransactionFee.Single -> {
add(FeeItem.Market(fee = value.transactionFee.normal))
}
}
val customFee = value.customFee ?: constructCustomFee()
customFee?.let(::add)
}
private fun MutableList<FeeItem>.addFeeItemsLimited(value: Input) {
when (value.transactionFee) {
is TransactionFee.Choosable -> {
add(FeeItem.Market(fee = value.transactionFee.normal))
add(FeeItem.Fast(fee = value.transactionFee.priority))
}
is TransactionFee.Single -> {
add(FeeItem.Market(fee = value.transactionFee.normal))
}
}
}
private fun MutableList<FeeItem>.addFeeItemSuggested(
feeStateConfiguration: FeeSelectorParams.FeeStateConfiguration.Suggestion,
) {
add(
FeeItem.Suggested(
title = feeStateConfiguration.title,
fee = feeStateConfiguration.fee,
),
)
}
private fun constructCustomFee(): FeeItem.Custom? {
val customFeeFields = customFeeFieldConverter.convert(normalFee)

View file

@ -18,13 +18,13 @@ internal class FeeSelectorLoadedTransformer(
private val feeCryptoCurrencyStatus: CryptoCurrencyStatus,
private val appCurrency: AppCurrency,
private val fees: TransactionFee,
private val suggestedFeeState: FeeSelectorParams.SuggestedFeeState,
private val feeStateConfiguration: FeeSelectorParams.FeeStateConfiguration,
private val isFeeApproximate: Boolean,
private val feeSelectorIntents: FeeSelectorIntents,
) : Transformer<FeeSelectorUM> {
private val feeItemsConverter = FeeItemConverter(
suggestedFeeState = suggestedFeeState,
feeStateConfiguration = feeStateConfiguration,
normalFee = fees.normal,
feeSelectorIntents = feeSelectorIntents,
appCurrency = appCurrency,

View file

@ -102,7 +102,7 @@ internal class SendConfirmComponent(
onLoadFee = params.onLoadFee,
feeCryptoCurrencyStatus = params.feeCryptoCurrencyStatus,
cryptoCurrencyStatus = params.cryptoCurrencyStatus,
suggestedFeeState = model.suggestedFeeState,
feeStateConfiguration = model.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,
),
onResult = model::onFeeResult,

View file

@ -26,6 +26,7 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.BlockchainErrorInfo
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
import com.tangem.domain.settings.NeverShowTapHelpUseCase
import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
@ -34,12 +35,11 @@ import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.domain.models.wallet.requireColdWallet
import com.tangem.features.send.v2.api.SendNotificationsComponent
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeNonce
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeStateConfiguration
import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.send.v2.api.subcomponents.notifications.SendNotificationsUpdateListener
@ -144,7 +144,7 @@ internal class SendConfirmModel @Inject constructor(
private var sendIdleTimer: Long = 0L
private var isAmountSubtractAvailable = false
internal var suggestedFeeState: FeeSelectorParams.SuggestedFeeState = FeeSelectorParams.SuggestedFeeState.None
internal var feeStateConfiguration: FeeStateConfiguration = FeeStateConfiguration.None
init {
modelScope.launch {

View file

@ -16,7 +16,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
import com.tangem.features.send.v2.api.SendNotificationsComponent
import com.tangem.features.send.v2.api.entity.PredefinedValues
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.api.params.FeeSelectorParams.*
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationComponentParams
import com.tangem.features.swap.v2.impl.amount.SwapAmountBlockComponent
@ -80,13 +80,13 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
private val feeSelectorBlockComponent = feeSelectorBlockComponentFactory.create(
context = child("sendWithSwapConfirmFeeBlock"),
params = FeeSelectorParams.FeeSelectorBlockParams(
params = FeeSelectorBlockParams(
state = model.uiState.value.feeSelectorUM,
onLoadFee = model::loadFee,
feeCryptoCurrencyStatus = model.primaryFeePaidCurrencyStatus,
cryptoCurrencyStatus = model.primaryCurrencyStatus,
suggestedFeeState = FeeSelectorParams.SuggestedFeeState.None,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.Screen,
feeStateConfiguration = FeeStateConfiguration.ExcludeLow,
feeDisplaySource = FeeDisplaySource.Screen,
),
onResult = model::onFeeResult,
)

View file

@ -48,7 +48,7 @@ internal fun getWcCommonScreen(
feeCryptoCurrencyStatus = model.cryptoCurrencyStatus,
cryptoCurrencyStatus = model.cryptoCurrencyStatus,
callback = model,
suggestedFeeState = model.suggestedFeeState,
feeStateConfiguration = model.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.BottomSheet,
),
)

View file

@ -27,7 +27,7 @@ internal class WcSendTransactionComponent(
onLoadFee = model::loadFee,
cryptoCurrencyStatus = model.cryptoCurrencyStatus,
feeCryptoCurrencyStatus = model.cryptoCurrencyStatus,
suggestedFeeState = model.suggestedFeeState,
feeStateConfiguration = model.feeStateConfiguration,
feeDisplaySource = FeeSelectorParams.FeeDisplaySource.BottomSheet,
),
onResult = model::updateFee,

View file

@ -18,6 +18,7 @@ import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.core.lce.Lce
import com.tangem.domain.models.network.Network
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.tokens.GetNetworkCoinStatusUseCase
import com.tangem.domain.tokens.error.CurrencyStatusError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
@ -28,10 +29,9 @@ import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
import com.tangem.domain.walletconnect.model.WcRequestError
import com.tangem.domain.walletconnect.model.WcRequestError.Companion.message
import com.tangem.domain.walletconnect.usecase.method.*
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.features.send.v2.api.callbacks.FeeSelectorModelCallback
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.params.FeeSelectorParams
import com.tangem.features.send.v2.api.params.FeeSelectorParams.FeeStateConfiguration
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.send.v2.api.subcomponents.feeSelector.entity.FeeSelectorData
import com.tangem.features.walletconnect.connections.routing.WcInnerRoute
@ -77,7 +77,7 @@ internal class WcSendTransactionModel @Inject constructor(
val stackNavigation = StackNavigation<WcTransactionRoutes>()
internal var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
internal var suggestedFeeState: FeeSelectorParams.SuggestedFeeState = FeeSelectorParams.SuggestedFeeState.None
internal var feeStateConfiguration: FeeStateConfiguration = FeeStateConfiguration.None
private var useCase: WcSignUseCase<*> by Delegates.notNull()
private var signState: WcSignState<*> by Delegates.notNull()
private var wcApproval: WcApproval? = null
@ -103,7 +103,7 @@ internal class WcSendTransactionModel @Inject constructor(
(useCase as? WcMutableFee)
?.dAppFee()
?.let { dAppFee ->
suggestedFeeState = FeeSelectorParams.SuggestedFeeState.Suggestion(
feeStateConfiguration = FeeStateConfiguration.Suggestion(
title = stringReference(useCase.session.sdkModel.appMetaData.name),
fee = dAppFee,
)