Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-25 22:40:08 +07:00
commit 7fe610ec37
26 changed files with 322 additions and 202 deletions

View file

@ -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<Map<String, List<WithdrawStoreData>>> 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<Map<String, List<WithdrawStoreData>>> = 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<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<Map<String, List<WithdrawStoreData>>> = 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<WithdrawStoreData>(
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)
}
}

View file

@ -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

View file

@ -1496,7 +1496,7 @@
<string name="tangem_pay_unfreeze_card_success">Ihre Karte ist entsperrt.</string>
<string name="tangem_pay_withdrawal">Abhebung</string>
<string name="tangempay_account_unable_to_use_rooted">Auf gerooteten Geräten nicht nutzbar.</string>
<string name="tangempay_cancel_kyc">KYC abbrechen</string>
<string name="tangempay_cancel_kyc">KYC vom Hauptbildschirm ausblenden</string>
<string name="tangempay_card_details_add_funds">Guthaben hinzufügen</string>
<string name="tangempay_card_details_add_funds_subtitle">Aufladeoptionen</string>
<string name="tangempay_card_details_card_number">Kartennummer</string>
@ -1562,10 +1562,10 @@
<string name="tangempay_kyc_in_progress_notification_button">Status anzeigen</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC für Tangem Pay in Arbeit</string>
<string name="tangempay_kyc_in_progress_popup_description">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.</string>
<string name="tangempay_kyc_rejected">KYC abgelehnt</string>
<string name="tangempay_kyc_rejected">Abgelehnt</string>
<string name="tangempay_kyc_rejected_button_text">KYC-Sperre ausblenden</string>
<string name="tangempay_kyc_rejected_description">Entschuldigung, wir konnten dies nicht überprüfen.</string>
<string name="tangempay_kyc_rejected_description_span">Dein Profil.</string>
<string name="tangempay_kyc_rejected_description">Leider konnten wir Ihre Identität</string>
<string name="tangempay_kyc_rejected_description_span">nicht verifizieren.</string>
<string name="tangempay_onboarding_banner_description">Holen Sie sich Ihre kostenlose virtuelle Tangem Visa-Karte</string>
<string name="tangempay_onboarding_banner_title">Nutzen Sie USDC für alltägliche Zahlungen</string>
<string name="tangempay_onboarding_get_card_button_text">Karte erhalten</string>

View file

@ -4,7 +4,7 @@
<string name="access_code_alert_skip_ok">Saltar de todos modos</string>
<string name="access_code_alert_skip_title">Código de acceso no establecido</string>
<string name="access_code_alert_validation_cancel">Cambiar código</string>
<string name="access_code_alert_validation_description">Su código de acceso se utilizará para desbloquear su billetera y proteger el acceso a sus activos.</string>
<string name="access_code_alert_validation_description">Su código de acceso desbloquea y protege el acceso a su billetera</string>
<string name="access_code_alert_validation_ok">Usar de todos modos</string>
<string name="access_code_alert_validation_title">Este código de acceso se puede adivinar fácilmente.</string>
<string name="access_code_check_title">Introduzca el código de acceso</string>
@ -399,6 +399,7 @@
<string name="common_unstake">Termine el staking</string>
<string name="common_utxo_validate_withdrawal_message_warning">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.</string>
<string name="common_value_copied">Valor copiado</string>
<string name="common_wallets">Billeteras</string>
<string name="common_week">semana</string>
<string name="common_with">con</string>
<string name="common_yes"></string>
@ -468,9 +469,15 @@
<string name="domain_receive_assets_onboarding_network_name">Red de %s</string>
<string name="domain_receive_assets_onboarding_title">Envíe fondos utilizando solo</string>
<string name="earn_best_opportunities">Las mejores oportunidades</string>
<string name="earn_clear_filter">Limpiar filtro</string>
<string name="earn_empty">La lista está temporalmente vacía porque se está actualizando. Vuelva a consultarla en un momento.</string>
<string name="earn_filter_all_networks">Todas las redes</string>
<string name="earn_filter_all_types">Todos los tipos</string>
<string name="earn_filter_by">Filtrar por</string>
<string name="earn_filter_my_networks">Mis redes</string>
<string name="earn_filter_networks">Redes</string>
<string name="earn_mostly_used">Mayormente usado</string>
<string name="earn_no_results">Sin resultados</string>
<string name="earn_title">Ganar</string>
<string name="email_preface_wc_error">Hola equipo de soporte, he encontrado un error con el código: %s</string>
<string name="email_subject_wc_error">Error de WalletConnect</string>
@ -543,7 +550,7 @@
<string name="express_status_buying">Comprando %s</string>
<string name="express_status_buying_active">Comprando %s...</string>
<string name="express_status_hide_button_text">Ocultar esta transacción</string>
<string name="express_status_hide_dialog_text">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.</string>
<string name="express_status_hide_dialog_text">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.</string>
<string name="express_status_hide_dialog_title">¿Ocultar el estado de la transacción?</string>
<string name="express_swap_not_supported_text">Este token no es compatible. Por favor, elige un token diferente para intercambiar.</string>
<string name="express_swap_not_supported_title">%s no está soportado</string>
@ -552,9 +559,9 @@
<string name="express_transaction_id">ID : %s</string>
<string name="express_transaction_id_copied">ID de transacción copiado</string>
<string name="exсhange_token_description">Convierta una de sus activos de su portafolio por este token</string>
<string name="fee_selector_choose_speed_description">Una mayor velocidad significa una confirmación más rápida y una tarifa de red más alta. %s</string>
<string name="fee_selector_choose_speed_description">Una mayor velocidad significa una confirmación más rápida\ny una tarifa de red más alta. %s</string>
<string name="fee_selector_choose_speed_title">Elija la velocidad</string>
<string name="fee_selector_choose_token_description">Elija qué token utilizar para pagar la tarifa de red. %s</string>
<string name="fee_selector_choose_token_description">Elige qué token utilizar para pagar\nla tarifa de red. %s</string>
<string name="fee_selector_choose_token_title">Elija token</string>
<string name="feed_market_and_news">Mercado y noticias</string>
<string name="feed_trending_now">De actualidad</string>
@ -577,7 +584,7 @@
<string name="generic_error_code">Ocurrió un error. Código: %s</string>
<string name="generic_requires_memo_error">Requiere memo</string>
<string name="give_permission_current_transaction">Esta transacción</string>
<string name="give_permission_policy_type_footer">Especifique el límite aprobado para el token seleccionado.</string>
<string name="give_permission_policy_type_footer">Al aprobar, permite que el contrato inteligente utilice sus tokens en transacciones futuras.</string>
<string name="give_permission_rows_amount">Montante %s</string>
<string name="give_permission_staking_footer">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.</string>
<string name="give_permission_staking_subtitle">Para continuar, debe autorizar el contrato inteligente de Polygon para utilizar su %s</string>
@ -733,7 +740,7 @@
<string name="markets_loading_no_data_title">Sin datos</string>
<string name="markets_pulse_common_title">Análisis del Mercado</string>
<string name="markets_quick_actions">Acciones rápidas</string>
<string name="markets_search_header_title">Busque en el mercado</string>
<string name="markets_search_header_title">Buscar tokens</string>
<string name="markets_search_result_title">Resultado</string>
<string name="markets_search_see_tokens_under_100k">Ver tokens con marketcap inferior a 100.000$</string>
<string name="markets_search_show_tokens">Mostrar tokens</string>
@ -748,10 +755,10 @@
<string name="markets_selector_interval_7d_title">7d</string>
<string name="markets_selector_interval_all_title">Todo</string>
<string name="markets_sort_by_experienced_buyers_title">Compradores experimentados</string>
<string name="markets_sort_by_rating_title">Evaluación</string>
<string name="markets_sort_by_rating_title">Capitalización de mercado</string>
<string name="markets_sort_by_title">Ordenar por</string>
<string name="markets_sort_by_top_gainers_title">Top Ganadores</string>
<string name="markets_sort_by_top_losers_title">Top Perdedores</string>
<string name="markets_sort_by_top_gainers_title">Ganadores</string>
<string name="markets_sort_by_top_losers_title">Perdedores</string>
<string name="markets_sort_by_trending_title">Tendencias</string>
<string name="markets_sort_by_yield_mode_title">Modo Rendimiento</string>
<string name="markets_staking_banner_description_placeholder">Staking es la forma más fácil de recibir recompensas por sus criptomonedas. %s</string>
@ -801,7 +808,7 @@
<string name="markets_token_details_market_capitalization">Capital. de mercado</string>
<string name="markets_token_details_market_capitalization_description">El valor total de una criptomoneda calculado multiplicando su precio por la cantidad de monedas en circulación</string>
<string name="markets_token_details_market_capitalization_full">Capital. de mercado</string>
<string name="markets_token_details_market_rating">Evaluación de mercado</string>
<string name="markets_token_details_market_rating">Posición en el mercado</string>
<string name="markets_token_details_market_rating_description">Posición en la clasificación de criptomonedas entre todas las monedas según la capitalización de mercado</string>
<string name="markets_token_details_market_rating_full">Evaluación de mercado</string>
<string name="markets_token_details_max_supply">Suministro máximo</string>
@ -823,6 +830,7 @@
<string name="markets_token_details_volume">Volumen</string>
<string name="markets_tooltip_message">Tire hacia arriba o toque la barra de búsqueda para agregar tokens directamente desde el mercado</string>
<string name="markets_tooltip_title">Agregar tokens</string>
<string name="markets_tooltip_v2_title">Añadir más tokens</string>
<string name="markets_yield_supply_banner_description">Potencie sus activos mientras los suministra con acceso inmediato. %s</string>
<string name="markets_yield_supply_banner_title">Activar Modo Rendimiento</string>
<string name="mobile_wallet_requires_min_os_warning_body">Debes actualizar a %1$s para crear una mobile wallet</string>
@ -840,7 +848,7 @@
<string name="news_quick_recap">Resumen rápido</string>
<string name="news_related_news">Noticias</string>
<string name="news_related_tokens">Tokens relacionados</string>
<string name="news_sources">Fuentes</string>
<string name="news_sources">Noticias relacionadas</string>
<string name="news_stay_in_the_loop">Manténgase informado</string>
<string name="nfc_error_unavailable">NFC no está disponible en su dispositivo</string>
<string name="nft_about_title">Acerca de NFT</string>
@ -927,9 +935,9 @@
<string name="onboarding_activation_error_message">Por favor repita la operación. La tarjeta/anillo se restablecerá a la configuración de fábrica.</string>
<string name="onboarding_activation_error_title">Error de activación</string>
<string name="onboarding_add_tokens">Agregar tokens</string>
<string name="onboarding_alert_message_not_max_backup_cards_added">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?</string>
<string name="onboarding_backup_exit_warning">El proceso de backup está parcialmente completo. No puede salir ahora.</string>
<string name="onboarding_bottom_sheet_passphrase_description">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.</string>
<string name="onboarding_alert_message_not_max_backup_cards_added">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?</string>
<string name="onboarding_backup_exit_warning">La copia de seguridad está parcialmente completa y no se puede salir ahora.</string>
<string name="onboarding_bottom_sheet_passphrase_description">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.</string>
<string name="onboarding_button_add_backup_card">Agregar una tarjeta o un anillo de backup</string>
<string name="onboarding_button_backup_card">Escanee la tarjeta</string>
<string name="onboarding_button_backup_card_format">Escanee la tarjeta núm. %d</string>
@ -939,7 +947,7 @@
<string name="onboarding_button_continue_wallet">Continuar a mi billetera</string>
<string name="onboarding_button_finalize_backup">Finalizar el backup</string>
<string name="onboarding_button_receive_crypto">Recibir cripto</string>
<string name="onboarding_button_scan_origin_card">Escanee la tarjeta principal</string>
<string name="onboarding_button_scan_origin_card">Escanee la tarjeta principal o anillo</string>
<string name="onboarding_button_skip_backup">Finalizar más tarde</string>
<string name="onboarding_button_what_does_it_mean">¿Cómo funciona?</string>
<string name="onboarding_create_wallet_body">Vamos a generar todas las claves en su tarjeta o anillos y crear una billetera segura</string>
@ -993,7 +1001,7 @@
<string name="onboarding_title_no_backup_cards">Ningunos dispositivos de backup</string>
<string name="onboarding_title_notifications">Notificaciones</string>
<string name="onboarding_title_one_backup_card">Un dispositivo de backup agregado</string>
<string name="onboarding_title_scan_origin_card">Prepare su tarjeta</string>
<string name="onboarding_title_scan_origin_card">Prepare su tarjeta o anillo</string>
<string name="onboarding_title_two_backup_cards">Dos dispositivos de backup agregados</string>
<string name="onboarding_top_up_body">Para empezar, simplemente recargue la billetera con cualquier cantidad</string>
<string name="onboarding_top_up_body_no_account_error">Para empezar, simplemente recargue la billetera con más de %1$s %2$s</string>
@ -1028,7 +1036,7 @@
<string name="onramp_max_amount_restriction">El monto de la compra no debe ser mayor a %s</string>
<string name="onramp_min_amount_restriction">La cantidad a comprar debe ser como mínimo %s</string>
<string name="onramp_no_available_providers">No hay proveedores disponibles para esta moneda</string>
<string name="onramp_offer_type_fastet">Más rápido</string>
<string name="onramp_offer_type_fastet">Procesamiento más rápido</string>
<string name="onramp_pay_with">Pagar con</string>
<string name="onramp_payment_method_subtitle">Método de pago</string>
<string name="onramp_provider_max_amount">Disponible hasta %s</string>
@ -1299,7 +1307,7 @@
<string name="staking_details_average_reward_rate">Tasa de recompensa promedio</string>
<string name="staking_details_banner_text">¿Cómo funciona el staking?</string>
<string name="staking_details_estimated_profit">%s beneficio estimado</string>
<string name="staking_details_market_rating">Calificación de mercado</string>
<string name="staking_details_market_rating">Posición en el mercado</string>
<string name="staking_details_metrics_block_header">Métrica</string>
<string name="staking_details_min_rewards_notification">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.</string>
<string name="staking_details_minimum_requirement">Mínimo requerido</string>
@ -1412,7 +1420,7 @@
<string name="staking_your_stakes">Sus stakes</string>
<string name="story_awe_description">Almacene sus criptomonedas de forma segura manteniendo las claves privadas almacenadas en su tarjeta</string>
<string name="story_awe_title">Billetera de hardware revolucionaria</string>
<string name="story_backup_description">Hasta 3 tarjetas físicas o anillos por billetera</string>
<string name="story_backup_description">Añade hasta 3 tarjetas o anillos a una billetera</string>
<string name="story_backup_title">Backup ultra seguro</string>
<string name="story_currencies_description">Una billetera de hardware para su Bitcoin, Ethereum y muchas más monedas simultáneamente todo en una sola tarjeta o anillo</string>
<string name="story_currencies_title">Miles de monedas</string>
@ -1428,6 +1436,9 @@
<string name="swap_give_permission_fee_footer">La red cobrará una tasa de aprobación del token para verificar que usted autoriza el uso de su token para el intercambio.</string>
<string name="swap_promo_text">Intercambie más tokens a mejores tasas directamente en su billetera.</string>
<string name="swap_promo_title">¡Nuevo proveedor de intercambio disponible!</string>
<string name="swap_search_suggestion_hint">¿Busca algo más?\n¡Intente buscar o explorar otra criptomoneda!</string>
<string name="swap_search_tooltip_description">Busque cualquier token, incluso si aún no está en su lista.</string>
<string name="swap_search_tooltip_title">Utilice la búsqueda para encontrar lo que necesite</string>
<string name="swap_story_fifth_subtitle">Siéntase seguro con una asistencia permanente que le ayudará con cualquier problema</string>
<string name="swap_story_fifth_title">Siempre aquí</string>
<string name="swap_story_first_subtitle">Múltiples proveedores de confianza en un solo lugar: intercambie cualquier activo sin esfuerzo en su billetera</string>
@ -1493,7 +1504,7 @@
<string name="tangem_pay_unfreeze_card_success">Tu tarjeta está descongelada.</string>
<string name="tangem_pay_withdrawal">Retirada</string>
<string name="tangempay_account_unable_to_use_rooted">No se puede usar en un dispositivo rooteado</string>
<string name="tangempay_cancel_kyc">Cancelar KYC</string>
<string name="tangempay_cancel_kyc">Ocultar verificación de la pantalla</string>
<string name="tangempay_card_details_add_funds">Agregar fondos</string>
<string name="tangempay_card_details_add_funds_subtitle">Opciones de recarga</string>
<string name="tangempay_card_details_card_number">Número de tarjeta</string>
@ -1554,15 +1565,15 @@
<string name="tangempay_kyc_confirm_cancellation_description">¿Seguro que desea detener el proceso KYC? Puede retomarlo en cualquier momento.</string>
<string name="tangempay_kyc_failed_description">No pudimos verificar tu perfil. Si tienes alguna pregunta, contacta con el soporte.</string>
<string name="tangempay_kyc_failed_title">Lamentablemente, no pudimos verificar tu identidad</string>
<string name="tangempay_kyc_has_failed">El proceso KYC ha fallado</string>
<string name="tangempay_kyc_has_failed">KYC rechazado</string>
<string name="tangempay_kyc_in_progress">KYC en curso</string>
<string name="tangempay_kyc_in_progress_notification_button">Ver estado</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC en progreso para Tangem Pay</string>
<string name="tangempay_kyc_in_progress_popup_description">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.</string>
<string name="tangempay_kyc_rejected">KYC rechazado</string>
<string name="tangempay_kyc_rejected">Rechazado</string>
<string name="tangempay_kyc_rejected_button_text">Ocultar el bloque KYC</string>
<string name="tangempay_kyc_rejected_description">Lo sentimos, no pudimos verificarle</string>
<string name="tangempay_kyc_rejected_description_span">su perfil.</string>
<string name="tangempay_kyc_rejected_description">Lo sentimos, no pudimos verificar</string>
<string name="tangempay_kyc_rejected_description_span">u identidad.</string>
<string name="tangempay_onboarding_banner_description">Obtén tu tarjeta virtual Tangem Visa gratuita</string>
<string name="tangempay_onboarding_banner_title">Usa USDC para pagos cotidianos</string>
<string name="tangempay_onboarding_get_card_button_text">Obtener tarjeta</string>
@ -1621,7 +1632,7 @@
<string name="token_swap_changelly_promotion_message">Cambie este token por otro por una tarifa de servicio de %1$s del %2$s al %3$s de febrero.</string>
<string name="token_swap_changelly_promotion_title">Intercambie con Changelly, %s comisiones</string>
<string name="token_swap_promotion_button">Intercambie ahora</string>
<string name="tokens_list_hot_crypto_header">Criptomonedas populares 🔥</string>
<string name="tokens_list_hot_crypto_header">Tendencia del mercado 🔥</string>
<string name="tokens_list_unavailable_to_purchase_header">No disponible para compra</string>
<string name="tokens_list_unavailable_to_sell_header">No disponible para vender</string>
<string name="tokens_list_unavailable_to_swap_header">No disponible para cambio desde %s</string>
@ -1670,7 +1681,7 @@
<string name="user_push_notification_agreement_header">¿Quiere utilizar\nnotificaciones push?</string>
<string name="user_push_notification_banner_subtitle">Active las notificaciones push y le avisaremos al instante cuando le lleguen fondos.</string>
<string name="user_push_notification_banner_title">No se pierda ninguna transacción</string>
<string name="user_wallet_list_add_button">Agregar una nueva billetera</string>
<string name="user_wallet_list_add_button">Agregar billetera</string>
<string name="user_wallet_list_delete_hw_prompt">Si olvida esta billetera sin una copia de seguridad, perderá permanentemente el acceso a sus fondos.</string>
<string name="user_wallet_list_delete_prompt">¿Estás seguro de que deseas olvidar esta billetera?</string>
<string name="user_wallet_list_error_unable_to_unlock">Ha ocurrido un error, por favor escanee su tarjeta o anillo para iniciar sesión</string>
@ -1748,7 +1759,7 @@
<string name="visa_unlock_notification_button">Desbloquear</string>
<string name="visa_unlock_notification_subtitle">Escanee su tarjeta para desbloquear el acceso</string>
<string name="visa_unlock_notification_title">Desbloqueo necesario</string>
<string name="wallet_add_common_title">Elija cómo agregar su billetera</string>
<string name="wallet_add_common_title">Elige tu tipo de billetera</string>
<string name="wallet_add_hardware_description">Escanee su tarjeta o anillo Tangem para restaurarlo o importarlo desde otra billetera.</string>
<string name="wallet_add_hardware_info_create">Crear una billetera de hardware</string>
<string name="wallet_add_hardware_purchase">¿Quiere comprar una  Billetera Tangem?</string>
@ -1838,7 +1849,7 @@
<string name="warning_access_denied_message">Use %s o escanee una tarjeta/anillo para desbloquear el acceso a su billetera</string>
<string name="warning_approval_in_progress_message">El proceso de obtención de permisos está actualmente en marcha y se completará pronto.</string>
<string name="warning_approval_in_progress_title">Aprobación en curso</string>
<string name="warning_backup_errors_message">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.</string>
<string name="warning_backup_errors_message">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.</string>
<string name="warning_backup_errors_title">Error de activación</string>
<string name="warning_beacon_chain_retirement_content">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</string>
<string name="warning_beacon_chain_retirement_title">BNB Beacon Chain se cerrará</string>
@ -1851,6 +1862,7 @@
<string name="warning_button_refresh">Actualizar</string>
<string name="warning_clore_migration_button">Iniciar migración</string>
<string name="warning_clore_migration_copy_button">Copiar</string>
<string name="warning_clore_migration_description">Para mantener el acceso a sus fondos, comience la migración de acuerdo con las pautas oficiales de Clore.</string>
<string name="warning_clore_migration_error_signing_not_supported">La firma de mensajes no es compatible con esta red</string>
<string name="warning_clore_migration_error_wallet_manager_not_found">No se puede firmar el mensaje. Por favor, inténtelo de nuevo.</string>
<string name="warning_clore_migration_message">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.</string>
@ -1873,7 +1885,7 @@
<string name="warning_express_approval_in_progress_title">Aprobación en proceso</string>
<string name="warning_express_dust_message">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.</string>
<string name="warning_express_no_exchangeable_coins_description">No tienes tokens en tu portafolio a los que puedas intercambiar %s. Por favor, añade otro token para realizar el intercambio.</string>
<string name="warning_express_no_exchangeable_coins_title">No hay tokens disponibles para intercambiar</string>
<string name="warning_express_no_exchangeable_coins_title">No se agregaron tokens compatibles</string>
<string name="warning_express_not_enough_fee_for_token_tx_description">Para realizar una transacción necesita depositar %1$s %2$s</string>
<string name="warning_express_not_enough_fee_for_token_tx_title">No se pueden cubrir %s tarifa</string>
<string name="warning_express_notification_invalid_reserve_amount_title">El monto a recibir debe ser de al menos %s</string>
@ -2045,11 +2057,11 @@
<string name="welcome_create_wallet_mobile_description">Crear o importar una billetera de software</string>
<string name="welcome_create_wallet_mobile_description_full">Cree o importe una billetera de software en su teléfono.</string>
<string name="welcome_create_wallet_mobile_title">Empezar con Mobile Wallet</string>
<string name="welcome_create_wallet_other_method">Otro método</string>
<string name="welcome_create_wallet_other_method">Otros métodos</string>
<string name="welcome_create_wallet_use_hardware_description">Utilice la billetera de hardware Tangem</string>
<string name="welcome_create_wallet_use_hardware_title">Obtenga más información y compre</string>
<string name="welcome_interrupted_backup_alert_discard">Ignorar</string>
<string name="welcome_interrupted_backup_alert_message">Tiene un backup interrumpido. ¿Quiere reanudarlo?</string>
<string name="welcome_interrupted_backup_alert_message">Su copia de seguridad se ha interrumpido. ¿Desea reanudarla?</string>
<string name="welcome_interrupted_backup_alert_resume">Sí, reanudar</string>
<string name="welcome_interrupted_backup_discard_discard">Descartar</string>
<string name="welcome_interrupted_backup_discard_message">Si descarta el backup ahora, tendrá que restablecer los dispositivos a los ajustes de fábrica para empezar de nuevo</string>

View file

@ -1499,7 +1499,7 @@
<string name="tangem_pay_unfreeze_card_success">Votre carte est dégelée.</string>
<string name="tangem_pay_withdrawal">Retrait</string>
<string name="tangempay_account_unable_to_use_rooted">Impossible à utiliser sur un appareil rooté</string>
<string name="tangempay_cancel_kyc">Annuler KYC</string>
<string name="tangempay_cancel_kyc">Masquer la vérification de l\'écran</string>
<string name="tangempay_card_details_add_funds">Ajouter des fonds</string>
<string name="tangempay_card_details_add_funds_subtitle">Options de recharge</string>
<string name="tangempay_card_details_card_number">Numéro de carte</string>
@ -1565,10 +1565,10 @@
<string name="tangempay_kyc_in_progress_notification_button">Voir le statut</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC en cours pour Tangem Pay</string>
<string name="tangempay_kyc_in_progress_popup_description">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.</string>
<string name="tangempay_kyc_rejected">KYC rejeté</string>
<string name="tangempay_kyc_rejected">Refusé</string>
<string name="tangempay_kyc_rejected_button_text">Masquer le bloc KYC</string>
<string name="tangempay_kyc_rejected_description">Désolé, nous n\'avons pas pu vérifier.</string>
<string name="tangempay_kyc_rejected_description_span">votre profil.</string>
<string name="tangempay_kyc_rejected_description">Désolé, nous n\'avons pas pu vérifier</string>
<string name="tangempay_kyc_rejected_description_span">votre identité.</string>
<string name="tangempay_onboarding_banner_description">Obtenez votre carte virtuelle Tangem Visa gratuite</string>
<string name="tangempay_onboarding_banner_title">Utilisez USDC pour les paiements quotidiens</string>
<string name="tangempay_onboarding_get_card_button_text">Obtenir la carte</string>

View file

@ -98,6 +98,7 @@
<string name="tangem_pay_unfreeze_card_failed">Impossibile sbloccare la carta. Riprova più tardi.</string>
<string name="tangem_pay_unfreeze_card_success">La tua carta è sbloccata.</string>
<string name="tangem_pay_withdrawal">Prelievo</string>
<string name="tangempay_cancel_kyc">Nascondi verifica dalla schermata</string>
<string name="tangempay_card_details_add_funds">Aggiungi fondi</string>
<string name="tangempay_card_details_add_funds_subtitle">Opzioni di ricarica</string>
<string name="tangempay_card_details_card_number">Numero carta</string>
@ -151,10 +152,14 @@
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
<string name="tangempay_kyc_failed_description">Non siamo riusciti a verificare il tuo profilo. Per domande, contatta il supporto.</string>
<string name="tangempay_kyc_failed_title">Purtroppo non siamo riusciti a verificare la tua identità</string>
<string name="tangempay_kyc_has_failed">KYC rifiutato</string>
<string name="tangempay_kyc_in_progress">KYC in corso</string>
<string name="tangempay_kyc_in_progress_notification_button">Visualizza stato</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC in corso per Tangem Pay</string>
<string name="tangempay_kyc_in_progress_popup_description">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.</string>
<string name="tangempay_kyc_rejected">Rifiutato</string>
<string name="tangempay_kyc_rejected_description">Spiacenti, non siamo riusciti a verificare</string>
<string name="tangempay_kyc_rejected_description_span">la tua identità.</string>
<string name="tangempay_onboarding_banner_description">Ottieni la tua carta virtuale Tangem Visa gratuita</string>
<string name="tangempay_onboarding_banner_title">Usa USDC per i pagamenti quotidiani</string>
<string name="tangempay_onboarding_get_card_button_text">Ottieni carta</string>

View file

@ -392,6 +392,7 @@
<string name="common_unstake">ステーキング解除</string>
<string name="common_utxo_validate_withdrawal_message_warning">%1$sの制限により、1つのトランザクションに収まるUTXOは%2$d個のみです。つまり、 %3$s以下しか送信できません。量を減らす必要があります。</string>
<string name="common_value_copied">値がコピーされました</string>
<string name="common_wallets">ウォレット</string>
<string name="common_week"></string>
<string name="common_with"></string>
<string name="common_yes">はい</string>
@ -1416,6 +1417,9 @@
<string name="swap_give_permission_fee_footer">ネットワークは、あなたがトークンのスワップを承認していることを確認するために、トークン承認手数料を請求します。</string>
<string name="swap_promo_text">より多くのトークンをより良いレートで、ウォレット内にて直接交換します。</string>
<string name="swap_promo_title">新しいスワッププロバイダーが利用可能になりました!</string>
<string name="swap_search_suggestion_hint">他のものをお探しですか?\n検索してみるか、別の暗号資産をチェックしてみましょう</string>
<string name="swap_search_tooltip_description">どのトークンでも検索できます。まだ一覧に表示されていないものでも検索可能です。</string>
<string name="swap_search_tooltip_title">必要なものは検索して見つけましょう。</string>
<string name="swap_story_fifth_subtitle">24時間体制のサポートであらゆる問題に対応します。</string>
<string name="swap_story_fifth_title">いつもここに</string>
<string name="swap_story_first_subtitle">複数の信頼できるプロバイダーが一箇所に集結。ウォレット内で様々な暗号資産を簡単に交換できます。</string>
@ -1481,7 +1485,7 @@
<string name="tangem_pay_unfreeze_card_success">カードの凍結が解除されました</string>
<string name="tangem_pay_withdrawal">出金</string>
<string name="tangempay_account_unable_to_use_rooted">Root化された端末では使用できません</string>
<string name="tangempay_cancel_kyc">KYCをキャンセル</string>
<string name="tangempay_cancel_kyc">メイン画面からKYCを非表示にする</string>
<string name="tangempay_card_details_add_funds">資金を追加</string>
<string name="tangempay_card_details_add_funds_subtitle">入金オプション</string>
<string name="tangempay_card_details_card_number">カード番号</string>
@ -1542,15 +1546,15 @@
<string name="tangempay_kyc_confirm_cancellation_description">KYC手続きを中止しますかいつでも再開できます。</string>
<string name="tangempay_kyc_failed_description">プロフィールを確認できませんでした。ご不明な点があればサポートまでお問い合わせください。</string>
<string name="tangempay_kyc_failed_title">申し訳ございませんが、本人確認を行うことができませんでした</string>
<string name="tangempay_kyc_has_failed">KYCの認証に失敗しました</string>
<string name="tangempay_kyc_has_failed">KYCが承認されませんでした</string>
<string name="tangempay_kyc_in_progress">KYC進行中</string>
<string name="tangempay_kyc_in_progress_notification_button">ステータスを表示</string>
<string name="tangempay_kyc_in_progress_notification_title">Tangem PayのKYC手続き進行中</string>
<string name="tangempay_kyc_in_progress_popup_description">書類は通常、5分以内に自動で確認されます。手動での審査が必要な稀な場合は、最大48時間かかることがあります。</string>
<string name="tangempay_kyc_rejected">KYCが承認されませんでした</string>
<string name="tangempay_kyc_rejected">拒否されました</string>
<string name="tangempay_kyc_rejected_button_text">KYCブロックを非表示</string>
<string name="tangempay_kyc_rejected_description">申し訳ありません、確認できませんでした</string>
<string name="tangempay_kyc_rejected_description_span">あなたのプロフィール</string>
<string name="tangempay_kyc_rejected_description">申し訳ございませんが、</string>
<string name="tangempay_kyc_rejected_description_span">本人確認ができませんでした</string>
<string name="tangempay_onboarding_banner_description">無料のTangem Visaバーチャルカードを入手</string>
<string name="tangempay_onboarding_banner_title">日常の支払いにUSDCを利用</string>
<string name="tangempay_onboarding_get_card_button_text">カードをGET</string>

View file

@ -31,7 +31,7 @@
<string name="account_could_not_archive_referral_program_title">Этот аккаунт не может быть архивирован.</string>
<string name="account_could_not_create">Мы не смогли создать аккаунт. Пожалуйста, попробуйте позже.</string>
<string name="account_create_success_message">Аккаунт создан</string>
<string name="account_details_archive">Архивный аккаунт</string>
<string name="account_details_archive">Архивировать аккаунт</string>
<string name="account_details_archive_action">Архив</string>
<string name="account_details_archive_description">Вы архивируете свой аккаунт, но в любое время можете вернуть его обратно</string>
<string name="account_details_archiving">Архивация...</string>
@ -412,6 +412,7 @@
<string name="common_unstake">Завершить стейкинг</string>
<string name="common_utxo_validate_withdrawal_message_warning">Из-за ограничений %1$s в одну транзакцию может поместиться только %2$d UTXO. Это означает, что вы можете отправить только %3$s или меньше. Вам нужно уменьшить сумму.</string>
<string name="common_value_copied">Значение скопировано</string>
<string name="common_wallets">Кошельки</string>
<string name="common_week">неделю</string>
<string name="common_with">с</string>
<string name="common_yes">Да</string>
@ -482,6 +483,7 @@
<string name="domain_receive_assets_onboarding_title">Отправляйте средства, используя только</string>
<string name="earn_best_opportunities">Лучшие возможности</string>
<string name="earn_clear_filter">Очистить фильтр</string>
<string name="earn_empty">Список временно пуст — он обновляется. Пожалуйста, зайдите чуть позже.</string>
<string name="earn_filter_all_networks">Все сети</string>
<string name="earn_filter_all_types">Все типы</string>
<string name="earn_filter_by">Фильтровать по</string>
@ -1466,6 +1468,8 @@
<string name="swap_give_permission_fee_footer">Комиссия сети за одобрение токена будет взиматься за подтверждение того, что именно вы разрешаете использовать ваш токен для обмена.</string>
<string name="swap_promo_text">Обменивайте больше токенов по лучшим курсам прямо в вашем кошельке.</string>
<string name="swap_promo_title">Новый провайдер обмена!</string>
<string name="swap_search_tooltip_description">Найдите любой токен, даже если его ещё нет в вашем списке</string>
<string name="swap_search_tooltip_title">Используйте поиск, чтобы найти то, что вам нужно.</string>
<string name="swap_story_fifth_subtitle">Чувствуйте уверенность с круглосуточной поддержкой, готовой помочь в любой ситуации!</string>
<string name="swap_story_fifth_title">Круглосуточная поддержка</string>
<string name="swap_story_first_subtitle">Надежные провайдеры в одном месте — обменивайте любые активы легко и быстро прямо в своем кошельке!</string>
@ -1511,6 +1515,8 @@
<string name="tangem_pay_freeze_card_freeze">Заморозить</string>
<string name="tangem_pay_freeze_card_success">Карта заморожена</string>
<string name="tangem_pay_get_help">Обратиться в поддержку</string>
<string name="tangem_pay_history_item_spend_mc_title_format" formatted="false">%s・%s</string>
<string name="tangem_pay_history_item_spend_mcc">MCC %s</string>
<string name="tangem_pay_other">Другое</string>
<string name="tangem_pay_rooted_device_subtitle">Невозможно использовать на устройствах с root-доступом.</string>
<string name="tangem_pay_status_completed">Успешно завершено</string>
@ -1528,7 +1534,7 @@
<string name="tangem_pay_unfreeze_card_success">Карта разморожена</string>
<string name="tangem_pay_withdrawal">Вывести</string>
<string name="tangempay_account_unable_to_use_rooted">Запрещено использовать на root-устройствах</string>
<string name="tangempay_cancel_kyc">Отменить KYC</string>
<string name="tangempay_cancel_kyc">Скрыть KYC с главной</string>
<string name="tangempay_card_details_add_funds">Пополнить</string>
<string name="tangempay_card_details_add_funds_subtitle">Способы пополнения</string>
<string name="tangempay_card_details_card_number">Номер</string>
@ -1588,11 +1594,15 @@
<string name="tangempay_kyc_confirm_cancellation_description">Если вы отмените KYC сейчас, вы сможете потом начать его заново</string>
<string name="tangempay_kyc_failed_description">Не удалось подтвердить ваш профиль. Если у вас есть вопросы, обратитесь в службу поддержки.</string>
<string name="tangempay_kyc_failed_title">К сожалению, нам не удалось подтвердить вашу личность</string>
<string name="tangempay_kyc_has_failed">KYC отклонено</string>
<string name="tangempay_kyc_in_progress">KYC в процессе</string>
<string name="tangempay_kyc_in_progress_notification_button">Посмотреть статус</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC в процессе для Tangem Pay</string>
<string name="tangempay_kyc_in_progress_popup_description">Обычно документы проверяются автоматически в течение 5 минут, в редких случах при необходимости ручной проверки до 48 часов.</string>
<string name="tangempay_kyc_rejected">KYC отклонено</string>
<string name="tangempay_kyc_rejected">Отклонено</string>
<string name="tangempay_kyc_rejected_button_text">Скрыть KYC с главной</string>
<string name="tangempay_kyc_rejected_description">Извините, мы не смогли подтвердить</string>
<string name="tangempay_kyc_rejected_description_span">ваш профиль.</string>
<string name="tangempay_onboarding_banner_description">Откройте бесплатную виртуальную карту Tangem Visa</string>
<string name="tangempay_onboarding_banner_title">Оплачивайте ежедневные покупки в USDC</string>
<string name="tangempay_onboarding_get_card_button_text">Открыть карту</string>

View file

@ -413,6 +413,7 @@
<string name="common_unstake">Скасувати стейкінг</string>
<string name="common_utxo_validate_withdrawal_message_warning">Через обмеження %1$s в одну транзакцію може поміститися тільки %2$d UTXO. Це означає, що ви можете відправити тільки %3$s або менше. Вам потрібно зменшити суму.</string>
<string name="common_value_copied">Скопійовано</string>
<string name="common_wallets">Гаманці</string>
<string name="common_week">тиждень</string>
<string name="common_with">з</string>
<string name="common_yes">Так</string>
@ -483,6 +484,7 @@
<string name="domain_receive_assets_onboarding_title">Надсилайте кошти, використовуючи лише</string>
<string name="earn_best_opportunities">Найкращі можливості</string>
<string name="earn_clear_filter">Очистити фільтр</string>
<string name="earn_empty">Список тимчасово порожній, оскільки триває оновлення. Спробуйте ще раз за мить.</string>
<string name="earn_filter_all_networks">Всі мережі</string>
<string name="earn_filter_all_types">Всі типи</string>
<string name="earn_filter_by">Фільтрувати за</string>
@ -490,6 +492,7 @@
<string name="earn_filter_networks">Мережі</string>
<string name="earn_mostly_used">Часто використовані</string>
<string name="earn_no_results">Немає результатів</string>
<string name="earn_title">Заробляйте</string>
<string name="email_preface_wc_error">Привіт, команда підтримки, я зіткнувся з помилкою з кодом: %s</string>
<string name="email_subject_wc_error">Помилка WalletConnect</string>
<string name="error_wrong_wallet_tapped">Ви використали картку або кільце від іншого гаманця. Прикладіть картку або кільце, пов\'язану з цим гаманцем.</string>
@ -853,6 +856,7 @@
<string name="mobile_wallet_requires_min_os_warning_body">Оновіться до версії %1$s, щоб створити мобільний гаманець</string>
<string name="mobile_wallet_requires_min_os_warning_title">Мобільний гаманець потребує %1$s або новіше.</string>
<string name="news_all_news">Всі новини</string>
<string name="news_like">Вподобайка</string>
<plurals name="news_published_hours_ago">
<item quantity="one">%d годину тому</item>
<item quantity="few">%d години тому</item>
@ -865,7 +869,10 @@
<item quantity="many">%d хвилин тому</item>
<item quantity="other">%d хвилин тому</item>
</plurals>
<string name="news_quick_recap">Короткий огляд</string>
<string name="news_related_news">Новини</string>
<string name="news_related_tokens">Пов\'язані токени</string>
<string name="news_sources">Схожі новини</string>
<string name="news_stay_in_the_loop">Залишайтеся в курсі подій</string>
<string name="nfc_error_unavailable">Функція NFC недоступна на вашому пристрої</string>
<string name="nft_about_title">Про NFT</string>
@ -1324,6 +1331,7 @@
<string name="staking_amount_tron_integer_error">Сума стейкінгу буде округлена до %1$s TRX відповідно до правил мережі.</string>
<string name="staking_amount_tron_integer_error_unstaking">Сума зняття зі стейкінгу буде округлена до %1$s TRX через мережеві правила.</string>
<string name="staking_apr_earn_badge">APR %1$s%%</string>
<string name="staking_cardano_details_rewards_info_text">Ваші винагороди за стейкінг почнуть надходити через 5 епох (~25 днів), поки ваша делегація реєструється та враховується мережею.</string>
<string name="staking_claim_unstaked">Зняти кошти</string>
<string name="staking_details_account_fee">Комісія за стейкінг-акаунт</string>
<string name="staking_details_account_fee_info">Стейкінг-акаунт — це спеціальний рахунок, на якому зберігаються застейкані SOL токени. Він створюється, коли ви делегуєте свої токени валідатору для участі у перевірці транзакцій та отримання винагород. За створення стейкінг-акаунту стягується невелика комісія, яка повертається після завершення стейкінгу.</string>
@ -1334,6 +1342,7 @@
<string name="staking_details_apr">APR</string>
<string name="staking_details_apy">APY</string>
<string name="staking_details_auto_claiming_rewards_daily_text">Винагороди автоматично накопичуються на вашому балансі щодня.</string>
<string name="staking_details_autocompound_rewards_earned">Винагороди реінвестуються у ваш баланс стейкінгу. Зароблено коштів: %s</string>
<string name="staking_details_available">Доступно</string>
<string name="staking_details_average_reward_rate">Середня ставка винагороди</string>
<string name="staking_details_banner_text">Що таке стейкінг?</string>
@ -1467,6 +1476,9 @@
<string name="swap_give_permission_fee_footer">Мережа стягує комісію за схвалення токену за підтвердження, що саме ви дозволяєте використовувати ваш токен для обміну.</string>
<string name="swap_promo_text">Обмінюйте більше токенів за вигіднішим курсом прямо у своєму гаманці.</string>
<string name="swap_promo_title">З\'явився новий провайдер обмінів!</string>
<string name="swap_search_suggestion_hint">Шукаєте щось інше?\nСпробуйте пошукати або перегляньте інші криптовалюти!</string>
<string name="swap_search_tooltip_description">Шукайте будь-який токен, навіть якщо його ще немає у вашому списку.</string>
<string name="swap_search_tooltip_title">Використовуйте пошук, щоб знайти потрібне</string>
<string name="swap_story_fifth_subtitle">Надійна підтримка 24/7, щоб ваші фінансові операції були швидкими та надійними!</string>
<string name="swap_story_fifth_title">Цілодобова підтримка</string>
<string name="swap_story_first_subtitle">Надійні провайдери дозволяють легко обмінювати активи, забезпечуючи повну безпеку у вашому гаманці</string>
@ -1513,6 +1525,8 @@
<string name="tangem_pay_freeze_card_success">Вашу картку заморожено.</string>
<string name="tangem_pay_get_help">Звернутися до підтримки</string>
<string name="tangem_pay_history_item_spend_mc_declined_reason">Причина: %s</string>
<string name="tangem_pay_history_item_spend_mc_title_format" formatted="false">%s.%s</string>
<string name="tangem_pay_history_item_spend_mcc">MCC %s</string>
<string name="tangem_pay_other">Інше</string>
<string name="tangem_pay_rooted_device_subtitle">Неможливо використовувати на пристроях з root-правами.</string>
<string name="tangem_pay_status_completed">Завершено</string>
@ -1530,7 +1544,7 @@
<string name="tangem_pay_unfreeze_card_success">Картку розморожено.</string>
<string name="tangem_pay_withdrawal">Виведення коштів</string>
<string name="tangempay_account_unable_to_use_rooted">Заборонено використовувати на root-пристроях</string>
<string name="tangempay_cancel_kyc">Скасувати KYC</string>
<string name="tangempay_cancel_kyc">Приховати KYC з головного екрана</string>
<string name="tangempay_card_details_add_funds">Поповнити рахунок</string>
<string name="tangempay_card_details_add_funds_subtitle">Варіанти поповнення</string>
<string name="tangempay_card_details_card_number">Номер картки</string>
@ -1567,6 +1581,7 @@
<string name="tangempay_card_details_swap_description">Обміняйте будь-який актив у вашому портфелі на картку</string>
<string name="tangempay_card_details_title">Реквізити картки</string>
<string name="tangempay_card_details_unfreeze_card">Розморозити картку</string>
<string name="tangempay_card_details_view_pin_code_description">Поверніться до додатка, якщо ви забудете його.</string>
<string name="tangempay_card_details_view_pin_code_title">Ваш ПІН</string>
<string name="tangempay_card_details_withdraw">Вивести</string>
<string name="tangempay_card_details_withdraw_error_title">Вивід наразі недоступний</string>
@ -1590,10 +1605,15 @@
<string name="tangempay_kyc_confirm_cancellation_description">Ви впевнені, що хочете зупинити процес KYC? Ви можете повернутися до нього в будь-який момент.</string>
<string name="tangempay_kyc_failed_description">Не вдалося підтвердити ваш профіль. Якщо у вас є питання, зверніться у службу підтримки.</string>
<string name="tangempay_kyc_failed_title">На жаль, нам не вдалося підтвердити вашу особу </string>
<string name="tangempay_kyc_has_failed">KYC відхилено</string>
<string name="tangempay_kyc_in_progress">KYC в процесі</string>
<string name="tangempay_kyc_in_progress_notification_button">Переглянути статус</string>
<string name="tangempay_kyc_in_progress_notification_title">Перевірка KYC для Tangem Pay в процесі</string>
<string name="tangempay_kyc_in_progress_popup_description">Документи зазвичай перевіряються автоматично протягом 5 хвилин. У рідкісних випадках, коли потрібна ручна перевірка, це може зайняти до 48 годин.</string>
<string name="tangempay_kyc_rejected">Відхилено</string>
<string name="tangempay_kyc_rejected_button_text">Приховати блок KYC</string>
<string name="tangempay_kyc_rejected_description">Вибачте, ми не змогли підтвердити</string>
<string name="tangempay_kyc_rejected_description_span">вашу особу.</string>
<string name="tangempay_onboarding_banner_description">Отримайте безкоштовну віртуальну картку Tangem Visa</string>
<string name="tangempay_onboarding_banner_title">Використовуйте USDC для щоденних платежів</string>
<string name="tangempay_onboarding_get_card_button_text">Отримати картку</string>

View file

@ -341,6 +341,7 @@
<string name="tangem_pay_unfreeze_card_failed">無法解凍卡片。請稍後再試。</string>
<string name="tangem_pay_unfreeze_card_success">您的卡片已解凍。</string>
<string name="tangem_pay_withdrawal">提現</string>
<string name="tangempay_cancel_kyc">在主畫面隱藏身份驗證</string>
<string name="tangempay_card_details_add_funds">添加资金</string>
<string name="tangempay_card_details_add_funds_subtitle">充值选项</string>
<string name="tangempay_card_details_card_number">卡號</string>
@ -394,10 +395,14 @@
<string name="tangempay_kyc_card_ready_notification_title">Tangem Pay</string>
<string name="tangempay_kyc_failed_description">我们无法验证您的资料。如有任何疑问,请联系客服。</string>
<string name="tangempay_kyc_failed_title">很抱歉,我们无法验证您的身份</string>
<string name="tangempay_kyc_has_failed">KYC 被拒絕</string>
<string name="tangempay_kyc_in_progress">KYC进行中</string>
<string name="tangempay_kyc_in_progress_notification_button">查看状态</string>
<string name="tangempay_kyc_in_progress_notification_title">Tangem Pay 的 KYC 正在進行中</string>
<string name="tangempay_kyc_in_progress_popup_description">文件通常會在 5 分鐘內自動驗證完成。如需人工審核的特殊情況,可能需要最長 48 小時。</string>
<string name="tangempay_kyc_rejected">已拒絕</string>
<string name="tangempay_kyc_rejected_description">抱歉,我們無法驗證</string>
<string name="tangempay_kyc_rejected_description_span">您的身份</string>
<string name="tangempay_onboarding_banner_description">獲取您的免費 Tangem Visa 虛擬卡</string>
<string name="tangempay_onboarding_banner_title">使用 USDC 進行日常支付</string>
<string name="tangempay_onboarding_get_card_button_text">获取卡片</string>

View file

@ -399,6 +399,7 @@
<string name="common_unstake">Unstake</string>
<string name="common_utxo_validate_withdrawal_message_warning">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.</string>
<string name="common_value_copied">Value copied</string>
<string name="common_wallets">Wallets</string>
<string name="common_week">week</string>
<string name="common_with">with</string>
<string name="common_yes">Yes</string>
@ -1436,7 +1437,9 @@
<string name="swap_give_permission_fee_footer">The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap.</string>
<string name="swap_promo_text">Exchange more tokens at better rates directly in your wallet.</string>
<string name="swap_promo_title">New Swap Provider Available!</string>
<string name="swap_search_suggestion_hint">Looking for something else?/nTry searching or explore another crypto!</string>
<string name="swap_search_suggestion_hint">Looking for something else?\nTry searching or explore another crypto!</string>
<string name="swap_search_tooltip_description">Search for any token, even if its not in your list yet.</string>
<string name="swap_search_tooltip_title">Use search to find what you need</string>
<string name="swap_story_fifth_subtitle">Feel confident with round-the-clock support to help with any issues</string>
<string name="swap_story_fifth_title">Always Here</string>
<string name="swap_story_first_subtitle">Multiple trusted providers in one place—swap any asset effortlessly in your wallet</string>
@ -1502,7 +1505,7 @@
<string name="tangem_pay_unfreeze_card_success">Your card is unfrozen.</string>
<string name="tangem_pay_withdrawal">Withdrawal</string>
<string name="tangempay_account_unable_to_use_rooted">Unable to use on rooted device</string>
<string name="tangempay_cancel_kyc">Cancel KYC</string>
<string name="tangempay_cancel_kyc">Hide KYC from main screen</string>
<string name="tangempay_card_details_add_funds">Add funds</string>
<string name="tangempay_card_details_add_funds_subtitle">Top-up options</string>
<string name="tangempay_card_details_card_number">Card Number</string>
@ -1563,12 +1566,12 @@
<string name="tangempay_kyc_confirm_cancellation_description">Are you sure you want to stop the KYC process? You can return to it anytime.</string>
<string name="tangempay_kyc_failed_description">We could not verify your profile. If you have any questions, please contact support.</string>
<string name="tangempay_kyc_failed_title">Unfortunately, we couldn\'t verify your identity </string>
<string name="tangempay_kyc_has_failed">KYC has failed</string>
<string name="tangempay_kyc_has_failed">KYC rejected</string>
<string name="tangempay_kyc_in_progress">KYC in progress</string>
<string name="tangempay_kyc_in_progress_notification_button">View Status</string>
<string name="tangempay_kyc_in_progress_notification_title">KYC in progress for Tangem Pay</string>
<string name="tangempay_kyc_in_progress_popup_description">Documents are usually verified automatically within 5 minutes. In rare cases, if manual review is required, it may take up to 48 hours.</string>
<string name="tangempay_kyc_rejected">KYC rejected</string>
<string name="tangempay_kyc_rejected">Rejected</string>
<string name="tangempay_kyc_rejected_button_text">Hide KYC block</string>
<string name="tangempay_kyc_rejected_description">Sorry, we couldn\'t verify</string>
<string name="tangempay_kyc_rejected_description_span">your profile.</string>
@ -1894,6 +1897,8 @@
<string name="warning_express_refresh_required_title">Service temporarily unavailable</string>
<string name="warning_express_too_maximum_amount_title">The amount of tokens to be swapped must not exceed %s</string>
<string name="warning_express_too_minimal_amount_title">The amount to swap must be at least %s</string>
<string name="warning_express_unsupported_pair_description">Swapping isn\'t available for this pair. Please select a different token and try again.</string>
<string name="warning_express_unsupported_pair_title">Unsupported token pair</string>
<string name="warning_express_wrong_amount_description">Please change the amount to swap</string>
<string name="warning_failed_to_verify_card_message">This card might be a production sample or counterfeit</string>
<string name="warning_failed_to_verify_card_title">Authenticity check failed</string>

View file

@ -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)

View file

@ -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<ExpressDataError, Unit> {
@ -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}")

View file

@ -18,5 +18,6 @@ class WithdrawStateConverter : Converter<WithdrawStoreData, TangemPayWithdrawSta
payInExtraId = exchangeData.payInExtraId,
)
},
txHash = value.txHash,
)
}

View file

@ -18,5 +18,6 @@ class WithdrawStoreDataConverter : Converter<TangemPayWithdrawState, WithdrawSto
payInExtraId = exchangeData.payInExtraId,
)
},
txHash = value.txHash,
)
}

View file

@ -3,6 +3,7 @@ package com.tangem.domain.pay
data class TangemPayWithdrawState(
val orderId: String,
val exchangeData: TangemPayWithdrawExchangeState?,
val txHash: String? = null,
)
data class TangemPayWithdrawExchangeState(

View file

@ -40,6 +40,7 @@ import com.tangem.feature.swap.domain.models.createFromAmountWithOffset
import com.tangem.feature.swap.domain.models.domain.*
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.async
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.IOException
@ -130,21 +131,48 @@ internal class DefaultSwapRepository(
userWallet: UserWallet,
initialCurrency: LeastTokenInfo,
currencyList: List<CryptoCurrency>,
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<NetworkLeastTokenInfo>,
): 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<NetworkLeastTokenInfo>,
): 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<CryptoCurrency>,
): List<NetworkLeastTokenInfo> {
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<NetworkLeastTokenInfo>,

View file

@ -19,6 +19,7 @@ class GetAvailablePairsUseCase(
userWallet = userWallet,
initialCurrency = initialCurrency,
currencyList = currencies,
isIgnoreExpress = true,
).pairs
}
}

View file

@ -22,6 +22,7 @@ interface SwapRepository {
userWallet: UserWallet,
initialCurrency: LeastTokenInfo,
currencyList: List<CryptoCurrency>,
isIgnoreExpress: Boolean = false,
): PairsWithProviders
suspend fun getExchangeStatus(userWallet: UserWallet, txId: String): Either<UnknownError, ExchangeStatusModel>

View file

@ -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(),
)
}

View file

@ -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,

View file

@ -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()

View file

@ -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,

View file

@ -64,9 +64,9 @@ internal class SwapNotificationsFactory(
)
}
fun getSwapNotSupportedNotifications(tokenName: String): ImmutableList<NotificationUM> {
fun getSwapNotSupportedNotifications(): ImmutableList<NotificationUM> {
return persistentListOf(
SwapNotificationUM.Warning.SwapNotSupported(tokenName),
SwapNotificationUM.Warning.SwapNotSupported,
)
}

View file

@ -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,
),
)

View file

@ -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()),