Updated on 2026-08-14
This commit is contained in:
parent
e5a5d5ef97
commit
2e59b7e116
28 changed files with 802 additions and 38 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 8285f8d2896d2994337f55a7b3a54fd5acc24304
|
||||
Subproject commit 098662beb5b0123b11f5ee4873d4bd667ac93c73
|
||||
|
|
@ -265,4 +265,18 @@ internal object TransactionDomainModule {
|
|||
): SendLargeSolanaTransactionUseCase {
|
||||
return SendLargeSolanaTransactionUseCase(cardSdkConfigRepository, walletManagersFacade)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSignCloreMessageUseCase(
|
||||
walletManagersFacade: WalletManagersFacade,
|
||||
cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
tangemHotWalletSignerFactory: TangemHotWalletSigner.Factory,
|
||||
): SignCloreMessageUseCase {
|
||||
return SignCloreMessageUseCase(
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
cardSdkConfigRepository = cardSdkConfigRepository,
|
||||
getHotWalletSigner = tangemHotWalletSignerFactory::create,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -299,6 +299,7 @@
|
|||
<string name="common_go_to_token">Ir al token</string>
|
||||
<string name="common_got_it">Entendido</string>
|
||||
<string name="common_hide">Ocultar</string>
|
||||
<string name="common_hold_to">Mantener para %s</string>
|
||||
<string name="common_hour">hora</string>
|
||||
<string name="common_import">Importe</string>
|
||||
<string name="common_in_progress">En progreso</string>
|
||||
|
|
@ -323,6 +324,7 @@
|
|||
<string name="common_no">No</string>
|
||||
<string name="common_no_address">Ninguna dirección</string>
|
||||
<string name="common_not_added">No agregadas</string>
|
||||
<string name="common_not_available">No disponible</string>
|
||||
<string name="common_not_now">Ahora no</string>
|
||||
<string name="common_now">Ahora</string>
|
||||
<string name="common_ok">OK</string>
|
||||
|
|
@ -373,6 +375,7 @@
|
|||
<string name="common_swap">Intercambiar</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_tap_and_hold_hint">Toque y mantenga presionado</string>
|
||||
<string name="common_terms_and_conditions">términos y condiciones</string>
|
||||
<string name="common_terms_of_use">Condiciones de uso</string>
|
||||
<string name="common_to">A</string>
|
||||
|
|
@ -462,6 +465,11 @@
|
|||
<string name="domain_receive_assets_onboarding_description">Enviar activos a otras redes resultará en una pérdida permanente.</string>
|
||||
<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_filter_all_networks">Todas las redes</string>
|
||||
<string name="earn_filter_all_types">Todos los tipos</string>
|
||||
<string name="earn_mostly_used">Mayormente usado</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>
|
||||
<string name="error_wrong_wallet_tapped">Ha usado una tarjeta de otra billetera. Toque la tarjeta asociada con esta billetera</string>
|
||||
|
|
@ -561,6 +569,8 @@
|
|||
<string name="feedback_subject_support_tangem">Comentarios en Tangem</string>
|
||||
<string name="feedback_subject_tx_failed">No se puede completar una transacción</string>
|
||||
<string name="feedback_token_description_error">Error de descripción de moneda</string>
|
||||
<string name="gasless_not_enough_funds_to_cover_token_fee">Fondos insuficientes</string>
|
||||
<string name="gasless_transaction_fee">Tarifa de transacción</string>
|
||||
<string name="generic_error">Ocurrió un error</string>
|
||||
<string name="generic_error_code">Ocurrió un error. Código: %s</string>
|
||||
<string name="generic_requires_memo_error">Requiere memo</string>
|
||||
|
|
@ -610,6 +620,7 @@
|
|||
<string name="hw_backup_need_title">Finalizar la copia de seguridad primero</string>
|
||||
<string name="hw_backup_no_backup">Incompleto</string>
|
||||
<string name="hw_backup_section_other_title">Otros métodos</string>
|
||||
<string name="hw_backup_seed_code_description">Guarde su frase de recuperación en un lugar seguro y manténgala privada para proteger sus fondos y configure un código de acceso para mayor seguridad.</string>
|
||||
<string name="hw_backup_seed_description">Guarde su frase de recuperación en un lugar seguro y manténgala en privado para proteger sus fondos.</string>
|
||||
<string name="hw_backup_seed_title">Frase de recuperación</string>
|
||||
<string name="hw_backup_to_secure_description">Para proteger su billetera con un código de acceso, complete el proceso de copia de seguridad.</string>
|
||||
|
|
@ -995,6 +1006,7 @@
|
|||
<string name="onboarding_wallet_info_title_fourth">Restaurar código de acceso</string>
|
||||
<string name="onboarding_wallet_info_title_second">Tarjetas idénticas</string>
|
||||
<string name="onboarding_wallet_info_title_third">Código de acceso</string>
|
||||
<string name="only_one_mobile_wallet_explanation">Solo puede tener una billetera móvil. Actualícela a la billetera de hardware Tangem o añada una nueva billetera de hardware.</string>
|
||||
<string name="onramp_all_offers_button_title">Todas las ofertas</string>
|
||||
<string name="onramp_avaiable_with_payment_methods">Disponible con %s</string>
|
||||
<string name="onramp_choose_provider_title_hint">La compra de criptomonedas en Tangem se lleva a cabo utilizando proveedores externos.</string>
|
||||
|
|
@ -1266,6 +1278,7 @@
|
|||
<string name="staking_amount_tron_integer_error">La cantidad de staking se redondeará a %1$s TRX debido a las reglas de la red.</string>
|
||||
<string name="staking_amount_tron_integer_error_unstaking">La cantidad de unstaking se redondeará a %1$s TRX debido a las reglas de la red.</string>
|
||||
<string name="staking_apr_earn_badge">APR %1$s%%</string>
|
||||
<string name="staking_cardano_details_rewards_info_text">Sus recompensas de staking comenzarán después de 5 épocas (~25 días) mientras su delegación esté registrada y contabilizada por la red.</string>
|
||||
<string name="staking_claim_unstaked">Reclamar lo que no está en staking</string>
|
||||
<string name="staking_details_account_fee">Tarifa de staking de la cuenta </string>
|
||||
<string name="staking_details_account_fee_info">Una cuenta de staking es una cuenta especial donde se almacenan los tokens SOL de staking. Se crea cuando delegas sus tokens a un validador para participar en la validación de transacciones y ganar recompensas. Se cobra una pequeña tarifa por crear la cuenta de staking, que se devuelve una vez que se completa el staking.</string>
|
||||
|
|
@ -1276,6 +1289,7 @@
|
|||
<string name="staking_details_apr">APR</string>
|
||||
<string name="staking_details_apy">APY</string>
|
||||
<string name="staking_details_auto_claiming_rewards_daily_text">Las recompensas se acumulan automáticamente en su saldo de staking diariamente.</string>
|
||||
<string name="staking_details_autocompound_rewards_earned">Las recompensas se acumulan en su saldo de staking. Fondos ganados: %s</string>
|
||||
<string name="staking_details_available">Disponible</string>
|
||||
<string name="staking_details_average_reward_rate">Tasa de recompensa promedio</string>
|
||||
<string name="staking_details_banner_text">¿Cómo funciona el staking?</string>
|
||||
|
|
@ -1420,6 +1434,7 @@
|
|||
<string name="swap_story_third_subtitle">Sencillo e intuitivo, permite cambiar tokens con solo unos cuantos toques</string>
|
||||
<string name="swap_story_third_title">Simplemente cómodo</string>
|
||||
<string name="swap_via_provider">Intercambio a través del proveedor</string>
|
||||
<string name="swap_your_assets_title">Sus activos</string>
|
||||
<string name="swapping_alert_cex_description">La cantidad incluye:\n• Tarifas del proveedor de servicios\n• Tarifas de red por enviar %s desde el intercambio a la dirección del usuario.</string>
|
||||
<string name="swapping_alert_cex_description_with_slippage">El importe incluye:\n- comisión del proveedor de servicios\n- comisión de red por el envío de %1$s desde el exchange de vuelta a la dirección del usuario. \n\nEl deslizamiento (slippage) del proveedor es de hasta %2$s</string>
|
||||
<string name="swapping_alert_dex_description">El importe incluye los honorarios del proveedor de servicios.</string>
|
||||
|
|
@ -1434,6 +1449,7 @@
|
|||
<string name="swapping_insufficient_funds">Fondos insuficientes</string>
|
||||
<string name="swapping_permission_header">Dar autorización</string>
|
||||
<string name="swapping_swap_action">Intercambiar</string>
|
||||
<string name="swapping_swap_action_in_progress">Intercambiando...</string>
|
||||
<string name="swapping_to_title">Usted recibe</string>
|
||||
<string name="swapping_token_list_title">Elige token</string>
|
||||
<string name="swapping_token_not_available">no disponible</string>
|
||||
|
|
@ -1452,6 +1468,9 @@
|
|||
<string name="tangem_pay_freeze_card_freeze">Mantén tu dinero seguro. Puedes desbloquear en cualquier momento.</string>
|
||||
<string name="tangem_pay_freeze_card_success">Tu tarjeta está congelada.</string>
|
||||
<string name="tangem_pay_get_help">Obtener ayuda</string>
|
||||
<string name="tangem_pay_history_item_spend_mc_declined_reason">Razón: %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">Otro</string>
|
||||
<string name="tangem_pay_rooted_device_subtitle">No se puede usar en dispositivos rooteados</string>
|
||||
<string name="tangem_pay_status_completed">Completado</string>
|
||||
|
|
@ -1528,10 +1547,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_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_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_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>
|
||||
|
|
@ -1818,7 +1842,17 @@
|
|||
<string name="warning_button_ok">Entendido</string>
|
||||
<string name="warning_button_really_cool">¡Realmente genial!</string>
|
||||
<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_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>
|
||||
<string name="warning_clore_migration_message_label">Mensaje</string>
|
||||
<string name="warning_clore_migration_open_portal_button">Abrir el portal de reclamaciones</string>
|
||||
<string name="warning_clore_migration_sheet_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_sheet_title">Migración de la red Clore</string>
|
||||
<string name="warning_clore_migration_sign_button">Firmar</string>
|
||||
<string name="warning_clore_migration_signature_label">Firma</string>
|
||||
<string name="warning_clore_migration_title">Migración de la red Clore</string>
|
||||
<string name="warning_demo_mode_message">Actualmente estás en el modo Demo</string>
|
||||
<string name="warning_demo_mode_title">Modo demo activo</string>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
<string name="account_form_create_button">Ajouter un compte</string>
|
||||
<string name="account_form_edit_button">Enregistrer</string>
|
||||
<string name="account_form_name">Nom du compte</string>
|
||||
<string name="account_form_name_already_exist_error_description">Un compte portant ce nom existe déjà. Veuillez choisir un autre nom.</string>
|
||||
<string name="account_form_name_already_exist_error_title">Nom de compte déjà utilisé</string>
|
||||
<string name="account_form_placeholder_edit_account">Compte</string>
|
||||
<string name="account_form_placeholder_new_account">Nouveau compte</string>
|
||||
|
|
@ -298,6 +299,7 @@
|
|||
<string name="common_go_to_token">Aller au jeton</string>
|
||||
<string name="common_got_it">Compris</string>
|
||||
<string name="common_hide">Cacher</string>
|
||||
<string name="common_hold_to">Maintenir contre %s</string>
|
||||
<string name="common_hour">heure</string>
|
||||
<string name="common_import">Importez</string>
|
||||
<string name="common_in_progress">En cours</string>
|
||||
|
|
@ -322,6 +324,7 @@
|
|||
<string name="common_no">Non</string>
|
||||
<string name="common_no_address">Aucune adresse</string>
|
||||
<string name="common_not_added">Non ajouté</string>
|
||||
<string name="common_not_available">Indisponible</string>
|
||||
<string name="common_not_now">Pas maintenant</string>
|
||||
<string name="common_now">Maintenant</string>
|
||||
<string name="common_ok">OK</string>
|
||||
|
|
@ -372,6 +375,7 @@
|
|||
<string name="common_swap">Échanger</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_tap_and_hold_hint">Appuyez et maintenez enfoncé</string>
|
||||
<string name="common_terms_and_conditions">termes et conditions</string>
|
||||
<string name="common_terms_of_use">Conditions d\'utilisation</string>
|
||||
<string name="common_to">À</string>
|
||||
|
|
@ -399,6 +403,8 @@
|
|||
<string name="common_yield_mode">Mode Rendement</string>
|
||||
<string name="contract_address_copied_message">Adresse du contrat copiée !</string>
|
||||
<string name="currency_subtitle_expanded">Réseaux disponibles</string>
|
||||
<string name="custom_token_another_account_dialog_description">La dérivation de votre token correspond à la dérivation de %1$s. Votre token sera ajouté à ce compte.</string>
|
||||
<string name="custom_token_another_account_dialog_title">La dérivation appartient à un autre compte.</string>
|
||||
<string name="custom_token_another_account_snackbar_text">Jeton ajouté au compte %1$s</string>
|
||||
<string name="custom_token_contract_address_input_title">Adresse du contrat</string>
|
||||
<string name="custom_token_creation_error_invalid_contract_address">L\'adresse du contrat n\'est pas valide</string>
|
||||
|
|
@ -459,6 +465,11 @@
|
|||
<string name="domain_receive_assets_onboarding_description">L’envoi d’actifs sur d’autres réseaux entraînera une perte définitive.</string>
|
||||
<string name="domain_receive_assets_onboarding_network_name">%s réseau</string>
|
||||
<string name="domain_receive_assets_onboarding_title">Envoyez des fonds en utilisant uniquement</string>
|
||||
<string name="earn_best_opportunities">Meilleures opportunités</string>
|
||||
<string name="earn_filter_all_networks">Tous les réseaux</string>
|
||||
<string name="earn_filter_all_types">Tous les types</string>
|
||||
<string name="earn_mostly_used">Principalement utilisé</string>
|
||||
<string name="earn_title">Gagner</string>
|
||||
<string name="email_preface_wc_error">Bonjour équipe de support, j’ai rencontré une erreur avec le code : %s</string>
|
||||
<string name="email_subject_wc_error">Erreur WalletConnect</string>
|
||||
<string name="error_wrong_wallet_tapped">Vous avez utilisé une carte d\'un autre portefeuille. Appuyez sur la carte associée à ce portefeuille</string>
|
||||
|
|
@ -558,6 +569,8 @@
|
|||
<string name="feedback_subject_support_tangem">Commentaires sur Tangem</string>
|
||||
<string name="feedback_subject_tx_failed">Impossible d\'effectuer une transaction</string>
|
||||
<string name="feedback_token_description_error">Erreur de description de la pièce</string>
|
||||
<string name="gasless_not_enough_funds_to_cover_token_fee">Fonds insuffisants</string>
|
||||
<string name="gasless_transaction_fee">Frais de transaction</string>
|
||||
<string name="generic_error">Une erreur s\'est produite</string>
|
||||
<string name="generic_error_code">Une erreur s\'est produite. Code:%s</string>
|
||||
<string name="generic_requires_memo_error">Un mémo est requis</string>
|
||||
|
|
@ -607,6 +620,7 @@
|
|||
<string name="hw_backup_need_title">Finalisez d\'abord la sauvegarde.</string>
|
||||
<string name="hw_backup_no_backup">Incomplet</string>
|
||||
<string name="hw_backup_section_other_title">Autres méthodes</string>
|
||||
<string name="hw_backup_seed_code_description">Conservez votre seed phrase dans un endroit sûr et gardez-la confidentielle afin de protéger vos fonds, puis configurez un code d\'accès pour plus de sécurité.</string>
|
||||
<string name="hw_backup_seed_description">Conservez votre seed phrase dans un endroit sûr et gardez-la confidentielle afin de protéger vos fonds.</string>
|
||||
<string name="hw_backup_seed_title">Seed phrase</string>
|
||||
<string name="hw_backup_to_secure_description">Pour sécuriser votre wallet avec un code d\'accès, effectuez la procédure de sauvegarde.</string>
|
||||
|
|
@ -644,7 +658,7 @@
|
|||
<string name="hw_upgrade_error_wallet2_card_required">Une erreur s\'est produite pendant l\'opération.</string>
|
||||
<string name="hw_upgrade_funds_access_description">Vos fonds restent en sécurité et entièrement accessibles pendant toute la durée du processus.</string>
|
||||
<string name="hw_upgrade_funds_access_title">Accès aux fonds</string>
|
||||
<string name="hw_upgrade_general_security_description">Après la mise à niveau, votre portefeuille mobile sera supprimé de l\'application et stocké sur votre hardware wallet; votre seedphrase restera en votre possession.</string>
|
||||
<string name="hw_upgrade_general_security_description">Après la mise à niveau, votre portefeuille mobile sera supprimé de l\'application et stocké sur votre hardware wallet; votre seed phrase restera en votre possession.</string>
|
||||
<string name="hw_upgrade_general_security_title">Sécurité générale</string>
|
||||
<string name="hw_upgrade_key_migration_description">Les clés privées seront transférées de l\'application vers votre hardware wallet Tangem.</string>
|
||||
<string name="hw_upgrade_key_migration_title">Migration des clés</string>
|
||||
|
|
@ -992,6 +1006,7 @@
|
|||
<string name="onboarding_wallet_info_title_fourth">Restauration du code d\'accès</string>
|
||||
<string name="onboarding_wallet_info_title_second">Cartes identiques</string>
|
||||
<string name="onboarding_wallet_info_title_third">Code d\'accès</string>
|
||||
<string name="only_one_mobile_wallet_explanation">Vous ne pouvez avoir qu\'un seul portefeuille mobile. Passez au portefeuille matériel Tangem ou ajoutez un nouveau portefeuille matériel.</string>
|
||||
<string name="onramp_all_offers_button_title">Toutes les offres</string>
|
||||
<string name="onramp_avaiable_with_payment_methods">Disponible avec %s</string>
|
||||
<string name="onramp_choose_provider_title_hint">L\'achat de crypto-monnaies sur Tangem est assuré par des fournisseurs tiers selon leurs conditions.</string>
|
||||
|
|
@ -1036,6 +1051,7 @@
|
|||
<string name="onramp_title_available_from">Disponible auprès de</string>
|
||||
<string name="onramp_title_available_up_to">Disponible jusqu\'à</string>
|
||||
<string name="onramp_title_you_get">Vous obtenez</string>
|
||||
<string name="onramp_tos_external_providers">Le service est fourni par un prestataire externe. Tangem n\'est pas responsable.</string>
|
||||
<string name="onramp_transaction_status_footer_text">Vous pouvez vérifier l\'état de la transaction à partir de la page du jeton</string>
|
||||
<string name="onramp_up_to_rate">Jusqu\'à</string>
|
||||
<string name="onramp_via">Via</string>
|
||||
|
|
@ -1248,18 +1264,21 @@
|
|||
<string name="settings_forget_wallet_footer">Cela supprimera le portefeuille de l\'application. Le portefeuille lui-même peut être ajouté à nouveau.</string>
|
||||
<string name="settings_upgrade_banner_advantage_feature_title">Facile à utiliser</string>
|
||||
<string name="settings_upgrade_banner_description">Gardez vos cryptomonnaies en sécurité et hors ligne. Aussi fin qu\'une carte de crédit, plus sûr qu\'un coffre-fort bancaire.</string>
|
||||
<string name="settings_upgrade_banner_seed_phrase_feature_title">Pas de seedphrase</string>
|
||||
<string name="settings_upgrade_banner_seed_phrase_feature_title">Pas de seed phrase</string>
|
||||
<string name="settings_upgrade_banner_superiority_feature_title">Le meilleur hardware wallet</string>
|
||||
<string name="settings_upgrade_banner_title">Tangem Hardware Wallet</string>
|
||||
<string name="settings_wallet_name_title">Nom</string>
|
||||
<string name="stake_token_description">Faites travailler votre jeton pour vous</string>
|
||||
<string name="staking_account_initialization_footer">Les frais de réseau sont une petite somme à payer pour traiter et confirmer ta transaction sur la blockchain.</string>
|
||||
<string name="staking_account_initialization_message">Pour commencer à staker, votre compte TON doit être activé avec une transaction de 1 TON. Les fonds restent sur votre compte, car cette étape sert uniquement à l\'activer pour le staking.</string>
|
||||
<string name="staking_account_initialization_title">Activation du compte</string>
|
||||
<string name="staking_alert_network_fee_updated_message">Les frais de réseau ont changé. Veuillez vérifier le nouveau montant avant de continuer.</string>
|
||||
<string name="staking_alert_network_fee_updated_title">Frais de réseau mis à jour</string>
|
||||
<string name="staking_amount_requirement_error">Le montant à staker doit être au moins %s</string>
|
||||
<string name="staking_amount_tron_integer_error">Le montant du staking sera arrondi à %1$s TRX en raison des règles du réseau.</string>
|
||||
<string name="staking_amount_tron_integer_error_unstaking">Le montant d\'annulation du staking sera arrondi à %1$s TRX en raison des règles du réseau.</string>
|
||||
<string name="staking_apr_earn_badge">TAEG %1$s%%</string>
|
||||
<string name="staking_cardano_details_rewards_info_text">Vos récompenses de staking commenceront après 5 époques (~25 jours), une fois que votre délégation aura été enregistrée et comptabilisée par le réseau.</string>
|
||||
<string name="staking_claim_unstaked">Réclamation déstakée</string>
|
||||
<string name="staking_details_account_fee">Frais de staking du compte</string>
|
||||
<string name="staking_details_account_fee_info">Un compte de staking est un compte spécial où sont stockés les jetons SOL stakés. Il est créé lorsque vous déléguez vos jetons à un validateur pour participer à la validation des transactions et gagner des récompenses. Des frais minimes sont facturés pour la création du compte de staking, qui sont restitués une fois le staking terminé.</string>
|
||||
|
|
@ -1270,6 +1289,7 @@
|
|||
<string name="staking_details_apr">APR</string>
|
||||
<string name="staking_details_apy">APY</string>
|
||||
<string name="staking_details_auto_claiming_rewards_daily_text">Les récompenses s\'accumulent automatiquement sur votre solde de staking quotidiennement.</string>
|
||||
<string name="staking_details_autocompound_rewards_earned">Les récompenses sont ajoutées à votre solde de staking. Fonds gagnés : %s</string>
|
||||
<string name="staking_details_available">Disponible</string>
|
||||
<string name="staking_details_average_reward_rate">Taux de récompense moyen</string>
|
||||
<string name="staking_details_banner_text">Qu\'est-ce que le Staking ?</string>
|
||||
|
|
@ -1325,6 +1345,7 @@
|
|||
<string name="staking_notification_restake_text">L\'option de restaker vous permet de déplacer vos fonds d\'un validateur à un autre sans avoir besoin de les déstaker.</string>
|
||||
<string name="staking_notification_stake_entire_balance_text">Vous êtes sur le point de staker l\'intégralité de votre solde. Nous vous recommandons de laisser un petit montant pour couvrir les frais de réseau pour unstaking ou la réclamation des récompenses.</string>
|
||||
<string name="staking_notification_ton_account_initialization_message">Pour commencer le staking, vous devez d’abord activer votre compte TON</string>
|
||||
<string name="staking_notification_ton_account_initialization_title">Activation du compte</string>
|
||||
<string name="staking_notification_ton_activate_account">Pour commencer à staker TON, effectuez d\'abord une transaction sortante de n\'importe quel montant — cela activera votre portefeuille.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_info">Jusqu\'à 0,2 TON peuvent être requis en plus des frais de réseau pour terminer la transaction. Tout montant non utilisé sera remboursé.</string>
|
||||
<string name="staking_notification_ton_extra_reserve_is_required">0,2 TON requis pour effectuer cette opération, en plus des frais de réseau. Veuillez recharger votre solde.</string>
|
||||
|
|
@ -1413,6 +1434,7 @@
|
|||
<string name="swap_story_third_subtitle">Simple et intuitif, vous permettant d\'échanger des jetons en quelques clics</string>
|
||||
<string name="swap_story_third_title">Plus Simple Que Jamais</string>
|
||||
<string name="swap_via_provider">Échange via le fournisseur</string>
|
||||
<string name="swap_your_assets_title">Vos actifs</string>
|
||||
<string name="swapping_alert_cex_description">Le montant comprend :\n• les frais du fournisseur de services\n• les frais de réseau pour l\'envoi de %s depuis l\'échange vers l\'adresse de l\'utilisateur.</string>
|
||||
<string name="swapping_alert_cex_description_with_slippage">Le montant comprend :\n• les frais du fournisseur de services\n• les frais de réseau pour l\'envoi de %1$s depuis l\'échange vers l\'adresse de l\'utilisateur. \n\nLe slippage du fournisseur peut atteindre %2$s</string>
|
||||
<string name="swapping_alert_dex_description">Le montant comprend les frais du fournisseur de services.</string>
|
||||
|
|
@ -1427,6 +1449,7 @@
|
|||
<string name="swapping_insufficient_funds">Fonds insuffisants</string>
|
||||
<string name="swapping_permission_header">Donner l\'autorisation</string>
|
||||
<string name="swapping_swap_action">Échanger</string>
|
||||
<string name="swapping_swap_action_in_progress">Échange...</string>
|
||||
<string name="swapping_to_title">Vous recevez</string>
|
||||
<string name="swapping_token_list_title">Choisir le jeton</string>
|
||||
<string name="swapping_token_not_available">non disponible</string>
|
||||
|
|
@ -1445,6 +1468,9 @@
|
|||
<string name="tangem_pay_freeze_card_freeze">Geler</string>
|
||||
<string name="tangem_pay_freeze_card_success">Votre carte est gelée.</string>
|
||||
<string name="tangem_pay_get_help">Obtenir de l\'aide</string>
|
||||
<string name="tangem_pay_history_item_spend_mc_declined_reason">Raison : %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">Autre</string>
|
||||
<string name="tangem_pay_rooted_device_subtitle">Impossible à utiliser sur les appareils rootés</string>
|
||||
<string name="tangem_pay_status_completed">Terminé</string>
|
||||
|
|
@ -1521,10 +1547,15 @@
|
|||
<string name="tangempay_kyc_confirm_cancellation_description">Êtes-vous sûr de vouloir interrompre le processus KYC ? Vous pouvez y revenir à tout moment.</string>
|
||||
<string name="tangempay_kyc_failed_description">Nous n\'avons pas pu vérifier votre profil. Pour toute question, veuillez contacter le support.</string>
|
||||
<string name="tangempay_kyc_failed_title">Malheureusement, nous n\'avons pas pu vérifier votre identité</string>
|
||||
<string name="tangempay_kyc_has_failed">KYC a échoué</string>
|
||||
<string name="tangempay_kyc_in_progress">KYC en cours</string>
|
||||
<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_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_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>
|
||||
|
|
@ -1579,6 +1610,7 @@
|
|||
<string name="token_details_token_type_subtitle_no_standard">Jeton dans le %%image%% %1$s réseau</string>
|
||||
<string name="token_details_unable_hide_alert_message">Le jeton %1$s (%2$s) est la principale devise du réseau %3$s et ne peut pas être masqué tant que vous avez d\'autres jetons de ce réseau dans la liste</string>
|
||||
<string name="token_details_unable_hide_alert_title">Impossible de masquer %s</string>
|
||||
<string name="token_receive_show_qr_code_title">Afficher le code QR</string>
|
||||
<string name="token_swap_changelly_promotion_message">Échangez ce jeton contre un autre moyennant des frais de service de %1$s du %2$s au %3$s février.</string>
|
||||
<string name="token_swap_changelly_promotion_title">Échangez avec Changelly, %s frais</string>
|
||||
<string name="token_swap_promotion_button">Échangez maintenant</string>
|
||||
|
|
@ -1710,6 +1742,12 @@
|
|||
<string name="visa_unlock_notification_subtitle">Scannez votre carte pour déverrouiller l\'accès</string>
|
||||
<string name="visa_unlock_notification_title">Déverrouillage nécessaire</string>
|
||||
<string name="wallet_add_common_title">Choisissez comment ajouter votre portefeuille</string>
|
||||
<string name="wallet_add_hardware_description">Scannez votre carte ou votre bague Tangem pour la restaurer ou l\'importer depuis un autre portefeuille.</string>
|
||||
<string name="wallet_add_hardware_info_create">Créer un Hardware Wallet</string>
|
||||
<string name="wallet_add_hardware_purchase">Vous souhaitez acheter un portefeuille Tangem ?</string>
|
||||
<string name="wallet_add_import_seed_phrase">Importer la seed phrase</string>
|
||||
<string name="wallet_add_mobile_description">Restaurez votre portefeuille sur votre téléphone ou importez-le depuis une autre application — pratique, mais moins sécurisé qu\'une carte Tangem.</string>
|
||||
<string name="wallet_add_support_title">Que choisir ?</string>
|
||||
<string name="wallet_balance_blockchain_unreachable_try_later">La blockchain n\'est pas accessible. Réessayez plus tard</string>
|
||||
<string name="wallet_balance_missing_derivation">Scanner la carte ou la bague</string>
|
||||
<string name="wallet_been_activated_message">Ce portefeuille a déjà été activé auparavant.\nSi cela n\'a pas été fait par vous, veuillez contacter le support.\nTangem ne vend jamais de portefeuilles avec le code d\'accès pré-généré.</string>
|
||||
|
|
@ -1766,9 +1804,9 @@
|
|||
<string name="wallet_import_navtitle">Ajouter un portefeuille existant</string>
|
||||
<string name="wallet_import_scan_description">Dispositifs physiques qui stockent votre clé privée hors ligne en toute sécurité.</string>
|
||||
<string name="wallet_import_scan_title">Scanner un Tangem Wallet</string>
|
||||
<string name="wallet_import_seed_description">Importez un portefeuille existant à l\'aide de votre seedphrase.</string>
|
||||
<string name="wallet_import_seed_description">Importez un portefeuille existant à l\'aide de votre seed phrase.</string>
|
||||
<string name="wallet_import_seed_navtitle">Importer un wallet</string>
|
||||
<string name="wallet_import_seed_title">Entrez la seedphrase</string>
|
||||
<string name="wallet_import_seed_title">Entrez la seed phrase</string>
|
||||
<string name="wallet_import_success_description">Vous avez importé votre portefeuille avec succès.</string>
|
||||
<string name="wallet_import_success_navtitle">Importer un wallet</string>
|
||||
<string name="wallet_import_success_title">Importation terminée</string>
|
||||
|
|
@ -1984,7 +2022,7 @@
|
|||
<string name="welcome_create_wallet_feature_delivery">Livraison rapide</string>
|
||||
<string name="welcome_create_wallet_feature_one_tap">Commencez en un seul clic</string>
|
||||
<string name="welcome_create_wallet_feature_seamless">Sans faille et sécurisé</string>
|
||||
<string name="welcome_create_wallet_feature_seedphrase">Pas de seedphrase</string>
|
||||
<string name="welcome_create_wallet_feature_seedphrase">Pas de seed phrase</string>
|
||||
<string name="welcome_create_wallet_feature_use">Facile à utiliser</string>
|
||||
<string name="welcome_create_wallet_hardware_description">Créez un harware wallet avec Tangem. Aussi fin qu\'une carte bancaire, aussi sûr qu\'un coffre-fort.</string>
|
||||
<string name="welcome_create_wallet_mobile_description">Créer ou importer un portefeuille logiciel</string>
|
||||
|
|
@ -2105,4 +2143,5 @@
|
|||
<string name="yield_module_unable_to_cover_fee_title">Impossible de couvrir les frais %s</string>
|
||||
<string name="yield_module_unavailable_subtitle">Le mode rendement n\'est pas disponible pour le moment. Veuillez réessayer plus tard.</string>
|
||||
<string name="yield_module_unavailable_title">Le mode Rendement est indisponible</string>
|
||||
<string name="yield_supply_chart_loading_error">Impossible de charger le graphique...</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@
|
|||
<string name="common_go_to_token">トークンへ移動</string>
|
||||
<string name="common_got_it">わかりました</string>
|
||||
<string name="common_hide">非表示</string>
|
||||
<string name="common_hold_to">%sまで長押し</string>
|
||||
<string name="common_hour">時間</string>
|
||||
<string name="common_import">インポート</string>
|
||||
<string name="common_in_progress">進行中</string>
|
||||
|
|
@ -368,6 +369,7 @@
|
|||
<string name="common_swap">スワップ</string>
|
||||
<string name="common_tangem">Tangem</string>
|
||||
<string name="common_tangem_wallet">Tangem Wallet</string>
|
||||
<string name="common_tap_and_hold_hint">タップして長押し</string>
|
||||
<string name="common_terms_and_conditions">利用規約</string>
|
||||
<string name="common_terms_of_use">利用規約</string>
|
||||
<string name="common_to">宛先</string>
|
||||
|
|
@ -456,6 +458,11 @@
|
|||
<string name="domain_receive_assets_onboarding_description">他のネットワークで資産を送金すると、永久に失われます。</string>
|
||||
<string name="domain_receive_assets_onboarding_network_name">%sネットワーク</string>
|
||||
<string name="domain_receive_assets_onboarding_title">下記のみを使用して資金を送金する</string>
|
||||
<string name="earn_best_opportunities">おすすめ</string>
|
||||
<string name="earn_filter_all_networks">すべてのネットワーク</string>
|
||||
<string name="earn_filter_all_types">すべての種類</string>
|
||||
<string name="earn_mostly_used">よく使われています</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>
|
||||
|
|
@ -935,11 +942,11 @@
|
|||
<string name="onboarding_navbar_upgrade_wallet_biometrics">生体認証</string>
|
||||
<string name="onboarding_seed_button_read_more">シードフレーズについてもっと読む</string>
|
||||
<plurals name="onboarding_seed_generate_message_words_count">
|
||||
<item quantity="other">これらの %d 単語を以下の順番通りに書き留め、安全かつ秘密の場所に保管してください。</item>
|
||||
<item quantity="other">以下に表示される%d個の単語を順番どおりに書き留め、安全で他人に知られない場所に保管してください。</item>
|
||||
</plurals>
|
||||
<string name="onboarding_seed_generate_title">あなたのシードフレーズ</string>
|
||||
<plurals name="onboarding_seed_generate_words_count">
|
||||
<item quantity="other">%d 単語</item>
|
||||
<item quantity="other">%d個の単語</item>
|
||||
</plurals>
|
||||
<string name="onboarding_seed_import_message">ウォレットをインポートするには、下のフィールドにシードフレーズを入力してください。</string>
|
||||
<string name="onboarding_seed_intro_button_generate">シードフレーズを生成する</string>
|
||||
|
|
@ -1252,6 +1259,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>
|
||||
|
|
@ -1441,6 +1449,9 @@
|
|||
<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_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>
|
||||
|
|
@ -1643,25 +1654,69 @@
|
|||
<string name="user_wallet_list_rename_popup_title">ウォレット名の変更</string>
|
||||
<string name="user_wallet_list_unlock_all">すべてのロックを解除</string>
|
||||
<string name="user_wallet_list_unlock_all_with">%sですべてをロック解除</string>
|
||||
<string name="visa_balance_limits_details_aml_verified">AML認証済み</string>
|
||||
<string name="visa_balance_limits_details_available">利用可能</string>
|
||||
<string name="visa_balance_limits_details_blocked">ブロック中</string>
|
||||
<string name="visa_balance_limits_details_debt">負債</string>
|
||||
<string name="visa_balance_limits_details_limits">利用上限</string>
|
||||
<string name="visa_balance_limits_details_no_otp_limit">その他(OTPなし)</string>
|
||||
<string name="visa_balance_limits_details_single_transaction">単一の取引</string>
|
||||
<string name="visa_balance_limits_details_total">合計</string>
|
||||
<plurals name="visa_limits_available_for_days_title">
|
||||
<item quantity="other">%d日間利用可能</item>
|
||||
</plurals>
|
||||
<string name="visa_main_available_balance_alert_message">利用可能残高は、保留中の取引、ブロック中の金額、デビット残高を考慮した、実際に利用できる資金を示します。</string>
|
||||
<string name="visa_main_available_till_date">%1$sまで利用可能</string>
|
||||
<string name="visa_main_balances_and_limits">残高と限度額</string>
|
||||
<string name="visa_main_button_alert_missing_payment_account_info_message">支払いアカウントの情報が見つかりません。サポートにお問い合わせください。</string>
|
||||
<string name="visa_main_button_alert_missing_token_info">トークンの情報を読み込めません。</string>
|
||||
<string name="visa_main_button_alert_still_loading">情報を読み込み中です。しばらくお待ちください。</string>
|
||||
<string name="visa_main_limits_alert_description_message">コストの管理、セキュリティの向上、リスク管理のために利用上限が設けられています。店舗でのカード決済では期間内に%1$s、サブスクリプションや支払いなどのその他の取引では%2$sまで利用できます。</string>
|
||||
<string name="visa_onboarding_access_code_description">アクセスコードは、支払いアカウントの管理および不正アクセスからの保護に使用されます。</string>
|
||||
<string name="visa_onboarding_access_code_navigation_title">アクセスコード</string>
|
||||
<string name="visa_onboarding_account_activation_navigation_title">アカウント有効化</string>
|
||||
<string name="visa_onboarding_approve_wallet_selector_notification_message">登録手続きを開始したウォレットを選択し、ブロックチェーン上でアカウントを作成するための取引に署名してください。</string>
|
||||
<string name="visa_onboarding_cancel_activation">有効化をキャンセル</string>
|
||||
<string name="visa_onboarding_close_alert_message">本当に終了してもよろしいですか?中断したところから後で続行できます。</string>
|
||||
<string name="visa_onboarding_in_progress_description">長くはかかりません。アカウントを設定しています。</string>
|
||||
<string name="visa_onboarding_in_progress_issuer_description">長くはかかりません。アクティベーションを完了しています。</string>
|
||||
<string name="visa_onboarding_in_progress_title">準備完了です!</string>
|
||||
<string name="visa_onboarding_other_wallet">その他のウォレット</string>
|
||||
<string name="visa_onboarding_pin_code_description">4桁のコードを設定します。 \nお支払いの際に使用されます。</string>
|
||||
<string name="visa_onboarding_pin_code_navigation_title">PINコード</string>
|
||||
<string name="visa_onboarding_pin_code_title">PINコードを作成する</string>
|
||||
<string name="visa_onboarding_pin_not_accepted">PINの認証に失敗しました。もう一度お試しいただくか、別のコードを使用してください。</string>
|
||||
<string name="visa_onboarding_pin_validation_error_message">無効な暗証番号:連続や繰り返しを避けてください</string>
|
||||
<string name="visa_onboarding_success_screen_description">準備完了です!</string>
|
||||
<string name="visa_onboarding_tangem_approve_description">Tangemカードを用意し、タップして承認してください。</string>
|
||||
<string name="visa_onboarding_tangem_approve_title">Tangemウォレットを準備してください。</string>
|
||||
<string name="visa_onboarding_wallet_connect_description">\nサードパーティのWebサイト\nで接続手続きを完了し、その後Tangemアプリに戻ってください。</string>
|
||||
<string name="visa_onboarding_wallet_connect_title">ウェブサイトに移動</string>
|
||||
<string name="visa_onboarding_wallet_connection_navigation_title">ウォレット接続</string>
|
||||
<string name="visa_onboarding_wallet_list_header">ウォレットを選択</string>
|
||||
<string name="visa_onboarding_welcome_back_button_title">有効化を続行</string>
|
||||
<string name="visa_onboarding_welcome_back_description">アカウントの設定を続けましょう。</string>
|
||||
<string name="visa_onboarding_welcome_back_title">お帰りなさい!</string>
|
||||
<string name="visa_onboarding_welcome_button_title">有効化を開始</string>
|
||||
<string name="visa_onboarding_welcome_description">手順に従ってアカウントを設定してください。</string>
|
||||
<string name="visa_onboarding_welcome_title">ようこそ!</string>
|
||||
<string name="visa_transaction_details_blockchain_amount">ブロックチェーン上の金額</string>
|
||||
<string name="visa_transaction_details_currency_code">通貨コード</string>
|
||||
<string name="visa_transaction_details_date">日付</string>
|
||||
<string name="visa_transaction_details_error_code">エラーコード</string>
|
||||
<string name="visa_transaction_details_header">取引詳細</string>
|
||||
<string name="visa_transaction_details_merchant_category_code">加盟店カテゴリーコード</string>
|
||||
<string name="visa_transaction_details_merchant_city">加盟店の所在地</string>
|
||||
<string name="visa_transaction_details_merchant_country_code">加盟店の国コード</string>
|
||||
<string name="visa_transaction_details_merchant_name">加盟店名</string>
|
||||
<string name="visa_transaction_details_request_id">リクエストID</string>
|
||||
<string name="visa_transaction_details_status">ステータス</string>
|
||||
<string name="visa_transaction_details_title">取引</string>
|
||||
<string name="visa_transaction_details_transaction_amount">取引金額</string>
|
||||
<string name="visa_transaction_details_transaction_hash">トランザクションハッシュ</string>
|
||||
<string name="visa_transaction_details_transaction_request">取引リクエスト</string>
|
||||
<string name="visa_transaction_details_transaction_status">取引ステータス</string>
|
||||
<string name="visa_transaction_details_type">種類</string>
|
||||
<string name="visa_tx_dispute_button">この取引に異議を唱える</string>
|
||||
<string name="visa_unlock_notification_button">ロック解除</string>
|
||||
<string name="visa_unlock_notification_subtitle">カードをスキャンしてアクセスロックを解除する</string>
|
||||
|
|
|
|||
|
|
@ -1800,7 +1800,17 @@
|
|||
<string name="warning_button_ok">Понятно!</string>
|
||||
<string name="warning_button_really_cool">Очень круто!</string>
|
||||
<string name="warning_button_refresh">Обновить</string>
|
||||
<string name="warning_clore_migration_button">Начать миграцию</string>
|
||||
<string name="warning_clore_migration_copy_button">Копировать</string>
|
||||
<string name="warning_clore_migration_error_signing_not_supported">Подписание сообщений не поддерживается в этой сети</string>
|
||||
<string name="warning_clore_migration_error_wallet_manager_not_found">Невозможно подписать сообщение. Пожалуйста, попробуй позже.</string>
|
||||
<string name="warning_clore_migration_message">Согласно официальной документации Clore, все монеты, полученные до 21 декабря, будут мигрированы в токен Clore (ERC-20); монеты, полученные после этой даты, — нет. Решение для перевода находится в разработке — следите за обновлениями.</string>
|
||||
<string name="warning_clore_migration_message_label">Сообщение</string>
|
||||
<string name="warning_clore_migration_open_portal_button">Открыть портал клейма</string>
|
||||
<string name="warning_clore_migration_sheet_description">Чтобы сохранить доступ к своим средствам, начните миграцию в соответствии с официальной инструкцией Clore.</string>
|
||||
<string name="warning_clore_migration_sheet_title">Миграция сети Clore</string>
|
||||
<string name="warning_clore_migration_sign_button">Подписать</string>
|
||||
<string name="warning_clore_migration_signature_label">Подпись</string>
|
||||
<string name="warning_clore_migration_title">Миграция сети Clore</string>
|
||||
<string name="warning_demo_mode_message">Вы находитесь в режиме демо</string>
|
||||
<string name="warning_demo_mode_title">Демо режим включен</string>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
<string name="account_form_edit_button">Зберегти</string>
|
||||
<string name="account_form_name">Назва акаунту</string>
|
||||
<string name="account_form_name_already_exist_error_description">Акаунт з такою назвою вже існує. Будь ласка, виберіть іншу назву.</string>
|
||||
<string name="account_form_name_already_exist_error_title">Обліковий запис з таким ім’ям уже існує</string>
|
||||
<string name="account_form_placeholder_edit_account">Акаунт</string>
|
||||
<string name="account_form_placeholder_new_account">Новий акаунт</string>
|
||||
<string name="account_form_title_create">Додати акаунт</string>
|
||||
|
|
|
|||
|
|
@ -1469,6 +1469,9 @@
|
|||
<string name="tangem_pay_freeze_card_freeze">Freeze</string>
|
||||
<string name="tangem_pay_freeze_card_success">Your card is frozen.</string>
|
||||
<string name="tangem_pay_get_help">Get Help</string>
|
||||
<string name="tangem_pay_history_item_spend_mc_declined_reason">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">Other</string>
|
||||
<string name="tangem_pay_rooted_device_subtitle">Unable to use on rooted devices</string>
|
||||
<string name="tangem_pay_status_completed">Completed</string>
|
||||
|
|
@ -1840,7 +1843,17 @@
|
|||
<string name="warning_button_ok">Ok, Got it!</string>
|
||||
<string name="warning_button_really_cool">Really cool!</string>
|
||||
<string name="warning_button_refresh">Refresh</string>
|
||||
<string name="warning_clore_migration_button">Start migration</string>
|
||||
<string name="warning_clore_migration_copy_button">Copy</string>
|
||||
<string name="warning_clore_migration_error_signing_not_supported">Message signing is not supported for this network</string>
|
||||
<string name="warning_clore_migration_error_wallet_manager_not_found">Unable to sign message. Please try again.</string>
|
||||
<string name="warning_clore_migration_message">According to Clore’s official documentation, all coins received before December 21 will be migrated to Clore (ERC-20 token); coins received after that date will not. A transfer solution is coming — stay tuned.</string>
|
||||
<string name="warning_clore_migration_message_label">Message</string>
|
||||
<string name="warning_clore_migration_open_portal_button">Open Claim portal</string>
|
||||
<string name="warning_clore_migration_sheet_description">To keep access to your funds, start the migration according to the official Clore guidelines.</string>
|
||||
<string name="warning_clore_migration_sheet_title">Clore Network Migration</string>
|
||||
<string name="warning_clore_migration_sign_button">Sign</string>
|
||||
<string name="warning_clore_migration_signature_label">Signature</string>
|
||||
<string name="warning_clore_migration_title">Clore Network Migration</string>
|
||||
<string name="warning_demo_mode_message">You are currently in the Demo mode</string>
|
||||
<string name="warning_demo_mode_title">Demo mode active</string>
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ import kotlinx.serialization.Serializable
|
|||
sealed class NavigationAction {
|
||||
data object Staking : NavigationAction()
|
||||
data class YieldSupply(val isActive: Boolean) : NavigationAction()
|
||||
data object CloreMigration : NavigationAction()
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.transaction.error
|
||||
|
||||
sealed class SignCloreMessageError {
|
||||
|
||||
data object WalletManagerNotFound : SignCloreMessageError()
|
||||
|
||||
data object MessageSigningNotSupported : SignCloreMessageError()
|
||||
|
||||
data class SigningFailed(val message: String) : SignCloreMessageError()
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.tangem.domain.transaction.usecase
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.left
|
||||
import arrow.core.right
|
||||
import com.tangem.blockchain.common.MessageSigner
|
||||
import com.tangem.blockchain.common.TransactionSigner
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.transaction.error.SignCloreMessageError
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
|
||||
class SignCloreMessageUseCase(
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val cardSdkConfigRepository: CardSdkConfigRepository,
|
||||
private val getHotWalletSigner: (UserWallet.Hot) -> TransactionSigner,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(
|
||||
userWallet: UserWallet,
|
||||
currency: CryptoCurrency,
|
||||
message: String,
|
||||
): Either<SignCloreMessageError, String> {
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = currency.network,
|
||||
)
|
||||
|
||||
if (walletManager == null) {
|
||||
return SignCloreMessageError.WalletManagerNotFound.left()
|
||||
}
|
||||
|
||||
if (walletManager !is MessageSigner) {
|
||||
return SignCloreMessageError.MessageSigningNotSupported.left()
|
||||
}
|
||||
|
||||
val signer = when (userWallet) {
|
||||
is UserWallet.Cold -> {
|
||||
val card = userWallet.scanResponse.card
|
||||
val isCardNotBackedUp = card.backupStatus?.isActive != true
|
||||
cardSdkConfigRepository.getCommonSigner(
|
||||
cardId = card.cardId.takeIf { isCardNotBackedUp },
|
||||
twinKey = null,
|
||||
)
|
||||
}
|
||||
is UserWallet.Hot -> getHotWalletSigner(userWallet)
|
||||
}
|
||||
|
||||
return when (val result = walletManager.signMessage(message, signer)) {
|
||||
is CompletionResult.Success -> result.data.right()
|
||||
is CompletionResult.Failure -> SignCloreMessageError.SigningFailed(
|
||||
message = result.error.message ?: "Unknown error",
|
||||
).left()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,7 @@ dependencies {
|
|||
/** Core modules */
|
||||
implementation(projects.common.routing)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.res)
|
||||
implementation(projects.core.ui)
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.core.analytics)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
||||
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.transaction.error.SignCloreMessageError
|
||||
import com.tangem.domain.transaction.usecase.SignCloreMessageUseCase
|
||||
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsStateFactory
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
// TODO: Remove after Clore migration ends ([REDACTED_TASK_KEY])
|
||||
@Suppress("LongParameterList")
|
||||
internal class CloreMigrationModel(
|
||||
private val stateFactory: TokenDetailsStateFactory,
|
||||
private val signCloreMessageUseCase: SignCloreMessageUseCase,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val router: InnerTokenDetailsRouter,
|
||||
private val userWallet: UserWallet,
|
||||
private val cryptoCurrency: CryptoCurrency,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val onStateUpdate: (TokenDetailsState) -> Unit,
|
||||
) {
|
||||
|
||||
private val state = MutableStateFlow(CloreMigrationState())
|
||||
|
||||
fun onCloreMigrationClick() {
|
||||
state.value = CloreMigrationState()
|
||||
updateBottomSheet()
|
||||
}
|
||||
|
||||
fun onCloreSignMessage(message: String) {
|
||||
if (message.isBlank()) return
|
||||
|
||||
state.value = state.value.copy(message = message)
|
||||
updateBottomSheet(isSigningInProgress = true)
|
||||
|
||||
coroutineScope.launch(dispatchers.main) {
|
||||
signCloreMessageUseCase(
|
||||
userWallet = userWallet,
|
||||
currency = cryptoCurrency,
|
||||
message = message,
|
||||
).fold(
|
||||
ifLeft = { error ->
|
||||
val errorMessage = when (error) {
|
||||
is SignCloreMessageError.SigningFailed -> stringReference(error.message)
|
||||
SignCloreMessageError.MessageSigningNotSupported ->
|
||||
resourceReference(R.string.warning_clore_migration_error_signing_not_supported)
|
||||
SignCloreMessageError.WalletManagerNotFound ->
|
||||
resourceReference(R.string.warning_clore_migration_error_wallet_manager_not_found)
|
||||
}
|
||||
state.value = state.value.copy(signature = "")
|
||||
updateBottomSheet()
|
||||
uiMessageSender.send(SnackbarMessage(errorMessage))
|
||||
},
|
||||
ifRight = { signature ->
|
||||
state.value = state.value.copy(signature = signature)
|
||||
onStateUpdate(stateFactory.getStateWithUpdatedCloreMigrationSignature(signature))
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onOpenCloreClaimPortal() {
|
||||
router.openUrl(CLAIM_PORTAL_URL)
|
||||
}
|
||||
|
||||
private fun updateBottomSheet(isSigningInProgress: Boolean = false) {
|
||||
val currentState = state.value
|
||||
onStateUpdate(
|
||||
stateFactory.getStateWithCloreMigrationBottomSheet(
|
||||
message = currentState.message,
|
||||
signature = currentState.signature,
|
||||
isSigningInProgress = isSigningInProgress,
|
||||
onMessageChange = { newMessage ->
|
||||
state.value = state.value.copy(message = newMessage)
|
||||
updateBottomSheet()
|
||||
},
|
||||
onSignClick = { onCloreSignMessage(state.value.message) },
|
||||
onCopyClick = {
|
||||
val signature = state.value.signature
|
||||
if (signature.isNotBlank()) {
|
||||
clipboardManager.setText(text = signature, isSensitive = false)
|
||||
uiMessageSender.send(
|
||||
SnackbarMessage(resourceReference(R.string.wallet_notification_address_copied)),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenPortalClick = { onOpenCloreClaimPortal() },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val CLAIM_PORTAL_URL = "https://claim-portal.clore.ai/"
|
||||
}
|
||||
}
|
||||
|
||||
private data class CloreMigrationState(
|
||||
val message: String = "",
|
||||
val signature: String = "",
|
||||
)
|
||||
|
|
@ -72,6 +72,19 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onBalanceSelect(config: TokenBalanceSegmentedButtonConfig)
|
||||
|
||||
fun onYieldInfoClick()
|
||||
|
||||
// region Clore migration
|
||||
// TODO: Remove after 2025-04-01 when Clore migration ends ([REDACTED_TASK_KEY])
|
||||
|
||||
fun onCloreMigrationClick()
|
||||
|
||||
fun onCloreSignMessage(message: String)
|
||||
|
||||
fun onOpenCloreClaimPortal()
|
||||
|
||||
// endregion Clore migration
|
||||
|
||||
fun onGoToRefundedTokenClick(cryptoCurrency: CryptoCurrency)
|
||||
|
||||
fun onOpenUrlClick(url: String)
|
||||
|
|
@ -79,6 +92,4 @@ interface TokenDetailsClickIntents {
|
|||
fun onConfirmDisposeExpressStatus()
|
||||
|
||||
fun onDisposeExpressStatus()
|
||||
|
||||
fun onYieldInfoClick()
|
||||
}
|
||||
|
|
@ -155,13 +155,17 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private val getAccountCryptoCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val yieldSupplyGetRewardsBalanceUseCase: YieldSupplyGetRewardsBalanceUseCase,
|
||||
) : Model(), TokenDetailsClickIntents, YieldSupplyDepositedWarningComponent.ModelCallback {
|
||||
private val signCloreMessageUseCase: SignCloreMessageUseCase,
|
||||
) : Model(),
|
||||
TokenDetailsClickIntents,
|
||||
YieldSupplyDepositedWarningComponent.ModelCallback {
|
||||
|
||||
private val params = paramsContainer.require<TokenDetailsComponent.Params>()
|
||||
private val userWalletId: UserWalletId = params.userWalletId
|
||||
private val cryptoCurrency: CryptoCurrency = params.currency
|
||||
|
||||
private val userWallet: UserWallet = getUserWalletUseCase(userWalletId).getOrNull() ?: error("UserWallet not found")
|
||||
private val userWallet: UserWallet = getUserWalletUseCase(userWalletId).getOrNull()
|
||||
?: error("UserWallet not found")
|
||||
|
||||
private val marketPriceJobHolder = JobHolder()
|
||||
private val refreshStateJobHolder = JobHolder()
|
||||
|
|
@ -193,6 +197,27 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
yieldSupplyFeatureToggles = yieldSupplyFeatureToggles,
|
||||
)
|
||||
|
||||
private val internalUiState = MutableStateFlow(stateFactory.getInitialState(cryptoCurrency))
|
||||
val uiState: StateFlow<TokenDetailsState> = internalUiState
|
||||
|
||||
// region Clore migration
|
||||
// TODO: Remove after Clore migration ends ([REDACTED_TASK_KEY])
|
||||
private val cloreMigrationModel by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
CloreMigrationModel(
|
||||
stateFactory = stateFactory,
|
||||
signCloreMessageUseCase = signCloreMessageUseCase,
|
||||
clipboardManager = clipboardManager,
|
||||
uiMessageSender = uiMessageSender,
|
||||
router = router,
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
coroutineScope = modelScope,
|
||||
dispatchers = dispatchers,
|
||||
onStateUpdate = { internalUiState.value = it },
|
||||
)
|
||||
}
|
||||
// endregion
|
||||
|
||||
private val expressStatusFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
expressStatusFactory.create(
|
||||
clickIntents = this,
|
||||
|
|
@ -215,9 +240,6 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
TokenDetailsCurrencyStatusAnalyticsSender(analyticsEventsHandler)
|
||||
}
|
||||
|
||||
private val internalUiState = MutableStateFlow(stateFactory.getInitialState(cryptoCurrency))
|
||||
val uiState: StateFlow<TokenDetailsState> = internalUiState
|
||||
|
||||
init {
|
||||
updateTopBarMenu()
|
||||
initButtons()
|
||||
|
|
@ -666,9 +688,8 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
vibratorHapticManager.performOneTime(TangemHapticEffect.OneTime.Click)
|
||||
clipboardManager.setText(text = extendedKey, isSensitive = true)
|
||||
|
||||
uiMessageSender.send(
|
||||
message = SnackbarMessage(message = resourceReference(R.string.wallet_notification_address_copied)),
|
||||
)
|
||||
val message = resourceReference(R.string.wallet_notification_address_copied)
|
||||
uiMessageSender.send(message = SnackbarMessage(message = message))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -785,7 +806,8 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
modelScope.launch(dispatchers.main) {
|
||||
when (val addresses = currencyStatus.value.networkAddress) {
|
||||
is NetworkAddress.Selectable -> {
|
||||
internalUiState.value = stateFactory.getStateWithChooseAddressBottomSheet(cryptoCurrency, addresses)
|
||||
internalUiState.value =
|
||||
stateFactory.getStateWithChooseAddressBottomSheet(cryptoCurrency, addresses)
|
||||
}
|
||||
is NetworkAddress.Single -> {
|
||||
router.openUrl(
|
||||
|
|
@ -1265,11 +1287,26 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleNavigationParam() {
|
||||
if (params.navigationAction is NavigationAction.Staking) {
|
||||
openStaking()
|
||||
when (params.navigationAction) {
|
||||
is NavigationAction.Staking -> openStaking()
|
||||
is NavigationAction.CloreMigration -> onCloreMigrationClick()
|
||||
is NavigationAction.YieldSupply,
|
||||
null,
|
||||
-> Unit
|
||||
}
|
||||
}
|
||||
|
||||
// region Clore migration
|
||||
// TODO: Remove after Clore migration ends ([REDACTED_TASK_KEY])
|
||||
|
||||
override fun onCloreMigrationClick() = cloreMigrationModel.onCloreMigrationClick()
|
||||
|
||||
override fun onCloreSignMessage(message: String) = cloreMigrationModel.onCloreSignMessage(message)
|
||||
|
||||
override fun onOpenCloreClaimPortal() = cloreMigrationModel.onOpenCloreClaimPortal()
|
||||
|
||||
// endregion Clore migration
|
||||
|
||||
private companion object {
|
||||
const val EXPRESS_STATUS_UPDATE_DELAY = 10_000L
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,9 +258,15 @@ internal sealed class TokenDetailsNotification(val config: NotificationConfig) {
|
|||
subtitle = resourceReference(id = R.string.warning_matic_migration_message),
|
||||
)
|
||||
|
||||
data object MigrationClore : Warning(
|
||||
data class MigrationClore(
|
||||
private val onMigrationClick: () -> Unit,
|
||||
) : Warning(
|
||||
title = resourceReference(id = R.string.warning_clore_migration_title),
|
||||
subtitle = resourceReference(id = R.string.warning_clore_migration_message),
|
||||
subtitle = resourceReference(id = R.string.warning_clore_migration_sheet_description),
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(id = R.string.warning_clore_migration_button),
|
||||
onClick = onMigrationClick,
|
||||
),
|
||||
)
|
||||
|
||||
data object UsedOutdatedData : TokenDetailsNotification(
|
||||
|
|
|
|||
|
|
@ -155,7 +155,9 @@ internal class TokenDetailsNotificationConverter(
|
|||
},
|
||||
)
|
||||
is CryptoCurrencyWarning.MigrationMaticToPol -> MigrationMaticToPol
|
||||
is CryptoCurrencyWarning.MigrationClore -> MigrationClore
|
||||
is CryptoCurrencyWarning.MigrationClore -> MigrationClore(
|
||||
onMigrationClick = clickIntents::onCloreMigrationClick,
|
||||
)
|
||||
is CryptoCurrencyWarning.UsedOutdatedDataWarning -> UsedOutdatedData
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import arrow.core.Either
|
|||
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.clore.CloreMigrationBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
|
@ -378,4 +379,62 @@ internal class TokenDetailsStateFactory(
|
|||
}.toImmutableList(),
|
||||
)
|
||||
}
|
||||
|
||||
// region Clore migration
|
||||
// TODO: Remove after Clore migration ends ([REDACTED_TASK_KEY])
|
||||
|
||||
fun getStateWithCloreMigrationBottomSheet(
|
||||
message: String,
|
||||
signature: String,
|
||||
isSigningInProgress: Boolean,
|
||||
onMessageChange: (String) -> Unit,
|
||||
onSignClick: () -> Unit,
|
||||
onCopyClick: () -> Unit,
|
||||
onOpenPortalClick: () -> Unit,
|
||||
): TokenDetailsState {
|
||||
return currentStateProvider().copy(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
content = CloreMigrationBottomSheetConfig(
|
||||
message = message,
|
||||
signature = signature,
|
||||
isSigningInProgress = isSigningInProgress,
|
||||
onMessageChange = onMessageChange,
|
||||
onSignClick = onSignClick,
|
||||
onCopyClick = onCopyClick,
|
||||
onOpenPortalClick = onOpenPortalClick,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getStateWithUpdatedCloreMigrationSignature(signature: String): TokenDetailsState {
|
||||
val state = currentStateProvider()
|
||||
val bottomSheetConfig = state.bottomSheetConfig ?: return state
|
||||
val content = bottomSheetConfig.content as? CloreMigrationBottomSheetConfig ?: return state
|
||||
|
||||
return state.copy(
|
||||
bottomSheetConfig = bottomSheetConfig.copy(
|
||||
content = content.copy(
|
||||
signature = signature,
|
||||
isSigningInProgress = false,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getStateWithCloreMigrationSigning(): TokenDetailsState {
|
||||
val state = currentStateProvider()
|
||||
val bottomSheetConfig = state.bottomSheetConfig ?: return state
|
||||
val content = bottomSheetConfig.content as? CloreMigrationBottomSheetConfig ?: return state
|
||||
|
||||
return state.copy(
|
||||
bottomSheetConfig = bottomSheetConfig.copy(
|
||||
content = content.copy(isSigningInProgress = true),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// endregion Clore migration
|
||||
}
|
||||
|
|
@ -35,6 +35,8 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.T
|
|||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsDialogs
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsTopAppBar
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenInfoBlock
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.clore.CloreMigrationBottomSheet
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.clore.CloreMigrationBottomSheetConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.express.ExpressStatusBottomSheet
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.staking.TokenStakingBlock
|
||||
import com.tangem.features.markets.token.block.TokenMarketBlockComponent
|
||||
|
|
@ -45,7 +47,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
// TODO: Split to blocks [REDACTED_JIRA]
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
internal fun TokenDetailsScreen(
|
||||
state: TokenDetailsState,
|
||||
|
|
@ -164,17 +166,25 @@ internal fun TokenDetailsScreen(
|
|||
|
||||
TokenDetailsDialogs(state = state)
|
||||
|
||||
state.bottomSheetConfig?.let { config ->
|
||||
when (config.content) {
|
||||
is TokenReceiveBottomSheetConfig -> {
|
||||
TokenReceiveBottomSheet(config = config)
|
||||
}
|
||||
is ChooseAddressBottomSheetConfig -> {
|
||||
ChooseAddressBottomSheet(config = config)
|
||||
}
|
||||
is ExpressStatusBottomSheetConfig -> {
|
||||
ExpressStatusBottomSheet(config = config)
|
||||
}
|
||||
TokenDetailsBottomSheets(state = state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenDetailsBottomSheets(state: TokenDetailsState) {
|
||||
state.bottomSheetConfig?.let { config ->
|
||||
when (config.content) {
|
||||
is TokenReceiveBottomSheetConfig -> {
|
||||
TokenReceiveBottomSheet(config = config)
|
||||
}
|
||||
is ChooseAddressBottomSheetConfig -> {
|
||||
ChooseAddressBottomSheet(config = config)
|
||||
}
|
||||
is ExpressStatusBottomSheetConfig -> {
|
||||
ExpressStatusBottomSheet(config = config)
|
||||
}
|
||||
is CloreMigrationBottomSheetConfig -> {
|
||||
CloreMigrationBottomSheet(config = config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,220 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.clore
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R as CoreR
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.fields.SimpleTextField
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun CloreMigrationBottomSheet(config: TangemBottomSheetConfig) {
|
||||
TangemModalBottomSheet<CloreMigrationBottomSheetConfig>(
|
||||
config = config,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
endIconRes = CoreR.drawable.ic_close_24,
|
||||
onEndClick = config.onDismissRequest,
|
||||
)
|
||||
},
|
||||
) { content: CloreMigrationBottomSheetConfig ->
|
||||
CloreMigrationBottomSheetContent(content = content)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CloreMigrationBottomSheetContent(content: CloreMigrationBottomSheetConfig) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.warning_clore_migration_sheet_title),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.h3,
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.warning_clore_migration_sheet_description),
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.body2,
|
||||
modifier = Modifier.padding(horizontal = 8.dp),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
MessageField(
|
||||
placeholder = stringResourceSafe(R.string.warning_clore_migration_message_label),
|
||||
value = content.message,
|
||||
onValueChange = content.onMessageChange,
|
||||
buttonText = stringResourceSafe(R.string.warning_clore_migration_sign_button),
|
||||
onButtonClick = content.onSignClick,
|
||||
isButtonEnabled = content.message.isNotBlank() && !content.isSigningInProgress,
|
||||
isLoading = content.isSigningInProgress,
|
||||
)
|
||||
|
||||
SignatureField(
|
||||
placeholder = stringResourceSafe(R.string.warning_clore_migration_signature_label),
|
||||
value = content.signature,
|
||||
onCopyClick = content.onCopyClick,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
PrimaryButton(
|
||||
text = stringResourceSafe(R.string.warning_clore_migration_open_portal_button),
|
||||
onClick = content.onOpenPortalClick,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
private fun MessageField(
|
||||
placeholder: String,
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
buttonText: String,
|
||||
onButtonClick: () -> Unit,
|
||||
isButtonEnabled: Boolean,
|
||||
isLoading: Boolean,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
shape = TangemTheme.shapes.roundedCornersSmall,
|
||||
)
|
||||
.heightIn(min = 56.dp)
|
||||
.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
SimpleTextField(
|
||||
value = value,
|
||||
onValueChange = onValueChange,
|
||||
placeholder = TextReference.Str(placeholder),
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = false,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
text = TextReference.Str(buttonText),
|
||||
onClick = onButtonClick,
|
||||
isEnabled = isButtonEnabled,
|
||||
isLoading = isLoading,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("FunctionSignature")
|
||||
@Composable
|
||||
private fun SignatureField(placeholder: String, value: String, onCopyClick: () -> Unit) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
shape = TangemTheme.shapes.roundedCornersSmall,
|
||||
)
|
||||
.heightIn(min = 56.dp)
|
||||
.padding(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
SimpleTextField(
|
||||
value = value,
|
||||
onValueChange = {},
|
||||
placeholder = TextReference.Str(placeholder),
|
||||
modifier = Modifier.weight(1f),
|
||||
readOnly = true,
|
||||
singleLine = false,
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
SecondarySmallButton(
|
||||
config = SmallButtonConfig(
|
||||
text = TextReference.Res(R.string.warning_clore_migration_copy_button),
|
||||
onClick = onCopyClick,
|
||||
isEnabled = value.isNotBlank(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun Preview_CloreMigrationBottomSheet() {
|
||||
TangemThemePreview {
|
||||
val config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
content = CloreMigrationBottomSheetConfig(
|
||||
message = "Claim request for CLORE tokens to Ethereum address " +
|
||||
"0x742d35Cc6634C0532925a3b844Bc9e7595f60126 from CEsMERNgBVPo9Dkc99pRDMPD3mxwPMxHZi",
|
||||
signature = "H4sIAAAAAAAEAGNgGAWjYBSMglEwCkYBHQEA",
|
||||
isSigningInProgress = false,
|
||||
onMessageChange = {},
|
||||
onSignClick = {},
|
||||
onCopyClick = {},
|
||||
onOpenPortalClick = {},
|
||||
),
|
||||
onDismissRequest = {},
|
||||
)
|
||||
|
||||
CloreMigrationBottomSheet(config)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
private fun Preview_CloreMigrationBottomSheet_Empty() {
|
||||
TangemThemePreview {
|
||||
val config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
content = CloreMigrationBottomSheetConfig(
|
||||
message = "",
|
||||
signature = "",
|
||||
isSigningInProgress = false,
|
||||
onMessageChange = {},
|
||||
onSignClick = {},
|
||||
onCopyClick = {},
|
||||
onOpenPortalClick = {},
|
||||
),
|
||||
onDismissRequest = {},
|
||||
)
|
||||
|
||||
CloreMigrationBottomSheet(config)
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.clore
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
|
||||
@Immutable
|
||||
data class CloreMigrationBottomSheetConfig(
|
||||
val message: String = "",
|
||||
val signature: String = "",
|
||||
val isSigningInProgress: Boolean = false,
|
||||
val onMessageChange: (String) -> Unit,
|
||||
val onSignClick: () -> Unit,
|
||||
val onCopyClick: () -> Unit,
|
||||
val onOpenPortalClick: () -> Unit,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
|
@ -202,6 +202,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
navigationAction = navigationAction,
|
||||
apy = apy,
|
||||
)
|
||||
is NavigationAction.CloreMigration -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -298,6 +299,7 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
},
|
||||
)
|
||||
}
|
||||
is NavigationAction.CloreMigration -> return
|
||||
}
|
||||
analyticsEventHandler.send(event)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
|||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.requireColdWallet
|
||||
|
|
@ -35,6 +36,7 @@ import com.tangem.domain.staking.multi.MultiStakingBalanceFetcher
|
|||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.Program
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.PromotionBannerClicked
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
|
||||
import com.tangem.domain.wallets.models.UnlockWalletsError
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
|
|
@ -65,6 +67,8 @@ internal interface WalletWarningsClickIntents {
|
|||
|
||||
fun onAddBackupCardClick()
|
||||
|
||||
fun onCloreMigrationClick(cryptoCurrencyStatus: CryptoCurrencyStatus)
|
||||
|
||||
fun onCloseAlreadySignedHashesWarningClick()
|
||||
|
||||
fun onGenerateMissedAddressesClick(missedAddressCurrencies: List<CryptoCurrency>)
|
||||
|
|
@ -146,6 +150,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
prepareAndStartOnboardingProcess()
|
||||
}
|
||||
|
||||
override fun onCloreMigrationClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
val userWallet = getSelectedUserWallet() ?: return
|
||||
|
||||
router.openTokenDetails(
|
||||
userWalletId = userWallet.walletId,
|
||||
currencyStatus = cryptoCurrencyStatus,
|
||||
navigationAction = NavigationAction.CloreMigration,
|
||||
)
|
||||
}
|
||||
|
||||
private fun prepareAndStartOnboardingProcess() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
getSelectedUserWallet()?.requireColdWallet()?.let {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ internal class WalletWarningsAnalyticsSender @Inject constructor(
|
|||
is WalletNotification.UsedOutdatedData,
|
||||
is WalletNotification.UnlockVisaAccess,
|
||||
is WalletNotification.Warning.YeildSupplyApprove, // TODO apply correct event
|
||||
is WalletNotification.CloreMigration,
|
||||
-> null
|
||||
is WalletNotification.FinishWalletActivation -> {
|
||||
val activationState = if (warning.isBackupExists) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import com.tangem.feature.wallet.impl.R
|
|||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
import com.tangem.utils.extensions.addIf
|
||||
import com.tangem.utils.extensions.isPositive
|
||||
import com.tangem.utils.extensions.orZero
|
||||
|
|
@ -317,6 +318,29 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
element = WalletNotification.Warning.SomeNetworksUnreachable,
|
||||
condition = flattenCurrencies.hasUnreachableNetworks(),
|
||||
)
|
||||
|
||||
addCloreMigrationNotification(flattenCurrencies, clickIntents)
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addCloreMigrationNotification(
|
||||
flattenCurrencies: Lce<TokenListError, List<CryptoCurrencyStatus>>,
|
||||
clickIntents: WalletClickIntents,
|
||||
) {
|
||||
val cloreCurrency = flattenCurrencies.findCloreCurrency() ?: return
|
||||
|
||||
add(
|
||||
WalletNotification.CloreMigration(
|
||||
onStartMigrationClick = { clickIntents.onCloreMigrationClick(cloreCurrency) },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun Lce<TokenListError, List<CryptoCurrencyStatus>>.findCloreCurrency(): CryptoCurrencyStatus? {
|
||||
val currencies = getOrNull(isPartialContentAccepted = true) ?: return null
|
||||
|
||||
return currencies.find { currencyStatus ->
|
||||
BlockchainUtils.isClore(currencyStatus.currency.network.rawId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addPushReminderNotification(
|
||||
|
|
|
|||
|
|
@ -414,4 +414,18 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
|
||||
data class CloreMigration(
|
||||
val onStartMigrationClick: () -> Unit,
|
||||
) : WalletNotification(
|
||||
config = NotificationConfig(
|
||||
title = resourceReference(com.tangem.core.res.R.string.warning_clore_migration_title),
|
||||
subtitle = resourceReference(com.tangem.core.res.R.string.warning_clore_migration_sheet_description),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
|
||||
text = resourceReference(com.tangem.core.res.R.string.warning_clore_migration_button),
|
||||
onClick = onStartMigrationClick,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
# https://github.com/tangem/tangem-sdk-android/
|
||||
# https://github.com/tangem/vico
|
||||
|
||||
tangemBlockchainSdk = "releases-5.32-1388"
|
||||
tangemBlockchainSdk = "releases-5.32-1404"
|
||||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "releases-5.32-574"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 28079b094a4518de068161226576747089519918
|
||||
Subproject commit cfc2c0ab47e2e821f38f463f32f120d620804c72
|
||||
Loading…
Add table
Add a link
Reference in a new issue