diff --git a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt index ea48365cb7..8be21bb8cf 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/TransactionDomainModule.kt @@ -79,6 +79,18 @@ internal object TransactionDomainModule { ) } + @Provides + @Singleton + fun provideOpenTrustlineUseCase( + cardSdkConfigRepository: CardSdkConfigRepository, + walletManagersFacade: WalletManagersFacade, + ): OpenTrustlineUseCase { + return OpenTrustlineUseCase( + cardSdkConfigRepository = cardSdkConfigRepository, + walletManagersFacade = walletManagersFacade, + ) + } + @Provides @Singleton fun provideDismissIncompleteTransactionUseCase( diff --git a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenActionsUtils.kt b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenActionsUtils.kt index 7337dccc5d..374cbde833 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenActionsUtils.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/tokens/TokenActionsUtils.kt @@ -6,6 +6,7 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList import com.tangem.domain.tokens.model.ScenarioUnavailabilityReason +@Suppress("CyclomaticComplexMethod") fun ScenarioUnavailabilityReason.getUnavailabilityReasonText(): TextReference { return when (val unavailabilityReason = this) { is ScenarioUnavailabilityReason.StakingUnavailable -> { @@ -46,6 +47,9 @@ fun ScenarioUnavailabilityReason.getUnavailabilityReasonText(): TextReference { ScenarioUnavailabilityReason.UnassociatedAsset -> resourceReference( id = R.string.warning_receive_blocked_hedera_token_association_required_message, ) + ScenarioUnavailabilityReason.TrustlineRequired -> resourceReference( + id = R.string.warning_receive_blocked_token_trustline_required_message, + ) ScenarioUnavailabilityReason.UsedOutdatedData -> { resourceReference(id = R.string.token_button_unavailability_reason_out_of_date_balance) } diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 24c3cc5827..e90c8e89e2 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1299,8 +1299,8 @@ Der Kontostand ist möglicherweise veraltet. Aktualisiere bittre die Seite. Nicht genug %1$s. Lade Dein XLM-Konto auf, um dieses Token zu verknüpfen Trustline aktivieren - Um dieses Token zu erhalten, muss eine Trustline aktiviert sein. Das Netzwerk benötigt eine Reserve von %1$s %2$s. - Trustline erforderlich + Um dieses Token zu erhalten, muss eine Trustline aktiviert sein. Das Netzwerk benötigt eine Reserve von %1$s %2$s. + Trustline erforderlich Unbekannte Domäne Trotzdem verbinden Zeitüberschreitungsfehler. Bitte versuche es später erneut. diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 722f628412..11cb1fb068 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -1279,8 +1279,8 @@ 残高が古い可能性があります。ページを更新してください。 %1$sが足りません。このトークンを関連付けるには、XLMアカウントにチャージしてください。 トラストラインを有効にする - このトークンを受け取るには、トラストラインを有効にする必要があります。ネットワークには%1$s %2$s予備金が必要です。 - トラストラインが必要 + このトークンを受け取るには、トラストラインを有効にする必要があります。ネットワークには%1$s %2$s予備金が必要です。 + トラストラインが必要 不明なドメイン とにかく接続する タイムアウトエラーが発生しました。しばらくしてからもう一度お試しください。 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 6be2e1fb65..8ac257b580 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1263,8 +1263,8 @@ Только для целей тестирования Возможно, баланс устарел. Обновите страницу. Открыть Trustline - Согласно правилам сети, чтобы пополнить этот токен, необходимо сначала открыть Trustline — это позволит вашему кошельку принимать и хранить этот актив. - Откройте Trustline + Согласно правилам сети, чтобы пополнить этот токен, необходимо сначала открыть Trustline — это позволит вашему кошельку принимать и хранить этот актив. + Откройте Trustline Пожалуйста, вернитесь в браузер и выполните повторное подключение через WalletConnect. Выбрана не верная карта или кольцо Адрес diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 59973b51ac..46db541274 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1344,8 +1344,8 @@ Balance may be outdated. Refresh the page. Not enough %1$s. Top up your XLM account to associate this token Enable Trustline - A Trustline must be enabled to receive this token. The network requires a %1$s %2$s reserve. - Trustline Required + A Trustline must be enabled to receive this token. The network requires a %1$s %2$s reserve. + Trustline Required Unknown domain Connect anyway Timeout error. Please, try again later. diff --git a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt index b426db7892..b3250351dd 100644 --- a/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt +++ b/data/manage-tokens/src/main/kotlin/com/tangem/data/managetokens/DefaultCustomTokensRepository.kt @@ -57,6 +57,7 @@ internal class DefaultCustomTokensRepository( -> true Blockchain.Cardano, Blockchain.Sui, + Blockchain.Stellar, -> blockchain.validateContractAddress(contractAddress) else -> blockchain.validateAddress(contractAddress) } diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkRequirementsConditionConverter.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkRequirementsConditionConverter.kt index 1e93352c42..f2cb03313a 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkRequirementsConditionConverter.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/utils/SdkRequirementsConditionConverter.kt @@ -8,7 +8,11 @@ internal class SdkRequirementsConditionConverter : Converter 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, diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/ScenarioUnavailabilityReason.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/ScenarioUnavailabilityReason.kt index 02f95ce1e1..bf816df605 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/ScenarioUnavailabilityReason.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/ScenarioUnavailabilityReason.kt @@ -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 } diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt index 844923dee0..54eac28f44 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/analytics/TokenScreenAnalyticsEvent.kt @@ -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 diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt index f76e272a6b..083b0aba95 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/warnings/CryptoCurrencyWarning.kt @@ -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() } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt index 77f16153ff..1e1a09d0d2 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCryptoCurrencyActionsUseCase.kt @@ -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 } } diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt index fbc6e1efdc..b02e4b6dda 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetCurrencyWarningsUseCase.kt @@ -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, diff --git a/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/AssetRequirementsCondition.kt b/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/AssetRequirementsCondition.kt index 2bb5c1d8fb..5826a800ab 100644 --- a/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/AssetRequirementsCondition.kt +++ b/domain/transaction/models/src/main/kotlin/com/tangem/domain/transaction/models/AssetRequirementsCondition.kt @@ -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`. */ diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/error/OpenTrustlineError.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/OpenTrustlineError.kt new file mode 100644 index 0000000000..a71270bf29 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/error/OpenTrustlineError.kt @@ -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 +} \ No newline at end of file diff --git a/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/OpenTrustlineUseCase.kt b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/OpenTrustlineUseCase.kt new file mode 100644 index 0000000000..1e3a9655a9 --- /dev/null +++ b/domain/transaction/src/main/java/com/tangem/domain/transaction/usecase/OpenTrustlineUseCase.kt @@ -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 { + 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)) }, + ) + } + } +} \ No newline at end of file diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/analytics/TokenDetailsNotificationsAnalyticsSender.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/analytics/TokenDetailsNotificationsAnalyticsSender.kt index b28e14d171..dbe31e24b9 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/analytics/TokenDetailsNotificationsAnalyticsSender.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/analytics/TokenDetailsNotificationsAnalyticsSender.kt @@ -51,6 +51,7 @@ internal class TokenDetailsNotificationsAnalyticsSender( is TokenDetailsNotification.RentInfo, is TokenDetailsNotification.NetworkShutdown, is TokenDetailsNotification.HederaAssociateWarning, + is TokenDetailsNotification.RequiredTrustlineWarning, is TokenDetailsNotification.KoinosMana, is TokenDetailsNotification.MigrationMaticToPol, is TokenDetailsNotification.UsedOutdatedData, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsClickIntents.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsClickIntents.kt index 6aab0064c7..e0e6cd1566 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsClickIntents.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsClickIntents.kt @@ -62,6 +62,8 @@ interface TokenDetailsClickIntents { fun onRetryIncompleteTransactionClick() + fun onOpenTrustlineClick() + fun onDismissIncompleteTransactionClick() fun onConfirmDismissIncompleteTransactionClick() diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt index 976ace101c..d2d966d302 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/model/TokenDetailsModel.kt @@ -56,9 +56,11 @@ import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent.Compan import com.tangem.domain.tokens.model.analytics.TokenSwapPromoAnalyticsEvent import com.tangem.domain.transaction.error.AssociateAssetError import com.tangem.domain.transaction.error.IncompleteTransactionError +import com.tangem.domain.transaction.error.OpenTrustlineError import com.tangem.domain.transaction.error.SendTransactionError import com.tangem.domain.transaction.usecase.AssociateAssetUseCase import com.tangem.domain.transaction.usecase.DismissIncompleteTransactionUseCase +import com.tangem.domain.transaction.usecase.OpenTrustlineUseCase import com.tangem.domain.transaction.usecase.RetryIncompleteTransactionUseCase import com.tangem.domain.txhistory.usecase.GetExplorerTransactionUrlUseCase import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase @@ -116,6 +118,7 @@ internal class TokenDetailsModel @Inject constructor( private val isDemoCardUseCase: IsDemoCardUseCase, private val associateAssetUseCase: AssociateAssetUseCase, private val retryIncompleteTransactionUseCase: RetryIncompleteTransactionUseCase, + private val openTrustlineUseCase: OpenTrustlineUseCase, private val dismissIncompleteTransactionUseCase: DismissIncompleteTransactionUseCase, private val reduxStateHolder: ReduxStateHolder, private val analyticsEventsHandler: AnalyticsEventHandler, @@ -893,6 +896,37 @@ internal class TokenDetailsModel @Inject constructor( } } + override fun onOpenTrustlineClick() { + analyticsEventsHandler.send( + TokenScreenAnalyticsEvent.Associate( + tokenSymbol = cryptoCurrency.symbol, + blockchain = cryptoCurrency.network.name, + ), + ) + modelScope.launch(dispatchers.mainImmediate) { + openTrustlineUseCase( + userWalletId = userWalletId, + currency = cryptoCurrency, + ).fold( + ifLeft = { e -> + Timber.e(e.message) + internalUiState.value = when (e) { + is OpenTrustlineError.SomeError -> + stateFactory.getStateWithErrorDialog(stringReference(e.message.orEmpty())) + is OpenTrustlineError.NotEnoughCoin -> { + val text = resourceReference( + id = R.string.warning_token_required_min_coin_reserve, + formatArgs = wrappedList(e.amount), + ) + stateFactory.getStateWithErrorDialog(text) + } + } + }, + ifRight = { internalUiState.value = stateFactory.getStateWithRemovedRequiredTrustlineNotification() }, + ) + } + } + override fun onDismissIncompleteTransactionClick() { analyticsEventsHandler.send( TokenScreenAnalyticsEvent.RevealCancel( diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt index 74eaebd01d..297bc67dfc 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/components/TokenDetailsNotification.kt @@ -193,6 +193,24 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) { ), ) + data class RequiredTrustlineWarning( + private val currency: CryptoCurrency, + private val amount: String, + private val currencySymbol: String, + private val onOpenClick: () -> Unit, + ) : Warning( + title = resourceReference(id = R.string.warning_token_trustline_title), + subtitle = resourceReference( + id = R.string.warning_token_trustline_subtitle, + formatArgs = wrappedList(amount, currencySymbol), + ), + iconResId = currency.networkIconResId, + buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig( + text = resourceReference(R.string.warning_token_trustline_button_title), + onClick = onOpenClick, + ), + ) + data class KaspaIncompleteTransactionWarning( private val currency: CryptoCurrency, private val amount: String, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt index c6faec47ad..67215ebe35 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsNotificationConverter.kt @@ -42,6 +42,12 @@ internal class TokenDetailsNotificationConverter( return newNotifications.toImmutableList() } + fun removeRequiredTrustlineWarning(currentState: TokenDetailsState): ImmutableList { + val newNotifications = currentState.notifications.toMutableList() + newNotifications.removeBy { it is RequiredTrustlineWarning } + return newNotifications.toImmutableList() + } + fun removeKaspaIncompleteTransactionWarning( currentState: TokenDetailsState, ): ImmutableList { @@ -118,6 +124,12 @@ internal class TokenDetailsNotificationConverter( feeCurrencySymbol = warning.feeCurrencySymbol, onAssociateClick = clickIntents::onAssociateClick, ) + is CryptoCurrencyWarning.RequiredTrustline -> RequiredTrustlineWarning( + currency = warning.currency, + amount = warning.requiredAmount.format { crypto(symbol = "", warning.currencyDecimals) }, + currencySymbol = warning.currencySymbol, + onOpenClick = clickIntents::onOpenTrustlineClick, + ) is KaspaWarnings.IncompleteTransaction -> KaspaIncompleteTransactionWarning( currency = warning.currency, amount = warning.amount.format { crypto(symbol = "", decimals = warning.currencyDecimals) }, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt index 222804e41b..4819797954 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsStateFactory.kt @@ -334,6 +334,11 @@ internal class TokenDetailsStateFactory( return state.copy(notifications = notificationConverter.removeHederaAssociateWarning(state)) } + fun getStateWithRemovedRequiredTrustlineNotification(): TokenDetailsState { + val state = currentStateProvider() + return state.copy(notifications = notificationConverter.removeRequiredTrustlineWarning(state)) + } + fun getStateWithRemovedKaspaIncompleteTransactionNotification(): TokenDetailsState { val state = currentStateProvider() return state.copy(