Updated on 2026-08-14
This commit is contained in:
parent
589805424e
commit
c448a1aebb
8 changed files with 64 additions and 57 deletions
|
|
@ -7,6 +7,7 @@ import com.tangem.domain.redux.ReduxStateHolder
|
|||
import com.tangem.domain.transaction.WalletAddressServiceRepository
|
||||
import com.tangem.domain.transaction.usecase.ParseSharedAddressUseCase
|
||||
import com.tangem.domain.transaction.usecase.ValidateWalletAddressUseCase
|
||||
import com.tangem.domain.transaction.usecase.IsMemoRequiredUseCase
|
||||
import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.delegate.DefaultUserWalletsSyncDelegate
|
||||
|
|
@ -210,6 +211,14 @@ internal object WalletsDomainModule {
|
|||
return ValidateWalletMemoUseCase(walletAddressServiceRepository = walletAddressServiceRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesIsMemoRequiredUseCase(
|
||||
walletAddressServiceRepository: WalletAddressServiceRepository,
|
||||
): IsMemoRequiredUseCase {
|
||||
return IsMemoRequiredUseCase(walletAddressServiceRepository = walletAddressServiceRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesParseSharedAddressUseCase(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.domain.transaction.usecase
|
||||
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.transaction.WalletAddressServiceRepository
|
||||
|
||||
class IsMemoRequiredUseCase(
|
||||
private val walletAddressServiceRepository: WalletAddressServiceRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(network: Network, destinationAddress: String): Boolean {
|
||||
return try {
|
||||
walletAddressServiceRepository.isMemoRequired(
|
||||
network = network,
|
||||
destinationAddress = destinationAddress,
|
||||
)
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ interface SendNotificationsComponent {
|
|||
val callback: ModelCallback,
|
||||
) {
|
||||
data class NotificationData(
|
||||
val destinationAddress: String,
|
||||
val destinationAddress: String?,
|
||||
val memo: String?,
|
||||
val amountValue: BigDecimal,
|
||||
val reduceAmountBy: BigDecimal,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import com.tangem.domain.tokens.GetCurrencyCheckUseCase
|
|||
import com.tangem.domain.tokens.IsAmountSubtractAvailableUseCase
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
|
||||
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
|
||||
import com.tangem.domain.transaction.usecase.ValidateWalletMemoUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent.Params.NotificationData
|
||||
|
|
@ -69,7 +68,6 @@ internal class NotificationsModel @Inject constructor(
|
|||
private val getCurrencyCheckUseCase: GetCurrencyCheckUseCase,
|
||||
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
|
||||
private val validateTransactionUseCase: ValidateTransactionUseCase,
|
||||
private val validateWalletMemoUseCase: ValidateWalletMemoUseCase,
|
||||
private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase,
|
||||
private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase,
|
||||
private val notificationsUpdateTrigger: SendNotificationsUpdateTrigger,
|
||||
|
|
@ -302,7 +300,7 @@ internal class NotificationsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private suspend fun MutableList<NotificationUM>.addWarningNotifications(
|
||||
destinationAddress: String,
|
||||
destinationAddress: String?,
|
||||
memo: String?,
|
||||
enteredAmount: BigDecimal,
|
||||
sendingAmount: BigDecimal,
|
||||
|
|
@ -311,14 +309,18 @@ internal class NotificationsModel @Inject constructor(
|
|||
isFeeCoverage: Boolean,
|
||||
currencyCheck: CryptoCurrencyCheck,
|
||||
) {
|
||||
val validationError = validateTransactionUseCase(
|
||||
userWalletId = userWalletId,
|
||||
amount = enteredAmount.convertToSdkAmount(cryptoCurrencyStatus),
|
||||
fee = fee,
|
||||
memo = memo,
|
||||
destination = destinationAddress,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
).leftOrNull()
|
||||
val validationError = if (destinationAddress != null) {
|
||||
validateTransactionUseCase(
|
||||
userWalletId = userWalletId,
|
||||
amount = enteredAmount.convertToSdkAmount(cryptoCurrencyStatus),
|
||||
fee = fee,
|
||||
memo = memo,
|
||||
destination = destinationAddress,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
).leftOrNull()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
addRentExemptionNotification(
|
||||
rentWarning = currencyCheck.rentWarning,
|
||||
|
|
@ -352,10 +354,6 @@ internal class NotificationsModel @Inject constructor(
|
|||
params.callback.onAmountReduceTo(reduceTo)
|
||||
},
|
||||
)
|
||||
addDestinationTagRequiredNotification(
|
||||
isMemoRequired = currencyCheck.isMemoRequired,
|
||||
memo = memo,
|
||||
)
|
||||
addHighFeeWarningNotification(
|
||||
enteredAmountValue = enteredAmount,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
|
|
@ -376,21 +374,6 @@ internal class NotificationsModel @Inject constructor(
|
|||
addTronNetworkFeesNotification()
|
||||
}
|
||||
|
||||
private suspend fun MutableList<NotificationUM>.addDestinationTagRequiredNotification(
|
||||
isMemoRequired: Boolean,
|
||||
memo: String?,
|
||||
) {
|
||||
if (!isMemoRequired || contains(NotificationUM.Error.DestinationTagRequired)) return
|
||||
val isMemoInvalid = memo.isNullOrEmpty() || validateWalletMemoUseCase(
|
||||
userWalletId = userWalletId,
|
||||
cryptoCurrency = currency,
|
||||
memo = memo,
|
||||
).isLeft()
|
||||
if (isMemoInvalid) {
|
||||
add(NotificationUM.Error.DestinationTagRequired)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<NotificationUM>.addTronNetworkFeesNotification() {
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val isTronToken = cryptoCurrency is CryptoCurrency.Token &&
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.swap.v2.impl.notifications.model
|
||||
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
|
|
@ -9,8 +8,7 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.express.models.ExpressError
|
||||
import com.tangem.domain.transaction.usecase.ValidateTransactionUseCase
|
||||
import com.tangem.domain.utils.convertToSdkAmount
|
||||
import com.tangem.domain.transaction.usecase.IsMemoRequiredUseCase
|
||||
import com.tangem.features.swap.v2.api.subcomponents.SwapAmountUpdateTrigger
|
||||
import com.tangem.features.swap.v2.impl.amount.entity.PriceImpact
|
||||
import com.tangem.features.swap.v2.impl.notifications.DefaultSwapNotificationsUpdateTrigger
|
||||
|
|
@ -28,7 +26,6 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -38,7 +35,7 @@ internal class SwapNotificationsModel @Inject constructor(
|
|||
private val swapNotificationsUpdateListener: SwapNotificationsUpdateListener,
|
||||
private val swapNotificationsUpdateTrigger: DefaultSwapNotificationsUpdateTrigger,
|
||||
private val swapAmountUpdateTrigger: SwapAmountUpdateTrigger,
|
||||
private val validateTransactionUseCase: ValidateTransactionUseCase,
|
||||
private val isMemoRequiredUseCase: IsMemoRequiredUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
|
@ -116,20 +113,18 @@ internal class SwapNotificationsModel @Inject constructor(
|
|||
|
||||
private suspend fun MutableList<NotificationUM>.addDestinationTagRequiredNotification() {
|
||||
val toCryptoCurrencyStatus = notificationData.toCryptoCurrencyStatus ?: return
|
||||
val userWalletId = notificationData.userWalletId ?: return
|
||||
val destinationAddress = notificationData.destinationAddress
|
||||
if (destinationAddress.isEmpty()) return
|
||||
|
||||
val validationError = validateTransactionUseCase(
|
||||
amount = BigDecimal.ZERO.convertToSdkAmount(toCryptoCurrencyStatus),
|
||||
fee = null,
|
||||
memo = notificationData.memo,
|
||||
destination = destinationAddress,
|
||||
userWalletId = userWalletId,
|
||||
network = toCryptoCurrencyStatus.currency.network,
|
||||
).leftOrNull()
|
||||
|
||||
if (validationError is BlockchainSdkError.DestinationTagRequired) {
|
||||
val isMemoRequired = if (notificationData.memo.isNullOrEmpty()) {
|
||||
isMemoRequiredUseCase(
|
||||
network = toCryptoCurrencyStatus.currency.network,
|
||||
destinationAddress = destinationAddress,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
if (isMemoRequired) {
|
||||
add(NotificationUM.Error.DestinationTagRequired)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.tangem.core.decompose.model.getOrCreateModel
|
|||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.swap.models.SwapDirection
|
||||
|
|
@ -113,10 +112,11 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor(
|
|||
appCurrency = params.appCurrency,
|
||||
callback = model,
|
||||
notificationData = SendNotificationsComponent.Params.NotificationData(
|
||||
destinationAddress = when (val currency = model.primaryCurrencyStatus.currency) {
|
||||
is CryptoCurrency.Token -> currency.contractAddress
|
||||
is CryptoCurrency.Coin -> "0"
|
||||
},
|
||||
/**
|
||||
* Null when destination is unknown at this point (e.g. CEX swap — address is only known
|
||||
* after receiving exchange-data). For DEX / DEX_BRIDGE, the address is known upfront.
|
||||
*/
|
||||
destinationAddress = null,
|
||||
memo = null,
|
||||
amountValue = model.confirmData.enteredFromAmount.orZero(),
|
||||
reduceAmountBy = model.confirmData.reduceAmountBy.orZero(),
|
||||
|
|
|
|||
|
|
@ -436,10 +436,11 @@ internal class SendWithSwapConfirmModel @Inject constructor(
|
|||
feeUMV2?.feeExtraInfo?.feeCryptoCurrencyStatus ?: params.primaryFeePaidCurrencyStatusFlow.value
|
||||
sendNotificationsUpdateTrigger.triggerUpdate(
|
||||
data = NotificationData(
|
||||
destinationAddress = when (val currency = primaryCurrencyStatus.currency) {
|
||||
is CryptoCurrency.Token -> currency.contractAddress
|
||||
is CryptoCurrency.Coin -> "0"
|
||||
},
|
||||
/**
|
||||
* Null when destination is unknown at this point (e.g. CEX swap — address is only known
|
||||
* after receiving exchange-data). For DEX / DEX_BRIDGE, the address is known upfront.
|
||||
*/
|
||||
destinationAddress = null,
|
||||
memo = null,
|
||||
amountValue = confirmData.enteredFromAmount.orZero(),
|
||||
reduceAmountBy = confirmData.reduceAmountBy,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import androidx.compose.ui.unit.dp
|
|||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.common.ui.notifications.notifications
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
||||
import com.tangem.features.send.v2.api.SendNotificationsComponent
|
||||
import com.tangem.features.send.v2.api.subcomponents.destination.SendDestinationBlockComponent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue