Updated on 2026-08-14
This commit is contained in:
parent
ab2f0f58bb
commit
22ad2ddc67
22 changed files with 190 additions and 15 deletions
|
|
@ -8,7 +8,11 @@ internal class SdkRequirementsConditionConverter : Converter<SdkRequirementsCond
|
|||
override fun convert(value: SdkRequirementsCondition): AssetRequirementsCondition {
|
||||
return when (value) {
|
||||
is SdkRequirementsCondition.PaidTransaction -> AssetRequirementsCondition.PaidTransaction
|
||||
is SdkRequirementsCondition.RequiredTrustline -> TODO("added in [REDACTED_TASK_KEY]")
|
||||
is SdkRequirementsCondition.RequiredTrustline -> AssetRequirementsCondition.RequiredTrustline(
|
||||
requiredAmount = requireNotNull(value.amount.value),
|
||||
currencySymbol = value.amount.currencySymbol,
|
||||
decimals = value.amount.decimals,
|
||||
)
|
||||
is SdkRequirementsCondition.PaidTransactionWithFee -> AssetRequirementsCondition.PaidTransactionWithFee(
|
||||
feeAmount = requireNotNull(value.feeAmount.value),
|
||||
feeCurrencySymbol = value.feeAmount.currencySymbol,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ sealed class ScenarioUnavailabilityReason {
|
|||
|
||||
data object UnassociatedAsset : ScenarioUnavailabilityReason()
|
||||
|
||||
data object TrustlineRequired : ScenarioUnavailabilityReason()
|
||||
|
||||
enum class WithdrawalScenario {
|
||||
SELL, SEND // TODO staking create&process STAKING
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ sealed class TokenScreenAnalyticsEvent(
|
|||
private const val SINGLE_WALLET = "Single Wallet"
|
||||
private const val LOADING = "Loading"
|
||||
private const val ASSET_REQUIREMENT = "AssetRequirement"
|
||||
private const val TRUSTLINE_REQUIREMENT = "TrustlineRequirement"
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
fun ScenarioUnavailabilityReason.toReasonAnalyticsText(): String {
|
||||
|
|
@ -177,6 +178,7 @@ sealed class TokenScreenAnalyticsEvent(
|
|||
is ScenarioUnavailabilityReason.StakingUnavailable,
|
||||
-> UNAVAILABLE
|
||||
ScenarioUnavailabilityReason.UnassociatedAsset -> ASSET_REQUIREMENT
|
||||
ScenarioUnavailabilityReason.TrustlineRequired -> TRUSTLINE_REQUIREMENT
|
||||
is ScenarioUnavailabilityReason.EmptyBalance -> EMPTY
|
||||
is ScenarioUnavailabilityReason.PendingTransaction -> PENDING
|
||||
ScenarioUnavailabilityReason.UsedOutdatedData -> CACHING
|
||||
|
|
|
|||
|
|
@ -61,4 +61,11 @@ sealed class CryptoCurrencyWarning {
|
|||
) : CryptoCurrencyWarning()
|
||||
|
||||
data object UsedOutdatedDataWarning : CryptoCurrencyWarning()
|
||||
|
||||
data class RequiredTrustline(
|
||||
val currency: CryptoCurrency,
|
||||
val currencySymbol: String,
|
||||
val requiredAmount: BigDecimal,
|
||||
val currencyDecimals: Int,
|
||||
) : CryptoCurrencyWarning()
|
||||
}
|
||||
|
|
@ -375,12 +375,14 @@ class GetCryptoCurrencyActionsUseCase(
|
|||
}
|
||||
|
||||
private fun getReceiveScenario(requirements: AssetRequirementsCondition?): ScenarioUnavailabilityReason {
|
||||
return if (requirements is AssetRequirementsCondition.PaidTransaction ||
|
||||
requirements is AssetRequirementsCondition.PaidTransactionWithFee
|
||||
) {
|
||||
ScenarioUnavailabilityReason.UnassociatedAsset
|
||||
} else {
|
||||
ScenarioUnavailabilityReason.None
|
||||
return when (requirements) {
|
||||
AssetRequirementsCondition.PaidTransaction,
|
||||
is AssetRequirementsCondition.PaidTransactionWithFee,
|
||||
-> ScenarioUnavailabilityReason.UnassociatedAsset
|
||||
is AssetRequirementsCondition.IncompleteTransaction,
|
||||
null,
|
||||
-> ScenarioUnavailabilityReason.None
|
||||
is AssetRequirementsCondition.RequiredTrustline -> ScenarioUnavailabilityReason.TrustlineRequired
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -222,6 +222,12 @@ class GetCurrencyWarningsUseCase(
|
|||
): CryptoCurrencyWarning? {
|
||||
return when (val requirements = walletManagersFacade.getAssetRequirements(userWalletId, currency)) {
|
||||
is AssetRequirementsCondition.PaidTransaction -> HederaWarnings.AssociateWarning(currency = currency)
|
||||
is AssetRequirementsCondition.RequiredTrustline -> CryptoCurrencyWarning.RequiredTrustline(
|
||||
currency = currency,
|
||||
requiredAmount = requirements.requiredAmount,
|
||||
currencyDecimals = requirements.decimals,
|
||||
currencySymbol = requirements.currencySymbol,
|
||||
)
|
||||
is AssetRequirementsCondition.PaidTransactionWithFee -> {
|
||||
HederaWarnings.AssociateWarningWithFee(
|
||||
currency = currency,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,15 @@ sealed class AssetRequirementsCondition {
|
|||
*/
|
||||
data object PaidTransaction : AssetRequirementsCondition()
|
||||
|
||||
/**
|
||||
* Trustlines are an explicit opt-in for an account to hold a particular asset.
|
||||
*/
|
||||
data class RequiredTrustline(
|
||||
val requiredAmount: BigDecimal,
|
||||
val currencySymbol: String,
|
||||
val decimals: Int,
|
||||
) : AssetRequirementsCondition()
|
||||
|
||||
/**
|
||||
* The exact value of the fee for this type of condition is stored in `feeAmount`.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.transaction.error
|
||||
|
||||
import java.math.BigDecimal
|
||||
|
||||
sealed interface OpenTrustlineError {
|
||||
val message: String?
|
||||
|
||||
data class SomeError(override val message: String?) : OpenTrustlineError
|
||||
data class NotEnoughCoin(val amount: BigDecimal, override val message: String?) : OpenTrustlineError
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.tangem.domain.transaction.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.catch
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.extensions.SimpleResult
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.transaction.error.OpenTrustlineError
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
|
||||
class OpenTrustlineUseCase(
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWalletId: UserWalletId,
|
||||
currency: CryptoCurrency,
|
||||
): Either<OpenTrustlineError, Unit> {
|
||||
return either {
|
||||
val signer = cardSdkConfigRepository.getCommonSigner(
|
||||
cardId = null,
|
||||
twinKey = null, // use null here because no assets support for Twin cards
|
||||
)
|
||||
|
||||
catch(
|
||||
block = {
|
||||
when (val result = walletManagersFacade.fulfillRequirements(userWalletId, currency, signer)) {
|
||||
is SimpleResult.Failure -> when (val error = result.error) {
|
||||
is BlockchainSdkError.Stellar.MinReserveRequired ->
|
||||
raise(OpenTrustlineError.NotEnoughCoin(error.amount, result.error.customMessage))
|
||||
else -> raise(OpenTrustlineError.SomeError(result.error.customMessage))
|
||||
}
|
||||
SimpleResult.Success -> Unit
|
||||
}
|
||||
},
|
||||
catch = { error -> raise(OpenTrustlineError.SomeError(error.message)) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue