Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-05 14:52:28 +01:00
parent 0091d0131f
commit 02c12c524b
11 changed files with 40 additions and 25 deletions

View file

@ -66,5 +66,9 @@
{
"name": "ADDRESS_SYNC_ENABLED",
"version": "undefined"
},
{
"name": "SWAP_SWITCH_TO_TRANSFER_ENABLED",
"version": "undefined"
}
]

View file

@ -1,3 +1,5 @@
package com.tangem.features.swap
interface SwapFeatureToggles
interface SwapFeatureToggles {
val isSwapSwitchToTransferEnabled: Boolean
}

View file

@ -1,5 +1,15 @@
package com.tangem.feature.swap
import com.tangem.core.configtoggle.FeatureToggles
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.features.swap.SwapFeatureToggles
import javax.inject.Inject
internal class DefaultSwapFeatureToggles : SwapFeatureToggles
internal class DefaultSwapFeatureToggles @Inject constructor(
featureTogglesManager: FeatureTogglesManager,
) : SwapFeatureToggles {
override val isSwapSwitchToTransferEnabled: Boolean = featureTogglesManager.isFeatureEnabled(
toggle = FeatureToggles.SWAP_SWITCH_TO_TRANSFER_ENABLED,
)
}

View file

@ -1,5 +1,6 @@
package com.tangem.feature.swap.di
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.feature.swap.DefaultSwapComponent
import com.tangem.feature.swap.DefaultSwapFeatureToggles
import com.tangem.features.swap.SwapComponent
@ -17,8 +18,8 @@ internal object SwapFeatureModule {
@Provides
@Singleton
fun provideSwapFeatureToggles(): SwapFeatureToggles {
return DefaultSwapFeatureToggles()
fun provideSwapFeatureToggles(featureTogglesManager: FeatureTogglesManager): SwapFeatureToggles {
return DefaultSwapFeatureToggles(featureTogglesManager)
}
}

View file

@ -98,6 +98,7 @@ import com.tangem.features.commonfeatures.api.choosetoken.ChooseTokenResult
import com.tangem.features.send.v2.api.entity.FeeSelectorUM
import com.tangem.features.send.v2.api.subcomponents.feeSelector.FeeSelectorReloadTrigger
import com.tangem.features.swap.SwapComponent
import com.tangem.features.swap.SwapFeatureToggles
import com.tangem.utils.Provider
import com.tangem.utils.coroutines.*
import com.tangem.utils.isNullOrZero
@ -144,13 +145,14 @@ internal class SwapModel @Inject constructor(
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
private val getPaymentAccountCryptoCurrencyStatusUseCase: GetPaymentAccountCryptoCurrencyStatusUseCase,
private val tangemPayWithdrawUseCase: TangemPayWithdrawUseCase,
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase,
private val appsFlyerStore: AppsFlyerStore,
private val messageSender: UiMessageSender,
private val initialCurrenciesResolver: InitialCurrenciesResolver,
private val allowPermissionsHandler: AllowPermissionsHandler,
private val swapFeatureToggles: SwapFeatureToggles,
) : Model() {
private val params = paramsContainer.require<SwapComponent.Params>()
@ -184,7 +186,7 @@ internal class SwapModel @Inject constructor(
isBalanceHiddenProvider = Provider { isBalanceHidden },
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
isAccountsModeProvider = Provider { isAccountsMode },
iGaslessFeeSupportedForNetwork = iGaslessFeeSupportedForNetwork,
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
)
private val inputNumberFormatter = InputNumberFormatter(
@ -1548,6 +1550,7 @@ internal class SwapModel @Inject constructor(
}
private fun filterTokensFromSelector() {
if (swapFeatureToggles.isSwapSwitchToTransferEnabled) return
val tokenFilter = { accountStatus: AccountStatus, currencyStatus: CryptoCurrencyStatus ->
if (currencyStatus.currency.isCustom) {
false

View file

@ -35,7 +35,7 @@ import java.math.BigDecimal
@Suppress("LargeClass")
internal class SwapNotificationsFactory(
private val actions: UiActions,
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
) {
fun getGeneralErrorStateNotifications(
@ -314,7 +314,7 @@ internal class SwapNotificationsFactory(
val isNotEnoughFee =
quoteModel.preparedSwapConfigState.includeFeeInAmount is IncludeFeeInAmount.BalanceNotEnough
val isGaslessAvailable = iGaslessFeeSupportedForNetwork(fromCurrency.network) &&
val isGaslessAvailable = isGaslessFeeSupportedForNetwork(fromCurrency.network) &&
quoteModel.swapProvider.type == ExchangeProviderType.CEX
if (shouldShowCoverWarning && !isGaslessAvailable || isNotEnoughFee) {
add(

View file

@ -57,12 +57,12 @@ internal class StateBuilder(
private val isBalanceHiddenProvider: Provider<Boolean>,
private val appCurrencyProvider: Provider<AppCurrency>,
private val isAccountsModeProvider: Provider<Boolean>,
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
) {
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
private val notificationsFactory by lazy(LazyThreadSafetyMode.NONE) {
SwapNotificationsFactory(actions, iGaslessFeeSupportedForNetwork)
SwapNotificationsFactory(actions, isGaslessFeeSupportedForNetwork)
}
fun createInitialLoadingState(): SwapStateHolder {

View file

@ -30,7 +30,7 @@ internal class StateBuilderInitialStateTest {
private val isBalanceHiddenProvider: Provider<Boolean> = mockk()
private val appCurrencyProvider: Provider<AppCurrency> = mockk()
private val isAccountsModeProvider: Provider<Boolean> = mockk()
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private lateinit var sut: StateBuilder
@ -47,7 +47,7 @@ internal class StateBuilderInitialStateTest {
isBalanceHiddenProvider = isBalanceHiddenProvider,
appCurrencyProvider = appCurrencyProvider,
isAccountsModeProvider = isAccountsModeProvider,
iGaslessFeeSupportedForNetwork = iGaslessFeeSupportedForNetwork,
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
)
}

View file

@ -25,7 +25,7 @@ internal class StateBuilderPairsTest {
private val isBalanceHiddenProvider: Provider<Boolean> = mockk()
private val appCurrencyProvider: Provider<AppCurrency> = mockk()
private val isAccountsModeProvider: Provider<Boolean> = mockk()
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private lateinit var sut: StateBuilder
@ -52,7 +52,7 @@ internal class StateBuilderPairsTest {
isBalanceHiddenProvider = isBalanceHiddenProvider,
appCurrencyProvider = appCurrencyProvider,
isAccountsModeProvider = isAccountsModeProvider,
iGaslessFeeSupportedForNetwork = iGaslessFeeSupportedForNetwork,
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
)
}

View file

@ -2,7 +2,6 @@ package com.tangem.feature.swap
import com.google.common.truth.Truth.assertThat
import com.tangem.domain.appcurrency.model.AppCurrency
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.swap.models.SwapCurrencyStatus
@ -14,12 +13,10 @@ import com.tangem.feature.swap.domain.models.ui.*
import com.tangem.feature.swap.models.*
import com.tangem.feature.swap.models.states.FeeItemState
import com.tangem.feature.swap.models.states.ProviderState
import com.tangem.feature.swap.models.states.SwapNotificationUM
import com.tangem.feature.swap.ui.StateBuilder
import com.tangem.utils.Provider
import io.mockk.every
import io.mockk.mockk
import kotlinx.collections.immutable.persistentListOf
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
@ -31,7 +28,7 @@ internal class StateBuilderQuotesTest {
private val isBalanceHiddenProvider: Provider<Boolean> = mockk()
private val appCurrencyProvider: Provider<AppCurrency> = mockk()
private val isAccountsModeProvider: Provider<Boolean> = mockk()
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private lateinit var sut: StateBuilder
@ -52,14 +49,14 @@ internal class StateBuilderQuotesTest {
every { isBalanceHiddenProvider() } returns false
every { appCurrencyProvider() } returns AppCurrency.Default
every { isAccountsModeProvider() } returns false
every { iGaslessFeeSupportedForNetwork(any()) } returns false
every { isGaslessFeeSupportedForNetwork(any()) } returns false
sut = StateBuilder(
actions = actions,
isBalanceHiddenProvider = isBalanceHiddenProvider,
appCurrencyProvider = appCurrencyProvider,
isAccountsModeProvider = isAccountsModeProvider,
iGaslessFeeSupportedForNetwork = iGaslessFeeSupportedForNetwork,
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
)
}

View file

@ -4,13 +4,11 @@ import com.google.common.truth.Truth.assertThat
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.swap.models.SwapCurrencyStatus
import com.tangem.domain.transaction.usecase.gasless.IsGaslessFeeSupportedForNetwork
import com.tangem.feature.swap.domain.models.domain.*
import com.tangem.feature.swap.domain.models.ui.*
import com.tangem.feature.swap.model.SwapProcessDataState
import com.tangem.feature.swap.models.*
import com.tangem.feature.swap.models.states.FeeItemState
import com.tangem.feature.swap.models.states.ProviderState
import com.tangem.feature.swap.models.states.SwapNotificationUM
import com.tangem.feature.swap.ui.StateBuilder
@ -30,7 +28,7 @@ internal class StateBuilderSwapDataTest {
private val isBalanceHiddenProvider: Provider<Boolean> = mockk()
private val appCurrencyProvider: Provider<AppCurrency> = mockk()
private val isAccountsModeProvider: Provider<Boolean> = mockk()
private val iGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork = mockk()
private lateinit var sut: StateBuilder
@ -51,14 +49,14 @@ internal class StateBuilderSwapDataTest {
every { isBalanceHiddenProvider() } returns false
every { appCurrencyProvider() } returns AppCurrency.Default
every { isAccountsModeProvider() } returns false
every { iGaslessFeeSupportedForNetwork(any()) } returns false
every { isGaslessFeeSupportedForNetwork(any()) } returns false
sut = StateBuilder(
actions = actions,
isBalanceHiddenProvider = isBalanceHiddenProvider,
appCurrencyProvider = appCurrencyProvider,
isAccountsModeProvider = isAccountsModeProvider,
iGaslessFeeSupportedForNetwork = iGaslessFeeSupportedForNetwork,
isGaslessFeeSupportedForNetwork = isGaslessFeeSupportedForNetwork,
)
}