Updated on 2026-08-14
This commit is contained in:
parent
78c4581372
commit
3069b8d32d
23 changed files with 287 additions and 20 deletions
|
|
@ -1,3 +1,5 @@
|
|||
package com.tangem.features.send.api
|
||||
|
||||
interface SendFeatureToggles
|
||||
interface SendFeatureToggles {
|
||||
val isHighFeeWarningEnabled: Boolean
|
||||
}
|
||||
|
|
@ -1,6 +1,16 @@
|
|||
package com.tangem.features.send
|
||||
|
||||
import com.tangem.core.configtoggle.FeatureToggles
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.features.send.api.SendFeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultSendFeatureToggles @Inject constructor() : SendFeatureToggles
|
||||
internal class DefaultSendFeatureToggles @Inject constructor(
|
||||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
) : SendFeatureToggles {
|
||||
|
||||
override val isHighFeeWarningEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.TWI_1367_HIGH_FEE_WARNING_ENABLED,
|
||||
)
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ import com.tangem.domain.feedback.models.FeedbackEmailType
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.isHotWallet
|
||||
import com.tangem.domain.quotes.IsHighNetworkFeeUseCase
|
||||
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
|
||||
import com.tangem.domain.settings.NeverShowTapHelpUseCase
|
||||
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
|
||||
|
|
@ -43,6 +44,7 @@ import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
|||
import com.tangem.domain.transaction.usecase.gasless.CreateAndSendGaslessTransactionUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.features.send.api.SendFeatureToggles
|
||||
import com.tangem.features.send.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.api.analytics.CommonSendAnalyticEvents.SendScreenSource
|
||||
import com.tangem.features.send.api.subcomponents.amount.SendAmountReduceTrigger
|
||||
|
|
@ -113,6 +115,8 @@ internal class SendConfirmModel @Inject constructor(
|
|||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val createAndSendGaslessTransactionUseCase: CreateAndSendGaslessTransactionUseCase,
|
||||
private val isHighNetworkFeeUseCase: IsHighNetworkFeeUseCase,
|
||||
private val sendFeatureToggles: SendFeatureToggles,
|
||||
sendBalanceUpdaterFactory: SendBalanceUpdater.Factory,
|
||||
) : Model(), SendConfirmClickIntents, FeeSelectorModelCallback, SendNotificationsComponent.ModelCallback {
|
||||
|
||||
|
|
@ -503,6 +507,7 @@ internal class SendConfirmModel @Inject constructor(
|
|||
|
||||
private fun updateConfirmNotifications() {
|
||||
modelScope.launch {
|
||||
val feeCryptoCurrencyStatus = getCurrencyStatusForFeePayment()
|
||||
notificationsUpdateTrigger.triggerUpdate(
|
||||
data = NotificationData(
|
||||
destinationAddress = confirmData.enteredDestination.orEmpty(),
|
||||
|
|
@ -512,9 +517,10 @@ internal class SendConfirmModel @Inject constructor(
|
|||
isIgnoreReduce = confirmData.isIgnoreReduce,
|
||||
fee = confirmData.fee,
|
||||
feeError = confirmData.feeError,
|
||||
feeCryptoCurrencyStatus = getCurrencyStatusForFeePayment(),
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
),
|
||||
)
|
||||
val isHighNetworkFee = isHighNetworkFee(feeCryptoCurrencyStatus.currency)
|
||||
_uiState.update { state ->
|
||||
state.copy(
|
||||
confirmUM = SendConfirmationNotificationsTransformerV2(
|
||||
|
|
@ -524,12 +530,19 @@ internal class SendConfirmModel @Inject constructor(
|
|||
cryptoCurrency = cryptoCurrencyStatus.currency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = params.analyticsCategoryName,
|
||||
isHighNetworkFee = isHighNetworkFee,
|
||||
).transform(uiState.value.confirmUM),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun isHighNetworkFee(feeCurrency: CryptoCurrency): Boolean {
|
||||
if (!sendFeatureToggles.isHighFeeWarningEnabled) return false
|
||||
val feeAmount = confirmData.fee?.amount?.value ?: return false
|
||||
return isHighNetworkFeeUseCase(feeCurrency, feeAmount)
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
private fun configConfirmNavigation() {
|
||||
combine(
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ internal class SendConfirmationNotificationsTransformerV2(
|
|||
private val cryptoCurrency: CryptoCurrency,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val analyticsCategoryName: String,
|
||||
private val isHighNetworkFee: Boolean = false,
|
||||
) : Transformer<ConfirmUM> {
|
||||
override fun transform(prevState: ConfirmUM): ConfirmUM {
|
||||
val state = prevState as? ConfirmUM.Content ?: return prevState
|
||||
|
|
@ -38,10 +39,17 @@ internal class SendConfirmationNotificationsTransformerV2(
|
|||
notifications = buildList {
|
||||
addTooHighNotification(feeSelectorUM)
|
||||
addTooLowNotification(feeSelectorUM)
|
||||
addHighNetworkFeeNotification()
|
||||
}.toPersistentList(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.addHighNetworkFeeNotification() {
|
||||
if (isHighNetworkFee) {
|
||||
add(NotificationUM.Warning.HighNetworkFee)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.addTooLowNotification(feeSelectorUM: FeeSelectorUM.Content) {
|
||||
if (FeeCalculationUtils.checkIfCustomFeeTooLow(feeSelectorUM)) {
|
||||
add(NotificationUM.Warning.FeeTooLow)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
|
||||
import com.tangem.domain.qrscanning.usecases.ParseQrCodeUseCase
|
||||
import com.tangem.domain.quotes.IsHighNetworkFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
|
|
@ -30,6 +31,7 @@ import com.tangem.domain.transaction.usecase.gasless.GetFeeForGaslessUseCase
|
|||
import com.tangem.domain.transaction.usecase.gasless.GetFeeForTokenUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.features.send.api.SendComponent
|
||||
import com.tangem.features.send.api.SendFeatureToggles
|
||||
import com.tangem.features.send.api.analytics.CommonSendAnalyticEvents
|
||||
import com.tangem.features.send.api.entity.PredefinedValues
|
||||
import com.tangem.features.send.api.subcomponents.feeSelector.FeeSelectorCheckReloadListener
|
||||
|
|
@ -122,6 +124,8 @@ internal abstract class SendModelTestBase {
|
|||
protected val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase = mockk(relaxed = true)
|
||||
protected val currenciesRepository: CurrenciesRepository = mockk(relaxed = true)
|
||||
protected val createAndSendGaslessTransactionUseCase: CreateAndSendGaslessTransactionUseCase = mockk(relaxed = true)
|
||||
protected val isHighNetworkFeeUseCase: IsHighNetworkFeeUseCase = mockk(relaxed = true)
|
||||
protected val sendFeatureToggles: SendFeatureToggles = mockk(relaxed = true)
|
||||
protected val sendAnalyticHelper: SendAnalyticHelper = mockk(relaxed = true)
|
||||
protected val sendBalanceUpdaterFactory: SendBalanceUpdater.Factory = mockk(relaxed = true)
|
||||
|
||||
|
|
@ -233,6 +237,8 @@ internal abstract class SendModelTestBase {
|
|||
manageCryptoCurrenciesUseCase = manageCryptoCurrenciesUseCase,
|
||||
currenciesRepository = currenciesRepository,
|
||||
createAndSendGaslessTransactionUseCase = createAndSendGaslessTransactionUseCase,
|
||||
isHighNetworkFeeUseCase = isHighNetworkFeeUseCase,
|
||||
sendFeatureToggles = sendFeatureToggles,
|
||||
sendBalanceUpdaterFactory = sendBalanceUpdaterFactory,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
val initialState: ConfirmUM = ConfirmUM.Empty
|
||||
|
||||
|
|
@ -98,6 +99,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
val initialState = createTestConfirmUM()
|
||||
|
||||
|
|
@ -120,6 +122,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
val initialState = createTestConfirmUM()
|
||||
|
||||
|
|
@ -145,6 +148,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
val initialState = createTestConfirmUM()
|
||||
|
||||
|
|
@ -158,6 +162,31 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
assertThat(content.notifications.first()).isInstanceOf(NotificationUM.Warning.TooHigh::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN high network fee WHEN transform THEN returns state with high network fee notification`() = runTest {
|
||||
// GIVEN
|
||||
val feeSelectorUM = createNormalFeeSelectorUM()
|
||||
val amountUM = createTestAmountUM()
|
||||
val transformer = SendConfirmationNotificationsTransformerV2(
|
||||
feeSelectorUM = feeSelectorUM,
|
||||
amountUM = amountUM,
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = true,
|
||||
)
|
||||
val initialState = createTestConfirmUM()
|
||||
|
||||
// WHEN
|
||||
val result = transformer.transform(initialState)
|
||||
|
||||
// THEN
|
||||
assertThat(result).isInstanceOf(ConfirmUM.Content::class.java)
|
||||
val content = result as ConfirmUM.Content
|
||||
assertThat(content.notifications).containsExactly(NotificationUM.Warning.HighNetworkFee)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN fee too low WHEN transform THEN returns state with too low notification`() = runTest {
|
||||
// GIVEN
|
||||
|
|
@ -170,6 +199,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
val initialState = createTestConfirmUM()
|
||||
|
||||
|
|
@ -196,6 +226,7 @@ class SendConfirmationNotificationsTransformerV2Test {
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
appCurrency = appCurrency,
|
||||
analyticsCategoryName = analyticsCategoryName,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
val initialState = createTestConfirmUM()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,4 +2,5 @@ package com.tangem.features.swap.v2.api
|
|||
|
||||
interface SwapFeatureToggles {
|
||||
val isSwapProviderFilterEnabled: Boolean
|
||||
val isHighFeeWarningEnabled: Boolean
|
||||
}
|
||||
|
|
@ -10,4 +10,7 @@ internal class DefaultSwapFeatureToggles @Inject constructor(
|
|||
) : SwapFeatureToggles {
|
||||
override val isSwapProviderFilterEnabled: Boolean =
|
||||
featureToggles.isFeatureEnabled(FeatureToggles.AND_15009_SWAP_PROVIDER_FILTER_ENABLED)
|
||||
|
||||
override val isHighFeeWarningEnabled: Boolean =
|
||||
featureToggles.isFeatureEnabled(FeatureToggles.TWI_1367_HIGH_FEE_WARNING_ENABLED)
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import com.tangem.domain.models.account.derivationIndex
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.isHotWallet
|
||||
import com.tangem.domain.quotes.IsHighNetworkFeeUseCase
|
||||
import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase
|
||||
import com.tangem.domain.swap.models.SwapAmountType
|
||||
import com.tangem.domain.swap.models.SwapDirection.Companion.withSwapDirection
|
||||
|
|
@ -47,6 +48,7 @@ import com.tangem.features.send.api.subcomponents.destination.entity.Destination
|
|||
import com.tangem.features.send.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
|
||||
import com.tangem.features.send.api.subcomponents.notifications.SendNotificationsUpdateListener
|
||||
import com.tangem.features.send.api.subcomponents.notifications.SendNotificationsUpdateTrigger
|
||||
import com.tangem.features.swap.v2.api.SwapFeatureToggles
|
||||
import com.tangem.features.swap.v2.api.subcomponents.SwapAmountUpdateTrigger
|
||||
import com.tangem.features.swap.v2.impl.R
|
||||
import com.tangem.features.swap.v2.impl.amount.SwapAmountReduceTrigger
|
||||
|
|
@ -89,6 +91,8 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
private val estimateFeeForTokenUseCase: EstimateFeeForTokenUseCase,
|
||||
private val estimateFeeForGaslessTxUseCase: EstimateFeeForGaslessTxUseCase,
|
||||
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase,
|
||||
private val isHighNetworkFeeUseCase: IsHighNetworkFeeUseCase,
|
||||
private val swapFeatureToggles: SwapFeatureToggles,
|
||||
private val getExplorerTransactionUrlUseCase: GetExplorerTransactionUrlUseCase,
|
||||
private val sendNotificationsUpdateTrigger: SendNotificationsUpdateTrigger,
|
||||
private val swapNotificationsUpdateTrigger: SwapNotificationsUpdateTrigger,
|
||||
|
|
@ -467,12 +471,19 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
feeValue = confirmData.fee?.amount?.value,
|
||||
),
|
||||
)
|
||||
val isHighNetworkFee = isHighNetworkFee(feeCryptoCurrencyStatus.currency)
|
||||
uiState.transformerUpdate(
|
||||
SendWithSwapConfirmationNotificationsTransformer(),
|
||||
SendWithSwapConfirmationNotificationsTransformer(isHighNetworkFee = isHighNetworkFee),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun isHighNetworkFee(feeCurrency: CryptoCurrency): Boolean {
|
||||
if (!swapFeatureToggles.isHighFeeWarningEnabled) return false
|
||||
val feeAmount = confirmData.fee?.amount?.value ?: return false
|
||||
return isHighNetworkFeeUseCase(feeCurrency, feeAmount)
|
||||
}
|
||||
|
||||
private fun subscribeOnNotificationUpdates() {
|
||||
combine(
|
||||
flow = sendNotificationsUpdateListener.hasErrorFlow,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import com.tangem.features.swap.v2.impl.sendviaswap.entity.SendWithSwapUM
|
|||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
internal class SendWithSwapConfirmationNotificationsTransformer : Transformer<SendWithSwapUM> {
|
||||
internal class SendWithSwapConfirmationNotificationsTransformer(
|
||||
private val isHighNetworkFee: Boolean,
|
||||
) : Transformer<SendWithSwapUM> {
|
||||
override fun transform(prevState: SendWithSwapUM): SendWithSwapUM {
|
||||
val confirmUM = prevState.confirmUM as? ConfirmUM.Content ?: return prevState
|
||||
val feeSelectorUM = prevState.feeSelectorUM as? FeeSelectorUM.Content ?: return prevState
|
||||
|
|
@ -34,11 +36,18 @@ internal class SendWithSwapConfirmationNotificationsTransformer : Transformer<Se
|
|||
notifications = buildList {
|
||||
addTooHighNotification(feeSelectorUM = feeSelectorUM)
|
||||
addTooLowNotification(feeSelectorUM = feeSelectorUM)
|
||||
addHighNetworkFeeNotification()
|
||||
}.toPersistentList(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.addHighNetworkFeeNotification() {
|
||||
if (isHighNetworkFee) {
|
||||
add(NotificationUM.Warning.HighNetworkFee)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.addTooLowNotification(feeSelectorUM: FeeSelectorUM.Content) {
|
||||
if (checkIfCustomFeeTooLow(feeSelectorUM = feeSelectorUM)) {
|
||||
add(NotificationUM.Warning.FeeTooLow)
|
||||
|
|
|
|||
|
|
@ -10,4 +10,5 @@ interface SwapFeatureToggles {
|
|||
val isSwapPredefinedButtonsEnabled: Boolean
|
||||
val isExpressShareButtonEnabled: Boolean
|
||||
val isSwapBestDexRateEnabled: Boolean
|
||||
val isHighFeeWarningEnabled: Boolean
|
||||
}
|
||||
|
|
@ -52,4 +52,9 @@ internal class DefaultSwapFeatureToggles @Inject constructor(
|
|||
get() = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.AND_15715_SWAP_BEST_DEX_RATE_ENABLED,
|
||||
) && isSwapIntegratedApproveEnabled
|
||||
|
||||
override val isHighFeeWarningEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(
|
||||
toggle = FeatureToggles.TWI_1367_HIGH_FEE_WARNING_ENABLED,
|
||||
)
|
||||
}
|
||||
|
|
@ -65,6 +65,7 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.models.wallet.isHotWallet
|
||||
import com.tangem.domain.pay.WithdrawalResult
|
||||
import com.tangem.domain.pay.usecase.GetPaymentAccountCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.quotes.IsHighNetworkFeeUseCase
|
||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions
|
||||
|
|
@ -173,6 +174,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val getSwapUiModeUseCase: GetSwapUiModeUseCase,
|
||||
private val setSwapUiModeUseCase: SetSwapUiModeUseCase,
|
||||
private val calculateAmountUseCase: CalculateAmountUseCase,
|
||||
private val isHighNetworkFeeUseCase: IsHighNetworkFeeUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<SwapComponent.Params>()
|
||||
|
|
@ -1103,7 +1105,7 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun setupLoadedState(
|
||||
private suspend fun setupLoadedState(
|
||||
provider: SwapProvider,
|
||||
state: SwapState,
|
||||
fromSwapCurrencyStatus: SwapCurrencyStatus,
|
||||
|
|
@ -1127,7 +1129,7 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupQuotesLoadedUiState(provider: SwapProvider, state: SwapState.QuotesLoadedState) {
|
||||
private suspend fun setupQuotesLoadedUiState(provider: SwapProvider, state: SwapState.QuotesLoadedState) {
|
||||
val loadedStates = dataState.getLastLoadedSuccessStates()
|
||||
val additionalBadge = SwapProviderResolver.resolveBadge(
|
||||
provider = provider,
|
||||
|
|
@ -1136,17 +1138,26 @@ internal class SwapModel @Inject constructor(
|
|||
state = state,
|
||||
isSwapBestDexRateEnabled = swapFeatureToggles.isSwapBestDexRateEnabled,
|
||||
)
|
||||
val swapFee = getSelectedSwapFee()
|
||||
uiState = stateBuilder.createQuotesLoadedState(
|
||||
uiStateHolder = uiState,
|
||||
quoteModel = state,
|
||||
feeCryptoCurrencyStatus = dataState.feePaidCryptoCurrency,
|
||||
swapProvider = provider,
|
||||
additionalBadge = additionalBadge,
|
||||
swapFee = getSelectedSwapFee(),
|
||||
swapFee = swapFee,
|
||||
feeError = feeSelectorRepository.state.value as? FeeSelectorUM.Error,
|
||||
isHighNetworkFee = isHighNetworkFee(swapFee),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun isHighNetworkFee(swapFee: SwapFee?): Boolean {
|
||||
if (!swapFeatureToggles.isHighFeeWarningEnabled) return false
|
||||
swapFee ?: return false
|
||||
val feeAmount = swapFee.fee.amount.value ?: return false
|
||||
return isHighNetworkFeeUseCase(swapFee.selectedFeeToken.currency, feeAmount)
|
||||
}
|
||||
|
||||
private fun sendAnalyticsForNotifications(
|
||||
provider: SwapProvider,
|
||||
fromToken: CryptoCurrencyStatus,
|
||||
|
|
@ -2077,12 +2088,14 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
analyticsEventHandler.send(SwapEvents.ProviderChosen(provider))
|
||||
uiState = stateBuilder.dismissBottomSheet(uiState)
|
||||
setupLoadedState(
|
||||
provider = provider,
|
||||
state = swapState,
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
)
|
||||
modelScope.launch {
|
||||
setupLoadedState(
|
||||
provider = provider,
|
||||
state = swapState,
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
onProviderFilterSelect = { filterType ->
|
||||
|
|
@ -2823,12 +2836,14 @@ internal class SwapModel @Inject constructor(
|
|||
}
|
||||
},
|
||||
)
|
||||
setupLoadedState(
|
||||
provider = provider,
|
||||
state = swapState,
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
)
|
||||
modelScope.launch {
|
||||
setupLoadedState(
|
||||
provider = provider,
|
||||
state = swapState,
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
TangemLogger.e("loadFee: ${feeError.error}, isHidden = true")
|
||||
refreshTransferUIStateIfNeeded()
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ internal class SwapNotificationsFactory(
|
|||
swapFee: SwapFee?,
|
||||
feeError: GetFeeError?,
|
||||
appRouter: AppRouter,
|
||||
isHighNetworkFee: Boolean = false,
|
||||
): ImmutableList<NotificationUM> {
|
||||
val warnings = buildList {
|
||||
maybeAddFeeErrorNotification(feeCryptoCurrencyStatus, quoteModel, feeError)
|
||||
|
|
@ -135,10 +136,17 @@ internal class SwapNotificationsFactory(
|
|||
maybeAddUnableCoverFeeWarning(quoteModel, feeCryptoCurrencyStatus, appRouter)
|
||||
maybeAddTransactionInProgressWarning(quoteModel)
|
||||
maybeAddPriceImpactNotification(quoteModel.priceImpact)
|
||||
maybeAddHighNetworkFeeWarning(isHighNetworkFee)
|
||||
}
|
||||
return warnings.toPersistentList()
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.maybeAddHighNetworkFeeWarning(isHighNetworkFee: Boolean) {
|
||||
if (isHighNetworkFee) {
|
||||
add(NotificationUM.Warning.HighNetworkFee)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.maybeAddRentExemptionError(quoteModel: SwapState.QuotesLoadedState) {
|
||||
quoteModel.currencyCheck?.rentWarning?.let {
|
||||
add(NotificationUM.Solana.RentInfo(it))
|
||||
|
|
|
|||
|
|
@ -577,6 +577,7 @@ internal class StateBuilder(
|
|||
additionalBadge: ProviderState.AdditionalBadge,
|
||||
swapFee: SwapFee?,
|
||||
feeError: FeeSelectorUM.Error?,
|
||||
isHighNetworkFee: Boolean,
|
||||
): SwapStateHolder {
|
||||
if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
if (uiStateHolder.receiveCardData !is SwapCardState.SwapCardData) return uiStateHolder
|
||||
|
|
@ -590,6 +591,7 @@ internal class StateBuilder(
|
|||
swapFee = swapFee,
|
||||
feeError = feeError?.error,
|
||||
appRouter = appRouter,
|
||||
isHighNetworkFee = isHighNetworkFee,
|
||||
)
|
||||
|
||||
val fromAccountTitleUM = when {
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ internal class StateBuilderSwapButtonTest {
|
|||
additionalBadge = ProviderState.AdditionalBadge.Empty,
|
||||
swapFee = null,
|
||||
feeError = null,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isTrue()
|
||||
|
|
@ -134,6 +135,7 @@ internal class StateBuilderSwapButtonTest {
|
|||
additionalBadge = ProviderState.AdditionalBadge.Empty,
|
||||
swapFee = null,
|
||||
feeError = null,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isFalse()
|
||||
|
|
@ -163,6 +165,7 @@ internal class StateBuilderSwapButtonTest {
|
|||
additionalBadge = ProviderState.AdditionalBadge.Empty,
|
||||
swapFee = null,
|
||||
feeError = null,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isFalse()
|
||||
|
|
@ -187,6 +190,7 @@ internal class StateBuilderSwapButtonTest {
|
|||
additionalBadge = ProviderState.AdditionalBadge.Empty,
|
||||
swapFee = buildSwapFee(),
|
||||
feeError = null,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isTrue()
|
||||
|
|
@ -215,6 +219,7 @@ internal class StateBuilderSwapButtonTest {
|
|||
additionalBadge = ProviderState.AdditionalBadge.Empty,
|
||||
swapFee = buildSwapFee(),
|
||||
feeError = null,
|
||||
isHighNetworkFee = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isFalse()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.usecase.GetPaymentAccountCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.quotes.IsHighNetworkFeeUseCase
|
||||
import com.tangem.domain.settings.usercountry.GetUserCountryUseCase
|
||||
import com.tangem.domain.settings.usercountry.models.UserCountry
|
||||
import com.tangem.domain.stories.ShouldShowStoriesUseCase
|
||||
|
|
@ -103,6 +104,7 @@ internal abstract class SwapModelTestBase {
|
|||
protected val getSwapUiModeUseCase: GetSwapUiModeUseCase = mockk(relaxed = true)
|
||||
protected val setSwapUiModeUseCase: SetSwapUiModeUseCase = mockk(relaxed = true)
|
||||
protected val calculateAmountUseCase: CalculateAmountUseCase = mockk(relaxed = true)
|
||||
protected val isHighNetworkFeeUseCase: IsHighNetworkFeeUseCase = mockk(relaxed = true)
|
||||
protected val isWalletBackupProblematicUseCase: IsWalletBackupProblematicUseCase = mockk(relaxed = true)
|
||||
protected val sendBackupProblemEmailUseCase: SendBackupProblemEmailUseCase = mockk(relaxed = true)
|
||||
|
||||
|
|
@ -175,6 +177,7 @@ internal abstract class SwapModelTestBase {
|
|||
getSwapUiModeUseCase = getSwapUiModeUseCase,
|
||||
setSwapUiModeUseCase = setSwapUiModeUseCase,
|
||||
calculateAmountUseCase = calculateAmountUseCase,
|
||||
isHighNetworkFeeUseCase = isHighNetworkFeeUseCase,
|
||||
isWalletBackupProblematicUseCase = isWalletBackupProblematicUseCase,
|
||||
sendBackupProblemEmailUseCase = sendBackupProblemEmailUseCase,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue