Updated on 2026-08-14

This commit is contained in:
Tangem 2026-06-30 10:33:11 +01:00
parent 62d1577a00
commit 9b101c4238
11 changed files with 167 additions and 20 deletions

View file

@ -179,11 +179,15 @@ sealed class NotificationUM(val config: NotificationConfig) {
subtitle = resourceReference(id = R.string.send_notification_invalid_reserve_amount_text), subtitle = resourceReference(id = R.string.send_notification_invalid_reserve_amount_text),
) )
data class NetworkAccountNotFunded(val coinName: String) : Error( data class NetworkAccountNotFunded(
val coinName: String,
val reserveAmount: String,
val reserveSymbol: String,
) : Error(
title = resourceReference(R.string.alert_failed_to_send_transaction_title), title = resourceReference(R.string.alert_failed_to_send_transaction_title),
subtitle = resourceReference( subtitle = resourceReference(
id = R.string.no_account_generic, id = R.string.no_account_generic,
formatArgs = wrappedList(coinName), formatArgs = wrappedList(coinName, reserveAmount, reserveSymbol),
), ),
) )
@ -191,6 +195,11 @@ sealed class NotificationUM(val config: NotificationConfig) {
title = resourceReference(id = R.string.send_validation_destination_tag_required_title), title = resourceReference(id = R.string.send_validation_destination_tag_required_title),
subtitle = resourceReference(id = R.string.send_validation_destination_tag_required_description), subtitle = resourceReference(id = R.string.send_validation_destination_tag_required_description),
) )
data object RequiredTrustline : Error(
title = resourceReference(id = R.string.common_error),
subtitle = resourceReference(id = R.string.no_trustline_xlm_asset),
)
} }
open class Warning( open class Warning(

View file

@ -120,40 +120,66 @@ object NotificationsFactory {
} }
} }
@Suppress("LongParameterList")
fun MutableList<NotificationUM>.addReserveAmountErrorNotification( fun MutableList<NotificationUM>.addReserveAmountErrorNotification(
reserveAmount: BigDecimal?, reserveAmount: BigDecimal?,
sendingAmount: BigDecimal, sendingAmount: BigDecimal,
cryptoCurrency: CryptoCurrency, cryptoCurrency: CryptoCurrency,
feeCryptoCurrency: CryptoCurrency?, feeCryptoCurrency: CryptoCurrency?,
isAccountFunded: Boolean, isAccountFunded: Boolean,
hasRequiredTrustline: Boolean,
) { ) {
val sendingCoinAmount = when (cryptoCurrency) { val sendingCoinAmount = when (cryptoCurrency) {
is CryptoCurrency.Coin -> sendingAmount is CryptoCurrency.Coin -> sendingAmount
is CryptoCurrency.Token -> BigDecimal.ZERO is CryptoCurrency.Token -> BigDecimal.ZERO
} }
if (feeCryptoCurrency == null && cryptoCurrency is CryptoCurrency.Token) { when {
// No need to show reserve amount warning if fee currency is unknown for token transfer // No need to show reserve amount warning if fee currency is unknown for token transfer
return feeCryptoCurrency == null && cryptoCurrency is CryptoCurrency.Token -> Unit
} else if (!isAccountFunded && reserveAmount != null && reserveAmount > sendingCoinAmount) {
// account not funded, sending coin amount < reserve (send coin with less amount OR send any token) // account not funded, sending coin amount < reserve (send coin with less amount OR send any token)
!isAccountFunded && reserveAmount != null && reserveAmount > sendingCoinAmount ->
addAccountNotFundedNotification(
reserveAmount = reserveAmount,
cryptoCurrency = cryptoCurrency,
feeCryptoCurrency = feeCryptoCurrency,
)
hasRequiredTrustline -> addTrustlineRequiredNotification()
}
}
if (cryptoCurrency is CryptoCurrency.Coin) { private fun MutableList<NotificationUM>.addAccountNotFundedNotification(
// Try to send coin amount less than reserve amount (e.g. less than 1 XLM in Stellar) reserveAmount: BigDecimal,
cryptoCurrency: CryptoCurrency,
feeCryptoCurrency: CryptoCurrency?,
) {
when (cryptoCurrency) {
// Try to send coin amount less than reserve amount (e.g. less than 1 XLM in Stellar)
is CryptoCurrency.Coin -> add(
NotificationUM.Error.ReserveAmount(
reserveAmount.format {
crypto(feeCryptoCurrency ?: cryptoCurrency)
},
),
)
// Try to send any token (e.g. USDC in Stellar, but account not funded -> user must send XLM at first)
is CryptoCurrency.Token -> {
checkNotNull(feeCryptoCurrency)
add( add(
NotificationUM.Error.ReserveAmount( NotificationUM.Error.NetworkAccountNotFunded(
reserveAmount.format { coinName = feeCryptoCurrency.name,
crypto(feeCryptoCurrency ?: cryptoCurrency) reserveAmount = reserveAmount.format {
crypto(symbol = "", decimals = feeCryptoCurrency.decimals)
}, },
reserveSymbol = feeCryptoCurrency.symbol,
), ),
) )
} else {
checkNotNull(feeCryptoCurrency)
// Try to send any token (e.g. USDC in Stellar, but account not funded -> user must send XLM at first)
add(NotificationUM.Error.NetworkAccountNotFunded(coinName = feeCryptoCurrency.name))
} }
} }
// TODO: check the RECEIVER account trustline before sending }
private fun MutableList<NotificationUM>.addTrustlineRequiredNotification() {
add(NotificationUM.Error.RequiredTrustline)
} }
fun MutableList<NotificationUM>.addMinimumAmountErrorNotification( fun MutableList<NotificationUM>.addMinimumAmountErrorNotification(

View file

@ -25,14 +25,17 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.account.status.usecase.GetAccountCurrencyByAddressUseCase
import com.tangem.domain.models.currency.CryptoCurrency import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.currency.CryptoCurrencyStatus
import com.tangem.domain.notifications.GetTronFeeNotificationShowCountUseCase import com.tangem.domain.notifications.GetTronFeeNotificationShowCountUseCase
import com.tangem.domain.notifications.IncrementNotificationsShowCountUseCase import com.tangem.domain.notifications.IncrementNotificationsShowCountUseCase
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase
import com.tangem.domain.tokens.GetCurrencyCheckUseCase import com.tangem.domain.tokens.GetCurrencyCheckUseCase
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
import com.tangem.domain.utils.convertToSdkAmount import com.tangem.domain.utils.convertToSdkAmount
import com.tangem.features.send.api.SendNotificationsComponent import com.tangem.features.send.api.SendNotificationsComponent
@ -70,9 +73,11 @@ internal class NotificationsModel @Inject constructor(
private val validateTransactionUseCase: ValidateTransactionUseCase, private val validateTransactionUseCase: ValidateTransactionUseCase,
private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase, private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase,
private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase, private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase,
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
private val getAccountCurrencyByAddressUseCase: GetAccountCurrencyByAddressUseCase,
private val notificationsUpdateTrigger: SendNotificationsUpdateTrigger, private val notificationsUpdateTrigger: SendNotificationsUpdateTrigger,
private val notificationsUpdateListener: SendNotificationsUpdateListener, private val notificationsUpdateListener: SendNotificationsUpdateListener,
private val analyticsEventHandler: AnalyticsEventHandler, analyticsEventHandler: AnalyticsEventHandler,
) : Model() { ) : Model() {
private val params: SendNotificationsComponent.Params = paramsContainer.require() private val params: SendNotificationsComponent.Params = paramsContainer.require()
@ -295,6 +300,7 @@ internal class NotificationsModel @Inject constructor(
cryptoCurrency = currency, cryptoCurrency = currency,
feeCryptoCurrency = feeCryptoCurrencyStatus.currency, feeCryptoCurrency = feeCryptoCurrencyStatus.currency,
isAccountFunded = currencyCheck.isAccountFunded, isAccountFunded = currencyCheck.isAccountFunded,
hasRequiredTrustline = recipientRequiresTrustline(notificationData.destinationAddress),
) )
addMinimumAmountErrorNotification( addMinimumAmountErrorNotification(
minimumSendAmount = currencyCheck.minimumSendAmount, minimumSendAmount = currencyCheck.minimumSendAmount,
@ -303,6 +309,24 @@ internal class NotificationsModel @Inject constructor(
) )
} }
private suspend fun recipientRequiresTrustline(destinationAddress: String?): Boolean {
val recipientAccount = destinationAddress
?.let { getAccountCurrencyByAddressUseCase(it).getOrNull() }
?.account
?: return false
val recipientCurrency = recipientAccount.cryptoCurrencies
.firstOrNull { it.isSameTokenAs(currency) }
?: return false
return getAssetRequirementsUseCase(
userWalletId = recipientAccount.userWalletId,
currency = recipientCurrency,
).getOrNull() is AssetRequirementsCondition.RequiredTrustline
}
private fun CryptoCurrency.isSameTokenAs(other: CryptoCurrency): Boolean {
return id.rawNetworkId == other.id.rawNetworkId && id.contractAddress == other.id.contractAddress
}
private suspend fun MutableList<NotificationUM>.addWarningNotifications( private suspend fun MutableList<NotificationUM>.addWarningNotifications(
destinationAddress: String?, destinationAddress: String?,
memo: String?, memo: String?,

View file

@ -257,6 +257,7 @@ internal class AddStakingNotificationsTransformer(
cryptoCurrency = cryptoCurrency, cryptoCurrency = cryptoCurrency,
feeCryptoCurrency = feeCryptoCurrencyStatus?.currency, feeCryptoCurrency = feeCryptoCurrencyStatus?.currency,
isAccountFunded = false, isAccountFunded = false,
hasRequiredTrustline = false,
) )
} }

View file

@ -60,6 +60,7 @@ sealed interface SwapState {
val currencyCheck: CryptoCurrencyCheck? = null, val currencyCheck: CryptoCurrencyCheck? = null,
val validationResult: Throwable? = null, val validationResult: Throwable? = null,
val minAdaValue: BigDecimal? = null, val minAdaValue: BigDecimal? = null,
val hasRequiredTrustline: Boolean = false,
) : SwapState ) : SwapState
data class EmptyAmountState( data class EmptyAmountState(

View file

@ -24,6 +24,7 @@ import com.tangem.domain.notifications.IncrementNotificationsShowCountUseCase
import com.tangem.domain.pay.WithdrawalResult import com.tangem.domain.pay.WithdrawalResult
import com.tangem.domain.swap.models.SwapCurrencyStatus import com.tangem.domain.swap.models.SwapCurrencyStatus
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase
import com.tangem.domain.tokens.GetCurrencyCheckUseCase import com.tangem.domain.tokens.GetCurrencyCheckUseCase
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
@ -31,6 +32,7 @@ import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.domain.transaction.error.GetFeeError import com.tangem.domain.transaction.error.GetFeeError
import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.error.SendTransactionError
import com.tangem.domain.transaction.models.AssetRequirementsCondition
import com.tangem.domain.transaction.models.TransactionFeeExtended import com.tangem.domain.transaction.models.TransactionFeeExtended
import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase import com.tangem.domain.transaction.usecase.CreateTransferTransactionUseCase
import com.tangem.domain.transaction.usecase.GetFeeUseCase import com.tangem.domain.transaction.usecase.GetFeeUseCase
@ -66,8 +68,10 @@ class SwapTransferInteractorImpl @Inject constructor(
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase, private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase, private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase,
private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase, private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase,
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase,
) : SwapTransferInteractor { ) : SwapTransferInteractor {
@Suppress("LongMethod")
override suspend fun updateTransfer( override suspend fun updateTransfer(
fromSwapCurrencyStatus: SwapCurrencyStatus, fromSwapCurrencyStatus: SwapCurrencyStatus,
toSwapCurrencyStatus: SwapCurrencyStatus, toSwapCurrencyStatus: SwapCurrencyStatus,
@ -109,6 +113,7 @@ class SwapTransferInteractorImpl @Inject constructor(
amount = fromTokenAmountValue, amount = fromTokenAmountValue,
fee = warningsFee, fee = warningsFee,
feeCurrencyBalanceAfterTransaction = null, feeCurrencyBalanceAfterTransaction = null,
recipientAddress = toSwapCurrencyStatus.destinationAddress(),
) )
val isAmountSubtractAvailable = isAmountSubtractAvailable( val isAmountSubtractAvailable = isAmountSubtractAvailable(
userWalletId = userWallet.walletId, userWalletId = userWallet.walletId,
@ -130,6 +135,10 @@ class SwapTransferInteractorImpl @Inject constructor(
) )
} }
val tronFeeNotificationShowCount = getTronFeeNotificationShowCountUseCase() val tronFeeNotificationShowCount = getTronFeeNotificationShowCountUseCase()
val hasRequiredTrustline = getAssetRequirementsUseCase(
userWalletId = toSwapCurrencyStatus.userWalletId,
currency = toToken,
).getOrNull() is AssetRequirementsCondition.RequiredTrustline
return SwapState.Transfer( return SwapState.Transfer(
userWallet = userWallet, userWallet = userWallet,
fromTokenInfo = fromTokenInfo, fromTokenInfo = fromTokenInfo,
@ -145,6 +154,7 @@ class SwapTransferInteractorImpl @Inject constructor(
isAmountSubtractAvailable = isAmountSubtractAvailable, isAmountSubtractAvailable = isAmountSubtractAvailable,
isSendingAmountLoading = coverageState.isSendingAmountLoading, isSendingAmountLoading = coverageState.isSendingAmountLoading,
currencyCheck = currencyCheck, currencyCheck = currencyCheck,
hasRequiredTrustline = hasRequiredTrustline,
) )
} }

View file

@ -21,6 +21,7 @@ import com.tangem.domain.notifications.IncrementNotificationsShowCountUseCase
import com.tangem.domain.pay.WithdrawalResult import com.tangem.domain.pay.WithdrawalResult
import com.tangem.domain.swap.models.SwapCurrencyStatus import com.tangem.domain.swap.models.SwapCurrencyStatus
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
import com.tangem.domain.tokens.GetAssetRequirementsUseCase
import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase import com.tangem.domain.tokens.GetBalanceNotEnoughForFeeWarningUseCase
import com.tangem.domain.tokens.GetCurrencyCheckUseCase import com.tangem.domain.tokens.GetCurrencyCheckUseCase
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
@ -42,6 +43,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import java.math.BigDecimal import java.math.BigDecimal
@ -65,6 +67,7 @@ internal class SwapTransferInteractorImplTest {
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase = mockk(relaxed = true) private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase = mockk(relaxed = true)
private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase = mockk(relaxed = true) private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase = mockk(relaxed = true)
private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase = mockk(relaxed = true) private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase = mockk(relaxed = true)
private val getAssetRequirementsUseCase: GetAssetRequirementsUseCase = mockk()
private val sut = SwapTransferInteractorImpl( private val sut = SwapTransferInteractorImpl(
swapFeatureToggles = swapFeatureToggles, swapFeatureToggles = swapFeatureToggles,
@ -82,8 +85,14 @@ internal class SwapTransferInteractorImplTest {
getBalanceNotEnoughForFeeWarningUseCase = getBalanceNotEnoughForFeeWarningUseCase, getBalanceNotEnoughForFeeWarningUseCase = getBalanceNotEnoughForFeeWarningUseCase,
getTronFeeNotificationShowCountUseCase = getTronFeeNotificationShowCountUseCase, getTronFeeNotificationShowCountUseCase = getTronFeeNotificationShowCountUseCase,
incrementNotificationsShowCountUseCase = incrementNotificationsShowCountUseCase, incrementNotificationsShowCountUseCase = incrementNotificationsShowCountUseCase,
getAssetRequirementsUseCase = getAssetRequirementsUseCase,
) )
@BeforeEach
fun setup() {
coEvery { getAssetRequirementsUseCase(any(), any()) } returns null.right()
}
@AfterEach @AfterEach
fun tearDown() { fun tearDown() {
clearAllMocks() clearAllMocks()
@ -429,6 +438,68 @@ internal class SwapTransferInteractorImplTest {
assertThat(result.isSendingAmountLoading).isTrue() assertThat(result.isSendingAmountLoading).isTrue()
} }
@Test
fun `GIVEN destination address WHEN updateTransfer THEN currency check requested with recipient and isAccountFunded flows through`() =
runTest {
// Arrange
val appCurrency = AppCurrency(code = "USD", name = "US Dollar", symbol = "$")
val userWallet: UserWallet = mockk(relaxed = true)
val fromCurrencyStatus = buildCurrencyStatus(
rawCurrencyId = FROM_RAW_CURRENCY_ID,
decimals = FROM_DECIMALS,
fiatRate = BigDecimal.TEN,
amount = BigDecimal("1.6"),
userWallet = userWallet,
)
val toCurrencyStatus = buildCurrencyStatus(
rawCurrencyId = TO_RAW_CURRENCY_ID,
decimals = TO_DECIMALS,
userWallet = userWallet,
destinationAddress = DESTINATION_ADDRESS,
)
every { getSelectedAppCurrencyUseCase() } returns flowOf(appCurrency.right())
every { getBalanceHidingSettingsUseCase.isBalanceHidden() } returns flowOf(false)
coEvery { isAccountsModeEnabledUseCase.invokeSync() } returns false
// Stub matches only when the destination address is forwarded as recipientAddress; the
// returned check has isAccountFunded = true (buildCurrencyCheck default).
val fundedCheck = buildCurrencyCheck()
coEvery {
getCurrencyCheckUseCase(
userWalletId = any(),
currencyStatus = any(),
feeCurrencyStatus = any(),
amount = any(),
fee = any(),
feeCurrencyBalanceAfterTransaction = any(),
recipientAddress = DESTINATION_ADDRESS,
)
} returns fundedCheck
coEvery { isAmountSubtractAvailableUseCase(any(), any(), any()) } returns false.right()
// Act
val result = sut.updateTransfer(
fromSwapCurrencyStatus = fromCurrencyStatus,
toSwapCurrencyStatus = toCurrencyStatus,
fromTokenAmount = "1,5",
feePaidCurrencyStatus = null,
fee = null,
) as SwapState.Transfer
// Assert
assertThat(result.currencyCheck?.isAccountFunded).isTrue()
coVerify {
getCurrencyCheckUseCase(
userWalletId = any(),
currencyStatus = any(),
feeCurrencyStatus = any(),
amount = any(),
fee = any(),
feeCurrencyBalanceAfterTransaction = any(),
recipientAddress = DESTINATION_ADDRESS,
)
}
}
// endregion // endregion
// region loadFee // region loadFee

View file

@ -332,6 +332,7 @@ sealed class SwapEvents(
fromCurrency: CryptoCurrency?, fromCurrency: CryptoCurrency?,
toCurrency: CryptoCurrency?, toCurrency: CryptoCurrency?,
feeNetwork: Network, feeNetwork: Network,
isTangemPay: Boolean,
) : SwapEvents( ) : SwapEvents(
event = "Transfer in Progress Screen Opened", event = "Transfer in Progress Screen Opened",
params = mapOf( params = mapOf(
@ -340,6 +341,7 @@ sealed class SwapEvents(
RECEIVE_TOKEN to toCurrency?.symbol.orEmpty(), RECEIVE_TOKEN to toCurrency?.symbol.orEmpty(),
"Receive Blockchain" to toCurrency?.network?.name.orEmpty(), "Receive Blockchain" to toCurrency?.network?.name.orEmpty(),
"Network fee" to feeNetwork.name, "Network fee" to feeNetwork.name,
"Pay Account" to isTangemPay.toString(),
), ),
), AppsFlyerIncludedEvent ), AppsFlyerIncludedEvent

View file

@ -1491,7 +1491,7 @@ internal class SwapModel @Inject constructor(
} }
private fun updateTransferModeTangemPayState() { private fun updateTransferModeTangemPayState() {
sendTransferInProgressEvent() sendTransferInProgressEvent(isTangemPay = true)
uiState = swapTransferStateBuilder.createTangemPayWithdrawalSuccessState( uiState = swapTransferStateBuilder.createTangemPayWithdrawalSuccessState(
uiState = uiState, uiState = uiState,
dataState = dataState, dataState = dataState,
@ -1541,7 +1541,7 @@ internal class SwapModel @Inject constructor(
"" ""
} }
updateWalletBalance() updateWalletBalance()
sendTransferInProgressEvent() sendTransferInProgressEvent(isTangemPay = false)
uiState = swapTransferStateBuilder.createSuccessState( uiState = swapTransferStateBuilder.createSuccessState(
uiState = uiState, uiState = uiState,
dataState = dataState, dataState = dataState,
@ -1564,7 +1564,7 @@ internal class SwapModel @Inject constructor(
) )
} }
private fun sendTransferInProgressEvent() { private fun sendTransferInProgressEvent(isTangemPay: Boolean) {
val fromSwapCurrencyStatus = dataState.fromSwapCurrencyStatus val fromSwapCurrencyStatus = dataState.fromSwapCurrencyStatus
val toSwapCurrencyStatus = dataState.toSwapCurrencyStatus val toSwapCurrencyStatus = dataState.toSwapCurrencyStatus
analyticsEventHandler.send( analyticsEventHandler.send(
@ -1572,6 +1572,7 @@ internal class SwapModel @Inject constructor(
fromCurrency = fromSwapCurrencyStatus?.currency, fromCurrency = fromSwapCurrencyStatus?.currency,
toCurrency = toSwapCurrencyStatus?.currency, toCurrency = toSwapCurrencyStatus?.currency,
feeNetwork = getFeeToken().network, feeNetwork = getFeeToken().network,
isTangemPay = isTangemPay,
), ),
) )
} }

View file

@ -222,6 +222,7 @@ internal class SwapNotificationsFactory(
cryptoCurrency = swapCurrencyStatus.currency, cryptoCurrency = swapCurrencyStatus.currency,
feeCryptoCurrency = feeCryptoCurrencyStatus?.currency, feeCryptoCurrency = feeCryptoCurrencyStatus?.currency,
isAccountFunded = true, // consider the account is funded on the provider side isAccountFunded = true, // consider the account is funded on the provider side
hasRequiredTrustline = false,
) )
addReduceAmountNotification( addReduceAmountNotification(
cryptoCurrencyStatus = swapCurrencyStatus.status, cryptoCurrencyStatus = swapCurrencyStatus.status,

View file

@ -126,7 +126,8 @@ internal class SwapTransferNotificationsFactory @Inject constructor() {
sendingAmount = amount.value, sendingAmount = amount.value,
cryptoCurrency = swapCurrencyStatus.currency, cryptoCurrency = swapCurrencyStatus.currency,
feeCryptoCurrency = feeCryptoCurrencyStatus?.currency, feeCryptoCurrency = feeCryptoCurrencyStatus?.currency,
isAccountFunded = true, isAccountFunded = state.currencyCheck?.isAccountFunded == true,
hasRequiredTrustline = state.hasRequiredTrustline,
) )
addReduceAmountNotification( addReduceAmountNotification(
cryptoCurrencyStatus = swapCurrencyStatus.status, cryptoCurrencyStatus = swapCurrencyStatus.status,