diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml
index fb1cde4a04..99020ba5c0 100644
--- a/core/res/src/main/res/values-fr/strings.xml
+++ b/core/res/src/main/res/values-fr/strings.xml
@@ -50,7 +50,6 @@
Thème
Paramètres de l\'application
Ces mots ne peuvent pas être récupérés en cas de perte. Assurez-vous de les conserver en lieu sûr.
- Ne partagez jamais ces mots. Quiconque les apprend peut voler toutes vos cryptomonnaies. Tangem ne vous les demandera jamais. Les %s mots ci-dessous constituent la phrase de récupération de votre portefeuille. Cette phrase vous permet de récupérer votre portefeuille en cas de perte de votre appareil.
Pour masquer ou afficher vos soldes, il suffit de retourner l\'écran de votre appareil vers le bas ou de le désactiver dans les paramètres
Ne plus afficher
Compris
@@ -118,6 +117,7 @@
Fermer
Confirmez
Continuer
+ Convertir
Copier
Copier l\'adresse
Créer
@@ -702,6 +702,11 @@
Par solde
Organiser les jetons
Dégrouper
+ Plus d\'infos
+ Vous pouvez activer les notifications pour Tangem dans les paramètres.
+ Activer plus tard
+ Paramètres
+ Activer les notifications
Recevez des alertes pour les transactions entrantes sur les réseaux pris en charge.
Sélectionnez dans la galerie
Paramètres
@@ -775,7 +780,9 @@
Vous avez spécifié une commission inférieure au montant recommandé, ce qui pourrait entraîner un retard dans votre transaction. Continuer?
Raison : %1$s\nCode : %2$s
La transaction est incomplète
+ Convertir en un autre jeton
Montant
+ Sera envoyé au destinataire
Vous pouvez définir vos frais de transaction en ajustant la valeur dans le champ Satoshi par vByte.
Les frais qui seront facturés pour votre transaction. Vous pouvez définir votre propre valeur.
Frais maximum
@@ -799,6 +806,7 @@
Vérifiez votre connexion réseau
Informations sur les frais de réseau inaccessibles
De
+ De %s
Limite de gaz
Il s\'agit du montant maximal de gaz qui sera dépensé pour effectuer une transaction ou un contrat. Une limite de gaz empêche des frais imprévus ou illimités lors de l\'exécution d\'une transaction.
Prix du gaz
@@ -806,6 +814,7 @@
Max
Somme maximale
Frais jusqu\'à
+ Mémo : %s
Mémo invalide
Couverture des frais de réseau
Fonds insuffisants pour le transfert, car le total des frais et du montant du transfert dépasse le solde existant
@@ -816,6 +825,7 @@
Les frais de douane sont élevés
En raison des particularités du réseau %1$s, les frais de transfert de la totalité du solde sont plus élevés. Pour réduire la commission, vous pouvez en laisser %2$s.
Les frais sont plus élevés
+ Le compte du bénéficiaire n\'est pas activé. Le montant minimum du transfert doit être égal ou supérieur au solde exonéré de loyer : %1$s.
Le solde de votre compte ne peut pas être inférieur au montant du loyer. Veuillez conserver au moins %1$s sur votre compte ou retirer tous les fonds.
La commission incluse dépasse le montant du transfert, ce qui entraîne une valeur négative
Montant invalide
@@ -835,6 +845,7 @@
Destinataire
Adresse non valide
Assurez-vous que l\'adresse du portefeuille de réception est sur le réseau %s pour éviter de perdre vos jetons
+ envoyer à %s
Envoyer à
Un Memo/Destination Tag est un identifiant unique permettant de différencier les transactions envoyées au même destinataire sur le même réseau. Attention : L\'omission d\'un mémo peut entraîner des fonds mal placés
Le Memo / Destination Tag est un code qui distingue les transactions envoyées à un destinataire partagé sur un réseau crypto.
@@ -851,6 +862,7 @@
les frais de réseau seront couverts en utilisant %1$s énergie
les frais de réseau seront réduits en utilisant %1$s énergie
y compris des frais de réseau de %1$s
+ À l\'adresse
La transaction a été signée avec succès et envoyée au nœud de blockchain. Le solde du portefeuille sera mis à jour après un certain temps
%1$s est un actif du réseau Tron. Pour calculer les frais et effectuer une transaction, déposez du Tron (TRX) sur votre compte.
Le montant dépasse le solde
@@ -860,6 +872,7 @@
Les frais de commissions dépassent le solde
Le total dépasse le solde
Échanger et envoyer
+ Montant à recevoir
Transaction envoyée
Scannez la carte/ bague que vous souhaitez configurer.
Oublier le portefeuille
@@ -1013,6 +1026,7 @@
Meilleurs Tarifs
Simple et intuitif, vous permettant d\'échanger des jetons en quelques clics
Plus Simple Que Jamais
+ Échange via le fournisseur
Le montant comprend :\n• les frais du fournisseur de services\n• les frais de réseau pour l\'envoi de %s depuis l\'échange vers l\'adresse de l\'utilisateur.
Le montant comprend :\n• les frais du fournisseur de services\n• les frais de réseau pour l\'envoi de %1$s depuis l\'échange vers l\'adresse de l\'utilisateur. \n\nLe slippage du fournisseur peut atteindre %2$s
Le montant comprend les frais du fournisseur de services.
@@ -1164,6 +1178,7 @@
Accédez à plus de 13 000 cryptomonnaies. Achetez, vendez, échangez et stakez en un seul clic.\nAssociez jusqu\'à trois cartes pour une sauvegarde.
Découvrez le Portefeuille Tangem
Recevez des notifications sur les transactions entrantes du portefeuille et les mises à jour de Tangem.
+ Notifications de transaction
Paramètres du portefeuille
Tangem
Utilisez %s ou scannez une carte/bague pour déverrouiller l\'accès à votre portefeuille
@@ -1255,6 +1270,7 @@
À des fins de test uniquement
Le solde peut être obsolète. Rafraîchissez la page.
Domaine malveillant
+ Si le problème persiste, n’hésitez pas à contacter notre support.
Le portefeuille Tangem ne prend actuellement pas en charge %ss
dApp non prise en charge
Connexions
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 0283698666..3f3874186f 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -1253,6 +1253,7 @@
Ваш отзыв мотивирует нас сделать кошелек Tangem еще лучше
Нравится Tangem?
Вам необходимо провести ассоциацию токена для того, чтобы иметь возможность принимать его
+ Вы должны открыть трастлайн для своего токена, чтобы иметь возможность получить на него средства.
Необходима плата за аренду сети
Требуется действие
Вы обращались в службу поддержки через приложение в течение 7 дней после создания кошелька? Если обращались или не уверены, нажмите «Да» и следуйте инструкциям.
@@ -1268,26 +1269,71 @@
Свайпните вниз для обновления или попробуйте позже.
Некоторые сети недоступны
Некоторые балансы токенов не удалось обновить
+ Недостаточно %s. Пополните свой XLM аккаунт чтобы открыть трастлайн.
Это Testnet карта. Он не может обрабатывать транзакции и используется только в целях тестирования и разработки.
Только для целей тестирования
Возможно, баланс устарел. Обновите страницу.
Открыть Trustline
Согласно правилам сети, чтобы пополнить этот токен, необходимо сначала открыть Trustline — это позволит вашему кошельку принимать и хранить этот актив.
- Откройте Trustline
+ Требуется трастлайн
+ Вредоносный домен
+ Неизвестный домен
+ Подключиться всё равно
+ Ошибка тайм-аута. Пожалуйста, попробуйте позже.
+ Не удалось подключиться через Wallet Connect
+ Этот домен не может быть верифицирован. Внимательно проверьте запрос перед одобрением.
Пожалуйста, вернитесь в браузер и выполните повторное подключение через WalletConnect.
+ Сессия Wallet Connect была завершена
+ Подписать всё равно
+ Код ошибки: %s. Если проблема сохраняется, обратитесь в нашу службу поддержки.
+ Если проблема сохраняется, обратитесь в нашу службу поддержки
+ Мы обнаружили неизвестную ошибку
+ Кошелек Tangem.в настоящий момент не поддерживает %s
Неподдерживаемый dApp
+ Мы обнаружили неизвестную ошибку
+ Tangem в настоящее время не поддерживает необходимую сеть для %s
+ Неподдерживаемые сети
+ Tangem поддерживает сеть, необходимую для %s
+ Верифицированный домен
Выбрана не верная карта или кольцо
+ Похоже, возникла проблема
+ Разрешение на использование
Адрес
Подключение
+ Загрузка
+ Сеть
+ Сети
+ Безлимитно
+ Кошелек
+ Подключенные сети
Посмотреть баланс кошелька и его активность
+ Подписать транзакцию без вашего участия
+ Запрос разрешения на транзакцию
+ Не имеет возможности
+ Хотели бы
Запрос на подключение
+ Подключения
Вложение
Копировать данные
+ Настраиваемый лимит
+ Отключить все
+ Отключить все dApp
+ Предварительные изменения
+ Не удалось выполнить симуляцию транзакции. Пожалуйста, действуйте с осторожностью.
+ Вредоносная транзакция
+ Добавьте сеть %s в ваш портфель для выбранного кошелька
+ В кошельке не добавлены необходимые сети
+ Новое подключение
+ Подключите свой кошелек к различным dApp
+ Нет подключений
+ Этот домен помечен как небезопасный несколькими поставщиками систем безопасности. Немедленно покиньте его, чтобы защитить свои активы.
+ Известный риск безопасности
Запрос от
Тип подписи
На
Запрос транзакции
Запрос транзакции
+ Безлимитное количество
Подключение кошелька
Отказаться
Вы не закончили резервное копирование. Хотите продолжить?
diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml
index 3669539d24..3387633667 100644
--- a/core/res/src/main/res/values-uk-rUA/strings.xml
+++ b/core/res/src/main/res/values-uk-rUA/strings.xml
@@ -722,6 +722,9 @@
Сортування токенів
Список
Більше
+ Ви можете ввімкнути сповіщення у налаштуваннях
+ Увімкнути пізніше
+ Налаштування
Увімкнути сповіщення
Отримуйте сповіщення про вхідні транзакції в підтримуваних мережах.
Виберіть з галереї
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 84c5ab2dc5..1e513517d1 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -948,6 +948,7 @@
Total amount exceeds balance
Swap and send
Send any token, and we’ll convert it on the way. Your recipient gets exactly what they need—seamlessly.
+ Recipient will receive
Will be sent a recipient
Amount to receive
Send with swap
@@ -1427,7 +1428,7 @@
Swipe down to refresh or try again later.
Some networks are unreachable
Some token balances could not be updated
- Not enough %s. Top up your XLM account to associate this token
+ Not enough %s. Top up your XLM account to open trustline.
This is a Testnet card. It cannot process transactions and should only be used for testing and development purposes.
For testing purposes only
Balance may be outdated. Refresh the page.
@@ -1482,7 +1483,7 @@
Estimated wallet changes
The transaction couldn\'t be simulated. Please proceed with caution.
Malicious transaction
- Add the %s network to your profile for this wallet
+ Add the %s network to your portfolio for this wallet
The wallet has no required networks
New connection
Connect your wallet to a different dApps
diff --git a/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt
index 36945de43e..f1423fabac 100644
--- a/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt
+++ b/core/utils/src/main/java/com/tangem/utils/StringsSigns.kt
@@ -14,4 +14,5 @@ object StringsSigns {
const val PERCENT = "%"
const val THREE_STARS = "\u2217\u2217\u2217"
const val PASSWORD_VISUAL_CHAR = '\u2022'
+ const val APPROXIMATE = "≈"
}
\ No newline at end of file
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountModel.kt
index f722d3e1ea..1172e472b4 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountModel.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountModel.kt
@@ -250,6 +250,7 @@ internal class SwapAmountModel @Inject constructor(
.onEach { currency ->
uiState.update { amountUM ->
if (amountUM is SwapAmountUM.Content) {
+ initPairs(currency)
amountUM.copy(
isPrimaryButtonEnabled = false,
secondaryAmount = SwapAmountFieldUM.Loading(
@@ -260,7 +261,6 @@ internal class SwapAmountModel @Inject constructor(
amountUM
}
}
- initPairs(currency)
}
.launchIn(modelScope)
}
@@ -400,6 +400,7 @@ internal class SwapAmountModel @Inject constructor(
swapDirection = swapDirection,
allowanceContract = quote.allowanceContract,
isApprovalNeeded = checkAllowance(state, quote),
+ fromAmount = fromAmountValue,
).convert(
SwapQuoteUMConverter.Data(
quote = quote,
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountQuoteUtils.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountQuoteUtils.kt
index b2b853bf9d..c4869a1825 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountQuoteUtils.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/SwapAmountQuoteUtils.kt
@@ -12,9 +12,13 @@ import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
import com.tangem.utils.extensions.isZero
import java.math.BigDecimal
import java.math.RoundingMode
+import kotlin.math.min
internal object SwapAmountQuoteUtils {
+ private const val MAX_DECIMALS = 8
+ private const val MIN_DECIMALS = 2
+
fun calculatePriceImpact(
fromTokenAmount: BigDecimal,
toTokenAmount: BigDecimal,
@@ -41,6 +45,11 @@ internal object SwapAmountQuoteUtils {
}
}
+ fun calculateRate(fromAmount: BigDecimal, toAmount: BigDecimal, toAmountDecimals: Int): BigDecimal {
+ val rateDecimals = if (toAmountDecimals == 0) MIN_DECIMALS else toAmountDecimals
+ return toAmount.divide(fromAmount, min(rateDecimals, MAX_DECIMALS), RoundingMode.HALF_UP)
+ }
+
fun SwapAmountUM.updateAmount(
onPrimaryAmount: SwapAmountFieldUM.Content.(CryptoCurrencyStatus) -> SwapAmountFieldUM,
onSecondaryAmount: SwapAmountFieldUM.Content.(CryptoCurrencyStatus) -> SwapAmountFieldUM,
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/converter/SwapQuoteUMConverter.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/converter/SwapQuoteUMConverter.kt
index 8abbd44af1..f5738cbd5e 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/converter/SwapQuoteUMConverter.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/model/converter/SwapQuoteUMConverter.kt
@@ -1,14 +1,20 @@
package com.tangem.features.swap.v2.impl.amount.model.converter
+import androidx.compose.ui.text.buildAnnotatedString
+import com.tangem.core.ui.extensions.annotatedReference
+import com.tangem.core.ui.extensions.appendSpace
import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.format.bigdecimal.anyDecimals
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.domain.express.models.ExpressProvider
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.swap.models.SwapDirection
import com.tangem.domain.swap.models.SwapQuoteModel
+import com.tangem.features.swap.v2.impl.amount.model.SwapAmountQuoteUtils.calculateRate
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM.Content.DifferencePercent
+import com.tangem.utils.StringsSigns
import com.tangem.utils.converter.Converter
import java.math.BigDecimal
@@ -18,10 +24,24 @@ internal class SwapQuoteUMConverter(
private val isApprovalNeeded: Boolean,
private val primaryCurrency: CryptoCurrency,
private val secondaryCurrency: CryptoCurrency,
+ private val fromAmount: BigDecimal,
) : Converter {
override fun convert(value: Data): SwapQuoteUM {
val (quote, provider) = value
+ val rate = calculateRate(
+ fromAmount = fromAmount,
+ toAmount = quote.toTokenAmount,
+ toAmountDecimals = secondaryCurrency.decimals,
+ )
+ val rateString = buildAnnotatedString {
+ append(BigDecimal.ONE.format { crypto(symbol = primaryCurrency.symbol, decimals = 0).anyDecimals() })
+ appendSpace()
+ append(StringsSigns.APPROXIMATE)
+ appendSpace()
+ append(rate.format { crypto(secondaryCurrency) })
+ }
+
return if (allowanceContract != null) {
if (isApprovalNeeded) {
SwapQuoteUM.Allowance(
@@ -36,6 +56,7 @@ internal class SwapQuoteUMConverter(
quoteAmountValue = stringReference(
quote.toTokenAmount.toQuoteValue(),
),
+ rate = annotatedReference(rateString),
)
}
} else {
@@ -46,6 +67,7 @@ internal class SwapQuoteUMConverter(
quoteAmountValue = stringReference(
quote.toTokenAmount.toQuoteValue(),
),
+ rate = annotatedReference(rateString),
)
}
}
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/ui/preview/SwapAmountContentPreview.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/ui/preview/SwapAmountContentPreview.kt
index 596cecef01..b40ecc6c80 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/ui/preview/SwapAmountContentPreview.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/amount/ui/preview/SwapAmountContentPreview.kt
@@ -5,6 +5,8 @@ import com.tangem.core.ui.components.atoms.text.TextEllipsis
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.appcurrency.model.AppCurrency
+import com.tangem.domain.express.models.ExpressProvider
+import com.tangem.domain.express.models.ExpressProviderType
import com.tangem.domain.express.models.ExpressRateType
import com.tangem.domain.models.currency.CryptoCurrency
import com.tangem.domain.models.network.Network
@@ -16,10 +18,11 @@ import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountType
import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
import kotlinx.collections.immutable.persistentListOf
+import java.math.BigDecimal
internal data object SwapAmountContentPreview {
- private val cryptoCurrencyStatus = CryptoCurrencyStatus(
+ val cryptoCurrencyStatus = CryptoCurrencyStatus(
currency = CryptoCurrency.Coin(
id = CryptoCurrency.ID.fromValue("coin⟨BITCOIN⟩bitcoin"),
network = Network(
@@ -41,12 +44,32 @@ internal data object SwapAmountContentPreview {
name = "Bitcoin",
symbol = "BTC",
decimals = 8,
- iconUrl = "",
+ iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/medium/bitcoin.png",
isCustom = false,
),
value = CryptoCurrencyStatus.Loading,
)
+ private val provider = ExpressProvider(
+ providerId = "changenow",
+ rateTypes = listOf(ExpressRateType.Float),
+ name = "ChangeNow",
+ type = ExpressProviderType.CEX,
+ imageLarge = "",
+ termsOfUse = "",
+ privacyPolicy = "",
+ isRecommended = true,
+ slippage = BigDecimal.ZERO,
+ )
+
+ private val quote = SwapQuoteUM.Content(
+ provider = provider,
+ quoteAmount = "123".toBigDecimal(),
+ quoteAmountValue = stringReference("123"),
+ rate = stringReference("1 USD ≈ 123.123 POL"),
+ diffPercent = SwapQuoteUM.Content.DifferencePercent.Best,
+ )
+
val emptyState = SwapAmountUM.Content(
isPrimaryButtonEnabled = false,
primaryAmount = SwapAmountFieldUM.Empty(
@@ -95,7 +118,7 @@ internal data object SwapAmountContentPreview {
selectedAmountType = SwapAmountType.From,
swapCurrencies = SwapCurrencies.EMPTY,
swapQuotes = persistentListOf(),
- selectedQuote = SwapQuoteUM.Empty,
+ selectedQuote = quote,
primaryCryptoCurrencyStatus = cryptoCurrencyStatus,
secondaryCryptoCurrencyStatus = cryptoCurrencyStatus,
swapRateType = ExpressRateType.Float,
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/chooseprovider/ui/preview/SwapChooseProviderContentPreview.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/chooseprovider/ui/preview/SwapChooseProviderContentPreview.kt
index 6558e68f96..b96c7acb4b 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/chooseprovider/ui/preview/SwapChooseProviderContentPreview.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/chooseprovider/ui/preview/SwapChooseProviderContentPreview.kt
@@ -36,6 +36,7 @@ internal object SwapChooseProviderContentPreview {
provider = provider1,
quoteAmount = "123".toBigDecimal(),
quoteAmountValue = stringReference("123"),
+ rate = stringReference("1 USD ≈ 123.123 POL"),
diffPercent = SwapQuoteUM.Content.DifferencePercent.Best,
)
@@ -43,6 +44,7 @@ internal object SwapChooseProviderContentPreview {
provider = provider2,
quoteAmount = "13.12".toBigDecimal(),
quoteAmountValue = stringReference("13.12"),
+ rate = stringReference("1 USD ≈ 12.123 POL"),
diffPercent = SwapQuoteUM.Content.DifferencePercent.Empty,
)
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt
index 7e3af10fa2..701181e121 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/ConfirmUM.kt
@@ -3,6 +3,8 @@ package com.tangem.features.swap.v2.impl.common.entity
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.notifications.NotificationUM
import com.tangem.core.ui.extensions.TextReference
+import com.tangem.domain.express.models.ExpressProvider
+import com.tangem.domain.swap.models.SwapDataModel
import kotlinx.collections.immutable.ImmutableList
@Immutable
@@ -18,6 +20,14 @@ internal sealed class ConfirmUM {
val notifications: ImmutableList,
) : ConfirmUM()
+ data class Success(
+ override val isPrimaryButtonEnabled: Boolean = true,
+ val transactionDate: Long,
+ val txUrl: String,
+ val swapDataModel: SwapDataModel,
+ val provider: ExpressProvider,
+ ) : ConfirmUM()
+
data object Empty : ConfirmUM() {
override val isPrimaryButtonEnabled: Boolean = false
}
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/SwapQuoteUM.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/SwapQuoteUM.kt
index 0b4abfd3c3..ec6aaf74e7 100644
--- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/SwapQuoteUM.kt
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/common/entity/SwapQuoteUM.kt
@@ -34,6 +34,7 @@ internal sealed class SwapQuoteUM {
val quoteAmount: BigDecimal,
val quoteAmountValue: TextReference,
val diffPercent: DifferencePercent,
+ val rate: TextReference,
) : SwapQuoteUM() {
sealed class DifferencePercent {
data object Empty : DifferencePercent()
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/SendWithSwapSuccessComponent.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/SendWithSwapSuccessComponent.kt
new file mode 100644
index 0000000000..26d40108f5
--- /dev/null
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/SendWithSwapSuccessComponent.kt
@@ -0,0 +1,37 @@
+package com.tangem.features.swap.v2.impl.sendviaswap.success
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.tangem.common.ui.navigationButtons.NavigationModelCallback
+import com.tangem.core.decompose.context.AppComponentContext
+import com.tangem.core.decompose.model.getOrCreateModel
+import com.tangem.core.ui.decompose.ComposableContentComponent
+import com.tangem.features.swap.v2.impl.sendviaswap.SendWithSwapRoute
+import com.tangem.features.swap.v2.impl.sendviaswap.entity.SendWithSwapUM
+import com.tangem.features.swap.v2.impl.sendviaswap.success.model.SendWithSwapSuccessModel
+import com.tangem.features.swap.v2.impl.sendviaswap.success.ui.SendWithSwapSuccessContent
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+internal class SendWithSwapSuccessComponent(
+ appComponentContext: AppComponentContext,
+ params: Params,
+) : ComposableContentComponent, AppComponentContext by appComponentContext {
+
+ private val model: SendWithSwapSuccessModel = getOrCreateModel(params = params)
+
+ @Composable
+ override fun Content(modifier: Modifier) {
+ val state by model.uiState.collectAsStateWithLifecycle()
+ SendWithSwapSuccessContent(sendWithSwapUM = state)
+ }
+
+ data class Params(
+ val sendWithSwapUMFlow: StateFlow,
+ val analyticsCategoryName: String,
+ val currentRoute: Flow,
+ val callback: NavigationModelCallback,
+ )
+}
\ No newline at end of file
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/di/SendWithSwapSuccessModule.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/di/SendWithSwapSuccessModule.kt
new file mode 100644
index 0000000000..f3cf9bc5a7
--- /dev/null
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/di/SendWithSwapSuccessModule.kt
@@ -0,0 +1,20 @@
+package com.tangem.features.swap.v2.impl.sendviaswap.success.di
+
+import com.tangem.core.decompose.di.ModelComponent
+import com.tangem.core.decompose.model.Model
+import com.tangem.features.swap.v2.impl.sendviaswap.success.model.SendWithSwapSuccessModel
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+@InstallIn(ModelComponent::class)
+internal interface SendWithSwapSuccessModule {
+
+ @Binds
+ @IntoMap
+ @ClassKey(SendWithSwapSuccessModel::class)
+ fun bindSendWithSwapSuccessModel(impl: SendWithSwapSuccessModel): Model
+}
\ No newline at end of file
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt
new file mode 100644
index 0000000000..63ad5d40da
--- /dev/null
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/model/SendWithSwapSuccessModel.kt
@@ -0,0 +1,81 @@
+package com.tangem.features.swap.v2.impl.sendviaswap.success.model
+
+import com.tangem.common.routing.AppRouter
+import com.tangem.common.ui.navigationButtons.NavigationButton
+import com.tangem.common.ui.navigationButtons.NavigationUM
+import com.tangem.core.decompose.di.ModelScoped
+import com.tangem.core.decompose.model.Model
+import com.tangem.core.decompose.model.ParamsContainer
+import com.tangem.core.navigation.share.ShareManager
+import com.tangem.core.navigation.url.UrlOpener
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.features.swap.v2.impl.R
+import com.tangem.features.swap.v2.impl.common.entity.ConfirmUM
+import com.tangem.features.swap.v2.impl.sendviaswap.entity.SendWithSwapUM
+import com.tangem.features.swap.v2.impl.sendviaswap.success.SendWithSwapSuccessComponent
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import kotlinx.coroutines.flow.StateFlow
+import javax.inject.Inject
+
+@ModelScoped
+internal class SendWithSwapSuccessModel @Inject constructor(
+ override val dispatchers: CoroutineDispatcherProvider,
+ private val urlOpener: UrlOpener,
+ private val shareManager: ShareManager,
+ private val appRouter: AppRouter,
+ paramsContainer: ParamsContainer,
+) : Model() {
+
+ private val params: SendWithSwapSuccessComponent.Params = paramsContainer.require()
+
+ val uiState: StateFlow = params.sendWithSwapUMFlow
+
+ val confirmUM = uiState.value.confirmUM as? ConfirmUM.Success
+
+ init {
+ configConfirmSuccessNavigation()
+ }
+
+ private fun configConfirmSuccessNavigation() {
+ params.callback.onNavigationResult(
+ NavigationUM.Content(
+ title = TextReference.EMPTY,
+ subtitle = null,
+ backIconRes = R.drawable.ic_close_24,
+ backIconClick = appRouter::pop,
+ primaryButton = NavigationButton(
+ textReference = resourceReference(R.string.common_close),
+ iconRes = null,
+ isEnabled = true,
+ isHapticClick = false,
+ onClick = appRouter::pop,
+ ),
+ prevButton = null,
+ secondaryPairButtonsUM = NavigationButton(
+ textReference = resourceReference(R.string.common_explore),
+ iconRes = R.drawable.ic_web_24,
+ onClick = ::onExploreClick,
+ ) to NavigationButton(
+ textReference = resourceReference(R.string.common_share),
+ iconRes = R.drawable.ic_share_24,
+ onClick = ::onShareClick,
+ ),
+ ),
+ )
+ }
+
+ private fun onExploreClick() {
+ if (confirmUM == null) return
+
+ // analyticsEventHandler.send(CommonSendAnalyticEvents.ExploreButtonClicked(params.analyticsCategoryName))
+ urlOpener.openUrl(confirmUM.txUrl)
+ }
+
+ private fun onShareClick() {
+ if (confirmUM == null) return
+
+ // analyticsEventHandler.send(CommonSendAnalyticEvents.ShareButtonClicked(params.analyticsCategoryName))
+ shareManager.shareText(confirmUM.txUrl)
+ }
+}
\ No newline at end of file
diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/ui/SendWithSwapSuccessContent.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/ui/SendWithSwapSuccessContent.kt
new file mode 100644
index 0000000000..4ea2e22fea
--- /dev/null
+++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/success/ui/SendWithSwapSuccessContent.kt
@@ -0,0 +1,441 @@
+package com.tangem.features.swap.v2.impl.sendviaswap.success.ui
+
+import android.content.res.Configuration
+import androidx.compose.animation.*
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.hapticfeedback.HapticFeedbackType
+import androidx.compose.ui.platform.LocalHapticFeedback
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.tangem.blockchain.common.transaction.Fee
+import com.tangem.blockchain.common.transaction.TransactionFee
+import com.tangem.common.ui.amountScreen.models.AmountState
+import com.tangem.common.ui.amountScreen.utils.getFiatReference
+import com.tangem.common.ui.navigationButtons.NavigationButton
+import com.tangem.common.ui.navigationButtons.NavigationUM
+import com.tangem.core.ui.components.SecondaryButtonIconStart
+import com.tangem.core.ui.components.SpacerW12
+import com.tangem.core.ui.components.currency.icon.CurrencyIcon
+import com.tangem.core.ui.components.icons.identicon.IdentIcon
+import com.tangem.core.ui.components.inputrow.InputRowBestRate
+import com.tangem.core.ui.components.rows.SelectorRowItem
+import com.tangem.core.ui.components.transactions.TransactionDoneTitle
+import com.tangem.core.ui.extensions.*
+import com.tangem.core.ui.format.bigdecimal.crypto
+import com.tangem.core.ui.format.bigdecimal.fee
+import com.tangem.core.ui.format.bigdecimal.fiat
+import com.tangem.core.ui.format.bigdecimal.format
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.core.ui.utils.DateTimeFormatters
+import com.tangem.core.ui.utils.singleEvent
+import com.tangem.core.ui.utils.toTimeFormat
+import com.tangem.domain.express.models.ExpressProvider
+import com.tangem.domain.express.models.ExpressProviderType
+import com.tangem.domain.swap.models.SwapDataModel
+import com.tangem.domain.swap.models.SwapDataTransactionModel
+import com.tangem.domain.utils.convertToSdkAmount
+import com.tangem.features.send.v2.api.entity.FeeExtraInfo
+import com.tangem.features.send.v2.api.entity.FeeItem
+import com.tangem.features.send.v2.api.entity.FeeNonce
+import com.tangem.features.send.v2.api.entity.FeeSelectorUM
+import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationTextFieldUM
+import com.tangem.features.send.v2.api.subcomponents.destination.entity.DestinationUM
+import com.tangem.features.swap.v2.impl.R
+import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountFieldUM
+import com.tangem.features.swap.v2.impl.amount.entity.SwapAmountUM
+import com.tangem.features.swap.v2.impl.amount.ui.preview.SwapAmountContentPreview
+import com.tangem.features.swap.v2.impl.common.entity.ConfirmUM
+import com.tangem.features.swap.v2.impl.common.entity.SwapQuoteUM
+import com.tangem.features.swap.v2.impl.sendviaswap.entity.SendWithSwapUM
+import kotlinx.collections.immutable.persistentListOf
+import java.math.BigDecimal
+
+private const val GRADIENT_ALPHA = 0.3f
+
+@Composable
+internal fun SendWithSwapSuccessContent(sendWithSwapUM: SendWithSwapUM) {
+ if (sendWithSwapUM.navigationUM !is NavigationUM.Content) return
+
+ val confirmUM = sendWithSwapUM.confirmUM as? ConfirmUM.Success ?: return
+ val amountUM = sendWithSwapUM.amountUM as? SwapAmountUM.Content ?: return
+ val quoteUM = amountUM.selectedQuote as? SwapQuoteUM.Content ?: return
+ val destinationUM = sendWithSwapUM.destinationUM as? DestinationUM.Content ?: return
+ val feeSelectorUM = sendWithSwapUM.feeSelectorUM as? FeeSelectorUM.Content ?: return
+
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(TangemTheme.colors.background.tertiary),
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(horizontal = 16.dp)
+ .verticalScroll(rememberScrollState()),
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ ) {
+ TransactionDoneTitle(
+ title = resourceReference(R.string.sent_transaction_sent_title),
+ subtitle = resourceReference(
+ id = R.string.send_date_format,
+ formatArgs = wrappedList(
+ confirmUM.transactionDate.toTimeFormat(DateTimeFormatters.dateFormatter),
+ confirmUM.transactionDate.toTimeFormat(),
+ ),
+ ),
+ modifier = Modifier.padding(vertical = 12.dp),
+ )
+ SwapAmountBlock(amountUM = amountUM)
+ InputRowBestRate(
+ imageUrl = confirmUM.provider.imageLarge,
+ title = stringReference(confirmUM.provider.name),
+ titleExtra = stringReference(confirmUM.provider.type.typeName),
+ subtitle = quoteUM.rate,
+ modifier = Modifier
+ .clip(TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.background.action),
+ )
+ DestinationBlock(destinationUM.addressTextField)
+ FeeBlock(feeSelectorUM = feeSelectorUM)
+ Spacer(Modifier.height(60.dp))
+ }
+ DoneButtons(
+ pairButtonsUM = sendWithSwapUM.navigationUM.secondaryPairButtonsUM,
+ modifier = Modifier
+ .align(Alignment.BottomCenter)
+ .background(
+ brush = Brush.verticalGradient(
+ colors = listOf(
+ Color.Transparent,
+ TangemTheme.colors.background.tertiary.copy(GRADIENT_ALPHA),
+ TangemTheme.colors.background.tertiary,
+ ),
+ ),
+ )
+ .padding(top = 24.dp)
+ .padding(horizontal = 16.dp),
+
+ )
+ }
+}
+
+@Composable
+private fun SwapAmountBlock(amountUM: SwapAmountUM.Content) {
+ AmountBlock(
+ title = resourceReference(
+ id = R.string.send_from_wallet_name,
+ formatArgs = wrappedList(
+ (amountUM.primaryAmount.amountField as? AmountState.Data)?.title
+ ?: TextReference.EMPTY,
+ ),
+ ),
+ amountFieldUM = amountUM.primaryAmount,
+ )
+ AmountBlock(
+ title = resourceReference(R.string.send_with_swap_recipient_amount_success_title),
+ amountFieldUM = amountUM.secondaryAmount,
+ )
+}
+
+@Composable
+private fun AmountBlock(title: TextReference, amountFieldUM: SwapAmountFieldUM, modifier: Modifier = Modifier) {
+ val amountFieldData = amountFieldUM.amountField as? AmountState.Data ?: return
+ val cryptoAmount = amountFieldData.amountTextField.cryptoAmount
+ val fiatAmount = amountFieldData.amountTextField.fiatAmount
+
+ Column(
+ modifier = modifier
+ .clip(TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.background.action)
+ .padding(12.dp),
+ ) {
+ Text(
+ text = title.resolveReference(),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 16.dp),
+ ) {
+ CurrencyIcon(
+ state = amountFieldData.tokenIconState,
+ )
+ Column(
+ verticalArrangement = Arrangement.spacedBy(2.dp),
+ ) {
+ Text(
+ text = cryptoAmount.value?.format {
+ crypto(
+ symbol = cryptoAmount.currencySymbol,
+ decimals = cryptoAmount.decimals,
+ )
+ }.orEmpty(),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.primary1,
+ )
+ Text(
+ text = fiatAmount.value.format {
+ fiat(
+ fiatCurrencyCode = amountFieldData.appCurrency.code,
+ fiatCurrencySymbol = amountFieldData.appCurrency.symbol,
+ )
+ },
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun FeeBlock(feeSelectorUM: FeeSelectorUM.Content) {
+ val feeExtraInfo = feeSelectorUM.feeExtraInfo
+ val feeFiatRateUM = feeSelectorUM.feeFiatRateUM
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .clip(TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.background.action)
+ .padding(TangemTheme.dimens.spacing12),
+ ) {
+ Text(
+ text = stringResourceSafe(com.tangem.common.ui.R.string.common_network_fee_title),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+
+ Box(modifier = Modifier.padding(top = TangemTheme.dimens.spacing8)) {
+ val feeAmount = feeSelectorUM.selectedFeeItem.fee.amount
+ SelectorRowItem(
+ titleRes = com.tangem.common.ui.R.string.common_fee_selector_option_market,
+ iconRes = com.tangem.common.ui.R.drawable.ic_bird_24,
+ preDot = stringReference(
+ feeAmount.value.format {
+ crypto(
+ symbol = feeAmount.currencySymbol,
+ decimals = feeAmount.decimals,
+ ).fee(canBeLower = feeExtraInfo.isFeeApproximate)
+ },
+ ),
+ postDot = if (feeExtraInfo.isFeeConvertibleToFiat && feeFiatRateUM != null) {
+ getFiatReference(feeAmount.value, feeFiatRateUM.rate, feeFiatRateUM.appCurrency)
+ } else {
+ null
+ },
+ ellipsizeOffset = feeAmount.currencySymbol.length,
+ isSelected = true,
+ showDivider = false,
+ showSelectedAppearance = false,
+ paddingValues = PaddingValues(),
+ )
+ }
+ }
+}
+
+@Composable
+private fun DestinationBlock(address: DestinationTextFieldUM.RecipientAddress, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier
+ .fillMaxWidth()
+ .clip(TangemTheme.shapes.roundedCornersXMedium)
+ .background(TangemTheme.colors.background.action)
+ .padding(12.dp),
+ ) {
+ Text(
+ text = stringResourceSafe(R.string.send_recipient),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(24.dp),
+ modifier = Modifier.padding(top = 8.dp),
+ ) {
+ Text(
+ modifier = Modifier.weight(1f),
+ text = address.value,
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.primary1,
+ )
+ IdentIcon(
+ address = address.value,
+ modifier = Modifier
+ .size(TangemTheme.dimens.size36)
+ .clip(RoundedCornerShape(18.dp))
+ .background(TangemTheme.colors.background.tertiary),
+ )
+ }
+ }
+}
+
+// TODO remove [REDACTED_TASK_KEY]
+@Composable
+private fun DoneButtons(pairButtonsUM: Pair?, modifier: Modifier = Modifier) {
+ val hapticFeedback = LocalHapticFeedback.current
+
+ AnimatedVisibility(
+ visible = pairButtonsUM != null,
+ modifier = modifier,
+ enter = slideInVertically().plus(fadeIn()),
+ exit = slideOutVertically().plus(fadeOut()),
+ label = "Animate show sent state buttons",
+ ) {
+ val (leftButton, rightButton) = remember(this) { requireNotNull(pairButtonsUM) }
+ Row {
+ SecondaryButtonIconStart(
+ text = leftButton.textReference.resolveReference(),
+ iconResId = requireNotNull(leftButton.iconRes),
+ onClick = {
+ singleEvent {
+ leftButton.onClick()
+ }
+ },
+ modifier = Modifier.weight(1f),
+ )
+ SpacerW12()
+ SecondaryButtonIconStart(
+ text = rightButton.textReference.resolveReference(),
+ iconResId = requireNotNull(rightButton.iconRes),
+ onClick = {
+ singleEvent {
+ hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
+ rightButton.onClick()
+ }
+ },
+ modifier = Modifier.weight(1f),
+ )
+ }
+ }
+}
+
+// region Preview
+@Suppress("LongMethod")
+@Composable
+@Preview(showBackground = true, widthDp = 360, heightDp = 720)
+@Preview(showBackground = true, widthDp = 360, heightDp = 720, uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun SendWithSwapSuccessContent_Preview() {
+ TangemThemePreview {
+ SendWithSwapSuccessContent(
+ sendWithSwapUM = SendWithSwapUM(
+ amountUM = SwapAmountContentPreview.defaultState,
+ destinationUM = DestinationUM.Content(
+ isPrimaryButtonEnabled = false,
+ addressTextField = DestinationTextFieldUM.RecipientAddress(
+ value = "0x391316d97a07027a0702c8A002c8A0C25d8470",
+ keyboardOptions = KeyboardOptions(),
+ placeholder = TextReference.EMPTY,
+ label = resourceReference(R.string.send_recipient),
+ isError = false,
+ error = null,
+ isValuePasted = false,
+ blockchainAddress = "0x391316d97a07027a0702c8A002c8A0C25d8470",
+ ),
+ memoTextField = null,
+ recent = persistentListOf(),
+ wallets = persistentListOf(),
+ networkName = "Polygon",
+ isValidating = false,
+ isInitialized = false,
+ isRedesignEnabled = false,
+ ),
+ feeSelectorUM = FeeSelectorUM.Content(
+ fees = TransactionFee.Single(
+ normal = Fee.Common(
+ BigDecimal.ONE.convertToSdkAmount(
+ SwapAmountContentPreview.cryptoCurrencyStatus.currency,
+ ),
+ ),
+ ),
+ feeItems = persistentListOf(),
+ selectedFeeItem = FeeItem.Market(
+ Fee.Common(
+ BigDecimal.ONE.convertToSdkAmount(
+ SwapAmountContentPreview.cryptoCurrencyStatus.currency,
+ ),
+ ),
+ ),
+ feeExtraInfo = FeeExtraInfo(
+ isFeeApproximate = false,
+ isFeeConvertibleToFiat = false,
+ isTronToken = false,
+ ),
+ feeFiatRateUM = null,
+ feeNonce = FeeNonce.None,
+ ),
+ confirmUM = ConfirmUM.Success(
+ isPrimaryButtonEnabled = true,
+ transactionDate = 8960,
+ txUrl = "https://tangem.com",
+ provider = ExpressProvider(
+ providerId = "changelly",
+ rateTypes = listOf(),
+ name = "Changelly",
+ type = ExpressProviderType.CEX,
+ imageLarge = "https://s3.eu-central-1.amazonaws.com/tangem.api/express/changelly-1024.png",
+ termsOfUse = "",
+ privacyPolicy = "",
+ isRecommended = false,
+ slippage = null,
+ ),
+ swapDataModel = SwapDataModel(
+ toTokenAmount = BigDecimal.TEN,
+ transaction = SwapDataTransactionModel.CEX(
+ fromAmount = BigDecimal.TEN,
+ toAmount = BigDecimal.TEN,
+ txValue = "cetero",
+ txId = "oporteat",
+ txTo = "graecis",
+ txExtraId = "expetendis",
+ externalTxId = "atomorum",
+ externalTxUrl = "https://tangem.com",
+ txExtraIdName = "Jeffry Blackwell",
+ ),
+ ),
+ ),
+ navigationUM = NavigationUM.Content(
+ title = TextReference.EMPTY,
+ subtitle = null,
+ backIconRes = R.drawable.ic_close_24,
+ backIconClick = {},
+ additionalIconRes = null,
+ additionalIconClick = null,
+ primaryButton = NavigationButton(
+ textReference = resourceReference(R.string.common_close),
+ isEnabled = true,
+ onClick = {},
+ ),
+ secondaryPairButtonsUM = NavigationButton(
+ textReference = resourceReference(R.string.common_explore),
+ iconRes = R.drawable.ic_web_24,
+ isEnabled = true,
+ onClick = {},
+ ) to NavigationButton(
+ textReference = resourceReference(R.string.common_share),
+ iconRes = R.drawable.ic_share_24,
+ isEnabled = true,
+ onClick = {},
+ ),
+ ),
+ ),
+ )
+ }
+}
+// endregion
\ No newline at end of file