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(