diff --git a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt index 42450edff8..0d9a4eba92 100644 --- a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt +++ b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt @@ -51,6 +51,16 @@ internal class DefaultTangemPayStorage @Inject constructor( private val withdrawStoreDataConverter by lazy { WithdrawStoreDataConverter() } private val withdrawStateConverter by lazy { WithdrawStateConverter() } + private val listType by lazy { + Types.newParameterizedType(List::class.java, WithdrawStoreData::class.java) + } + private val mapType by lazy { + Types.newParameterizedType(Map::class.java, String::class.java, listType) + } + private val adapter: JsonAdapter>> by lazy { + appPreferencesStore.moshi.adapter(mapType) + } + override suspend fun storeCustomerWalletAddress(userWalletId: UserWalletId, customerWalletAddress: String) { withContext(dispatcherProvider.io) { appPreferencesStore @@ -152,15 +162,19 @@ internal class DefaultTangemPayStorage @Inject constructor( } override suspend fun storeWithdrawOrder(userWalletId: UserWalletId, data: TangemPayWithdrawState) { - val listType = Types.newParameterizedType(List::class.java, WithdrawStoreData::class.java) - val mapType = Types.newParameterizedType(Map::class.java, String::class.java, listType) - val adapter: JsonAdapter>> = appPreferencesStore.moshi.adapter(mapType) appPreferencesStore.editData { prefs -> val walletKey = createWithdrawOrderIdKey(userWalletId) - val currentMap = prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY]?.let(adapter::fromJson).orEmpty() - val updatedList = currentMap[walletKey].orEmpty() + withdrawStoreDataConverter.convert(data) - prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] = adapter - .toJson(currentMap + (walletKey to updatedList)) + val currentMap = prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] + ?.let(adapter::fromJson) + .orEmpty() + val newItem = withdrawStoreDataConverter.convert(data) + val currentList = currentMap[walletKey].orEmpty() + val updatedList = buildList(currentList.size + 1) { + for (item in currentList) { if (item.orderId != newItem.orderId) add(item) } + add(newItem) + } + prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] = + adapter.toJson(currentMap + (walletKey to updatedList)) } } @@ -170,9 +184,6 @@ internal class DefaultTangemPayStorage @Inject constructor( } override suspend fun getWithdrawOrders(userWalletId: UserWalletId): List { - val listType = Types.newParameterizedType(List::class.java, WithdrawStoreData::class.java) - val mapType = Types.newParameterizedType(Map::class.java, String::class.java, listType) - val adapter: JsonAdapter>> = appPreferencesStore.moshi.adapter(mapType) val map = appPreferencesStore.data.firstOrNull() ?.get(PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY)?.let(adapter::fromJson).orEmpty() return map[createWithdrawOrderIdKey(userWalletId)].orEmpty().map(withdrawStateConverter::convert) @@ -190,15 +201,22 @@ internal class DefaultTangemPayStorage @Inject constructor( } override suspend fun deleteWithdrawOrder(userWalletId: UserWalletId, orderId: String) { - appPreferencesStore.editData { mutablePreferences -> - val orders = mutablePreferences.getObjectMap( - PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY, - ) - .minus(createWithdrawOrderIdKey(userWalletId)) - mutablePreferences.setObjectMap( - key = PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY, - value = orders, - ) + appPreferencesStore.editData { prefs -> + val walletKey = createWithdrawOrderIdKey(userWalletId) + val currentMap = prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY]?.let(adapter::fromJson) + .orEmpty() + val currentList = currentMap[walletKey].orEmpty() + val updatedList = buildList(currentList.size) { + for (item in currentList) { + if (item.orderId != orderId) add(item) + } + } + val updatedMap = if (updatedList.isEmpty()) { + currentMap - walletKey + } else { + currentMap + (walletKey to updatedList) + } + prefs[PreferencesKeys.TANGEM_PAY_WITHDRAW_ORDERS_KEY] = adapter.toJson(updatedMap) } } diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt index bd69d9835d..285f2c46e9 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/DefaultRampManager.kt @@ -86,7 +86,7 @@ internal class DefaultRampManager( cryptoCurrency: CryptoCurrency, ): ScenarioUnavailabilityReason { val availabilityState = runSuspendCatching { - getExchangeableState(userWalletId, cryptoCurrency) + getExchangeableState() }.getOrNull() ?: ExpressAvailabilityState.Error return availabilityState.toReason(cryptoCurrency.name) } @@ -142,21 +142,9 @@ internal class DefaultRampManager( } } - private suspend fun getExchangeableState( - userWalletId: UserWalletId, - cryptoCurrency: CryptoCurrency, - ): ExpressAvailabilityState { - val asset = expressServiceFetcher.getInitializationStatus(userWalletId).firstOrNull() - ?: return ExpressAvailabilityState.Loading - return when (asset) { - is Lce.Error -> ExpressAvailabilityState.Error - is Lce.Loading -> ExpressAvailabilityState.Loading - is Lce.Content -> { - val foundAsset = asset.getOrNull()?.find { cryptoCurrency.findAssetPredicate(assetId = it.id) } - foundAsset?.isExchangeAvailable?.toSwapAvailabilityState() - ?: ExpressAvailabilityState.AssetNotFound - } - } + private fun getExchangeableState(): ExpressAvailabilityState { + // In task [REDACTED_TASK_KEY], removed all checks to make all tokens available + return ExpressAvailabilityState.Available } private suspend fun getOnrampAvailableState( @@ -190,14 +178,6 @@ internal class DefaultRampManager( } } - private fun Boolean.toSwapAvailabilityState(): ExpressAvailabilityState { - return if (this) { - ExpressAvailabilityState.Available - } else { - ExpressAvailabilityState.NotExchangeable - } - } - private fun Boolean.toOnrampAvailabilityState(): ExpressAvailabilityState { return if (this) { ExpressAvailabilityState.Available diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 5ee7d6ff61..9903332ae6 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1496,7 +1496,7 @@ Ihre Karte ist entsperrt. Abhebung Auf gerooteten Geräten nicht nutzbar. - KYC abbrechen + KYC vom Hauptbildschirm ausblenden Guthaben hinzufügen Aufladeoptionen Kartennummer @@ -1562,10 +1562,10 @@ Status anzeigen KYC für Tangem Pay in Arbeit Dokumente werden in der Regel innerhalb von 5 Minuten automatisch überprüft. In seltenen Fällen, wenn eine manuelle Überprüfung erforderlich ist, kann es bis zu 48 Stunden dauern. - KYC abgelehnt + Abgelehnt KYC-Sperre ausblenden - Entschuldigung, wir konnten dies nicht überprüfen. - Dein Profil. + Leider konnten wir Ihre Identität + nicht verifizieren. Holen Sie sich Ihre kostenlose virtuelle Tangem Visa-Karte Nutzen Sie USDC für alltägliche Zahlungen Karte erhalten diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index fac79c1d1f..462fd75c00 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -4,7 +4,7 @@ Saltar de todos modos Código de acceso no establecido Cambiar código - Su código de acceso se utilizará para desbloquear su billetera y proteger el acceso a sus activos. + Su código de acceso desbloquea y protege el acceso a su billetera Usar de todos modos Este código de acceso se puede adivinar fácilmente. Introduzca el código de acceso @@ -399,6 +399,7 @@ Termine el staking Debido a limitaciones sobre %1$s, solo %2$d UTXO pueden caber en una sola transacción. Esto significa que solo puedes enviar %3$s o menos. Debe reducir la cantidad. Valor copiado + Billeteras semana con @@ -468,9 +469,15 @@ Red de %s Envíe fondos utilizando solo Las mejores oportunidades + Limpiar filtro + La lista está temporalmente vacía porque se está actualizando. Vuelva a consultarla en un momento. Todas las redes Todos los tipos + Filtrar por + Mis redes + Redes Mayormente usado + Sin resultados Ganar Hola equipo de soporte, he encontrado un error con el código: %s Error de WalletConnect @@ -543,7 +550,7 @@ Comprando %s Comprando %s... Ocultar esta transacción - Una vez oculto, el estado de la transacción no se puede volver a ver. En su lugar, basta con deslizar el dedo para descartarla. + Si oculta esta transacción, ya no aparecerá en la pantalla de estado. Si solo quieres cerrar la pantalla de estado y volver más tarde, solo tiene que deslizar el dedo hacia otro lado. ¿Ocultar el estado de la transacción? Este token no es compatible. Por favor, elige un token diferente para intercambiar. %s no está soportado @@ -552,9 +559,9 @@ ID : %s ID de transacción copiado Convierta una de sus activos de su portafolio por este token - Una mayor velocidad significa una confirmación más rápida y una tarifa de red más alta. %s + Una mayor velocidad significa una confirmación más rápida\ny una tarifa de red más alta. %s Elija la velocidad - Elija qué token utilizar para pagar la tarifa de red. %s + Elige qué token utilizar para pagar\nla tarifa de red. %s Elija token Mercado y noticias De actualidad @@ -577,7 +584,7 @@ Ocurrió un error. Código: %s Requiere memo Esta transacción - Especifique el límite aprobado para el token seleccionado. + Al aprobar, permite que el contrato inteligente utilice sus tokens en transacciones futuras. Montante %s La función Aprobar es necesaria para otorgar permiso a otra dirección para usar una cantidad específica de sus tokens. Por diseño, los contratos inteligentes no pueden acceder a sus tokens sin su aprobación. Al \"desbloquear\" sus tokens, autoriza al contrato inteligente de StakeKit a usarlos. Los mineros de la red reciben una tarifa de gas (pagada por usted) por registrar esta acción en la cadena de bloques. Puede apostar su token después de dar su aprobación. Para continuar, debe autorizar el contrato inteligente de Polygon para utilizar su %s @@ -733,7 +740,7 @@ Sin datos Análisis del Mercado Acciones rápidas - Busque en el mercado + Buscar tokens Resultado Ver tokens con marketcap inferior a 100.000$ Mostrar tokens @@ -748,10 +755,10 @@ 7d Todo Compradores experimentados - Evaluación + Capitalización de mercado Ordenar por - Top Ganadores - Top Perdedores + Ganadores + Perdedores Tendencias Modo Rendimiento Staking es la forma más fácil de recibir recompensas por sus criptomonedas. %s @@ -801,7 +808,7 @@ Capital. de mercado El valor total de una criptomoneda calculado multiplicando su precio por la cantidad de monedas en circulación Capital. de mercado - Evaluación de mercado + Posición en el mercado Posición en la clasificación de criptomonedas entre todas las monedas según la capitalización de mercado Evaluación de mercado Suministro máximo @@ -823,6 +830,7 @@ Volumen Tire hacia arriba o toque la barra de búsqueda para agregar tokens directamente desde el mercado Agregar tokens + Añadir más tokens Potencie sus activos mientras los suministra con acceso inmediato. %s Activar Modo Rendimiento Debes actualizar a %1$s para crear una mobile wallet @@ -840,7 +848,7 @@ Resumen rápido Noticias Tokens relacionados - Fuentes + Noticias relacionadas Manténgase informado NFC no está disponible en su dispositivo Acerca de NFT @@ -927,9 +935,9 @@ Por favor repita la operación. La tarjeta/anillo se restablecerá a la configuración de fábrica. Error de activación Agregar tokens - Ha agregado una tarjeta/anillo de backup. Cuando el proceso de backup finalice, no podrá añadir más dispositivos de backup. Si tiene otra tarjeta o anillo, agréguela al backup. ¿Quiere continuar el proceso de backup? - El proceso de backup está parcialmente completo. No puede salir ahora. - La frase de contraseña es una característica de seguridad avanzada utilizada por las billeteras criptográficas. Agrega una palabra o frase adicional de su elección a su frase de recuperación ya existente para desbloquear un conjunto completamente nuevo de direcciones. + Ha añadido una tarjeta o anillo como copia de seguridad. Una vez finalizada la copia de seguridad, no puedes añadir más dispositivos. Si tiene una tarjeta o anillo más, añádalo ahora. ¿Quiere continuar? + La copia de seguridad está parcialmente completa y no se puede salir ahora. + Una frase de contraseña es una función de seguridad opcional que añade una palabra o frase a su frase de recuperación, creando un nuevo conjunto de direcciones de billetera para una mayor protección. Agregar una tarjeta o un anillo de backup Escanee la tarjeta Escanee la tarjeta núm. %d @@ -939,7 +947,7 @@ Continuar a mi billetera Finalizar el backup Recibir cripto - Escanee la tarjeta principal + Escanee la tarjeta principal o anillo Finalizar más tarde ¿Cómo funciona? Vamos a generar todas las claves en su tarjeta o anillos y crear una billetera segura @@ -993,7 +1001,7 @@ Ningunos dispositivos de backup Notificaciones Un dispositivo de backup agregado - Prepare su tarjeta + Prepare su tarjeta o anillo Dos dispositivos de backup agregados Para empezar, simplemente recargue la billetera con cualquier cantidad Para empezar, simplemente recargue la billetera con más de %1$s %2$s @@ -1028,7 +1036,7 @@ El monto de la compra no debe ser mayor a %s La cantidad a comprar debe ser como mínimo %s No hay proveedores disponibles para esta moneda - Más rápido + Procesamiento más rápido Pagar con Método de pago Disponible hasta %s @@ -1299,7 +1307,7 @@ Tasa de recompensa promedio ¿Cómo funciona el staking? %s beneficio estimado - Calificación de mercado + Posición en el mercado Métrica Según las reglas de la red %1$s, se pueden reclamar recompensas desde %2$s. Las cantidades a continuación se acreditarán en su cuenta al deshacer el staking. Mínimo requerido @@ -1412,7 +1420,7 @@ Sus stakes Almacene sus criptomonedas de forma segura manteniendo las claves privadas almacenadas en su tarjeta Billetera de hardware revolucionaria - Hasta 3 tarjetas físicas o anillos por billetera + Añade hasta 3 tarjetas o anillos a una billetera Backup ultra seguro Una billetera de hardware para su Bitcoin, Ethereum y muchas más monedas simultáneamente – todo en una sola tarjeta o anillo Miles de monedas @@ -1428,6 +1436,9 @@ La red cobrará una tasa de aprobación del token para verificar que usted autoriza el uso de su token para el intercambio. Intercambie más tokens a mejores tasas directamente en su billetera. ¡Nuevo proveedor de intercambio disponible! + ¿Busca algo más?\n¡Intente buscar o explorar otra criptomoneda! + Busque cualquier token, incluso si aún no está en su lista. + Utilice la búsqueda para encontrar lo que necesite Siéntase seguro con una asistencia permanente que le ayudará con cualquier problema Siempre aquí Múltiples proveedores de confianza en un solo lugar: intercambie cualquier activo sin esfuerzo en su billetera @@ -1493,7 +1504,7 @@ Tu tarjeta está descongelada. Retirada No se puede usar en un dispositivo rooteado - Cancelar KYC + Ocultar verificación de la pantalla Agregar fondos Opciones de recarga Número de tarjeta @@ -1554,15 +1565,15 @@ ¿Seguro que desea detener el proceso KYC? Puede retomarlo en cualquier momento. No pudimos verificar tu perfil. Si tienes alguna pregunta, contacta con el soporte. Lamentablemente, no pudimos verificar tu identidad - El proceso KYC ha fallado + KYC rechazado KYC en curso Ver estado KYC en progreso para Tangem Pay Los documentos suelen verificarse automáticamente en menos de 5 minutos. En casos excepcionales que requieran revisión manual, el proceso puede tardar hasta 48 horas. - KYC rechazado + Rechazado Ocultar el bloque KYC - Lo sentimos, no pudimos verificarle - su perfil. + Lo sentimos, no pudimos verificar + u identidad. Obtén tu tarjeta virtual Tangem Visa gratuita Usa USDC para pagos cotidianos Obtener tarjeta @@ -1621,7 +1632,7 @@ Cambie este token por otro por una tarifa de servicio de %1$s del %2$s al %3$s de febrero. Intercambie con Changelly, %s comisiones Intercambie ahora - Criptomonedas populares 🔥 + Tendencia del mercado 🔥 No disponible para compra No disponible para vender No disponible para cambio desde %s @@ -1670,7 +1681,7 @@ ¿Quiere utilizar\nnotificaciones push? Active las notificaciones push y le avisaremos al instante cuando le lleguen fondos. No se pierda ninguna transacción - Agregar una nueva billetera + Agregar billetera Si olvida esta billetera sin una copia de seguridad, perderá permanentemente el acceso a sus fondos. ¿Estás seguro de que deseas olvidar esta billetera? Ha ocurrido un error, por favor escanee su tarjeta o anillo para iniciar sesión @@ -1748,7 +1759,7 @@ Desbloquear Escanee su tarjeta para desbloquear el acceso Desbloqueo necesario - Elija cómo agregar su billetera + Elige tu tipo de billetera Escanee su tarjeta o anillo Tangem para restaurarlo o importarlo desde otra billetera. Crear una billetera de hardware ¿Quiere comprar una  Billetera Tangem? @@ -1838,7 +1849,7 @@ Use %s o escanee una tarjeta/anillo para desbloquear el acceso a su billetera El proceso de obtención de permisos está actualmente en marcha y se completará pronto. Aprobación en curso - Parece que la activación de la tarjeta no ha funcionado correctamente. Esto puede deberse a un problema con el módulo NFC de su dispositivo o a una mala conexión de la tarjeta con su dispositivo. Comuníquese con nuestro equipo de soporte para obtener ayuda. + La activación no se completó correctamente. Esto podría deberse a un problema de NFC o a una lectura incorrecta. Contacte con nuestro equipo de soporte para obtener ayuda. Error de activación El 3 de diciembre de 2024, la red BEP-2 fue desactivada por decisión de los desarrolladores de la red y ya no es compatible BNB Beacon Chain se cerrará @@ -1851,6 +1862,7 @@ Actualizar Iniciar migración Copiar + Para mantener el acceso a sus fondos, comience la migración de acuerdo con las pautas oficiales de Clore. La firma de mensajes no es compatible con esta red No se puede firmar el mensaje. Por favor, inténtelo de nuevo. Según la documentación oficial de Clore, todas las monedas recibidas antes del 21 de diciembre serán migradas a Clore (token ERC-20); las monedas recibidas después de esa fecha no lo serán. Se está desarrollando una solución de transferencia — mantente atento. @@ -1873,7 +1885,7 @@ Aprobación en proceso El monto mínimo de transacción es %1$s. Asegúrese de que el saldo restante después del canje no sea inferior a %2$s. No tienes tokens en tu portafolio a los que puedas intercambiar %s. Por favor, añade otro token para realizar el intercambio. - No hay tokens disponibles para intercambiar + No se agregaron tokens compatibles Para realizar una transacción necesita depositar %1$s %2$s No se pueden cubrir %s tarifa El monto a recibir debe ser de al menos %s @@ -2045,11 +2057,11 @@ Crear o importar una billetera de software Cree o importe una billetera de software en su teléfono. Empezar con Mobile Wallet - Otro método + Otros métodos Utilice la billetera de hardware Tangem Obtenga más información y compre Ignorar - Tiene un backup interrumpido. ¿Quiere reanudarlo? + Su copia de seguridad se ha interrumpido. ¿Desea reanudarla? Sí, reanudar Descartar Si descarta el backup ahora, tendrá que restablecer los dispositivos a los ajustes de fábrica para empezar de nuevo diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index a89fafa94f..fcdf84f726 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -1499,7 +1499,7 @@ Votre carte est dégelée. Retrait Impossible à utiliser sur un appareil rooté - Annuler KYC + Masquer la vérification de l\'écran Ajouter des fonds Options de recharge Numéro de carte @@ -1565,10 +1565,10 @@ Voir le statut KYC en cours pour Tangem Pay Les documents sont généralement vérifiés automatiquement en moins de 5 minutes. Dans de rares cas nécessitant une vérification manuelle, le processus peut prendre jusqu’à 48 heures. - KYC rejeté + Refusé Masquer le bloc KYC - Désolé, nous n\'avons pas pu vérifier. - votre profil. + Désolé, nous n\'avons pas pu vérifier + votre identité. Obtenez votre carte virtuelle Tangem Visa gratuite Utilisez USDC pour les paiements quotidiens Obtenir la carte diff --git a/core/res/src/main/res/values-it/strings.xml b/core/res/src/main/res/values-it/strings.xml index 50290eaea8..9cd39c1c7a 100644 --- a/core/res/src/main/res/values-it/strings.xml +++ b/core/res/src/main/res/values-it/strings.xml @@ -98,6 +98,7 @@ Impossibile sbloccare la carta. Riprova più tardi. La tua carta è sbloccata. Prelievo + Nascondi verifica dalla schermata Aggiungi fondi Opzioni di ricarica Numero carta @@ -151,10 +152,14 @@ Tangem Pay Non siamo riusciti a verificare il tuo profilo. Per domande, contatta il supporto. Purtroppo non siamo riusciti a verificare la tua identità + KYC rifiutato KYC in corso Visualizza stato KYC in corso per Tangem Pay I documenti vengono solitamente verificati automaticamente entro 5 minuti. In rari casi, se è necessaria una revisione manuale, il processo può richiedere fino a 48 ore. + Rifiutato + Spiacenti, non siamo riusciti a verificare + la tua identità. Ottieni la tua carta virtuale Tangem Visa gratuita Usa USDC per i pagamenti quotidiani Ottieni carta diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 46949f43d3..6b87995090 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -392,6 +392,7 @@ ステーキング解除 %1$sの制限により、1つのトランザクションに収まるUTXOは%2$d個のみです。つまり、 %3$s以下しか送信できません。量を減らす必要があります。 値がコピーされました + ウォレット はい @@ -1416,6 +1417,9 @@ ネットワークは、あなたがトークンのスワップを承認していることを確認するために、トークン承認手数料を請求します。 より多くのトークンをより良いレートで、ウォレット内にて直接交換します。 新しいスワッププロバイダーが利用可能になりました! + 他のものをお探しですか?\n検索してみるか、別の暗号資産をチェックしてみましょう! + どのトークンでも検索できます。まだ一覧に表示されていないものでも検索可能です。 + 必要なものは検索して見つけましょう。 24時間体制のサポートであらゆる問題に対応します。 いつもここに 複数の信頼できるプロバイダーが一箇所に集結。ウォレット内で様々な暗号資産を簡単に交換できます。 @@ -1481,7 +1485,7 @@ カードの凍結が解除されました 出金 Root化された端末では使用できません - KYCをキャンセル + メイン画面からKYCを非表示にする 資金を追加 入金オプション カード番号 @@ -1542,15 +1546,15 @@ KYC手続きを中止しますか?いつでも再開できます。 プロフィールを確認できませんでした。ご不明な点があればサポートまでお問い合わせください。 申し訳ございませんが、本人確認を行うことができませんでした - KYCの認証に失敗しました + KYCが承認されませんでした KYC進行中 ステータスを表示 Tangem PayのKYC手続き進行中 書類は通常、5分以内に自動で確認されます。手動での審査が必要な稀な場合は、最大48時間かかることがあります。 - KYCが承認されませんでした + 拒否されました KYCブロックを非表示 - 申し訳ありません、確認できませんでした - あなたのプロフィール。 + 申し訳ございませんが、 + 本人確認ができませんでした。 無料のTangem Visaバーチャルカードを入手 日常の支払いにUSDCを利用 カードをGET diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 550f256f3f..5a0683d679 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -31,7 +31,7 @@ Этот аккаунт не может быть архивирован. Мы не смогли создать аккаунт. Пожалуйста, попробуйте позже. Аккаунт создан - Архивный аккаунт + Архивировать аккаунт Архив Вы архивируете свой аккаунт, но в любое время можете вернуть его обратно Архивация... @@ -412,6 +412,7 @@ Завершить стейкинг Из-за ограничений %1$s в одну транзакцию может поместиться только %2$d UTXO. Это означает, что вы можете отправить только %3$s или меньше. Вам нужно уменьшить сумму. Значение скопировано + Кошельки неделю с Да @@ -482,6 +483,7 @@ Отправляйте средства, используя только Лучшие возможности Очистить фильтр + Список временно пуст — он обновляется. Пожалуйста, зайдите чуть позже. Все сети Все типы Фильтровать по @@ -1466,6 +1468,8 @@ Комиссия сети за одобрение токена будет взиматься за подтверждение того, что именно вы разрешаете использовать ваш токен для обмена. Обменивайте больше токенов по лучшим курсам прямо в вашем кошельке. Новый провайдер обмена! + Найдите любой токен, даже если его ещё нет в вашем списке + Используйте поиск, чтобы найти то, что вам нужно. Чувствуйте уверенность с круглосуточной поддержкой, готовой помочь в любой ситуации! Круглосуточная поддержка Надежные провайдеры в одном месте — обменивайте любые активы легко и быстро прямо в своем кошельке! @@ -1511,6 +1515,8 @@ Заморозить Карта заморожена Обратиться в поддержку + %s・%s + MCC %s Другое Невозможно использовать на устройствах с root-доступом. Успешно завершено @@ -1528,7 +1534,7 @@ Карта разморожена Вывести Запрещено использовать на root-устройствах - Отменить KYC + Скрыть KYC с главной Пополнить Способы пополнения Номер @@ -1588,11 +1594,15 @@ Если вы отмените KYC сейчас, вы сможете потом начать его заново Не удалось подтвердить ваш профиль. Если у вас есть вопросы, обратитесь в службу поддержки. К сожалению, нам не удалось подтвердить вашу личность + KYC отклонено KYC в процессе Посмотреть статус KYC в процессе для Tangem Pay Обычно документы проверяются автоматически в течение 5 минут, в редких случах при необходимости ручной проверки – до 48 часов. - KYC отклонено + Отклонено + Скрыть KYC с главной + Извините, мы не смогли подтвердить + ваш профиль. Откройте бесплатную виртуальную карту Tangem Visa Оплачивайте ежедневные покупки в USDC Открыть карту 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 fa1ef254d0..94cc71f5db 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -413,6 +413,7 @@ Скасувати стейкінг Через обмеження %1$s в одну транзакцію може поміститися тільки %2$d UTXO. Це означає, що ви можете відправити тільки %3$s або менше. Вам потрібно зменшити суму. Скопійовано + Гаманці тиждень з Так @@ -483,6 +484,7 @@ Надсилайте кошти, використовуючи лише Найкращі можливості Очистити фільтр + Список тимчасово порожній, оскільки триває оновлення. Спробуйте ще раз за мить. Всі мережі Всі типи Фільтрувати за @@ -490,6 +492,7 @@ Мережі Часто використовані Немає результатів + Заробляйте Привіт, команда підтримки, я зіткнувся з помилкою з кодом: %s Помилка WalletConnect Ви використали картку або кільце від іншого гаманця. Прикладіть картку або кільце, пов\'язану з цим гаманцем. @@ -853,6 +856,7 @@ Оновіться до версії %1$s, щоб створити мобільний гаманець Мобільний гаманець потребує %1$s або новіше. Всі новини + Вподобайка %d годину тому %d години тому @@ -865,7 +869,10 @@ %d хвилин тому %d хвилин тому + Короткий огляд + Новини Пов\'язані токени + Схожі новини Залишайтеся в курсі подій Функція NFC недоступна на вашому пристрої Про NFT @@ -1324,6 +1331,7 @@ Сума стейкінгу буде округлена до %1$s TRX відповідно до правил мережі. Сума зняття зі стейкінгу буде округлена до %1$s TRX через мережеві правила. APR %1$s%% + Ваші винагороди за стейкінг почнуть надходити через 5 епох (~25 днів), поки ваша делегація реєструється та враховується мережею. Зняти кошти Комісія за стейкінг-акаунт Стейкінг-акаунт — це спеціальний рахунок, на якому зберігаються застейкані SOL токени. Він створюється, коли ви делегуєте свої токени валідатору для участі у перевірці транзакцій та отримання винагород. За створення стейкінг-акаунту стягується невелика комісія, яка повертається після завершення стейкінгу. @@ -1334,6 +1342,7 @@ APR APY Винагороди автоматично накопичуються на вашому балансі щодня. + Винагороди реінвестуються у ваш баланс стейкінгу. Зароблено коштів: %s Доступно Середня ставка винагороди Що таке стейкінг? @@ -1467,6 +1476,9 @@ Мережа стягує комісію за схвалення токену за підтвердження, що саме ви дозволяєте використовувати ваш токен для обміну. Обмінюйте більше токенів за вигіднішим курсом прямо у своєму гаманці. З\'явився новий провайдер обмінів! + Шукаєте щось інше?\nСпробуйте пошукати або перегляньте інші криптовалюти! + Шукайте будь-який токен, навіть якщо його ще немає у вашому списку. + Використовуйте пошук, щоб знайти потрібне Надійна підтримка 24/7, щоб ваші фінансові операції були швидкими та надійними! Цілодобова підтримка Надійні провайдери дозволяють легко обмінювати активи, забезпечуючи повну безпеку у вашому гаманці @@ -1513,6 +1525,8 @@ Вашу картку заморожено. Звернутися до підтримки Причина: %s + %s.%s + MCC %s Інше Неможливо використовувати на пристроях з root-правами. Завершено @@ -1530,7 +1544,7 @@ Картку розморожено. Виведення коштів Заборонено використовувати на root-пристроях - Скасувати KYC + Приховати KYC з головного екрана Поповнити рахунок Варіанти поповнення Номер картки @@ -1567,6 +1581,7 @@ Обміняйте будь-який актив у вашому портфелі на картку Реквізити картки Розморозити картку + Поверніться до додатка, якщо ви забудете його. Ваш ПІН Вивести Вивід наразі недоступний @@ -1590,10 +1605,15 @@ Ви впевнені, що хочете зупинити процес KYC? Ви можете повернутися до нього в будь-який момент. Не вдалося підтвердити ваш профіль. Якщо у вас є питання, зверніться у службу підтримки. На жаль, нам не вдалося підтвердити вашу особу + KYC відхилено KYC в процесі Переглянути статус Перевірка KYC для Tangem Pay в процесі Документи зазвичай перевіряються автоматично протягом 5 хвилин. У рідкісних випадках, коли потрібна ручна перевірка, це може зайняти до 48 годин. + Відхилено + Приховати блок KYC + Вибачте, ми не змогли підтвердити + вашу особу. Отримайте безкоштовну віртуальну картку Tangem Visa Використовуйте USDC для щоденних платежів Отримати картку diff --git a/core/res/src/main/res/values-zh-rTW/strings.xml b/core/res/src/main/res/values-zh-rTW/strings.xml index f2a8057772..c410e833bc 100644 --- a/core/res/src/main/res/values-zh-rTW/strings.xml +++ b/core/res/src/main/res/values-zh-rTW/strings.xml @@ -341,6 +341,7 @@ 無法解凍卡片。請稍後再試。 您的卡片已解凍。 提現 + 在主畫面隱藏身份驗證 添加资金 充值选项 卡號 @@ -394,10 +395,14 @@ Tangem Pay 我们无法验证您的资料。如有任何疑问,请联系客服。 很抱歉,我们无法验证您的身份 + KYC 被拒絕 KYC进行中 查看状态 Tangem Pay 的 KYC 正在進行中 文件通常會在 5 分鐘內自動驗證完成。如需人工審核的特殊情況,可能需要最長 48 小時。 + 已拒絕 + 抱歉,我們無法驗證 + 您的身份 獲取您的免費 Tangem Visa 虛擬卡 使用 USDC 進行日常支付 获取卡片 diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 55ca27cb0a..dbc8f644d4 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -399,6 +399,7 @@ Unstake Due to %1$s limitations only %2$d UTXOs can fit in a single transaction. This means you can only send %3$s or less. You need to reduce the amount. Value copied + Wallets week with Yes @@ -1436,7 +1437,9 @@ The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap. Exchange more tokens at better rates directly in your wallet. New Swap Provider Available! - Looking for something else?/nTry searching or explore another crypto! + Looking for something else?\nTry searching or explore another crypto! + Search for any token, even if it’s not in your list yet. + Use search to find what you need Feel confident with round-the-clock support to help with any issues Always Here Multiple trusted providers in one place—swap any asset effortlessly in your wallet @@ -1502,7 +1505,7 @@ Your card is unfrozen. Withdrawal Unable to use on rooted device - Cancel KYC + Hide KYC from main screen Add funds Top-up options Card Number @@ -1563,12 +1566,12 @@ Are you sure you want to stop the KYC process? You can return to it anytime. We could not verify your profile. If you have any questions, please contact support. Unfortunately, we couldn\'t verify your identity - KYC has failed + KYC rejected KYC in progress View Status KYC in progress for Tangem Pay Documents are usually verified automatically within 5 minutes. In rare cases, if manual review is required, it may take up to 48 hours. - KYC rejected + Rejected Hide KYC block Sorry, we couldn\'t verify your profile. @@ -1894,6 +1897,8 @@ Service temporarily unavailable The amount of tokens to be swapped must not exceed %s The amount to swap must be at least %s + Swapping isn\'t available for this pair. Please select a different token and try again. + Unsupported token pair Please change the amount to swap This card might be a production sample or counterfeit Authenticity check failed diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt index cdad87d12b..02d63db72f 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/entity/WithdrawStoreData.kt @@ -7,6 +7,7 @@ import com.squareup.moshi.JsonClass data class WithdrawStoreData( @Json(name = "orderId") val orderId: String, @Json(name = "exchangeData") val exchangeData: ExchangeStoreData?, + @Json(name = "txHash") val txHash: String?, ) @JsonClass(generateAdapter = false) diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt index 922b617842..7bf21432a7 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayWithdrawRepository.kt @@ -110,12 +110,15 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( val storeData = TangemPayWithdrawState( orderId = orderId, exchangeData = exchangeData, + txHash = withdrawTxHash, ) if (order != null && !withdrawTxHash.isNullOrEmpty()) { - finalizeWithdraw(userWallet = userWallet, txHash = withdrawTxHash, exchangeData = exchangeData) - .onLeft { - tangemPayStorage.storeWithdrawOrder(userWalletId = userWallet.walletId, data = storeData) - } + finalizeWithdraw( + userWallet = userWallet, + txHash = withdrawTxHash, + exchangeData = exchangeData, + orderId = orderId, + ) } else { tangemPayStorage.storeWithdrawOrder(userWalletId = userWallet.walletId, data = storeData) } @@ -124,6 +127,7 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( private suspend fun finalizeWithdraw( userWallet: UserWallet, + orderId: String, txHash: String, exchangeData: TangemPayWithdrawExchangeState, ): Either { @@ -135,10 +139,9 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( payInAddress = exchangeData.payInAddress, txHash = txHash, payInExtraId = exchangeData.payInExtraId, - ) - .onLeft { error -> - Timber.tag(TAG).e(error.toString()) - } + ).also { + tangemPayStorage.deleteWithdrawOrder(userWallet.walletId, orderId) + } } override suspend fun hasWithdrawOrder(userWallet: UserWallet): Boolean { @@ -168,19 +171,23 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( private suspend fun pollWithdrawOrderIfNeeds(userWallet: UserWallet, data: TangemPayWithdrawState) { val exchangeData = data.exchangeData ?: return + val storedHash = data.txHash val orderId = data.orderId - val order = orderRepository.getOrderData(userWalletId = userWallet.walletId, orderId = orderId).getOrNull() - ?: return - val txHash = order.withdrawTxHash + val txHash = if (storedHash.isNullOrEmpty()) { + val order = orderRepository.getOrderData(userWalletId = userWallet.walletId, orderId = orderId).getOrNull() + ?: return + order.withdrawTxHash.also { fetchedHash -> + tangemPayStorage.storeWithdrawOrder( + userWalletId = userWallet.walletId, + data = data.copy(txHash = fetchedHash), + ) + } + } else { + storedHash + } if (!txHash.isNullOrEmpty()) { - finalizeWithdraw(userWallet = userWallet, txHash = txHash, exchangeData = exchangeData) - .onRight { - tangemPayStorage.deleteWithdrawOrder(userWalletId = userWallet.walletId, orderId = orderId) - } - .onLeft { - startWithdrawOrderPolling(userWallet = userWallet, orderId = orderId, exchangeData = exchangeData) - } + finalizeWithdraw(userWallet = userWallet, txHash = txHash, exchangeData = exchangeData, orderId = orderId) } else { startWithdrawOrderPolling(userWallet = userWallet, orderId = orderId, exchangeData = exchangeData) } @@ -204,20 +211,14 @@ internal class DefaultTangemPayWithdrawRepository @Inject constructor( .onRight { order -> val txHash = order.withdrawTxHash if (txHash.isNullOrEmpty()) return@onRight - finalizeWithdraw(userWallet = userWallet, txHash = txHash, exchangeData = exchangeData) - .onRight { - tangemPayStorage.deleteWithdrawOrder( - userWalletId = userWallet.walletId, - orderId = orderId, - ) - withdrawPollingMutex.withLock { withdrawPollingJobs.remove(orderId) } - return@launch - } - .onLeft { error -> - Timber.tag(TAG).e("finalizeWithdraw error: $error") - withdrawPollingMutex.withLock { withdrawPollingJobs.remove(orderId) } - return@launch - } + finalizeWithdraw( + userWallet = userWallet, + txHash = txHash, + exchangeData = exchangeData, + orderId = orderId, + ) + withdrawPollingMutex.withLock { withdrawPollingJobs.remove(orderId) } + return@launch } .onLeft { error -> Timber.tag(TAG).e("getOrderData error ${error.errorCode}") diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt index 5bcefd3b8e..019ee19504 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/util/WithdrawStateConverter.kt @@ -18,5 +18,6 @@ class WithdrawStateConverter : Converter, + isIgnoreExpress: Boolean, ): PairsWithProviders { return withContext(coroutineDispatcher.io) { - try { - val initial = NetworkLeastTokenInfo( - contractAddress = initialCurrency.contractAddress, - network = initialCurrency.network, - ) - val currenciesList = currencyList - .filter { currency -> - val requirements = walletManagersFacade.getAssetRequirements(userWallet.walletId, currency) - val isAvailableForSwap = rampStateManager.checkAssetRequirements(requirements) - isAvailableForSwap - } - .map { currency -> leastTokenInfoConverter.convert(currency) } + val currenciesList = filterByAssetRequirements(userWallet, currencyList) + if (isIgnoreExpress) { + buildLocalPairs(initialCurrency, currenciesList) + } else { + fetchExpressPairs(userWallet, initialCurrency, currenciesList) + } + } + } + + private fun buildLocalPairs( + initialCurrency: LeastTokenInfo, + currenciesList: List, + ): PairsWithProviders { + val pairs = currenciesList.map { tokenInfo -> + SwapPairLeast( + from = initialCurrency, + to = LeastTokenInfo( + contractAddress = tokenInfo.contractAddress, + network = tokenInfo.network, + ), + providers = emptyList(), + ) + } + return PairsWithProviders(pairs = pairs, allProviders = emptyList()) + } + + private suspend fun fetchExpressPairs( + userWallet: UserWallet, + initialCurrency: LeastTokenInfo, + currenciesList: List, + ): PairsWithProviders { + try { + val initial = NetworkLeastTokenInfo( + contractAddress = initialCurrency.contractAddress, + network = initialCurrency.network, + ) + + val allPairs = supervisorScope { val pairsDeferred = async { getPairsInternal( userWallet = userWallet, @@ -161,27 +189,36 @@ internal class DefaultSwapRepository( ) } - val pairs = pairsDeferred.await().getOrThrow() - val reversedPairs = reversedPairsDeferred.await().getOrThrow() + pairsDeferred.await().getOrThrow() + reversedPairsDeferred.await().getOrThrow() + } - val allPairs = pairs + reversedPairs - - return@withContext swapPairInfoConverter.convert( - SwapPairsWithProviders( - swapPair = allPairs, - providers = emptyList(), - ), - ) - } catch (exception: Exception) { - if (exception is ApiResponseError.HttpException) { - throw ExpressException(errorsDataConverter.convert(exception.errorBody.orEmpty())) - } else { - throw exception - } + return swapPairInfoConverter.convert( + SwapPairsWithProviders( + swapPair = allPairs, + providers = emptyList(), + ), + ) + } catch (exception: Exception) { + if (exception is ApiResponseError.HttpException) { + throw ExpressException(errorsDataConverter.convert(exception.errorBody.orEmpty())) + } else { + throw exception } } } + private suspend fun filterByAssetRequirements( + userWallet: UserWallet, + currencyList: List, + ): List { + return currencyList + .filter { currency -> + val requirements = walletManagersFacade.getAssetRequirements(userWallet.walletId, currency) + rampStateManager.checkAssetRequirements(requirements) + } + .map { currency -> leastTokenInfoConverter.convert(currency) } + } + private suspend fun getPairsInternal( userWallet: UserWallet, from: List, diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetAvailablePairsUseCase.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetAvailablePairsUseCase.kt index 8d51f01469..c0bfc9041f 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetAvailablePairsUseCase.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetAvailablePairsUseCase.kt @@ -19,6 +19,7 @@ class GetAvailablePairsUseCase( userWallet = userWallet, initialCurrency = initialCurrency, currencyList = currencies, + isIgnoreExpress = true, ).pairs } } \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt index ee0b2065d3..a23260fb53 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/api/SwapRepository.kt @@ -22,6 +22,7 @@ interface SwapRepository { userWallet: UserWallet, initialCurrency: LeastTokenInfo, currencyList: List, + isIgnoreExpress: Boolean = false, ): PairsWithProviders suspend fun getExchangeStatus(userWallet: UserWallet, txId: String): Either diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/AccountTokenItemConverter.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/AccountTokenItemConverter.kt index adcecd045b..919e908498 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/AccountTokenItemConverter.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/AccountTokenItemConverter.kt @@ -36,11 +36,8 @@ internal class AccountTokenItemConverter( isExpanded = true, isCollapsable = false, tokens = value.currencyList.map { accountSwapCurrency -> - if (accountSwapCurrency.isAvailable) { - createAvailableItemConverter() - } else { - createUnavailableItemConverter() - }.convert(accountSwapCurrency.cryptoCurrencyStatus) + createAvailableItemConverter() + .convert(accountSwapCurrency.cryptoCurrencyStatus) }.map(TokensListItemUM::Token).toPersistentList(), ) } diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt index ba936978ec..791af35a8c 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverter.kt @@ -17,6 +17,7 @@ import com.tangem.feature.swap.models.TokenToSelectState import com.tangem.feature.swap.presentation.R import com.tangem.utils.Provider import com.tangem.utils.converter.Converter +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList internal class TokensDataConverter( @@ -31,14 +32,9 @@ internal class TokensDataConverter( val availableTitle = TokenToSelectState.Title( resourceReference(R.string.exchange_tokens_available_tokens_header), ) - val unavailableTitle = TokenToSelectState.Title( - resourceReference( - R.string.exchange_tokens_unavailable_tokens_header, - wrappedList(value.fromCurrency.name), - ), - ) + val allTokens = group.available + group.unavailable return SwapSelectTokenStateHolder( - availableTokens = group.available.map { tokenWithBalanceToTokenToSelect(it, true) } + availableTokens = allTokens.map { tokenWithBalanceToTokenToSelect(it, true) } .toMutableList() .apply { if (this.isNotEmpty()) { @@ -46,14 +42,7 @@ internal class TokensDataConverter( } } .toImmutableList(), - unavailableTokens = group.unavailable.map { tokenWithBalanceToTokenToSelect(it, false) } - .toMutableList() - .apply { - if (this.isNotEmpty()) { - this.add(0, unavailableTitle) - } - } - .toImmutableList(), + unavailableTokens = persistentListOf(), tokensListData = TokenListUMData.EmptyList, onSearchEntered = onSearchEntered, onTokenSelected = onTokenSelected, diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverterV2.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverterV2.kt index af538747a6..668b30aa88 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverterV2.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/converters/TokensDataConverterV2.kt @@ -46,11 +46,8 @@ internal class TokensDataConverterV2( } else { val tokensList = accountList.flatMap { (_, currencyList) -> currencyList.asSequence().map { accountSwapCurrency -> - if (accountSwapCurrency.isAvailable) { - accountListItemConverter.createAvailableItemConverter() - } else { - accountListItemConverter.createUnavailableItemConverter() - }.convert(accountSwapCurrency.cryptoCurrencyStatus) + accountListItemConverter.createAvailableItemConverter() + .convert(accountSwapCurrency.cryptoCurrencyStatus) }.map(TokensListItemUM::Token).toPersistentList() }.toPersistentList() diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index 1f5c403663..20ebd990d5 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -645,21 +645,14 @@ internal class SwapModel @Inject constructor( tokensDataState = state, ) - if (!isTokenAvailableForSwap(state, selectedCurrency, isReverseFromTo)) { - analyticsEventHandler.send( - SwapEvents.NoticeUnavailableToSwapPair( - sendToken = fromCurrencyStatus.currency.symbol, - receiveToken = toCurrencyStatus.currency.symbol, - sendBlockchain = fromCurrencyStatus.currency.network.name, - receiveBlockchain = toCurrencyStatus.currency.network.name, - ), - ) - uiState = stateBuilder.createSwapNotSupportedState( - uiStateHolder = uiState, + if (handleSwapNotSupported( + state = state, fromToken = fromCurrencyStatus, toToken = toCurrencyStatus, + fromAccount = fromAccount, toAccount = toAccount, ) + ) { return } @@ -1397,6 +1390,17 @@ internal class SwapModel @Inject constructor( toAccount = toAccount, selectedProvider = null, ) + swapRouter.openScreen(SwapNavScreen.Main) + if (handleSwapNotSupported( + state = tokens, + fromToken = fromToken, + toToken = toToken, + fromAccount = fromAccount, + toAccount = toAccount, + ) + ) { + return + } modelScope.launch { updateFeePaidCryptoCurrencyFor(fromToken) } @@ -1409,7 +1413,6 @@ internal class SwapModel @Inject constructor( reduceBalanceBy = lastReducedBalanceBy.value, toProvidersList = findSwapProviders(fromToken, toToken), ) - swapRouter.openScreen(SwapNavScreen.Main) updateTokensState(tokens) } } @@ -2011,6 +2014,37 @@ internal class SwapModel @Inject constructor( .orEmpty() } + /** + * @return true if swap is not supported and UI was updated to show error state + */ + private fun handleSwapNotSupported( + state: TokensDataStateExpress, + fromToken: CryptoCurrencyStatus, + toToken: CryptoCurrencyStatus, + fromAccount: Account.CryptoPortfolio?, + toAccount: Account.CryptoPortfolio?, + ): Boolean { + val selectedCurrency = if (isOrderReversed) fromToken else toToken + if (isTokenAvailableForSwap(state, selectedCurrency, isOrderReversed)) return false + + analyticsEventHandler.send( + SwapEvents.NoticeUnavailableToSwapPair( + sendToken = fromToken.currency.symbol, + receiveToken = toToken.currency.symbol, + sendBlockchain = fromToken.currency.network.name, + receiveBlockchain = toToken.currency.network.name, + ), + ) + uiState = stateBuilder.createSwapNotSupportedState( + uiStateHolder = uiState, + fromToken = fromToken, + toToken = toToken, + fromAccount = fromAccount, + toAccount = toAccount, + ) + return true + } + private fun isTokenAvailableForSwap( state: TokensDataStateExpress, selectedCurrency: CryptoCurrencyStatus, diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt index fdb774f17d..d57d2943f2 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapNotificationsFactory.kt @@ -64,9 +64,9 @@ internal class SwapNotificationsFactory( ) } - fun getSwapNotSupportedNotifications(tokenName: String): ImmutableList { + fun getSwapNotSupportedNotifications(): ImmutableList { return persistentListOf( - SwapNotificationUM.Warning.SwapNotSupported(tokenName), + SwapNotificationUM.Warning.SwapNotSupported, ) } diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/models/states/SwapNotificationUM.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/models/states/SwapNotificationUM.kt index 7e5209dca5..e158fd5f3b 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/models/states/SwapNotificationUM.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/models/states/SwapNotificationUM.kt @@ -132,15 +132,12 @@ internal object SwapNotificationUM { ), ) - data class SwapNotSupported( - val tokenName: String, - ) : Warning( + data object SwapNotSupported : Warning( title = resourceReference( - id = com.tangem.feature.swap.presentation.R.string.express_swap_not_supported_title, - formatArgs = wrappedList(tokenName), + id = com.tangem.feature.swap.presentation.R.string.warning_express_unsupported_pair_title, ), subtitle = resourceReference( - com.tangem.feature.swap.presentation.R.string.express_swap_not_supported_text, + com.tangem.feature.swap.presentation.R.string.warning_express_unsupported_pair_description, ), ) diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt index a30871f920..2a61151dde 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/ui/StateBuilder.kt @@ -197,12 +197,15 @@ internal class StateBuilder( uiStateHolder: SwapStateHolder, fromToken: CryptoCurrencyStatus, toToken: CryptoCurrencyStatus, + fromAccount: Account.CryptoPortfolio?, toAccount: Account.CryptoPortfolio?, ): SwapStateHolder { if (uiStateHolder.sendCardData !is SwapCardState.SwapCardData) return uiStateHolder return uiStateHolder.copy( sendCardData = SwapCardState.SwapCardData( - type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.Inputtable), + type = requireNotNull(uiStateHolder.sendCardData.type as? TransactionCardType.Inputtable).copy( + accountTitleUM = getFromCardAccountTitle(fromAccount), + ), amountTextFieldValue = null, amountEquivalent = "0 ${appCurrencyProvider.invoke().symbol}", token = fromToken, @@ -233,7 +236,7 @@ internal class StateBuilder( networkIconRes = getActiveIconRes(toToken.currency.network.rawId), isBalanceHidden = isBalanceHiddenProvider(), ), - notifications = notificationsFactory.getSwapNotSupportedNotifications(toToken.currency.name), + notifications = notificationsFactory.getSwapNotSupportedNotifications(), fee = FeeItemState.Empty, swapButton = SwapButton( walletInteractionIcon = walletInterationIcon(userWalletProvider()),