diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt index f023d7fea9..75b406ee1b 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/actions/BaseActionsFactory.kt @@ -1,5 +1,6 @@ package com.tangem.domain.tokens.actions +import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.exchange.RampStateManager import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrencyStatus @@ -65,6 +66,12 @@ internal open class BaseActionsFactory( currency: CryptoCurrency, requirementsDeferred: Deferred?, ): ScenarioUnavailabilityReason { + // Start2Coin (S2C) are legacy single-currency cards that do not support buying crypto in-app + // (historically only Receive/Send were offered for them). + if (userWallet is UserWallet.Cold && userWallet.cardTypesResolver.isStart2Coin()) { + return ScenarioUnavailabilityReason.BuyUnavailable(currency.name) + } + val onrampUnavailabilityReason = rampStateManager.availableForBuy( userWallet = userWallet, cryptoCurrency = currency, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformer.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformer.kt index 87a40e29dd..46f2b89ec5 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformer.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformer.kt @@ -43,16 +43,21 @@ internal class UpdateTransferTransformer( }, ) } - val swapAndSendRow = swapAction?.let { action -> - TransferUM.Row( - isLoading = action.unavailabilityReason.isLoading, - isEnabled = action.unavailabilityReason == ScenarioUnavailabilityReason.None, - onClick = { - onActionDispatched() - clickIntents.onSwapAndSendClick(action.unavailabilityReason) - }, - ) - } + // Send&Swap is only meaningful when Swap itself is available, so it is shown only in that case + // (mirrors the main-screen Transfer quick actions, which synthesize Send&Swap only when swap is available). + // This prevents a disabled Send&Swap row for cards that cannot swap at all (e.g. S2C single-currency cards). + val swapAndSendRow = swapAction + ?.takeIf { it.unavailabilityReason == ScenarioUnavailabilityReason.None } + ?.let { + TransferUM.Row( + isLoading = false, + isEnabled = true, + onClick = { + onActionDispatched() + clickIntents.onSwapAndSendClick(it.unavailabilityReason) + }, + ) + } val sellRow = sellAction?.let { action -> TransferUM.Row( isLoading = action.unavailabilityReason.isOutdatedLoading(), diff --git a/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformerTest.kt b/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformerTest.kt index c4354538ab..e50e0b4c1a 100644 --- a/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformerTest.kt +++ b/features/tokendetails/impl/src/test/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/transformer/UpdateTransferTransformerTest.kt @@ -352,6 +352,28 @@ class UpdateTransferTransformerTest { } } + @Test + fun `GIVEN Swap action present but unavailable WHEN transform THEN Swap shown disabled AND swapAndSend is null`() { + // Arrange — cards that cannot swap (e.g. S2C single-currency) still expose a Swap action, + // but with a non-None reason. Swap stays visible-but-disabled per design, while Send&Swap + // must not appear at all (it is meaningful only when swap is available). + val transformer = createTransformer( + actions = listOf( + TokenActionsState.ActionState.Send(ScenarioUnavailabilityReason.None), + TokenActionsState.ActionState.Swap(ScenarioUnavailabilityReason.Unreachable, false), + ), + ) + + // Act + val result = transformer.transform(initialState()) + + // Assert + val content = result.transferUM as TransferUM.Content + assertThat(content.swap).isNotNull() + assertThat(content.swap?.isEnabled).isFalse() + assertThat(content.swapAndSend).isNull() + } + @Test fun `GIVEN no Swap action WHEN transform THEN swapAndSend row is null`() { // Arrange