Updated on 2026-08-14
This commit is contained in:
parent
466b6e578b
commit
df4288e70a
27 changed files with 381 additions and 31 deletions
|
|
@ -594,7 +594,7 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun associateAsset(
|
||||
override suspend fun fulfillRequirements(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
signer: TransactionSigner,
|
||||
|
|
@ -613,6 +613,21 @@ class DefaultWalletManagersFacade(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun discardRequirements(userWalletId: UserWalletId, currency: CryptoCurrency): SimpleResult {
|
||||
return withContext(dispatchers.io) {
|
||||
val walletManager = getOrCreateWalletManager(userWalletId = userWalletId, network = currency.network)
|
||||
val currencyType = cryptoCurrencyTypeConverter.convert(currency)
|
||||
|
||||
if (walletManager !is AssetRequirementsManager) {
|
||||
return@withContext SimpleResult.Failure(
|
||||
BlockchainSdkError.CustomError("WalletManager is not implemented AssetRequirementsManager"),
|
||||
)
|
||||
}
|
||||
|
||||
walletManager.discardRequirements(currencyType)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun checkUtxoConsolidationAvailability(userWalletId: UserWalletId, network: Network): Boolean {
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
val walletManager = getOrCreateWalletManager(
|
||||
|
|
|
|||
|
|
@ -233,12 +233,14 @@ interface WalletManagersFacade {
|
|||
*/
|
||||
suspend fun getAssetRequirements(userWalletId: UserWalletId, currency: CryptoCurrency): AssetRequirementsCondition?
|
||||
|
||||
suspend fun associateAsset(
|
||||
suspend fun fulfillRequirements(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
signer: TransactionSigner,
|
||||
): SimpleResult
|
||||
|
||||
suspend fun discardRequirements(userWalletId: UserWalletId, currency: CryptoCurrency): SimpleResult
|
||||
|
||||
/**
|
||||
* Indicates UTXO consolidation availability
|
||||
*
|
||||
|
|
|
|||
|
|
@ -7,13 +7,20 @@ import com.tangem.blockchain.common.trustlines.AssetRequirementsCondition as Sdk
|
|||
internal class SdkRequirementsConditionConverter : Converter<SdkRequirementsCondition, AssetRequirementsCondition> {
|
||||
override fun convert(value: SdkRequirementsCondition): AssetRequirementsCondition {
|
||||
return when (value) {
|
||||
SdkRequirementsCondition.PaidTransaction -> AssetRequirementsCondition.PaidTransaction
|
||||
is SdkRequirementsCondition.PaidTransaction -> AssetRequirementsCondition.PaidTransaction
|
||||
is SdkRequirementsCondition.PaidTransactionWithFee -> AssetRequirementsCondition.PaidTransactionWithFee(
|
||||
feeAmount = requireNotNull(value.feeAmount.value),
|
||||
feeCurrencySymbol = value.feeAmount.currencySymbol,
|
||||
decimals = value.feeAmount.decimals,
|
||||
)
|
||||
is SdkRequirementsCondition.IncompleteTransaction -> TODO()
|
||||
is SdkRequirementsCondition.IncompleteTransaction -> AssetRequirementsCondition.IncompleteTransaction(
|
||||
amount = requireNotNull(value.amount.value),
|
||||
currencySymbol = value.amount.currencySymbol,
|
||||
currencyDecimals = value.amount.decimals,
|
||||
feeAmount = requireNotNull(value.feeAmount.value),
|
||||
feeCurrencySymbol = value.feeAmount.currencySymbol,
|
||||
feeCurrencyDecimals = value.feeAmount.decimals,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.domain.tokens.model.warnings
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed class KaspaWarnings : CryptoCurrencyWarning() {
|
||||
|
||||
abstract val currency: CryptoCurrency
|
||||
|
||||
data class IncompleteTransaction(
|
||||
override val currency: CryptoCurrency,
|
||||
val amount: BigDecimal,
|
||||
val currencySymbol: String,
|
||||
val currencyDecimals: Int,
|
||||
) : KaspaWarnings()
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.tokens
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
|
||||
import com.tangem.domain.tokens.repository.CurrencyChecksRepository
|
||||
|
|
@ -22,7 +23,8 @@ class GetCurrencyCheckUseCase(
|
|||
recipientAddress: String? = null,
|
||||
): CryptoCurrencyCheck {
|
||||
return withContext(dispatchers.io) {
|
||||
val network = currencyStatus.currency.network
|
||||
val currency = currencyStatus.currency
|
||||
val network = currency.network
|
||||
val dustValue = currencyChecksRepository.getDustValue(userWalletId, network)
|
||||
val reserveAmount = currencyChecksRepository.getReserveAmount(userWalletId, network)
|
||||
val minimumSendAmount = currencyChecksRepository.getMinimumSendAmount(userWalletId, network)
|
||||
|
|
@ -39,10 +41,11 @@ class GetCurrencyCheckUseCase(
|
|||
recipientAddress,
|
||||
)
|
||||
} ?: false
|
||||
val utxoAmountLimit = if (amount != null && fee != null) {
|
||||
val utxoAmountLimit = if (currency is CryptoCurrency.Coin && amount != null && fee != null) {
|
||||
currencyChecksRepository.checkUtxoAmountLimit(
|
||||
userWalletId = userWalletId,
|
||||
network = network,
|
||||
currency = currencyStatus.currency,
|
||||
amount = amount,
|
||||
fee = fee,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.domain.staking.repositories.StakingRepository
|
|||
import com.tangem.domain.tokens.model.*
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||
import com.tangem.domain.tokens.model.warnings.HederaWarnings
|
||||
import com.tangem.domain.tokens.model.warnings.KaspaWarnings
|
||||
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
|
||||
import com.tangem.domain.tokens.repository.*
|
||||
import com.tangem.domain.transaction.models.AssetRequirementsCondition
|
||||
|
|
@ -20,7 +21,7 @@ import com.tangem.utils.isNullOrZero
|
|||
import kotlinx.coroutines.flow.*
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
class GetCurrencyWarningsUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
|
|
@ -79,7 +80,17 @@ class GetCurrencyWarningsUseCase(
|
|||
getAssetRequirementsWarning(userWalletId = userWalletId, currency = currency),
|
||||
getMigrationFromMaticToPolWarning(currency),
|
||||
)
|
||||
}.flowOn(dispatchers.io)
|
||||
}
|
||||
.onEmpty {
|
||||
setOfNotNull(
|
||||
getNetworkUnavailableWarning(currencyStatus),
|
||||
getNetworkNoAccountWarning(currencyStatus),
|
||||
getBeaconChainShutdownWarning(currency.network.id),
|
||||
getAssetRequirementsWarning(userWalletId = userWalletId, currency = currency),
|
||||
getMigrationFromMaticToPolWarning(currency),
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
}
|
||||
|
||||
private suspend fun getSwapPromoNotificationWarning(
|
||||
|
|
@ -298,12 +309,22 @@ class GetCurrencyWarningsUseCase(
|
|||
): CryptoCurrencyWarning? {
|
||||
return when (val requirements = walletManagersFacade.getAssetRequirements(userWalletId, currency)) {
|
||||
is AssetRequirementsCondition.PaidTransaction -> HederaWarnings.AssociateWarning(currency = currency)
|
||||
is AssetRequirementsCondition.PaidTransactionWithFee -> HederaWarnings.AssociateWarningWithFee(
|
||||
currency = currency,
|
||||
fee = requirements.feeAmount,
|
||||
feeCurrencySymbol = requirements.feeCurrencySymbol,
|
||||
feeCurrencyDecimals = requirements.decimals,
|
||||
)
|
||||
is AssetRequirementsCondition.PaidTransactionWithFee -> {
|
||||
HederaWarnings.AssociateWarningWithFee(
|
||||
currency = currency,
|
||||
fee = requirements.feeAmount,
|
||||
feeCurrencySymbol = requirements.feeCurrencySymbol,
|
||||
feeCurrencyDecimals = requirements.decimals,
|
||||
)
|
||||
}
|
||||
is AssetRequirementsCondition.IncompleteTransaction ->
|
||||
KaspaWarnings.IncompleteTransaction(
|
||||
currency = currency,
|
||||
amount = requirements.amount,
|
||||
currencySymbol = requirements.currencySymbol,
|
||||
currencyDecimals = requirements.currencyDecimals,
|
||||
)
|
||||
|
||||
null -> null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.domain.tokens.repository
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.CurrencyAmount
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
|
|
@ -38,6 +39,7 @@ interface CurrencyChecksRepository {
|
|||
suspend fun checkUtxoAmountLimit(
|
||||
userWalletId: UserWalletId,
|
||||
network: Network,
|
||||
currency: CryptoCurrency,
|
||||
amount: BigDecimal,
|
||||
fee: BigDecimal,
|
||||
): UtxoAmountLimit?
|
||||
|
|
|
|||
|
|
@ -17,4 +17,16 @@ sealed class AssetRequirementsCondition {
|
|||
val feeCurrencySymbol: String,
|
||||
val decimals: Int,
|
||||
) : AssetRequirementsCondition()
|
||||
|
||||
/**
|
||||
* The exact value of the fee for this type of condition is stored in `feeAmount`.
|
||||
*/
|
||||
data class IncompleteTransaction(
|
||||
val amount: BigDecimal,
|
||||
val currencySymbol: String,
|
||||
val currencyDecimals: Int,
|
||||
val feeAmount: BigDecimal,
|
||||
val feeCurrencySymbol: String,
|
||||
val feeCurrencyDecimals: Int,
|
||||
) : AssetRequirementsCondition()
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.tangem.domain.transaction.error
|
||||
|
||||
sealed class IncompleteTransactionError {
|
||||
data class DataError(val message: String?) : IncompleteTransactionError()
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ class AssociateAssetUseCase(
|
|||
|
||||
catch(
|
||||
block = {
|
||||
when (val result = walletManagersFacade.associateAsset(userWalletId, currency, signer)) {
|
||||
when (val result = walletManagersFacade.fulfillRequirements(userWalletId, currency, signer)) {
|
||||
is SimpleResult.Failure -> raise(AssociateAssetError.DataError(result.error.customMessage))
|
||||
SimpleResult.Success -> Unit
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.domain.transaction.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.transaction.error.IncompleteTransactionError
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
class DismissIncompleteTransactionUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
): Either<IncompleteTransactionError, Unit> {
|
||||
return either {
|
||||
catch(
|
||||
block = {
|
||||
when (val result = walletManagersFacade.discardRequirements(userWalletId, currency)) {
|
||||
is SimpleResult.Failure -> raise(
|
||||
IncompleteTransactionError.DataError(result.error.customMessage),
|
||||
)
|
||||
SimpleResult.Success -> Unit
|
||||
}
|
||||
},
|
||||
catch = { error -> IncompleteTransactionError.DataError(error.message) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.domain.transaction.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.transaction.error.IncompleteTransactionError
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
class RetryIncompleteTransactionUseCase(
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
): Either<IncompleteTransactionError, Unit> {
|
||||
return either {
|
||||
val signer = cardSdkConfigRepository.getCommonSigner(cardId = null)
|
||||
|
||||
catch(
|
||||
block = {
|
||||
when (val result = walletManagersFacade.fulfillRequirements(userWalletId, currency, signer)) {
|
||||
is SimpleResult.Failure -> raise(
|
||||
IncompleteTransactionError.DataError(result.error.customMessage),
|
||||
)
|
||||
SimpleResult.Success -> Unit
|
||||
}
|
||||
},
|
||||
catch = { error -> IncompleteTransactionError.DataError(error.message) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue