diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt index 5b41f9ef63..a1759b9e86 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/ui/SwapState.kt @@ -54,6 +54,7 @@ sealed interface SwapState { val isAccountsMode: Boolean, val isFeeCoverage: Boolean, val sendingAmount: BigDecimal, + val isSendingAmountLoading: Boolean = false, val currencyCheck: CryptoCurrencyCheck? = null, val validationResult: Throwable? = null, val minAdaValue: BigDecimal? = null, diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt index ff071510a7..03f6d275be 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImpl.kt @@ -40,7 +40,6 @@ import com.tangem.feature.swap.domain.fee.TransactionFeeResult import com.tangem.feature.swap.domain.models.SwapAmount import com.tangem.feature.swap.domain.models.ui.SwapState import com.tangem.feature.swap.domain.models.ui.TokenSwapInfo -import com.tangem.features.send.api.subcomponents.feeSelector.utils.FeeCalculationUtils.checkAndCalculateSubtractedAmount import com.tangem.features.send.api.subcomponents.feeSelector.utils.FeeCalculationUtils.checkFeeCoverage import com.tangem.features.swap.SwapFeatureToggles import com.tangem.utils.extensions.orZero @@ -107,7 +106,7 @@ class SwapTransferInteractorImpl @Inject constructor( fee = warningsFee, feeCurrencyBalanceAfterTransaction = null, ) - val (isFeeCoverage, sendingAmount) = getCoverageState( + val coverageState = getCoverageState( fromTokenInfo = fromTokenInfo, userWallet = userWallet, fee = fee, @@ -130,8 +129,9 @@ class SwapTransferInteractorImpl @Inject constructor( appCurrency = appCurrency, isBalanceHidden = isBalanceHidden, isAccountsMode = isAccountsMode, - isFeeCoverage = isFeeCoverage, - sendingAmount = sendingAmount, + isFeeCoverage = coverageState.isFeeCoverage, + sendingAmount = coverageState.sendingAmount, + isSendingAmountLoading = coverageState.isSendingAmountLoading, currencyCheck = currencyCheck, ) } @@ -155,7 +155,7 @@ class SwapTransferInteractorImpl @Inject constructor( userWallet: UserWallet, fee: Fee?, currencyCheck: CryptoCurrencyCheck, - ): Pair { + ): CoverageState { val swapCurrencyStatus = fromTokenInfo.swapCurrencyStatus val isAmountSubtractAvailable = isAmountSubtractAvailable( userWalletId = userWallet.walletId, @@ -173,16 +173,29 @@ class SwapTransferInteractorImpl @Inject constructor( feeValue = feeValue, reduceAmountBy = reduceAmountBy, ) - val sendingAmount = checkAndCalculateSubtractedAmount( - isAmountSubtractAvailable = isAmountSubtractAvailable, - cryptoCurrencyStatus = fromTokenInfo.swapCurrencyStatus.status, - amountValue = amount.value, - feeValue = feeValue, - reduceAmountBy = reduceAmountBy, + // When fee coverage applies, the entered amount can't be sent together with the fee, so the + // sent (and therefore received) amount is the entered amount reduced by the fee. This tracks the + // input: as the user edits the amount, the received amount changes with it. + val sendingAmount = if (isFeeCoverage) { + (amount.value - feeValue).coerceAtLeast(BigDecimal.ZERO) + } else { + amount.value + } + // While subtraction is possible but the fee has not loaded yet, the final received amount + // (entered - fee) is unknown, so it must be shown as loading instead of the un-subtracted value. + return CoverageState( + isFeeCoverage = isFeeCoverage, + sendingAmount = sendingAmount, + isSendingAmountLoading = fee == null && isAmountSubtractAvailable, ) - return isFeeCoverage to sendingAmount } + private data class CoverageState( + val isFeeCoverage: Boolean, + val sendingAmount: BigDecimal, + val isSendingAmountLoading: Boolean, + ) + private suspend fun isAmountSubtractAvailable( userWalletId: UserWalletId, currency: CryptoCurrency, diff --git a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt index fc31a2c1ef..cdecb5a391 100644 --- a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt +++ b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/transfer/SwapTransferInteractorImplTest.kt @@ -299,7 +299,7 @@ internal class SwapTransferInteractorImplTest { } returns true.right() // entered amount = full balance → balance < amount + fee, balance > fee, balance >= amount - // → isFeeCoverage = true, sendingAmount = balance - fee + // → isFeeCoverage = true, sendingAmount = entered - fee (== balance - fee at max) val result = sut.updateTransfer( fromSwapCurrencyStatus = fromCurrencyStatus, toSwapCurrencyStatus = toCurrencyStatus, @@ -310,6 +310,113 @@ internal class SwapTransferInteractorImplTest { assertThat(result.isFeeCoverage).isTrue() assertThat(result.sendingAmount).isEqualTo(balance - feeValue) + assertThat(result.isSendingAmountLoading).isFalse() + } + + @Test + fun `GIVEN subtract available and sub-max amount in coverage zone WHEN updateTransfer THEN sendingAmount is entered minus fee`() = + runTest { + val appCurrency = AppCurrency(code = "USD", name = "US Dollar", symbol = "$") + val userWallet: UserWallet = mockk(relaxed = true) + val balance = BigDecimal("1.5") + val feeValue = BigDecimal("0.2") + // entered is below the balance but still within one fee of it → coverage applies, yet the + // received amount must track the entered amount (entered - fee), not clamp to balance - fee. + val enteredAmount = BigDecimal("1.45") + val fromCurrencyStatus = buildCurrencyStatus( + rawCurrencyId = FROM_RAW_CURRENCY_ID, + decimals = FROM_DECIMALS, + fiatRate = BigDecimal.TEN, + amount = balance, + userWallet = userWallet, + ) + val toCurrencyStatus = buildCurrencyStatus( + rawCurrencyId = TO_RAW_CURRENCY_ID, + decimals = TO_DECIMALS, + userWallet = userWallet, + ) + val fee: Fee = mockk(relaxed = true) { + every { amount.value } returns feeValue + } + every { getSelectedAppCurrencyUseCase() } returns flowOf(appCurrency.right()) + every { getBalanceHidingSettingsUseCase.isBalanceHidden() } returns flowOf(false) + coEvery { isAccountsModeEnabledUseCase.invokeSync() } returns false + coEvery { + getCurrencyCheckUseCase( + userWalletId = any(), + currencyStatus = any(), + feeCurrencyStatus = any(), + amount = any(), + fee = any(), + feeCurrencyBalanceAfterTransaction = any(), + recipientAddress = any(), + ) + } returns buildCurrencyCheck() + coEvery { + isAmountSubtractAvailableUseCase(any(), any(), any()) + } returns true.right() + + val result = sut.updateTransfer( + fromSwapCurrencyStatus = fromCurrencyStatus, + toSwapCurrencyStatus = toCurrencyStatus, + fromTokenAmount = enteredAmount.toPlainString(), + feePaidCurrencyStatus = null, + fee = fee, + ) as SwapState.Transfer + + assertThat(result.isFeeCoverage).isTrue() + assertThat(result.sendingAmount).isEqualTo(enteredAmount - feeValue) + // it must NOT clamp to balance - fee + assertThat(result.sendingAmount).isNotEqualTo(balance - feeValue) + } + + @Test + fun `GIVEN subtract available but fee not loaded yet WHEN updateTransfer THEN isSendingAmountLoading is true`() = + runTest { + val appCurrency = AppCurrency(code = "USD", name = "US Dollar", symbol = "$") + val userWallet: UserWallet = mockk(relaxed = true) + val balance = BigDecimal("1.5") + val fromCurrencyStatus = buildCurrencyStatus( + rawCurrencyId = FROM_RAW_CURRENCY_ID, + decimals = FROM_DECIMALS, + fiatRate = BigDecimal.TEN, + amount = balance, + userWallet = userWallet, + ) + val toCurrencyStatus = buildCurrencyStatus( + rawCurrencyId = TO_RAW_CURRENCY_ID, + decimals = TO_DECIMALS, + userWallet = userWallet, + ) + every { getSelectedAppCurrencyUseCase() } returns flowOf(appCurrency.right()) + every { getBalanceHidingSettingsUseCase.isBalanceHidden() } returns flowOf(false) + coEvery { isAccountsModeEnabledUseCase.invokeSync() } returns false + coEvery { + getCurrencyCheckUseCase( + userWalletId = any(), + currencyStatus = any(), + feeCurrencyStatus = any(), + amount = any(), + fee = any(), + feeCurrencyBalanceAfterTransaction = any(), + recipientAddress = any(), + ) + } returns buildCurrencyCheck() + coEvery { + isAmountSubtractAvailableUseCase(any(), any(), any()) + } returns true.right() + + // subtraction is possible but the fee has not loaded yet (fee = null) → the received amount + // depends on the fee, so it can't be known yet and must be reported as loading. + val result = sut.updateTransfer( + fromSwapCurrencyStatus = fromCurrencyStatus, + toSwapCurrencyStatus = toCurrencyStatus, + fromTokenAmount = balance.toPlainString(), + feePaidCurrencyStatus = null, + fee = null, + ) as SwapState.Transfer + + assertThat(result.isSendingAmountLoading).isTrue() } // endregion diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilder.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilder.kt index 6afae71a25..10a023634f 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilder.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilder.kt @@ -21,6 +21,7 @@ import com.tangem.core.ui.extensions.wrappedList import com.tangem.core.ui.format.bigdecimal.crypto import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.format +import com.tangem.core.ui.format.bigdecimal.simple import com.tangem.core.ui.utils.parseBigDecimalOrNull import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.account.Account @@ -31,11 +32,11 @@ import com.tangem.feature.swap.domain.models.ui.SwapState import com.tangem.feature.swap.domain.models.ui.TokenSwapInfo import com.tangem.feature.swap.model.SwapProcessDataState import com.tangem.feature.swap.models.* -import com.tangem.feature.swap.ui.SwapAmountScreenClickIntents -import com.tangem.feature.swap.ui.swapSuccessNavigation import com.tangem.feature.swap.models.SwapButton.Mode import com.tangem.feature.swap.models.states.SwapNotificationUM import com.tangem.feature.swap.presentation.R +import com.tangem.feature.swap.ui.SwapAmountScreenClickIntents +import com.tangem.feature.swap.ui.swapSuccessNavigation import com.tangem.features.send.api.utils.formatFooterFiatFee import com.tangem.features.send.api.utils.getTronTokenFeeSendingText import com.tangem.utils.extensions.orZero @@ -59,11 +60,9 @@ internal class SwapTransferStateBuilder @Inject constructor( fee: Fee?, ): SwapStateHolder { val fromTokenSwapInfo = transferState.fromTokenInfo - val toTokenSwapInfo = transferState.toTokenInfo val isInsufficientBalance = transferState.isInsufficientBalance val prevSendCard = uiStateHolder.sendCardData as? SwapCardState.SwapCardData val prevAmountField = prevSendCard?.amountField - val displayValue = prevAmountField?.value.orEmpty() val notifications = notificationsFactory.getNotifications( transferState = transferState, feeCryptoCurrencyStatus = feePaidCryptoCurrencyStatus, @@ -75,25 +74,14 @@ internal class SwapTransferStateBuilder @Inject constructor( return uiStateHolder.copy( sendCardData = createSendSwapCardState( actions = actions, - displayValue = displayValue, tokenSwapInfo = fromTokenSwapInfo, appCurrency = transferState.appCurrency, isAccountsMode = transferState.isAccountsMode, - isFromCard = true, isBalanceHidden = transferState.isBalanceHidden, isInsufficientBalance = isInsufficientBalance, prevAmountField = prevAmountField, ), - receiveCardData = createSendSwapCardState( - actions = actions, - displayValue = displayValue, - tokenSwapInfo = toTokenSwapInfo, - appCurrency = transferState.appCurrency, - isAccountsMode = transferState.isAccountsMode, - isFromCard = false, - isBalanceHidden = transferState.isBalanceHidden, - isInsufficientBalance = isInsufficientBalance, - ), + receiveCardData = createReceiveCard(actions = actions, transferState = transferState), isInsufficientFunds = isInsufficientBalance, swapButton = SwapButton( walletInteractionIcon = walletInterationIcon(transferState.userWallet), @@ -109,14 +97,12 @@ internal class SwapTransferStateBuilder @Inject constructor( @Suppress("LongParameterList") private fun createSendSwapCardState( actions: UiActions, - displayValue: String, tokenSwapInfo: TokenSwapInfo, appCurrency: AppCurrency, isAccountsMode: Boolean, - isFromCard: Boolean, isBalanceHidden: Boolean, isInsufficientBalance: Boolean, - prevAmountField: AmountFieldModel? = null, + prevAmountField: AmountFieldModel?, ): SwapCardState { val swapCurrencyStatus = tokenSwapInfo.swapCurrencyStatus val currency = swapCurrencyStatus.currency @@ -126,7 +112,7 @@ internal class SwapTransferStateBuilder @Inject constructor( actions = actions, swapCurrencyStatus = tokenSwapInfo.swapCurrencyStatus, isAccountsMode = isAccountsMode, - isFromCard = isFromCard, + isFromCard = true, isInsufficientBalance = isInsufficientBalance, ), currencyIconState = iconConverter.convert( @@ -140,18 +126,61 @@ internal class SwapTransferStateBuilder @Inject constructor( balance = swapCurrencyStatus.status.getFormattedAmount(), isBalanceHidden = isBalanceHidden, appCurrency = appCurrency, - amountField = if (isFromCard) { - buildAmountField( - actions = actions, - prevAmountField = prevAmountField, - swapCurrencyStatus = swapCurrencyStatus, - appCurrency = appCurrency, - ) + amountField = buildAmountField( + actions = actions, + prevAmountField = prevAmountField, + swapCurrencyStatus = swapCurrencyStatus, + appCurrency = appCurrency, + ), + ) + } + + /** + * Builds the read-only receive card from [SwapState.Transfer.sendingAmount] — the amount that will + * actually be received, already reduced by the fee when fee coverage applies. While the reduced amount + * is not yet known (fee still loading) the amount and fiat fields are null, which makes the read-only + * card render a shimmer instead of the un-subtracted value. + */ + private fun createReceiveCard(actions: UiActions, transferState: SwapState.Transfer): SwapCardState { + val toTokenSwapInfo = transferState.toTokenInfo + val swapCurrencyStatus = toTokenSwapInfo.swapCurrencyStatus + val currency = swapCurrencyStatus.currency + val appCurrency = transferState.appCurrency + val sendingAmount = transferState.sendingAmount + // No reduction can happen when the balance is insufficient (fee coverage requires balance >= amount), + // so there is nothing to wait for — show the amount instead of a shimmer. + val isLoading = transferState.isSendingAmountLoading && !transferState.isInsufficientBalance + val fiatRate = swapCurrencyStatus.status.value.fiatRate + + return SwapCardState.SwapCardData( + type = createSendTransactionCardType( + actions = actions, + swapCurrencyStatus = swapCurrencyStatus, + isAccountsMode = transferState.isAccountsMode, + isFromCard = false, + isInsufficientBalance = transferState.isInsufficientBalance, + ), + currencyIconState = iconConverter.convert( + value = swapCurrencyStatus.status, + ), + tokenSymbol = stringReference(currency.symbol), + amountEquivalent = if (isLoading) { + null } else { - // Read-only receive card mirrors the same display value the "from" card shows in transfer mode. + getFormattedFiatAmount(appCurrency = appCurrency, amount = fiatRate?.multiply(sendingAmount)) + }, + balance = swapCurrencyStatus.status.getFormattedAmount(), + isBalanceHidden = transferState.isBalanceHidden, + appCurrency = appCurrency, + amountField = if (isLoading) { + null + } else { + val value = sendingAmount.format { + simple(decimals = currency.decimals) + } displayAmountField( actions = actions, - value = displayValue, + value = value, swapCurrencyStatus = swapCurrencyStatus, appCurrency = appCurrency, ) @@ -324,6 +353,10 @@ internal class SwapTransferStateBuilder @Inject constructor( ) return uiStateHolder.copy( notifications = notifications, + // Rebuild the receive card from the refreshed transferState: this path runs after the fee + // selector resolves, when sendingAmount may have just been reduced by the fee. Only the + // receive card is rebuilt to avoid clobbering the user's in-progress input on the "from" card. + receiveCardData = createReceiveCard(actions = actions, transferState = transferState), swapButton = uiStateHolder.swapButton.copy( isEnabled = getTransferButtonEnabled(notifications, fee, isTangemPayWithdrawal), ), diff --git a/features/swap/impl/src/test/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilderTest.kt b/features/swap/impl/src/test/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilderTest.kt index 30cb7b21ba..a5d4203e98 100644 --- a/features/swap/impl/src/test/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilderTest.kt +++ b/features/swap/impl/src/test/java/com/tangem/feature/swap/ui/transfer/SwapTransferStateBuilderTest.kt @@ -22,6 +22,7 @@ import com.tangem.core.ui.format.bigdecimal.crypto import com.tangem.core.ui.format.bigdecimal.fee import com.tangem.core.ui.format.bigdecimal.fiat import com.tangem.core.ui.format.bigdecimal.format +import com.tangem.core.ui.utils.parseBigDecimal import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.account.Account import com.tangem.domain.models.network.Network @@ -371,6 +372,123 @@ internal class SwapTransferStateBuilderTest { } } + @Test + fun `GIVEN fee coverage reduces amount WHEN createTransferState THEN receive card shows reduced sendingAmount`() = + runTest { + // entered 1.5, but fee coverage reduces the received (sending) amount to 1.3 + val sendingAmount = BigDecimal("1.3") + val transferState = buildTransferState( + fromAmount = BigDecimal("1.5"), + toAmount = sendingAmount, + isAccountsMode = false, + isFeeCoverage = true, + ) + + val result = sut.createTransferState( + actions = actions, + transferState = transferState, + uiStateHolder = baseStateHolder(), + feePaidCryptoCurrencyStatus = null, + fee = mockk(relaxed = true), + ) + + val sendCard = result.sendCardData as SwapCardState.SwapCardData + val receiveCard = result.receiveCardData as SwapCardState.SwapCardData + val expectedFiat = stringReference( + toCurrencyStatus.status.value.fiatRate!!.multiply(sendingAmount).format { + fiat(fiatCurrencyCode = AppCurrency.Default.code, fiatCurrencySymbol = AppCurrency.Default.symbol) + }, + ) + // the "from" card keeps the user's typed value, the receive card shows the reduced amount + its fiat + assertThat(sendCard.amountField?.value).isEqualTo(initialAmountValue) + assertThat(receiveCard.amountField?.value).isEqualTo( + sendingAmount.parseBigDecimal(transferState.toTokenInfo.tokenAmount.decimals), + ) + assertThat(receiveCard.amountEquivalent).isEqualTo(expectedFiat) + } + + @Test + fun `GIVEN sendingAmount loading WHEN createTransferState THEN receive card amount and fiat shimmer`() = + runTest { + // fee not loaded yet → reduced amount unknown → receive card shimmers (null amount + null fiat) + val transferState = buildTransferState( + fromAmount = BigDecimal("1.5"), + toAmount = BigDecimal("1.5"), + isAccountsMode = false, + isSendingAmountLoading = true, + ) + + val result = sut.createTransferState( + actions = actions, + transferState = transferState, + uiStateHolder = baseStateHolder(), + feePaidCryptoCurrencyStatus = null, + fee = null, + ) + + val receiveCard = result.receiveCardData as SwapCardState.SwapCardData + assertThat(receiveCard.amountField).isNull() + assertThat(receiveCard.amountEquivalent).isNull() + } + + @Test + fun `GIVEN sendingAmount loading but insufficient balance WHEN createTransferState THEN receive card shows amount not shimmer`() = + runTest { + // Insufficient balance → fee coverage can't apply, so there is no reduction to wait for. + // The receive card must show the amount instead of shimmering. + val amount = BigDecimal("99") + val transferState = buildTransferState( + fromAmount = amount, + toAmount = amount, + isAccountsMode = false, + isInsufficientBalance = true, + isSendingAmountLoading = true, + ) + + val result = sut.createTransferState( + actions = actions, + transferState = transferState, + uiStateHolder = baseStateHolder(), + feePaidCryptoCurrencyStatus = null, + fee = null, + ) + + val receiveCard = result.receiveCardData as SwapCardState.SwapCardData + assertThat(receiveCard.amountField?.value).isEqualTo( + amount.parseBigDecimal(transferState.toTokenInfo.tokenAmount.decimals), + ) + assertThat(receiveCard.amountEquivalent).isNotNull() + } + + @Test + fun `GIVEN reduced sendingAmount WHEN updateTransferButtonEnableState THEN receive card is rebuilt to reduced amount`() = + runTest { + // After the fee resolves, sendingAmount is reduced; the refresh path must rebuild the receive card + // so it no longer shows the stale full amount. + val sendingAmount = BigDecimal("1.3") + val transferState = buildTransferState( + fromAmount = BigDecimal("1.5"), + toAmount = sendingAmount, + isAccountsMode = false, + isFeeCoverage = true, + ) + + val result = sut.updateTransferButtonEnableState( + dataState = SwapProcessDataState(), + transferState = transferState, + actions = actions, + uiStateHolder = baseStateHolder(), + feePaidCryptoCurrencyStatus = null, + fee = mockk(relaxed = true), + isTangemPayWithdrawal = false, + ) + + val receiveCard = result.receiveCardData as SwapCardState.SwapCardData + assertThat(receiveCard.amountField?.value).isEqualTo( + sendingAmount.parseBigDecimal(transferState.toTokenInfo.tokenAmount.decimals), + ) + } + @Test fun `GIVEN Tron fee WHEN updateTransferButtonEnableState THEN transferFooter uses Tron token fee sending text`() = runTest { @@ -747,8 +865,12 @@ internal class SwapTransferStateBuilderTest { ) { val sendCard = result.sendCardData as SwapCardState.SwapCardData val receiveCard = result.receiveCardData as SwapCardState.SwapCardData + // The "from" card preserves the user's typed value; the receive card shows the (possibly + // fee-reduced) sendingAmount formatted with the receive token's decimals. assertThat(sendCard.amountField?.value).isEqualTo(initialAmountValue) - assertThat(receiveCard.amountField?.value).isEqualTo(initialAmountValue) + assertThat(receiveCard.amountField?.value).isEqualTo( + transferState.sendingAmount.parseBigDecimal(transferState.toTokenInfo.tokenAmount.decimals), + ) assertThat(sendCard.currencyIconState).isEqualTo(fromIcon) assertThat(receiveCard.currencyIconState).isEqualTo(toIcon) assertThat(sendCard.isBalanceHidden).isEqualTo(transferState.isBalanceHidden) @@ -778,6 +900,8 @@ internal class SwapTransferStateBuilderTest { toAmount: BigDecimal, isAccountsMode: Boolean, isInsufficientBalance: Boolean = false, + isFeeCoverage: Boolean = false, + isSendingAmountLoading: Boolean = false, ): SwapState.Transfer { val fromInfo = TokenSwapInfo( tokenAmount = SwapAmount(value = fromAmount, decimals = fromCurrencyStatus.currency.decimals), @@ -798,8 +922,9 @@ internal class SwapTransferStateBuilderTest { appCurrency = AppCurrency.Default, isBalanceHidden = false, isAccountsMode = isAccountsMode, - isFeeCoverage = false, + isFeeCoverage = isFeeCoverage, sendingAmount = toAmount, + isSendingAmountLoading = isSendingAmountLoading, ) }