Updated on 2026-08-14
This commit is contained in:
commit
8af3e349a7
49 changed files with 837 additions and 488 deletions
|
|
@ -1,6 +1,9 @@
|
|||
package com.tangem.common.ui.amountScreen.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
|
|
@ -127,6 +130,8 @@ private fun AmountInfoMain(amountUM: AmountState, modifier: Modifier = Modifier)
|
|||
AnimatedContent(
|
||||
targetState = amountUM,
|
||||
modifier = modifier,
|
||||
contentKey = { amountUM.javaClass }, // Show animation only when the state type changes [Empty -> Data]
|
||||
transitionSpec = { fadeIn().togetherWith(fadeOut()) },
|
||||
) { currentAmount ->
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(2.dp),
|
||||
|
|
|
|||
|
|
@ -274,6 +274,14 @@ sealed class NotificationUM(val config: NotificationConfig) {
|
|||
title = resourceReference(id = R.string.yield_module_balance_info_sheet_title, wrappedList(tokenName)),
|
||||
subtitle = resourceReference(id = R.string.yield_module_balance_info_sheet_subtitle),
|
||||
)
|
||||
|
||||
data class YieldSupplyNotAllAmountSupplied(val formattedAmount: String, val symbol: String) : Warning(
|
||||
title = resourceReference(
|
||||
id = R.string.yield_module_amount_not_transfered_to_aave_title,
|
||||
formatArgs = wrappedList(formattedAmount, symbol),
|
||||
),
|
||||
subtitle = TextReference.EMPTY,
|
||||
)
|
||||
}
|
||||
|
||||
open class Info(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.yieldSupplyKey
|
||||
import com.tangem.domain.models.currency.yieldSupplyNotAllAmountSupplied
|
||||
import com.tangem.domain.models.staking.YieldBalance
|
||||
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
|
|
@ -271,8 +270,7 @@ class TokenItemStateConverter(
|
|||
isFlickering = status.value.isFlickering(),
|
||||
icons = buildList {
|
||||
if (status.value.yieldSupplyStatus?.isActive == true &&
|
||||
status.value.yieldSupplyStatus?.isAllowedToSpend == false ||
|
||||
status.yieldSupplyNotAllAmountSupplied()
|
||||
status.value.yieldSupplyStatus?.isAllowedToSpend == false
|
||||
) {
|
||||
TokenItemState.FiatAmountState.Content.IconUM(
|
||||
iconRes = R.drawable.ic_alert_triangle_20,
|
||||
|
|
|
|||
|
|
@ -1675,31 +1675,82 @@
|
|||
<string name="xtz_withdrawal_message_ignore">Nein, alles senden</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Um %s XTZ reduziert</string>
|
||||
<string name="xtz_withdrawal_message_warning">Damit Sie beim nächsten Aufladen Ihrer Brieftasche keine erhöhte Provision zahlen, soll der Betrag um %s XTZ reduziert werden</string>
|
||||
<string name="yield_module_alert_description">Wenn der Yield-Modus aktiviert ist, gehen alle zukünftigen Einzahlungen an diese Adresse an Aave. Du kannst über Dein Guthaben weiterhin frei verfügen.</string>
|
||||
<string name="yield_module_alert_title">Deine %s wird an Aave übermittelt</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">Die Bereitstellung von %1$s %2$s für Aave steht aus</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Genehmigen</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Die Genehmigung Deines Tokens wurde widerrufen. Erteilen diese erneut, um die Servicefunktionalität fortzusetzen.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Genehmigung erforderlich</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">Die Gebühr wird abgezogen und Dein Vermögen wird erneut verliehen.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">Um weiterhin Geld verdienen zu können, ist eine Genehmigung erforderlich.</string>
|
||||
<string name="yield_module_approve_sheet_title">Genehmigung bestätigen</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">Deine Gelder werden derzeit dem Aave-Protokoll bereitgestellt, Du kannst sie jedoch jederzeit verwalten.</string>
|
||||
<string name="yield_module_balance_info_sheet_title">Deine%s ist in Aave hinterlegt</string>
|
||||
<string name="yield_module_chart_loading_error">Chart konnte nicht geladen werden...</string>
|
||||
<string name="yield_module_deposit_error_notification_title">Der erhaltene Betrag %1$s %2$s wurde nicht auf Aave eingezahlt.</string>
|
||||
<string name="yield_module_earn_badge">APY %1$s%%</string>
|
||||
<string name="yield_module_earn_sheet_available_title">Verfügbar</string>
|
||||
<string name="yield_module_earn_sheet_current_apy_title">Aktueller effektiver Jahreszins</string>
|
||||
<string name="yield_module_earn_sheet_fee_description">Beim Aufladen zum Ausleihen wird eine Netzwerkgebühr von maximal %1$s vom Guthaben abgezogen.</string>
|
||||
<string name="yield_module_earn_sheet_high_fee_description">Die Netzwerkgebühr ist derzeit zu hoch, um die Kreditvergabe durchzuführen. Die Mittel werden bereitgestellt, sobald sie auf %1$s oder darunter fallen. </string>
|
||||
<string name="yield_module_earn_sheet_my_funds_title">Meine Mittel</string>
|
||||
<string name="yield_module_earn_sheet_provider_description">Dein %1$s ist nun bei Aave hinterlegt und bringt Zinsen ein. Du besitzt einen %2$s-Token, der Dein Guthaben repräsentiert und mit der Zeit wächst. Wenn Du mehr Geld einzahlst, wird dieses an Aave weitergeleitet, um Zinsen abzüglich einer Transaktionsgebühr zu erwirtschaften.</string>
|
||||
<string name="yield_module_earn_sheet_title">Ertragsmodus</string>
|
||||
<string name="yield_module_earn_sheet_total_earnings_title">Gesamtverdienst</string>
|
||||
<string name="yield_module_earn_sheet_transfers_title">Übertragungen zu Aave</string>
|
||||
<string name="yield_module_explore_sheet_explore_aave_button_title">Entdecke Aave</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_note">Dies ist die aktuelle Liefergebühr auf %s. Die tatsächlichen Kosten werden auf der Registerkarte \"Aktivierung\" angezeigt.</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_title">Aktuelle Gebühr</string>
|
||||
<string name="yield_module_fee_policy_sheet_description">Alle zukünftigen %s-Einzahlungen werden automatisch an Aave geliefert, wobei die Transaktionsgebühr abgezogen wird.</string>
|
||||
<string name="yield_module_fee_policy_sheet_fee_note">Bei jeder zukünftigen Aufladung wird eine Netzwerkgebühr von ungefähr %1$s (%2$s) abgezogen, die Ihr Limit von %3$s (%4$s) nicht überschreitet.</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_note">Wenn die Netzwerkgebühren über die maximale Gebühr steigen, wird die Transaktion erst durchgeführt, wenn diese sinken. Du kannst dieses Limit später ändern.</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_title">Maximale Gebühr</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">Dies ist die niedrigste Einzahlung, die an Aave gesendet werden kann. Um Einzahlungen rentabel zu halten, verarbeiten wir sie nicht, wenn die Netzwerkgebühren 4 % des Betrags übersteigen.</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">Der Mindestbetrag wird aus der aktuellen Netzwerkgebühr berechnet, um sicherzustellen, dass er 4%% nicht überschreitet, was den Mindestbetrag %1$s (%2$s) ergibt.</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_title">Mindestaufladung</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">Gebührenpolitik</string>
|
||||
<string name="yield_module_high_fee_error">Die Netzwerkgebühr ist derzeit zu hoch. Warte, bis sie unter Dein Limit fällt.</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem erhebt außerdem eine Servicegebühr von 3% auf den erzielten Ertrag.</string>
|
||||
<string name="yield_module_high_fee_error">Deine Gelder werden automatisch an Aave überwiesen, sobald die Netzwerkgebühren niedriger sind oder Dein Guthaben den erforderlichen Mindestbetrag erreicht.</string>
|
||||
<string name="yield_module_historical_returns">Historische Renditen</string>
|
||||
<string name="yield_module_promo_screen_cash_out_title">Sofortige Auszahlung</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Die Freigabe für Deine Token im Yield-Modus wurde widerrufen. Öffne den Token, um die Berechtigung erneut zu erteilen.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Token-Genehmigung erforderlich</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Prüfe Deine Netzwerkverbindung</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Informationen zu den Netzwerkgebühren nicht erreichbar</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_subtitle">Jede Einzahlung, die Du tätigst, wird automatisch an Aave weitergeleitet.</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_title">Automatische Übertragung zu Aave</string>
|
||||
<string name="yield_module_promo_screen_cash_out_subtitle">Senden, tauschen oder verkaufen Deine Gelder sofort, wann immer Du willst.</string>
|
||||
<string name="yield_module_promo_screen_cash_out_title">Jederzeit Zugriff auf Dein Geld</string>
|
||||
<string name="yield_module_promo_screen_how_it_works_button_title">Wie funktioniert das?</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_subtitle">Aave ist ein dezentrales Protokoll, das einen Gesamtwert von über 81,9 Milliarden US-Dollar verwaltet.</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_title">Dezentral und selbstverwahrend</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">Durch die Nutzung dieses Dienstes erklärst Du Dich mit provider\n%1$s und %2$s einverstanden</string>
|
||||
<string name="yield_module_promo_screen_title">Mit Aave verbinden</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s • Variabler Zinssatz</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% • Variabler Zinssatz</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Durchschnitt %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Renditen des letzten Jahres</string>
|
||||
<string name="yield_module_rate_info_sheet_description">Der aktuelle Zinssatz ist immer variabel und wird automatisch vom Aave On-Chain-Smart-Contract auf der Grundlage von Angebot und Nachfrage in Echtzeit berechnet.</string>
|
||||
<string name="yield_module_rate_info_sheet_powered_by">Unterstützt durch</string>
|
||||
<string name="yield_module_rate_info_sheet_title">Der Zinssatz ist variabel</string>
|
||||
<string name="yield_module_receive_sheet_description">Wenn Du dein Guthaben auflädst, wird es automatisch an Aave weitergeleitet, um Zinsen zu verdienen. zur Deckung der Transaktionsgebühr wird ein Betrag von %s abgezogen.</string>
|
||||
<string name="yield_module_start_earning">Beginn des Verdienstes</string>
|
||||
<string name="yield_module_start_earning_sheet_description">Dein %s wird an Aave übermittelt, bleibt aber verwaltbar.</string>
|
||||
<string name="yield_module_start_earning_sheet_fee_policy">Siehe Gebührenrichtlinie</string>
|
||||
<string name="yield_module_start_earning_sheet_next_deposits">Deine nächste Aufladung wird automatisch an Aave weitergeleitet.</string>
|
||||
<string name="yield_module_status_active">Aktiv</string>
|
||||
<string name="yield_module_status_paused">Pausiert</string>
|
||||
<string name="yield_module_stop_earning">Deaktiviere den Yield-Modus</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">Wenn Du diese Option deaktivierst, wird Dein Geld von Aave auf %s in Deiner Wallet abgehoben und es werden keine Belohnungen mehr verdient.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">Die Netzwerkgebühr wird von dem Betrag, den Du abhebst, abgezogen.</string>
|
||||
<string name="yield_module_supply_apr">Effektiver Jahreszins für Versorgung</string>
|
||||
<string name="yield_module_token_details_earn_notification_apy">Effektiver Jahreszins</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Lass Dein Geld arbeiten – verdiene Zinsen auf Dein Guthaben.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Verdienst auf Dein Guthaben</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Zinsen fallen automatisch an</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Ertragsmodus</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Bearbeitung Deiner Einzahlung</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Lass dein Guthaben arbeiten</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automatisch</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Einzahlung von %1$s %2$s zur Deckung der Netzwerkgebühr für Transaktionen</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Die Gebühr %s kann nicht gedeckt werden</string>
|
||||
<string name="yield_module_unavailable_subtitle">Der Stakingservice ist derzeit nicht verfügbar. Bitte versuche es später erneut.</string>
|
||||
<string name="yield_module_unavailable_title">Einnahmen nicht verfügbar</string>
|
||||
<string name="yield_supply_chart_loading_error">Chart konnte nicht geladen werden...</string>
|
||||
|
|
|
|||
|
|
@ -1106,6 +1106,7 @@
|
|||
<string name="story_web3_title">Compatible con Web 3.0</string>
|
||||
<string name="sui_not_enough_coin_for_fee_description">Se requiere una transacción entrante de al menos %1$s para proceder</string>
|
||||
<string name="sui_not_enough_coin_for_fee_title">Fondos insuficientes</string>
|
||||
<string name="swap_approve_description">Al aprobar, permites que el contrato inteligente use tus tokens en futuras transacciones.</string>
|
||||
<string name="swap_fixed_rate">Tasa Fija</string>
|
||||
<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>
|
||||
|
|
@ -1400,6 +1401,7 @@
|
|||
<string name="wc_alert_wrong_card_title">Tenemos algún tipo de problema</string>
|
||||
<string name="wc_all_dapps_disconnected">Todas las dApps desconectadas</string>
|
||||
<string name="wc_allow_to_spend">Permitir gastar</string>
|
||||
<string name="wc_approve_description">Al aprobar, permites que la dApp o el contrato inteligente utilicen los tokens en futuras transacciones.</string>
|
||||
<string name="wc_common_address">Dirección</string>
|
||||
<string name="wc_common_connect">Conectar</string>
|
||||
<string name="wc_common_loading">Cargando</string>
|
||||
|
|
@ -1474,4 +1476,82 @@
|
|||
<string name="xtz_withdrawal_message_ignore">No, enviar todo</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Reducir en %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_warning">Para evitar pagar una comisión mayor la próxima vez que recargue su billetera, reduzca el importe en %s XTZ</string>
|
||||
<string name="yield_module_alert_description">Con el modo Rendimiento activo, todos los depósitos futuros a esta dirección irán a Aave. Puede seguir gestionando sus fondos libremente.</string>
|
||||
<string name="yield_module_alert_title">Su %s se suministra a Aave</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">El suministro de %1$s %2$s a Aave está pendiente</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Aprobar</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Se ha revocado la aprobación de su token. Concédalo de nuevo para reanudar el servicio.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Aprobación necesaria</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">Se le descontará la comisión y se le volverán a prestar sus activos.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">Para seguir ganando, se requiere aprobación.</string>
|
||||
<string name="yield_module_approve_sheet_title">Confirmar aprobación</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">Sus fondos se suministran actualmente al protocolo Aave, pero puede gestionarlos en cualquier momento.</string>
|
||||
<string name="yield_module_balance_info_sheet_title">Su %s está depositado en Aave</string>
|
||||
<string name="yield_module_chart_loading_error">No se puede cargar el gráfico...</string>
|
||||
<string name="yield_module_deposit_error_notification_title">La cantidad recibida, %1$s %2$s no fue suministrada a Aave.</string>
|
||||
<string name="yield_module_earn_badge">APY %1$s%%</string>
|
||||
<string name="yield_module_earn_sheet_available_title">Disponible</string>
|
||||
<string name="yield_module_earn_sheet_current_apy_title">APY actual</string>
|
||||
<string name="yield_module_earn_sheet_fee_description">En las recargas para préstamos, se deducirá del saldo una comisión de red no superior a %1$s.</string>
|
||||
<string name="yield_module_earn_sheet_high_fee_description">La tasa de red es actualmente demasiado alta para ejecutar préstamos. Los fondos se suministrarán una vez que baje a %1$s o menos.</string>
|
||||
<string name="yield_module_earn_sheet_my_funds_title">Mis fondos</string>
|
||||
<string name="yield_module_earn_sheet_provider_description">Su %1$s está ahora depositado en Aave y devenga intereses. Tiene un token%2$s, que representa su saldo y crece con el tiempo. Cuando deposite más fondos, estos se suministrarán a Aave para ganar intereses, menos una comisión por transacción.</string>
|
||||
<string name="yield_module_earn_sheet_title">Modo de rendimiento</string>
|
||||
<string name="yield_module_earn_sheet_total_earnings_title">Ganancias totales</string>
|
||||
<string name="yield_module_earn_sheet_transfers_title">Transferencias a Aave</string>
|
||||
<string name="yield_module_explore_sheet_explore_aave_button_title">Explore Aave</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_note">Esta es la tarifa de suministro actual en %s. El coste real se mostrará en la pestaña de activación.</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_title">Tarifa actual</string>
|
||||
<string name="yield_module_fee_policy_sheet_description">Todos los depósitos futuros %s se proporcionarán a Aave automáticamente, con la tarifa de transacción deducida.</string>
|
||||
<string name="yield_module_fee_policy_sheet_fee_note">Se deducirá una comisión de red aproximada de %1$s (%2$s) de cada recarga futura, y no superará su límite de %3$s (%4$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_note">Si las tarifas de red superan la tarifa máxima, la transacción no se realizará hasta que disminuyan. Puede cambiar este límite más adelante.</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_title">Tarifa máxima</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">El monto mínimo se calcula a partir de la tarifa de red actual para garantizar que no exceda 4%%, lo que hace que el mínimo sea %1$s (%2$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_title">Recarga mínima</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">Política de tarifas</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem también cobra una comisión de servicio del 3% sobre el rendimiento obtenido.</string>
|
||||
<string name="yield_module_high_fee_error">Sus fondos se suministrarán automáticamente a Aave una vez que las comisiones de red sean más bajas o su saldo alcance el importe mínimo requerido.</string>
|
||||
<string name="yield_module_historical_returns">Rendimientos históricos</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Se ha revocado la autorización para su token en el modo Rendimiento. Abra el token para volver a conceder el permiso.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Se necesita la aprobación de Token</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Compruebe su conexión de red</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Información de tarifas de red inaccesible</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_subtitle">Cada depósito que realice se suministrará a Aave automáticamente.</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_title">Transferencia automática a Aave</string>
|
||||
<string name="yield_module_promo_screen_cash_out_subtitle">Envíe, intercambie o venda sus fondos al instante, cuando quiera.</string>
|
||||
<string name="yield_module_promo_screen_cash_out_title">Acceda a sus fondos en cualquier momento</string>
|
||||
<string name="yield_module_promo_screen_how_it_works_button_title">¿Cómo funciona?</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_subtitle">Aave es un protocolo descentralizado que administra más de 81.9 billones de dólares en valor total.</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_title">Descentralizado y autocustodiado</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">Al utilizar este servicio, usted acepta que el proveedor\n%1$s y %2$s</string>
|
||||
<string name="yield_module_promo_screen_title">Conectar Aave</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% - Tipo de interés variable</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Promedio %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Resultados del año pasado</string>
|
||||
<string name="yield_module_rate_info_sheet_description">La tasa de interés actual siempre es variable y calculada automáticamente por el contrato inteligente onchain de Aave, en función de la oferta y la demanda en tiempo real.</string>
|
||||
<string name="yield_module_rate_info_sheet_powered_by">Desarrollado por</string>
|
||||
<string name="yield_module_rate_info_sheet_title">El tipo de interés es variable</string>
|
||||
<string name="yield_module_receive_sheet_description">Cuando recargue, sus fondos se enviarán automáticamente a Aave para comenzar a ganar intereses. %s se deducirá para cubrir la tarifa de transacción.</string>
|
||||
<string name="yield_module_start_earning">Suministro de activos</string>
|
||||
<string name="yield_module_start_earning_sheet_description">Su %s se suministrará a Aave, pero seguirá siendo gestionable.</string>
|
||||
<string name="yield_module_start_earning_sheet_fee_policy">Ver política de tarifas</string>
|
||||
<string name="yield_module_start_earning_sheet_next_deposits">Sus próximas recargas se suministrarán automáticamente a Aave.</string>
|
||||
<string name="yield_module_status_active">Activo</string>
|
||||
<string name="yield_module_status_paused">En pausa</string>
|
||||
<string name="yield_module_stop_earning">Desactivar el modo de rendimiento</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">Al desactivar esto, retirará sus fondos de Aave a %s en su billetera y dejará de ganar recompensas.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">La comisión de red se deducirá del importe que retire.</string>
|
||||
<string name="yield_module_supply_apr">Suministro APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_apy">APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Deje que sus fondos hagan el trabajo mientras usted mantiene el control.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Los intereses se devengan automáticamente</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Modo de rendimiento</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Procesando su depósito</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Haga que sus activos trabajen para usted</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automático</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Deposite algo de %1$s %2$s para cubrir la tarifa de red para las transacciones</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">No se puede cubrir la tarifa %s</string>
|
||||
<string name="yield_module_unavailable_subtitle">El servicio de intereses no está disponible en este momento. Vuelva a intentarlo más tarde.</string>
|
||||
<string name="yield_module_unavailable_title">Ganancias no disponibles</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1080,6 +1080,7 @@
|
|||
<string name="story_web3_title">Compatible avec Web 3.0</string>
|
||||
<string name="sui_not_enough_coin_for_fee_description">Une transaction entrante d\'au moins de %1$s est requise pour continuer</string>
|
||||
<string name="sui_not_enough_coin_for_fee_title">Fonds insuffisants</string>
|
||||
<string name="swap_approve_description">En approuvant, vous autorisez le contrat intelligent à utiliser vos jetons dans de futures transactions.</string>
|
||||
<string name="swap_fixed_rate">Taux fixe</string>
|
||||
<string name="swap_give_permission_fee_footer">Le réseau facturera des frais d\'approbation de jeton pour vérifier que vous autorisez l\'utilisation de votre jeton pour l\'échange.</string>
|
||||
<string name="swap_promo_text">Échangez plus de jetons à de meilleurs taux directement dans votre portefeuille.</string>
|
||||
|
|
@ -1386,6 +1387,7 @@
|
|||
<string name="wc_alert_wrong_card_title">Nous avons un problème.</string>
|
||||
<string name="wc_all_dapps_disconnected">Toutes les dApps sont déconnectées</string>
|
||||
<string name="wc_allow_to_spend">Autoriser à dépenser</string>
|
||||
<string name="wc_approve_description">En approuvant, vous autorisez la dApp ou le contrat intelligent à utiliser les jetons dans de futures transactions.</string>
|
||||
<string name="wc_common_address">Adresse</string>
|
||||
<string name="wc_common_connect">Connecter</string>
|
||||
<string name="wc_common_loading">Chargement</string>
|
||||
|
|
@ -1453,4 +1455,80 @@
|
|||
<string name="xtz_withdrawal_message_ignore">Non, envoyer toute la somme</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Réduire de %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_warning">Pour ne pas payer un fraid de commissions élevé la prochaine fois que vous rechargez votre portefeuille, veuillez réduire le montant de %s XTZ</string>
|
||||
<string name="yield_module_alert_description">Vos fonds sont actuellement fournis au protocole Aave, mais vous pouvez les gérer à tout moment.</string>
|
||||
<string name="yield_module_alert_title">Vos %s sont fournis à Aave.</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">Le transfert de %1$s %2$s vers Aave est en attente.</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Donnez votre accord</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Un problème est survenu lors de votre précédente approbation, nous avons donc besoin d\'une nouvelle approbation. Choisissez comment vous souhaitez procéder.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Autorisation nécessaire</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">Les frais seront prélevés et vos actifs seront à nouveau prêtés.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">Pour continuer à percevoir des revenus, une autorisation est nécessaire.</string>
|
||||
<string name="yield_module_approve_sheet_title">Confirmer l\'approbation</string>
|
||||
<string name="yield_module_balance_info_sheet_title">Vos %s sont déposés dans Aave.</string>
|
||||
<string name="yield_module_chart_loading_error">Impossible de charger le graphique...</string>
|
||||
<string name="yield_module_deposit_error_notification_title">Le montant reçu, %1$s %2$s, n\'a pas été fourni à Aave.</string>
|
||||
<string name="yield_module_earn_badge">APY %1$s%%</string>
|
||||
<string name="yield_module_earn_sheet_available_title">Disponible</string>
|
||||
<string name="yield_module_earn_sheet_current_apy_title">APY actuel</string>
|
||||
<string name="yield_module_earn_sheet_fee_description">Lors du rechargement pour le dépôt, des frais de réseau ne dépassant pas %1$s seront déduits du solde.</string>
|
||||
<string name="yield_module_earn_sheet_high_fee_description">Les frais de réseau sont actuellement trop élevés pour permettre l\'exécution des prêts. Les fonds seront versés dès qu\'ils auront baissé à %1$s ou moins.</string>
|
||||
<string name="yield_module_earn_sheet_my_funds_title">Mes fonds</string>
|
||||
<string name="yield_module_earn_sheet_provider_description">Vos %1$s sont désormais déposés chez Aave et rapportent des intérêts. Vous détenez %2$s tokens, ce qui représente votre solde et augmente au fil du temps. Lorsque vous déposez davantage de fonds, ceux-ci sont fournis à Aave afin de rapporter des intérêts, moins les frais de transaction.</string>
|
||||
<string name="yield_module_earn_sheet_title">Gagner</string>
|
||||
<string name="yield_module_earn_sheet_total_earnings_title">Total des gains</string>
|
||||
<string name="yield_module_earn_sheet_transfers_title">Transferts vers Aave</string>
|
||||
<string name="yield_module_explore_sheet_explore_aave_button_title">Découvrez Aave</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_note">Il s\'agit des frais d\'approvisionnement actuels sur %s. Le coût réel sera indiqué dans l\'onglet Activation.</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_title">Frais actuels</string>
|
||||
<string name="yield_module_fee_policy_sheet_description">Tous les futurs dépôts %s seront automatiquement fournis à Aave, après déduction des frais de transaction.</string>
|
||||
<string name="yield_module_fee_policy_sheet_fee_note">Des frais de réseau d\'environ %1$s (%2$s) seront déduits de chaque recharge future, sans dépasser votre limite de %3$s (%4$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_note">Si les frais de réseau dépassent le montant maximal, la transaction ne sera pas effectuée tant qu\'ils n\'auront pas diminué. Vous pouvez modifier cette limite ultérieurement.</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_title">Frais maximaux</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">Le montant minimum est calculé à partir des frais de réseau actuels afin de garantir qu\'il ne dépasse pas 4 %, ce qui donne un minimum de %1$s (%2$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_title">Recharge minimale</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">Politique tarifaire</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem prélève également des frais de service de 3% sur les revenus générés.</string>
|
||||
<string name="yield_module_high_fee_error">Vos fonds seront automatiquement transférés vers Aave dès que les frais de réseau seront moins élevés ou que votre solde atteindra le montant minimum requis.</string>
|
||||
<string name="yield_module_historical_returns">Rendements historiques</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Approbations de tokens nécessaires</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Vérifiez votre connexion réseau.</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Informations sur les frais de réseau inaccessibles</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_subtitle">Chaque dépôt que vous effectuez sera automatiquement transféré à Aave.</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_title">Transfert automatique vers Aave</string>
|
||||
<string name="yield_module_promo_screen_cash_out_subtitle">Envoyez, échangez ou vendez vos fonds instantanément, quand vous le souhaitez.</string>
|
||||
<string name="yield_module_promo_screen_cash_out_title">Accédez à vos fonds à tout moment</string>
|
||||
<string name="yield_module_promo_screen_how_it_works_button_title">Comment ça marche ?</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_subtitle">Aave est un protocole décentralisé qui gère plus de 81,9 milliards de dollars en valeur totale.</string>
|
||||
<string name="yield_module_promo_screen_self_custodial_title">Décentralisé et auto-détenu</string>
|
||||
<string name="yield_module_promo_screen_terms_disclaimer">En utilisant ce service, vous acceptez les conditions générales du fournisseur %1$s et %2$s.</string>
|
||||
<string name="yield_module_promo_screen_title">Connecter Aave</string>
|
||||
<string name="yield_module_promo_screen_variable_rate_info">Aave %1$s%% • Taux d\'intérêt variable</string>
|
||||
<string name="yield_module_provider">Aave</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_average">Moyenne %s</string>
|
||||
<string name="yield_module_rate_info_sheet_chart_title">Rendements de l\'année dernière</string>
|
||||
<string name="yield_module_rate_info_sheet_description">Le taux d\'intérêt actuel est toujours variable et calculé automatiquement par le contrat intelligent Aave, en fonction de l\'offre et de la demande en temps réel.</string>
|
||||
<string name="yield_module_rate_info_sheet_powered_by">Alimenté par</string>
|
||||
<string name="yield_module_rate_info_sheet_title">Le taux d\'intérêt est variable.</string>
|
||||
<string name="yield_module_receive_sheet_description">Lorsque vous effectuez un dépôt, vos fonds sont automatiquement transférés vers Aave afin de commencer à générer des intérêts. %s sera déduit pour couvrir les frais de transaction.</string>
|
||||
<string name="yield_module_start_earning">Actifs d\'approvisionnement</string>
|
||||
<string name="yield_module_start_earning_sheet_description">Vos %s seront fournis à Aave, mais resteront gérables.</string>
|
||||
<string name="yield_module_start_earning_sheet_fee_policy">Voir la politique tarifaire</string>
|
||||
<string name="yield_module_start_earning_sheet_next_deposits">Vos prochains dépôts seront automatiquement transférés vers Aave.</string>
|
||||
<string name="yield_module_status_active">Actif</string>
|
||||
<string name="yield_module_status_paused">En pause</string>
|
||||
<string name="yield_module_stop_earning">Désactiver le mode rendement</string>
|
||||
<string name="yield_module_stop_earning_sheet_description">En désactivant cela, vos fonds seront retirés d\'Aave vers %s dans votre portefeuille et vous ne gagnerez plus de récompenses.</string>
|
||||
<string name="yield_module_stop_earning_sheet_fee_note">Les frais de réseau seront déduits du montant que vous retirez.</string>
|
||||
<string name="yield_module_supply_apr">Rendement annuel brut (APY)</string>
|
||||
<string name="yield_module_token_details_earn_notification_apy">APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Laissez vos fonds travailler pour vous tout en gardant le contrôle.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Les intérêts sont cumulés automatiquement.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Mode de rendement</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Traitement de votre dépôt</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Faites fructifier vos actifs</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Automatique</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Déposez %1$s %2$s pour couvrir les frais de réseau liés aux transactions.</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Impossible de couvrir les frais %s</string>
|
||||
<string name="yield_module_unavailable_subtitle">Le service d\'intérêt n\'est pas disponible pour le moment. Veuillez réessayer plus tard.</string>
|
||||
<string name="yield_module_unavailable_title">Gains indisponibles</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
<string name="account_archived_recover_error_title">アカウントを復元できません</string>
|
||||
<string name="account_archived_title">アーカイブ済み</string>
|
||||
<string name="account_could_not_archive">アカウントをアーカイブできませんでした。しばらくしてからもう一度お試しください。</string>
|
||||
<string name="account_could_not_archive_referral_program_message">このアカウントは紹介プログラムに参加しています。</string>
|
||||
<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>
|
||||
|
|
@ -42,6 +44,8 @@
|
|||
<string name="account_form_title_edit">アカウントを編集</string>
|
||||
<string name="account_label_tokens_info">%1$s ( %2$s内)</string>
|
||||
<string name="account_main_account_title">メインアカウント</string>
|
||||
<string name="account_recover_limit_dialog_description">すでにアクティブアカウントの上限%1$s件を超えています。復元するには、1つをアーカイブしてください。</string>
|
||||
<string name="account_recover_limit_dialog_title">アカウントを復元できません</string>
|
||||
<string name="account_recover_success_message">アカウントが回復しました</string>
|
||||
<string name="account_reorder_description">アカウントを長押しして並べ替える</string>
|
||||
<string name="account_unsaved_dialog_action_first">編集を続ける</string>
|
||||
|
|
@ -1738,14 +1742,13 @@
|
|||
<string name="xtz_withdrawal_message_warning">次回ウォレットにチャージするときに手数料の増加を避けるには、金額を%s XTZ減らしてください。</string>
|
||||
<string name="yield_module_alert_description">あなたの資金は現在Aaveプロトコルに供給されていますが、いつでも管理できます。</string>
|
||||
<string name="yield_module_alert_title">%sはAaveに供給されています</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">受け取った金額%1$s %2$sはAaveに入金されませんでした。</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">Aaveへの%1$s %2$sの供給は保留中です</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">承認する</string>
|
||||
<string name="yield_module_approve_needed_notification_description">前回の承認に問題があったため、新しい承認が必要です。手続き方法を選択してください。</string>
|
||||
<string name="yield_module_approve_needed_notification_title">承認が必要</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">手数料が差し引かれ、あなたの資産は再び貸し出されます。</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">引き続き収益を得るには承認が必要です。</string>
|
||||
<string name="yield_module_approve_sheet_title">承認を確定する</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">資産残高に関するテキスト [プレースホルダー]</string>
|
||||
<string name="yield_module_balance_info_sheet_title">あなたの%sはAaveに預けられています</string>
|
||||
<string name="yield_module_chart_loading_error">チャートを読み込めません・・</string>
|
||||
<string name="yield_module_deposit_error_notification_title">受け取った金額%1$s %2$sはAaveに入金されませんでした。</string>
|
||||
|
|
@ -1763,19 +1766,19 @@
|
|||
<string name="yield_module_fee_policy_sheet_current_fee_note">これは%sの現在の供給手数料です。実際のコストはアクティベーションタブに表示されます。</string>
|
||||
<string name="yield_module_fee_policy_sheet_current_fee_title">現在の手数料</string>
|
||||
<string name="yield_module_fee_policy_sheet_description">今後の%sの入金はすべて、取引手数料が差し引かれて自動的にAaveに供給されます。</string>
|
||||
<string name="yield_module_fee_policy_sheet_fee_note">今後のチャージごとに、おおよそ%1$s(%2$s)のネットワーク手数料が差し引かれますが、上限の%3$s(%4$s)を超えることはありません。</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_note">ネットワーク手数料が上限手数料を超えた場合、手数料が下がるまで取引は成立しません。この制限は後で変更できます。</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_title">最大手数料</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">これがAaveに供給できる最小金額です。利回りモードの収益性を保つため、ネットワーク手数料が金額の4%を超える場合は資産を供給しません。</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">最小金額は現在のネットワーク手数料に基づいて計算されており、手数料が4%を超えないように設定されています。その結果、最小金額は%1$s(%2$s)となります。</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_title">最低入金額</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">手数料ポリシー</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangemはまた、得られた利回りに対して3%のサービス手数料を差し引きます。</string>
|
||||
<string name="yield_module_high_fee_error">ネットワーク手数料が下がるか、残高が最低必要額に達すると、資金は自動的にAaveに供給されます。</string>
|
||||
<string name="yield_module_historical_returns">過去のリターン</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">ここに説明を入力してください。1〜3行が理想的です。[プレースホルダー]</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">トークンの承認が必要</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">ネットワーク接続を確認してください</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">ネットワーク手数料についての情報にアクセスできません</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_subtitle">アカウントへの入金はすべて自動的にAaveに貸し出されます。</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_subtitle">あなたが行うすべての入金は、自動的にAaveへ供給されます。</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_title">Aaveへの自動送金</string>
|
||||
<string name="yield_module_promo_screen_cash_out_subtitle">いつでも、即座に資金を送信、交換、売却できます。</string>
|
||||
<string name="yield_module_promo_screen_cash_out_title">いつでも資金にアクセス可能</string>
|
||||
|
|
|
|||
|
|
@ -395,6 +395,7 @@
|
|||
<string name="express_more_providers_soon">Больше провайдеров на подходе.\nСледите за обновлениями!</string>
|
||||
<string name="express_provider">Провайдер</string>
|
||||
<string name="express_provider_best_rate">Лучший курс</string>
|
||||
<string name="express_provider_great_rate">Лучший выбор</string>
|
||||
<string name="express_provider_max_amount">Доступно до %s</string>
|
||||
<string name="express_provider_min_amount">Доступно с %s</string>
|
||||
<string name="express_provider_not_available">Недоступно для этой пары</string>
|
||||
|
|
@ -1236,6 +1237,7 @@
|
|||
<string name="token_button_unavailability_reason_pending_transaction_send">Отправка средств станет доступной после завершения транзакции(-ий) в сети %s</string>
|
||||
<string name="token_button_unavailability_reason_sell_unavailable">Продажа %s в данный момент не поддерживается ни одним провайдером. Мы работаем над добавлением новых возможностей. Следите за нашими новостями.</string>
|
||||
<string name="token_button_unavailability_reason_staking_unavailable">Стейкинг %s в данный момент не поддерживается ни одним провайдером. Мы работаем над добавлением новых возможностей. Следите за нашими новостями.</string>
|
||||
<string name="token_button_unavailability_reason_yield_supply_approval">Разрешение было отозвано. Ваши средства остаются в Yield сервисе. Чтобы совершать операции, перейдите в Yield сервис и снова выдайте разрешение.</string>
|
||||
<string name="token_details_generate_xpub">Сгенерировать XPUB</string>
|
||||
<string name="token_details_hide_alert_hide">Скрыть</string>
|
||||
<string name="token_details_hide_alert_message">Вы скрываете токен с главного экрана, но в любой момент сможете добавить его обратно через страницу управления токенами.</string>
|
||||
|
|
@ -1494,6 +1496,7 @@
|
|||
<string name="wc_alert_wrong_card_title">Похоже, возникла проблема</string>
|
||||
<string name="wc_all_dapps_disconnected">Все dapps отключены</string>
|
||||
<string name="wc_allow_to_spend">Разрешение на использование</string>
|
||||
<string name="wc_approve_description">Подтверждая, вы разрешаете смарт-контракту использовать ваши токены в будущих транзакциях.</string>
|
||||
<string name="wc_common_address">Адрес</string>
|
||||
<string name="wc_common_connect">Подключение</string>
|
||||
<string name="wc_common_loading">Загрузка</string>
|
||||
|
|
@ -1569,14 +1572,15 @@
|
|||
<string name="xtz_withdrawal_message_ignore">Нет, отправить все</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Уменьшить на %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_warning">Чтобы не платить повышенную комиссию при следующем пополнении кошелька, уменьшите сумму на %s XTZ</string>
|
||||
<string name="yield_module_alert_description">Ваши средства сейчас размещены в протоколе AAVE, но вы можете управлять ими в любое время.</string>
|
||||
<string name="yield_module_alert_description">При активном режиме доходности все будущие депозиты на этот адрес будут направляться в Aave. Вы по-прежнему можете свободно управлять своими средствами.</string>
|
||||
<string name="yield_module_alert_title">Ваш %s внесён в Aave</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Выдать разрешение</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Что-то пошло не так с вашим предыдущим разрешением, поэтому требуется новое. Выберите, как хотите продолжить.</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Разрешение для вашего токена было отозвано. Выдайте его снова, чтобы продолжить работу сервиса.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Необходимо разрешение</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">Комиссия будет списана, и ваши активы снова начнут приносить доход.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">Чтобы продолжить зарабатывать, нужно выдать разрешение.</string>
|
||||
<string name="yield_module_approve_sheet_title">Подтвердить разрешение</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">Ваши средства в данный момент размещены в протоколе Aave, но вы можете воспользоваться ими в любое время.</string>
|
||||
<string name="yield_module_balance_info_sheet_title">Ваш %s внесён в Aave</string>
|
||||
<string name="yield_module_chart_loading_error">Невозможно загрузить график</string>
|
||||
<string name="yield_module_deposit_error_notification_title">Полученная сумма, %1$s %2$s, не была зачислена на Aave.</string>
|
||||
|
|
@ -1599,6 +1603,7 @@
|
|||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem взимает комиссию за обслуживание в размере 3% от полученного дохода.</string>
|
||||
<string name="yield_module_high_fee_error">Ваши средства будут автоматически переведены в Aave, как только комиссия сети снизится или баланс достигнет минимально необходимой суммы.</string>
|
||||
<string name="yield_module_historical_returns">Историческая доходность</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Разрешение для вашего токена в Yield сервисе было отозвано. Откройте токен, чтобы выдать разрешение снова.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Необходимо разрешение для токена</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Проверьте ваше интернет соединение</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Информация о комиссии недоступна</string>
|
||||
|
|
@ -1632,13 +1637,13 @@
|
|||
<string name="yield_module_token_details_earn_notification_apy">APY</string>
|
||||
<string name="yield_module_token_details_earn_notification_description">Пусть ваши деньги работают — зарабатывайте проценты на свой баланс.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_subtitle">Проценты начисляются автоматически.</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Доходность</string>
|
||||
<string name="yield_module_token_details_earn_notification_earning_on_your_balance_title">Режим доходности</string>
|
||||
<string name="yield_module_token_details_earn_notification_processing">Отправка ваших средств</string>
|
||||
<string name="yield_module_token_details_earn_notification_title">Пусть ваш баланс работает на вас!</string>
|
||||
<string name="yield_module_transfer_mode_automatic">Автоматически</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Внесите немного %1$s %2$s, чтобы покрыть комиссию сети за транзакции.</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Невозможно покрыть комиссию в %s</string>
|
||||
<string name="yield_module_unavailable_subtitle">Сервис начисления процентов в данный момент недоступен. Пожалуйста, попробуйте позже.</string>
|
||||
<string name="yield_module_unavailable_title">Данные о доходе недоступны</string>
|
||||
<string name="yield_module_unavailable_subtitle">Сервис доходности в данный момент недоступен. Пожалуйста, попробуйте позже.</string>
|
||||
<string name="yield_module_unavailable_title">Режим доходности недоступен</string>
|
||||
<string name="yield_supply_chart_loading_error">Невозможно загрузить график</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1086,6 +1086,7 @@
|
|||
<string name="story_web3_title">Web 3.0 сумісність</string>
|
||||
<string name="sui_not_enough_coin_for_fee_description">Для відправки потрібна вхідна транзакція на суму не менше %1$s</string>
|
||||
<string name="sui_not_enough_coin_for_fee_title">Недостатньо коштів</string>
|
||||
<string name="swap_approve_description">Підтверджуючи, ви дозволяєте смартконтракту використовувати ваші токени в майбутніх транзакціях.</string>
|
||||
<string name="swap_give_permission_fee_footer">Мережа стягує комісію за схвалення токену за підтвердження, що саме ви дозволяєте використовувати ваш токен для обміну.</string>
|
||||
<string name="swap_promo_text">Обмінюйте більше токенів за вигіднішим курсом прямо у своєму гаманці.</string>
|
||||
<string name="swap_promo_title">З\'явився новий провайдер обмінів!</string>
|
||||
|
|
@ -1366,6 +1367,7 @@
|
|||
<string name="wc_alert_wrong_card_description">Обрана не вірна картка або кільце</string>
|
||||
<string name="wc_alert_wrong_card_title">Схоже, виникла проблема</string>
|
||||
<string name="wc_all_dapps_disconnected">Усі dApps відключені</string>
|
||||
<string name="wc_approve_description">Підтверджуючи, ви дозволяєте dApp або смартконтракту використовувати токени в майбутніх транзакціях.</string>
|
||||
<string name="wc_common_address">Адреса</string>
|
||||
<string name="wc_common_connect">Підключення</string>
|
||||
<string name="wc_common_network">Мережа</string>
|
||||
|
|
@ -1431,4 +1433,5 @@
|
|||
<string name="xtz_withdrawal_message_reduce">Зменшити на %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_warning">Щоб не платити підвищену комісію при наступному поповненні гаманця, зменште суму на %s XTZ</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">Це найменший депозит, який можна надіслати в Aave. Щоб депозити залишалися прибутковими, ми не обробляємо їх, коли комісія мережі перевищує 4% від суми.</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Дозвіл для вашого токена в режимі Yield було відкликано. Відкрийте токен, щоб надати дозвіл знову.</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@
|
|||
<string name="common_enable">Enable</string>
|
||||
<string name="common_enabled">Enabled</string>
|
||||
<string name="common_error">Error</string>
|
||||
<string name="common_estimated_fee">Estimated fee</string>
|
||||
<string name="common_exchange">Swap</string>
|
||||
<string name="common_explore">Explore</string>
|
||||
<string name="common_explore_transaction_history">Explore transaction history</string>
|
||||
|
|
@ -484,7 +485,7 @@
|
|||
<string name="express_provider">Provider</string>
|
||||
<string name="express_provider_best_rate">Best rate</string>
|
||||
<string name="express_provider_fca_warning_list">FCA Warning List</string>
|
||||
<string name="express_provider_great_rate">Great rate</string>
|
||||
<string name="express_provider_great_rate">Best choice</string>
|
||||
<string name="express_provider_in_fca_warning_list">Provider in FCA warning list</string>
|
||||
<string name="express_provider_max_amount">Available up to %s</string>
|
||||
<string name="express_provider_min_amount">Available from %s</string>
|
||||
|
|
@ -1369,7 +1370,7 @@
|
|||
<string name="token_button_unavailability_reason_pending_transaction_send">Sending funds will be available once the pending transaction(s) in network %s is complete</string>
|
||||
<string name="token_button_unavailability_reason_sell_unavailable">Selling %s is not supported by current providers, but we are working to add more options.</string>
|
||||
<string name="token_button_unavailability_reason_staking_unavailable">Staking %s is not supported by current providers, but we are working to add more options.</string>
|
||||
<string name="token_button_unavailability_reason_yield_supply_approval">Text here</string>
|
||||
<string name="token_button_unavailability_reason_yield_supply_approval">Approval has been revoked. Your funds remain in Yield mode. To perform actions, please go to Yield mode and grant permission again.</string>
|
||||
<string name="token_details_generate_xpub">Generate XPUB</string>
|
||||
<string name="token_details_hide_alert_hide">Hide</string>
|
||||
<string name="token_details_hide_alert_message">You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page.</string>
|
||||
|
|
@ -1812,16 +1813,16 @@
|
|||
<string name="xtz_withdrawal_message_ignore">No, send all</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Reduce by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_warning">To avoid paying an increased commission the next time you top up your wallet, reduce the amount by %s XTZ</string>
|
||||
<string name="yield_module_alert_description">Your funds are currently supplied to the Aave protocol, but you can manage them at any time.</string>
|
||||
<string name="yield_module_alert_description">With Yield mode active, all future deposits to this address will go to Aave. You can still manage your funds freely.</string>
|
||||
<string name="yield_module_alert_title">Your %s is supplied to Aave</string>
|
||||
<string name="yield_module_amount_not_transfered_to_aave_title">Supplying %1$s %2$s to Aave is pending</string>
|
||||
<string name="yield_module_approve_needed_notification_cta">Give Approve</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Something went wrong with your previous approval, so we need a new one. Choose how you’d like to proceed.</string>
|
||||
<string name="yield_module_approve_needed_notification_description">Your token’s approval has been revoked. Grant it again to resume service functionality.</string>
|
||||
<string name="yield_module_approve_needed_notification_title">Approve needed</string>
|
||||
<string name="yield_module_approve_sheet_fee_note">The fee will be taken out, and your assets will be lent again.</string>
|
||||
<string name="yield_module_approve_sheet_subtitle">To continue earning, approval is required.</string>
|
||||
<string name="yield_module_approve_sheet_title">Confirm approval</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">Text about your money in balance [PLACEHOLDER]</string>
|
||||
<string name="yield_module_balance_info_sheet_subtitle">Your funds are currently supplied to the Aave protocol, but you can manage them at any time.</string>
|
||||
<string name="yield_module_balance_info_sheet_title">Your %s is deposited in Aave</string>
|
||||
<string name="yield_module_chart_loading_error">Unable to load chart...</string>
|
||||
<string name="yield_module_deposit_error_notification_title">The amount received, %1$s %2$s was not supplied to Aave.</string>
|
||||
|
|
@ -1832,7 +1833,7 @@
|
|||
<string name="yield_module_earn_sheet_high_fee_description">The network fee is currently too high to execute lending. Funds will be supplied once it drops to %1$s or below. </string>
|
||||
<string name="yield_module_earn_sheet_my_funds_title">My funds</string>
|
||||
<string name="yield_module_earn_sheet_provider_description">Your %1$s is now deposited in Aave and earning interest. You hold a%2$s token, which represents your balance and grows over time. When you deposit more funds, they\'ll be supplied to Aave to earn interest, minus a transaction fee.</string>
|
||||
<string name="yield_module_earn_sheet_title">Earn</string>
|
||||
<string name="yield_module_earn_sheet_title">Yield mode</string>
|
||||
<string name="yield_module_earn_sheet_total_earnings_title">Total earnings</string>
|
||||
<string name="yield_module_earn_sheet_transfers_title">Transfers to Aave</string>
|
||||
<string name="yield_module_explore_sheet_explore_aave_button_title">Explore Aave</string>
|
||||
|
|
@ -1842,14 +1843,14 @@
|
|||
<string name="yield_module_fee_policy_sheet_fee_note">An approximate network fee of %1$s (%2$s) will be deducted from each future top-up, and it won’t exceed your %3$s (%4$s) limit.</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_note">If network fees rise above maximum fee, the transaction won’t go through until they decrease. You can change this limit later.</string>
|
||||
<string name="yield_module_fee_policy_sheet_max_fee_title">Maximum fee</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">The minimum amount is calculated from the current network fee to ensure it does not exceed 4%, which makes the minimum %1$s (%2$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_note">The minimum amount is calculated from the current network fee to ensure it does not exceed 4%%, which makes the minimum %1$s (%2$s).</string>
|
||||
<string name="yield_module_fee_policy_sheet_min_amount_title">Minimum top-up</string>
|
||||
<string name="yield_module_fee_policy_sheet_title">Fee policy</string>
|
||||
<string name="yield_module_fee_policy_tangem_service_fee_title">Tangem also takes a 3% service fee on yield earned.</string>
|
||||
<string name="yield_module_high_fee_error">Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount.</string>
|
||||
<string name="yield_module_historical_returns">Historical returns</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Write description here. In one, two or three lines will be awesome. [PLACEHOLDER]</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Token approvals needed</string>
|
||||
<string name="yield_module_main_view_approve_notification_description">Approval for your token in the Yield mode has been revoked. Open the token to grant permission again.</string>
|
||||
<string name="yield_module_main_view_approve_notification_title">Token approval needed</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_description">Check your network connection</string>
|
||||
<string name="yield_module_network_fee_unreachable_notification_title">Network fee info unreachable</string>
|
||||
<string name="yield_module_promo_screen_auto_balance_subtitle">Every deposit you make will be supplied to Aave automatically.</string>
|
||||
|
|
@ -1872,7 +1873,7 @@
|
|||
<string name="yield_module_start_earning">Supply assets</string>
|
||||
<string name="yield_module_start_earning_sheet_description">Your %s will be supplied to Aave, but will remain manageable.</string>
|
||||
<string name="yield_module_start_earning_sheet_fee_policy">See fee policy</string>
|
||||
<string name="yield_module_start_earning_sheet_next_deposits">Your next deposits will be automatically supplied to Aave.</string>
|
||||
<string name="yield_module_start_earning_sheet_next_deposits">Your next top-ups will be automatically supplied to Aave.</string>
|
||||
<string name="yield_module_status_active">Active</string>
|
||||
<string name="yield_module_status_paused">Paused</string>
|
||||
<string name="yield_module_stop_earning">Disable yield mode</string>
|
||||
|
|
@ -1888,7 +1889,7 @@
|
|||
<string name="yield_module_transfer_mode_automatic">Automatic</string>
|
||||
<string name="yield_module_unable_to_cover_fee_description">Deposit some %1$s %2$s to cover the network fee for transactions</string>
|
||||
<string name="yield_module_unable_to_cover_fee_title">Unable to cover %s fee</string>
|
||||
<string name="yield_module_unavailable_subtitle">The interest service isn’t available at the moment. Please try again later.</string>
|
||||
<string name="yield_module_unavailable_title">Earnings unavailable</string>
|
||||
<string name="yield_module_unavailable_subtitle">The Yield mode service isn’t available at the moment. Please try again later.</string>
|
||||
<string name="yield_module_unavailable_title">Yield mode unavailable</string>
|
||||
<string name="yield_supply_chart_loading_error">Unable to load chart...</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ object TangemBlogUrlBuilder {
|
|||
|
||||
const val RESOURCE_TO_LEARN_ABOUT_APPROVING_IN_SWAP = "https://tangem.com/en/blog/post/give-revoke-permission/"
|
||||
|
||||
const val YIELD_SUPPLY_HOW_IT_WORKS_URL = "https://tangem.com/en/blog/post/savings-account"
|
||||
const val YIELD_SUPPLY_HOW_IT_WORKS_URL = "https://tangem.com/en/blog/post/yield-mode"
|
||||
const val YIELD_SUPPLY_TOS_URL = "https://aave.com/terms-of-service"
|
||||
const val YIELD_SUPPLY_PRIVACY_URL = "https://aave.com/privacy-policy"
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.tangem.data.tokens.repository
|
|||
|
||||
import com.tangem.blockchain.blockchains.polkadot.ExistentialDepositProvider
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchainsdk.utils.toBlockchain
|
||||
import com.tangem.data.tokens.converters.UtxoConverter
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
|
|
@ -19,7 +18,6 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|||
import com.tangem.utils.extensions.isZero
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal class DefaultCurrencyChecksRepository(
|
||||
|
|
@ -168,27 +166,4 @@ internal class DefaultCurrencyChecksRepository(
|
|||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getProtocolBalance(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): BigDecimal? {
|
||||
val token = cryptoCurrencyStatus.currency as? CryptoCurrency.Token ?: return null
|
||||
val isActive = cryptoCurrencyStatus.value.yieldSupplyStatus?.isActive ?: false
|
||||
if (!isActive) return null
|
||||
return runCatching {
|
||||
val walletManager = walletManagersFacade.getOrCreateWalletManager(
|
||||
userWalletId = userWalletId,
|
||||
blockchain = token.network.toBlockchain(),
|
||||
derivationPath = token.network.derivationPath.value,
|
||||
) ?: error("Wallet manager not found")
|
||||
walletManager.getEffectiveProtocolBalance(
|
||||
token = Token(
|
||||
symbol = token.symbol,
|
||||
contractAddress = token.contractAddress,
|
||||
decimals = token.decimals,
|
||||
),
|
||||
)
|
||||
}.onFailure(Timber::e).getOrThrow()
|
||||
}
|
||||
}
|
||||
|
|
@ -16,11 +16,13 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldMarketToken
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyMarketChartData
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.collections.map
|
||||
|
||||
internal class DefaultYieldSupplyRepository(
|
||||
|
|
@ -30,6 +32,8 @@ internal class DefaultYieldSupplyRepository(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : YieldSupplyRepository {
|
||||
|
||||
private val statusMap: MutableMap<String, YieldSupplyEnterStatus> = ConcurrentHashMap()
|
||||
|
||||
override suspend fun getCachedMarkets(): List<YieldMarketToken>? = withContext(dispatchers.io) {
|
||||
val cache = store.getSyncOrNull().orEmpty()
|
||||
val domain = cache.map(YieldMarketTokenConverter::convert)
|
||||
|
|
@ -97,6 +101,17 @@ internal class DefaultYieldSupplyRepository(
|
|||
).getOrThrow().isActive
|
||||
}
|
||||
|
||||
override suspend fun saveTokenProtocolStatus(
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
yieldSupplyEnterStatus: YieldSupplyEnterStatus,
|
||||
) {
|
||||
statusMap[cryptoCurrency.id.value] = yieldSupplyEnterStatus
|
||||
}
|
||||
|
||||
override fun getTokenProtocolStatus(cryptoCurrencyToken: CryptoCurrency): YieldSupplyEnterStatus? {
|
||||
return statusMap[cryptoCurrencyToken.id.value]
|
||||
}
|
||||
|
||||
private fun List<YieldMarketToken>.enrichNetworkIds(): List<YieldMarketToken> {
|
||||
val chainIdMap = Blockchain.entries.associate { it.getChainId() to it.toNetworkId() }
|
||||
return this.map { token ->
|
||||
|
|
|
|||
|
|
@ -73,10 +73,4 @@ sealed class CryptoCurrencyWarning {
|
|||
val requiredAmount: BigDecimal,
|
||||
val currencyDecimals: Int,
|
||||
) : CryptoCurrencyWarning()
|
||||
|
||||
data class YieldSupplyNotDepositedAmount(
|
||||
val currency: CryptoCurrency,
|
||||
val currencySymbol: String,
|
||||
val amount: BigDecimal,
|
||||
) : CryptoCurrencyWarning()
|
||||
}
|
||||
|
|
@ -51,8 +51,7 @@ class GetCurrencyWarningsUseCase(
|
|||
flowOf(currencyChecksRepository.getRentInfoWarning(userWalletId, currencyStatus)),
|
||||
flowOf(currencyChecksRepository.getExistentialDeposit(userWalletId, currency.network)),
|
||||
flowOf(currencyChecksRepository.getFeeResourceAmount(userWalletId, currency.network)),
|
||||
flowOf(currencyChecksRepository.getProtocolBalance(userWalletId, currencyStatus)),
|
||||
) { coinRelatedWarnings, maybeRentWarning, maybeEdWarning, maybeFeeResource, yieldSupplyProtocolBalance ->
|
||||
) { coinRelatedWarnings, maybeRentWarning, maybeEdWarning, maybeFeeResource ->
|
||||
setOfNotNull(
|
||||
maybeRentWarning,
|
||||
maybeEdWarning?.let { getExistentialDepositWarning(currency, it) },
|
||||
|
|
@ -63,7 +62,6 @@ class GetCurrencyWarningsUseCase(
|
|||
getBeaconChainShutdownWarning(rawId = currency.network.id.rawId),
|
||||
getAssetRequirementsWarning(userWalletId = userWalletId, currency = currency),
|
||||
getMigrationFromMaticToPolWarning(currency),
|
||||
getYieldSupplyWarning(cryptoCurrencyStatus = currencyStatus, yieldSupplyProtocolBalance),
|
||||
)
|
||||
}.flowOn(dispatchers.io)
|
||||
}
|
||||
|
|
@ -263,28 +261,6 @@ class GetCurrencyWarningsUseCase(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getYieldSupplyWarning(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
protocolBalance: BigDecimal?,
|
||||
): CryptoCurrencyWarning? {
|
||||
val value = cryptoCurrencyStatus.value
|
||||
val isActive = value.yieldSupplyStatus?.isActive == true
|
||||
val amount = value.amount
|
||||
|
||||
if (!isActive || protocolBalance == null || amount == null) return null
|
||||
|
||||
val notDepositedAmount = amount.minus(protocolBalance)
|
||||
return if (notDepositedAmount > BigDecimal.ZERO) {
|
||||
CryptoCurrencyWarning.YieldSupplyNotDepositedAmount(
|
||||
currency = cryptoCurrencyStatus.currency,
|
||||
amount = notDepositedAmount,
|
||||
currencySymbol = cryptoCurrencyStatus.currency.symbol,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun BigDecimal?.isZero(): Boolean {
|
||||
return this?.signum() == 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,11 +61,4 @@ interface CurrencyChecksRepository {
|
|||
currencyStatus: CryptoCurrencyStatus,
|
||||
balanceAfterTransaction: BigDecimal,
|
||||
): CryptoCurrencyWarning.Rent?
|
||||
|
||||
/**
|
||||
* Returns the YieldSupplied protocol balance in Aave for the given `cryptoCurrency`.
|
||||
* This represents the amount supplied to the protocol for the specified `userWalletId`
|
||||
* (e.g., aTokens balance). Returns null if not applicable or unknown.
|
||||
*/
|
||||
suspend fun getProtocolBalance(userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus): BigDecimal?
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.tangem.domain.yield.supply.models
|
||||
|
||||
enum class YieldSupplyEnterStatus {
|
||||
Enter,
|
||||
Exit,
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.yield.supply
|
|||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.yield.supply.models.YieldMarketToken
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyMarketChartData
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
|
@ -56,4 +57,30 @@ interface YieldSupplyRepository {
|
|||
*/
|
||||
@Throws
|
||||
suspend fun deactivateProtocol(cryptoCurrencyToken: CryptoCurrency.Token): Boolean
|
||||
|
||||
/**
|
||||
* Save the last user-initiated yield protocol action for the given currency.
|
||||
*
|
||||
* The saved value helps the UI render an intermediate "processing" state while waiting
|
||||
* for the definitive protocol status to be fetched from the network. This information
|
||||
* is transient and not intended to be persisted across app restarts.
|
||||
*
|
||||
* @param cryptoCurrencyToken the currency or token the action relates to
|
||||
* @param yieldSupplyEnterStatus the last action intent: [YieldSupplyEnterStatus.Enter] or [YieldSupplyEnterStatus.Exit]
|
||||
*/
|
||||
suspend fun saveTokenProtocolStatus(
|
||||
cryptoCurrencyToken: CryptoCurrency,
|
||||
yieldSupplyEnterStatus: YieldSupplyEnterStatus,
|
||||
)
|
||||
|
||||
/**
|
||||
* Get the last saved user-initiated yield protocol action for the given currency, if any.
|
||||
*
|
||||
* Used to determine whether the UI should display an intermediate "processing" state
|
||||
* until the protocol status retrieved from backend reflects the change.
|
||||
*
|
||||
* @param cryptoCurrencyToken the currency or token to query
|
||||
* @return the last action intent or null if nothing has been recorded
|
||||
*/
|
||||
fun getTokenProtocolStatus(cryptoCurrencyToken: CryptoCurrency): YieldSupplyEnterStatus?
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import arrow.core.Either
|
|||
import arrow.core.Either.Companion.catch
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.yieldSupplyKey
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.quotes.QuotesRepository
|
||||
|
|
@ -51,7 +52,9 @@ class YieldSupplyGetMaxFeeUseCase(
|
|||
?: error("Native fiat rate is missing")
|
||||
require(nativeFiatRate > BigDecimal.ZERO) { "Native fiat rate must be > 0" }
|
||||
|
||||
val marketToken = yieldSupplyRepository.getTokenStatus(token)
|
||||
val cachedMarketToken = yieldSupplyRepository.getCachedMarkets().orEmpty()
|
||||
.firstOrNull { it.yieldSupplyKey == token.yieldSupplyKey() }
|
||||
val marketToken = cachedMarketToken ?: yieldSupplyRepository.getTokenStatus(token)
|
||||
val maxFeeNative = marketToken.maxFeeNative.toBigDecimal()
|
||||
|
||||
val rateRatio = nativeFiatRate.divide(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
import com.tangem.domain.account.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
|
|
@ -37,6 +38,7 @@ internal class SwapSelectTokensModel @Inject constructor(
|
|||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val isAccountsModeEnabledUseCase: IsAccountsModeEnabledUseCase,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<SwapSelectTokensUM> = controller.state
|
||||
|
|
@ -77,10 +79,14 @@ internal class SwapSelectTokensModel @Inject constructor(
|
|||
selectedTokenItemState = selectedTokenItemState,
|
||||
onRemoveClick = ::onRemoveFromTokenClick,
|
||||
isAccountsMode = isAccountsMode,
|
||||
account = getAccountCurrencyStatusUseCase.invokeSync(
|
||||
userWalletId = params.userWalletId,
|
||||
currency = status.currency,
|
||||
).getOrNull()?.account,
|
||||
account = if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
getAccountCurrencyStatusUseCase.invokeSync(
|
||||
userWalletId = params.userWalletId,
|
||||
currency = status.currency,
|
||||
).getOrNull()?.account
|
||||
} else {
|
||||
null
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -104,10 +110,14 @@ internal class SwapSelectTokensModel @Inject constructor(
|
|||
transformer = SelectToTokenTransformer(
|
||||
selectedTokenItemState = selectedTokenItemState,
|
||||
isAccountsMode = isAccountsMode,
|
||||
account = getAccountCurrencyStatusUseCase.invokeSync(
|
||||
userWalletId = params.userWalletId,
|
||||
currency = status.currency,
|
||||
).getOrNull()?.account,
|
||||
account = if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
getAccountCurrencyStatusUseCase.invokeSync(
|
||||
userWalletId = params.userWalletId,
|
||||
currency = status.currency,
|
||||
).getOrNull()?.account
|
||||
} else {
|
||||
null
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -142,8 +142,8 @@ internal class SendAmountModel @Inject constructor(
|
|||
) { newCryptoCurrencyStatus, account, isAccountsMode ->
|
||||
maxAmountBoundary = MaxEnterAmountConverter().convert(newCryptoCurrencyStatus)
|
||||
cryptoCurrencyStatus = newCryptoCurrencyStatus
|
||||
initMinBoundary(cryptoCurrencyStatus, account, isAccountsMode)
|
||||
}.flowOn(dispatchers.default)
|
||||
initMinBoundary(newCryptoCurrencyStatus, account, isAccountsMode)
|
||||
}.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ internal class StakingModel @Inject constructor(
|
|||
}
|
||||
|
||||
private var isAccountInitialized: Boolean = true
|
||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus by Delegates.notNull()
|
||||
private lateinit var cryptoCurrencyStatus: CryptoCurrencyStatus
|
||||
private var stakingActions: List<StakingAction> = emptyList()
|
||||
private var feeCryptoCurrencyStatus: CryptoCurrencyStatus? = null
|
||||
private var minimumTransactionAmount: EnterAmountBoundary? = null
|
||||
|
|
@ -1299,6 +1299,7 @@ internal class StakingModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun isCaseWithUnitializedTonAccount(): Boolean {
|
||||
if (!::cryptoCurrencyStatus.isInitialized) return false
|
||||
return value.currentStep == StakingStep.Confirmation &&
|
||||
isTon(cryptoCurrencyStatus.currency.network.rawId) &&
|
||||
!isAccountInitialized
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import com.tangem.features.tokenreceive.entity.ReceiveAddress.Type.Ens
|
|||
import com.tangem.features.tokenreceive.entity.ReceiveAddress.Type.Primary
|
||||
import com.tangem.features.tokenreceive.ui.state.TokenReceiveUM
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.extensions.addIf
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
|
@ -138,12 +137,7 @@ internal class TokenReceiveStateFactory(
|
|||
tokenName: String,
|
||||
tokenReceiveNotification: List<TokenReceiveNotification>,
|
||||
): List<NotificationUM> {
|
||||
val yieldSupplyNotification: TokenReceiveNotification? =
|
||||
tokenReceiveNotification.firstOrNull { it.isYieldSupplyNotification }
|
||||
return buildList {
|
||||
addIf(yieldSupplyNotification != null) {
|
||||
NotificationUM.Warning.YieldSupplyIsActive(tokenName)
|
||||
}
|
||||
add(
|
||||
NotificationUM.Info(
|
||||
title = resourceReference(
|
||||
|
|
|
|||
|
|
@ -156,10 +156,6 @@ internal class TokenDetailsNotificationConverter(
|
|||
)
|
||||
is CryptoCurrencyWarning.MigrationMaticToPol -> MigrationMaticToPol
|
||||
is CryptoCurrencyWarning.UsedOutdatedDataWarning -> UsedOutdatedData
|
||||
is CryptoCurrencyWarning.YieldSupplyNotDepositedAmount -> YieldSupplyNotTransferedToAave(
|
||||
tokenName = warning.currencySymbol,
|
||||
amount = warning.amount.format { crypto(symbol = "", decimals = warning.currency.decimals) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,14 @@ private fun TokenList(
|
|||
end = TangemTheme.dimens.spacing16,
|
||||
)
|
||||
|
||||
// workaround to force recomposition of list items when the list is updated
|
||||
// because sometimes items disappear after reordering in 1.7.4+ compose-runtime version
|
||||
// check removing after update to compose-runtime 1.8.0+
|
||||
val forceRecompose = remember { mutableIntStateOf(0) }
|
||||
LaunchedEffect(state.items) {
|
||||
forceRecompose.intValue++
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopCenter)
|
||||
|
|
@ -143,13 +151,15 @@ private fun TokenList(
|
|||
}
|
||||
}
|
||||
|
||||
DraggableItem(
|
||||
index = index,
|
||||
item = item,
|
||||
reorderableState = reorderableListState,
|
||||
onDragStart = onDragStart,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
)
|
||||
key(forceRecompose.intValue) {
|
||||
DraggableItem(
|
||||
index = index,
|
||||
item = item,
|
||||
reorderableState = reorderableListState,
|
||||
onDragStart = onDragStart,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class DefaultUserWalletImageFetcher @Inject constructor(
|
|||
|
||||
override fun walletImage(walletId: UserWalletId, size: ArtworkSize): Flow<UserWalletItemUM.ImageState> =
|
||||
getUserWalletUseCase.invokeFlow(walletId)
|
||||
.transformLatest {
|
||||
.transform {
|
||||
it.fold(
|
||||
ifLeft = { emit(UserWalletItemUM.ImageState.Loading) },
|
||||
ifRight = { wallet -> emitAll(walletImage(wallet, size)) },
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
package com.tangem.features.yield.supply.impl.common
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Trigger for entering/exiting protocol from other components
|
||||
*/
|
||||
interface YieldSupplyProtocolTrigger {
|
||||
suspend fun onEnterProtocol()
|
||||
suspend fun onExitProtocol()
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener to observe entering/exiting protocol events
|
||||
*/
|
||||
interface YieldSupplyProtocolListener {
|
||||
val enterProtocolTriggerFlow: Flow<Unit>
|
||||
val exitProtocolTriggerFlow: Flow<Unit>
|
||||
}
|
||||
|
||||
@Singleton
|
||||
internal class DefaultYieldSupplyProtocolTrigger @Inject constructor() :
|
||||
YieldSupplyProtocolTrigger,
|
||||
YieldSupplyProtocolListener {
|
||||
|
||||
override val enterProtocolTriggerFlow = MutableSharedFlow<Unit>()
|
||||
override val exitProtocolTriggerFlow = MutableSharedFlow<Unit>()
|
||||
|
||||
override suspend fun onEnterProtocol() {
|
||||
enterProtocolTriggerFlow.emit(Unit)
|
||||
}
|
||||
|
||||
override suspend fun onExitProtocol() {
|
||||
exitProtocolTriggerFlow.emit(Unit)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,10 +13,12 @@ internal sealed class YieldSupplyFeeUM {
|
|||
data object Error : YieldSupplyFeeUM()
|
||||
data class Content(
|
||||
val transactionDataList: ImmutableList<TransactionData.Uncompiled>,
|
||||
val feeValue: TextReference,
|
||||
val currentNetworkFeeValue: TextReference,
|
||||
val maxNetworkFeeValue: TextReference,
|
||||
val minAmountFeeValue: TextReference,
|
||||
val feeFiatValue: TextReference,
|
||||
val tokenFeeFiatValue: TextReference,
|
||||
val maxNetworkFeeFiatValue: TextReference,
|
||||
val minTopUpFiatValue: TextReference,
|
||||
val feeNoteValue: TextReference = TextReference.EMPTY,
|
||||
val minFeeNoteValue: TextReference = TextReference.EMPTY,
|
||||
) : YieldSupplyFeeUM()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ package com.tangem.features.yield.supply.impl.common.ui
|
|||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.LinkAnnotation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.withLink
|
||||
|
|
@ -85,13 +87,17 @@ internal fun YieldSupplyActionContent(
|
|||
),
|
||||
) {
|
||||
val fee = when (val yieldSupplyFeeUM = yieldSupplyActionUM.yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeValue
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeFiatValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.common_network_fee_title),
|
||||
value = fee,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(14.dp))
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -138,10 +144,11 @@ private class YieldSupplyActionContentPreviewProvider : PreviewParameterProvider
|
|||
currencyIconState = CurrencyIconState.Loading,
|
||||
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
|
||||
transactionDataList = persistentListOf(),
|
||||
feeValue = stringReference("0.00020 ETH • \$0.99"),
|
||||
currentNetworkFeeValue = stringReference("1.45 USDT • \$1.45"),
|
||||
maxNetworkFeeValue = stringReference("8.50 USDT • \$8.50"),
|
||||
minAmountFeeValue = stringReference("50 USDT • \$50"),
|
||||
feeFiatValue = stringReference("$0.99"),
|
||||
tokenFeeFiatValue = stringReference("$1.45"),
|
||||
maxNetworkFeeFiatValue = stringReference("$8.50"),
|
||||
minTopUpFiatValue = stringReference("$50"),
|
||||
feeNoteValue = TextReference.EMPTY,
|
||||
),
|
||||
isPrimaryButtonEnabled = false,
|
||||
isTransactionSending = false,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,12 @@
|
|||
package com.tangem.features.yield.supply.impl.common.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
|
|
@ -23,15 +18,11 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.features.yield.supply.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun YieldSupplyFeeRow(title: TextReference, value: TextReference?) {
|
||||
internal fun YieldSupplyFeeRow(title: TextReference, value: TextReference?, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(14.dp))
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
modifier = modifier,
|
||||
) {
|
||||
Text(
|
||||
text = title.resolveReference(),
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@ package com.tangem.features.yield.supply.impl.di
|
|||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.features.yield.supply.impl.DefaultYieldSupplyFeatureToggles
|
||||
import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles
|
||||
import com.tangem.features.yield.supply.impl.common.DefaultYieldSupplyProtocolTrigger
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyProtocolListener
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyProtocolTrigger
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -22,17 +18,4 @@ internal object YieldSupplyFeatureModule {
|
|||
fun provideYieldFeatureToggles(featureTogglesManager: FeatureTogglesManager): YieldSupplyFeatureToggles {
|
||||
return DefaultYieldSupplyFeatureToggles(featureTogglesManager)
|
||||
}
|
||||
}
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
internal interface YieldSupplyProtocolModuleBinds {
|
||||
|
||||
@Singleton
|
||||
@Binds
|
||||
fun bindYieldSupplyProtocolTrigger(impl: DefaultYieldSupplyProtocolTrigger): YieldSupplyProtocolTrigger
|
||||
|
||||
@Singleton
|
||||
@Binds
|
||||
fun bindYieldSupplyProtocolListener(impl: DefaultYieldSupplyProtocolTrigger): YieldSupplyProtocolListener
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ internal sealed class YieldSupplyUM {
|
|||
val subtitle: TextReference,
|
||||
val rewardsApy: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
val isAllowedToSpend: Boolean,
|
||||
val showWarningIcon: Boolean,
|
||||
) : YieldSupplyUM()
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -15,12 +15,14 @@ import com.tangem.core.ui.extensions.stringReference
|
|||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.TxInfo
|
||||
import com.tangem.domain.models.currency.yieldSupplyNotAllAmountSupplied
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.yield.supply.YieldSupplyStatus
|
||||
import com.tangem.domain.networks.single.SingleNetworkStatusFetcher
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyActivateUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyDeactivateUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
|
||||
|
|
@ -28,7 +30,6 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyIsAvailableUseCase
|
|||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.api.YieldSupplyComponent
|
||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyProtocolListener
|
||||
import com.tangem.features.yield.supply.impl.main.entity.YieldSupplyUM
|
||||
import com.tangem.features.yield.supply.impl.main.model.transformers.YieldSupplyTokenStatusSuccessTransformer
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -58,7 +59,7 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
private val yieldSupplyIsAvailableUseCase: YieldSupplyIsAvailableUseCase,
|
||||
private val yieldSupplyActivateUseCase: YieldSupplyActivateUseCase,
|
||||
private val yieldSupplyDeactivateUseCase: YieldSupplyDeactivateUseCase,
|
||||
private val yieldSupplyProtocolListener: YieldSupplyProtocolListener,
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) : Model(), YieldSupplyClickIntents {
|
||||
|
||||
private val params = paramsContainer.require<YieldSupplyComponent.Params>()
|
||||
|
|
@ -86,38 +87,6 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
|
||||
init {
|
||||
checkIfYieldSupplyIsAvailable()
|
||||
observeProtocolEvents()
|
||||
}
|
||||
|
||||
private fun observeProtocolEvents() {
|
||||
yieldSupplyProtocolListener.exitProtocolTriggerFlow.onEach {
|
||||
uiState.update {
|
||||
YieldSupplyUM.Processing.Exit
|
||||
}
|
||||
coroutineScope.launch(dispatchers.io) {
|
||||
delay(PROCESSING_UPDATE_DELAY)
|
||||
singleNetworkStatusFetcher(
|
||||
params = SingleNetworkStatusFetcher.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
),
|
||||
)
|
||||
}
|
||||
}.launchIn(modelScope)
|
||||
yieldSupplyProtocolListener.enterProtocolTriggerFlow.onEach {
|
||||
uiState.update {
|
||||
YieldSupplyUM.Processing.Enter
|
||||
}
|
||||
coroutineScope.launch(dispatchers.io) {
|
||||
delay(PROCESSING_UPDATE_DELAY)
|
||||
singleNetworkStatusFetcher(
|
||||
params = SingleNetworkStatusFetcher.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
),
|
||||
)
|
||||
}
|
||||
}.launchIn(modelScope)
|
||||
}
|
||||
|
||||
private fun checkIfYieldSupplyIsAvailable() {
|
||||
|
|
@ -141,7 +110,6 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = false,
|
||||
).onEach { maybeCryptoCurrency ->
|
||||
Timber.tag("getSingleCryptoCurrencyStatusUseCase").d("update $maybeCryptoCurrency")
|
||||
maybeCryptoCurrency.fold(
|
||||
ifRight = { cryptoCurrencyStatus ->
|
||||
cryptoCurrencyStatusFlow.update { cryptoCurrencyStatus }
|
||||
|
|
@ -174,7 +142,7 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
)
|
||||
}.onLeft {
|
||||
Timber.e(it)
|
||||
uiState.update { YieldSupplyUM.Unavailable }
|
||||
uiState.update { YieldSupplyUM.Initial }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -213,53 +181,56 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
@Suppress("MaximumLineLength")
|
||||
private fun onCryptoCurrencyStatusUpdated(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
val yieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus
|
||||
val hasActiveTransaction = cryptoCurrencyStatus.value.hasCurrentNetworkTransactions
|
||||
val yieldTransaction = cryptoCurrencyStatus.value.pendingTransactions.firstOrNull {
|
||||
it.type is TxInfo.TransactionType.YieldSupply
|
||||
}?.type as? TxInfo.TransactionType.YieldSupply
|
||||
sendInfoAboutProtocolStatus(cryptoCurrencyStatus)
|
||||
val tokenProtocolStatus = yieldSupplyRepository.getTokenProtocolStatus(cryptoCurrency)
|
||||
val isActive = yieldSupplyStatus?.isActive == true
|
||||
|
||||
when {
|
||||
hasActiveTransaction && yieldTransaction != null -> {
|
||||
coroutineScope.launch(dispatchers.io) {
|
||||
delay(PROCESSING_UPDATE_DELAY)
|
||||
singleNetworkStatusFetcher(
|
||||
params = SingleNetworkStatusFetcher.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
),
|
||||
)
|
||||
}
|
||||
uiState.update {
|
||||
when (yieldTransaction) {
|
||||
TxInfo.TransactionType.YieldSupply.Enter -> YieldSupplyUM.Processing.Enter
|
||||
TxInfo.TransactionType.YieldSupply.Exit -> YieldSupplyUM.Processing.Exit
|
||||
}
|
||||
}
|
||||
!isActive && tokenProtocolStatus == YieldSupplyEnterStatus.Enter -> {
|
||||
uiState.update { YieldSupplyUM.Processing.Enter }
|
||||
fetchCurrencyWithDelay()
|
||||
}
|
||||
yieldSupplyStatus?.isActive == true -> {
|
||||
val cryptoCurrencyToken = cryptoCurrency as? CryptoCurrency.Token ?: return
|
||||
if (!yieldSupplyStatus.isAllowedToSpend) {
|
||||
analyticsEventsHandler.send(
|
||||
YieldSupplyAnalytics.NoticeApproveNeeded(
|
||||
token = cryptoCurrency.symbol,
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
),
|
||||
)
|
||||
}
|
||||
loadActiveState(
|
||||
cryptoCurrencyToken = cryptoCurrencyToken,
|
||||
yieldSupplyStatus = yieldSupplyStatus,
|
||||
)
|
||||
isActive && tokenProtocolStatus == YieldSupplyEnterStatus.Exit -> {
|
||||
uiState.update { YieldSupplyUM.Processing.Exit }
|
||||
fetchCurrencyWithDelay()
|
||||
}
|
||||
|
||||
else -> {
|
||||
loadTokenStatus()
|
||||
sendInfoAboutProtocolStatus(cryptoCurrencyStatus)
|
||||
if (isActive) {
|
||||
loadActiveState(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
yieldSupplyStatus = requireNotNull(yieldSupplyStatus),
|
||||
)
|
||||
} else {
|
||||
loadTokenStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadActiveState(cryptoCurrencyToken: CryptoCurrency.Token, yieldSupplyStatus: YieldSupplyStatus) {
|
||||
private fun fetchCurrencyWithDelay() {
|
||||
coroutineScope.launch(dispatchers.io) {
|
||||
delay(PROCESSING_UPDATE_DELAY)
|
||||
singleNetworkStatusFetcher(
|
||||
params = SingleNetworkStatusFetcher.Params(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadActiveState(cryptoCurrencyStatus: CryptoCurrencyStatus, yieldSupplyStatus: YieldSupplyStatus) {
|
||||
val cryptoCurrencyToken = cryptoCurrency as? CryptoCurrency.Token ?: return
|
||||
val showWarningIcon = !yieldSupplyStatus.isAllowedToSpend ||
|
||||
cryptoCurrencyStatus.yieldSupplyNotAllAmountSupplied()
|
||||
if (!yieldSupplyStatus.isAllowedToSpend) {
|
||||
analyticsEventsHandler.send(
|
||||
YieldSupplyAnalytics.NoticeApproveNeeded(
|
||||
token = cryptoCurrency.symbol,
|
||||
blockchain = cryptoCurrency.network.name,
|
||||
),
|
||||
)
|
||||
}
|
||||
modelScope.launch(dispatchers.default) {
|
||||
yieldSupplyGetTokenStatusUseCase(cryptoCurrencyToken)
|
||||
.onRight { tokenStatus ->
|
||||
|
|
@ -278,7 +249,7 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
stringReference(" ${tokenStatus.apy}%"),
|
||||
),
|
||||
onClick = ::onActiveClick,
|
||||
isAllowedToSpend = yieldSupplyStatus.isAllowedToSpend,
|
||||
showWarningIcon = showWarningIcon,
|
||||
apy = tokenStatus.apy.toString(),
|
||||
)
|
||||
}
|
||||
|
|
@ -294,7 +265,7 @@ internal class YieldSupplyModel @Inject constructor(
|
|||
),
|
||||
rewardsApy = TextReference.EMPTY,
|
||||
onClick = ::onActiveClick,
|
||||
isAllowedToSpend = yieldSupplyStatus.isAllowedToSpend,
|
||||
showWarningIcon = showWarningIcon,
|
||||
apy = "",
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ private fun SupplyContent(supplyUM: YieldSupplyUM.Content) {
|
|||
)
|
||||
}
|
||||
SpacerW8()
|
||||
AnimatedVisibility(supplyUM.isAllowedToSpend.not()) {
|
||||
AnimatedVisibility(supplyUM.showWarningIcon) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_alert_triangle_20),
|
||||
contentDescription = null,
|
||||
|
|
@ -317,7 +317,7 @@ private class PreviewProvider : PreviewParameterProvider<YieldSupplyUM> {
|
|||
rewardsApy = stringReference("5.1 % APY"),
|
||||
onClick = {},
|
||||
apy = "5.1",
|
||||
isAllowedToSpend = false,
|
||||
showWarningIcon = false,
|
||||
),
|
||||
YieldSupplyUM.Content(
|
||||
title = stringReference("Aave lending is active"),
|
||||
|
|
@ -325,7 +325,7 @@ private class PreviewProvider : PreviewParameterProvider<YieldSupplyUM> {
|
|||
rewardsApy = stringReference("5.1 % APY"),
|
||||
onClick = {},
|
||||
apy = "5.1",
|
||||
isAllowedToSpend = true,
|
||||
showWarningIcon = true,
|
||||
),
|
||||
YieldSupplyUM.Loading,
|
||||
YieldSupplyUM.Processing.Enter,
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ internal class YieldSupplyActiveComponent(
|
|||
state = state,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
chartComponent = chartComponent,
|
||||
onReadMoreClick = params.callback::onReadMoreClick,
|
||||
modifier = Modifier,
|
||||
)
|
||||
}
|
||||
|
|
@ -76,5 +77,6 @@ internal class YieldSupplyActiveComponent(
|
|||
fun onBackClick()
|
||||
fun onStopEarning()
|
||||
fun onApprove()
|
||||
fun onReadMoreClick()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.yield.supply.impl.subcomponents.active.entity
|
|||
|
||||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
internal data class YieldSupplyActiveContentUM(
|
||||
val totalEarnings: TextReference,
|
||||
|
|
@ -9,10 +10,11 @@ internal data class YieldSupplyActiveContentUM(
|
|||
val providerTitle: TextReference,
|
||||
val subtitle: TextReference,
|
||||
val subtitleLink: TextReference,
|
||||
val notificationUM: NotificationUM?,
|
||||
val notifications: ImmutableList<NotificationUM>,
|
||||
val minAmount: TextReference?,
|
||||
val currentFee: TextReference?,
|
||||
val feeDescription: TextReference?,
|
||||
val minFeeDescription: TextReference?,
|
||||
val apy: TextReference? = null,
|
||||
val isHighFee: Boolean = false,
|
||||
)
|
||||
|
|
@ -4,10 +4,12 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.YieldSupplyActiveComponent
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.YieldSupplyActiveEntryComponent
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyApproveComponent
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent
|
||||
import com.tangem.utils.TangemBlogUrlBuilder
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -16,6 +18,7 @@ internal class YieldSupplyActiveEntryModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
paramsContainer: ParamsContainer,
|
||||
private val router: Router,
|
||||
private val urlOpener: UrlOpener,
|
||||
) : Model(), YieldSupplyActiveComponent.ModelCallback,
|
||||
YieldSupplyStopEarningComponent.ModelCallback,
|
||||
YieldSupplyApproveComponent.ModelCallback {
|
||||
|
|
@ -37,4 +40,8 @@ internal class YieldSupplyActiveEntryModel @Inject constructor(
|
|||
override fun onApprove() {
|
||||
router.push(YieldSupplyActiveRoute.Approve)
|
||||
}
|
||||
|
||||
override fun onReadMoreClick() {
|
||||
urlOpener.openUrl(TangemBlogUrlBuilder.YIELD_SUPPLY_HOW_IT_WORKS_URL)
|
||||
}
|
||||
}
|
||||
|
|
@ -12,11 +12,11 @@ import com.tangem.core.ui.extensions.resourceReference
|
|||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetProtocolBalanceUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyMinAmountUseCase
|
||||
|
|
@ -24,14 +24,20 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyGetCurrentFeeUseCase
|
|||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetMaxFeeUseCase
|
||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.common.formatter.YieldSupplyAmountFormatter
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.YieldSupplyActiveComponent
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers.YieldSupplyActiveMinAmountTransformer
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers.YieldSupplyActiveFeeContentTransformer
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.transformer.update
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.math.BigDecimal
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -65,11 +71,12 @@ internal class YieldSupplyActiveModel @Inject constructor(
|
|||
formatArgs = wrappedList(cryptoCurrency.symbol, cryptoCurrency.symbol),
|
||||
),
|
||||
subtitleLink = resourceReference(R.string.common_read_more),
|
||||
notificationUM = null,
|
||||
notifications = persistentListOf(),
|
||||
minAmount = null,
|
||||
currentFee = null,
|
||||
feeDescription = null,
|
||||
isHighFee = false,
|
||||
minFeeDescription = null,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -108,27 +115,13 @@ internal class YieldSupplyActiveModel @Inject constructor(
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
).getOrNull()
|
||||
|
||||
val approvalNotification = if (cryptoCurrencyStatus.value.yieldSupplyStatus?.isAllowedToSpend != true) {
|
||||
NotificationUM.Error(
|
||||
title = resourceReference(R.string.yield_module_approve_needed_notification_title),
|
||||
subtitle = resourceReference(R.string.yield_module_approve_needed_notification_description),
|
||||
iconResId = R.drawable.ic_alert_triangle_20,
|
||||
buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(R.string.yield_module_approve_needed_notification_cta),
|
||||
onClick = params.callback::onApprove,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
loadApy()
|
||||
loadMinAmount()
|
||||
loadFees()
|
||||
|
||||
uiState.update {
|
||||
it.copy(
|
||||
notificationUM = approvalNotification,
|
||||
notifications = getNotifications(cryptoCurrencyStatus),
|
||||
availableBalance = stringReference(
|
||||
protocolBalance.format {
|
||||
crypto(
|
||||
|
|
@ -153,31 +146,77 @@ internal class YieldSupplyActiveModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}.onLeft {
|
||||
uiState.update {
|
||||
it.copy(
|
||||
apy = TextReference.Str(DASH_SIGN),
|
||||
)
|
||||
}
|
||||
Timber.e("Error loading token status")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNotifications(cryptoCurrencyStatus: CryptoCurrencyStatus): ImmutableList<NotificationUM> {
|
||||
val approvalNotification = if (cryptoCurrencyStatus.value.yieldSupplyStatus?.isAllowedToSpend != true) {
|
||||
NotificationUM.Error(
|
||||
title = resourceReference(R.string.yield_module_approve_needed_notification_title),
|
||||
subtitle = resourceReference(R.string.yield_module_approve_needed_notification_description),
|
||||
iconResId = R.drawable.ic_alert_triangle_20,
|
||||
buttonState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
|
||||
text = resourceReference(R.string.yield_module_approve_needed_notification_cta),
|
||||
onClick = params.callback::onApprove,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val notSuppliedNotification = getNotSuppliedNotification(cryptoCurrencyStatus)
|
||||
return listOfNotNull(
|
||||
approvalNotification,
|
||||
notSuppliedNotification,
|
||||
).toPersistentList()
|
||||
}
|
||||
|
||||
private fun getNotSuppliedNotification(cryptoCurrencyStatus: CryptoCurrencyStatus): NotificationUM? {
|
||||
val value = cryptoCurrencyStatus.value
|
||||
val isActive = value.yieldSupplyStatus?.isActive == true
|
||||
val effectiveProtocolBalance = value.yieldSupplyStatus?.effectiveProtocolBalance ?: null
|
||||
val amount = value.amount
|
||||
|
||||
if (!isActive || effectiveProtocolBalance == null || amount == null) return null
|
||||
|
||||
val notDepositedAmount = amount.minus(effectiveProtocolBalance)
|
||||
return if (notDepositedAmount > BigDecimal.ZERO) {
|
||||
val formattedAmount =
|
||||
notDepositedAmount.format { crypto(symbol = "", decimals = cryptoCurrencyStatus.currency.decimals) }
|
||||
NotificationUM.Warning.YieldSupplyNotAllAmountSupplied(
|
||||
formattedAmount = formattedAmount,
|
||||
symbol = cryptoCurrency.symbol,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadMinAmount() {
|
||||
modelScope.launch(dispatchers.default) {
|
||||
yieldSupplyMinAmountUseCase(
|
||||
params.userWallet,
|
||||
cryptoCurrencyStatusFlow.value,
|
||||
).onRight { minAmount ->
|
||||
val minAmountTextReference = YieldSupplyAmountFormatter(
|
||||
cryptoCurrencyStatusFlow.value.currency,
|
||||
appCurrency,
|
||||
).invoke(
|
||||
feeValue = minAmount,
|
||||
fiatRate = cryptoCurrencyStatusFlow.value.value.fiatRate,
|
||||
showCrypto = false,
|
||||
uiState.update(
|
||||
YieldSupplyActiveMinAmountTransformer(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatusFlow.value,
|
||||
appCurrency = appCurrency,
|
||||
minAmount = minAmount,
|
||||
),
|
||||
)
|
||||
uiState.update {
|
||||
it.copy(minAmount = minAmountTextReference)
|
||||
}
|
||||
}.onLeft {
|
||||
uiState.update {
|
||||
it.copy(minAmount = TextReference.Str(DASH_SIGN))
|
||||
it.copy(
|
||||
minAmount = TextReference.Str(DASH_SIGN),
|
||||
feeDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -197,33 +236,23 @@ internal class YieldSupplyActiveModel @Inject constructor(
|
|||
cryptoCurrencyStatus = cryptoStatus,
|
||||
).getOrNull()
|
||||
|
||||
val currentFeeText = currentFee?.let {
|
||||
YieldSupplyAmountFormatter(
|
||||
cryptoStatus.currency,
|
||||
appCurrency,
|
||||
).invoke(
|
||||
feeValue = it,
|
||||
fiatRate = cryptoStatus.value.fiatRate,
|
||||
showCrypto = false,
|
||||
if (currentFee != null && maxFee != null) {
|
||||
uiState.update(
|
||||
YieldSupplyActiveFeeContentTransformer(
|
||||
cryptoCurrencyStatus = cryptoStatus,
|
||||
appCurrency = appCurrency,
|
||||
feeValue = currentFee,
|
||||
maxNetworkFee = maxFee,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
val isHighFee = if (currentFee != null && maxFee != null) currentFee > maxFee else false
|
||||
|
||||
val maxFiatFee = maxFee?.multiply(cryptoStatus.value.fiatRate)
|
||||
.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
val feeDescription = if (isHighFee) {
|
||||
resourceReference(R.string.yield_module_earn_sheet_high_fee_description, wrappedList(maxFiatFee))
|
||||
} else {
|
||||
resourceReference(R.string.yield_module_earn_sheet_fee_description, wrappedList(maxFiatFee))
|
||||
}
|
||||
|
||||
uiState.update {
|
||||
it.copy(
|
||||
currentFee = currentFeeText ?: stringReference(DASH_SIGN),
|
||||
isHighFee = isHighFee,
|
||||
feeDescription = feeDescription,
|
||||
)
|
||||
uiState.update {
|
||||
it.copy(
|
||||
currentFee = stringReference(DASH_SIGN),
|
||||
feeDescription = null,
|
||||
isHighFee = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Computes fee description and current fee values for Active screen based on token rates.
|
||||
*/
|
||||
internal class YieldSupplyActiveFeeContentTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val feeValue: BigDecimal,
|
||||
private val maxNetworkFee: BigDecimal,
|
||||
) : Transformer<YieldSupplyActiveContentUM> {
|
||||
|
||||
override fun transform(prevState: YieldSupplyActiveContentUM): YieldSupplyActiveContentUM {
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val tokenFiatRate = cryptoCurrencyStatus.value.fiatRate
|
||||
|
||||
val tokenCryptoFeeValueText = feeValue.format { crypto(cryptoCurrency) }
|
||||
val tokenFiatFee = tokenFiatRate?.let(feeValue::multiply)
|
||||
val tokenFiatFeeValueText = tokenFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val maxFeeCryptoValueText = maxNetworkFee.format { crypto(cryptoCurrency) }
|
||||
val maxFiatFee = tokenFiatRate?.let { rate -> maxNetworkFee.multiply(rate) }
|
||||
val maxFiatFeeValueText = maxFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val feeNoteValue: TextReference = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_fee_note,
|
||||
formatArgs = wrappedList(
|
||||
stringReference(tokenFiatFeeValueText),
|
||||
stringReference(tokenCryptoFeeValueText),
|
||||
stringReference(maxFiatFeeValueText),
|
||||
stringReference(maxFeeCryptoValueText),
|
||||
),
|
||||
)
|
||||
|
||||
val isHighFee = feeValue > maxNetworkFee
|
||||
|
||||
return prevState.copy(
|
||||
currentFee = stringReference(tokenFiatFeeValueText),
|
||||
feeDescription = feeNoteValue,
|
||||
isHighFee = isHighFee,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.tangem.features.yield.supply.impl.subcomponents.active.model.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
* Computes and sets minimum amount (fiat) and fee description note
|
||||
*/
|
||||
internal class YieldSupplyActiveMinAmountTransformer(
|
||||
private val cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
private val appCurrency: AppCurrency,
|
||||
private val minAmount: BigDecimal,
|
||||
) : Transformer<YieldSupplyActiveContentUM> {
|
||||
|
||||
override fun transform(prevState: YieldSupplyActiveContentUM): YieldSupplyActiveContentUM {
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val tokenFiatRate = cryptoCurrencyStatus.value.fiatRate
|
||||
|
||||
val minAmountCryptoText = minAmount.format { crypto(cryptoCurrency) }
|
||||
val minAmountFiat = tokenFiatRate?.let(minAmount::multiply)
|
||||
val minAmountFiatText = minAmountFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val minFeeNoteValue = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
|
||||
formatArgs = wrappedList(
|
||||
minAmountFiatText,
|
||||
minAmountCryptoText,
|
||||
),
|
||||
)
|
||||
|
||||
return prevState.copy(
|
||||
minAmount = stringReference(minAmountFiatText),
|
||||
minFeeDescription = minFeeNoteValue,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -28,17 +28,20 @@ import androidx.compose.ui.unit.dp
|
|||
import com.tangem.common.ui.notifications.NotificationUM
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.active.entity.YieldSupplyActiveContentUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun YieldSupplyActiveContent(
|
||||
state: YieldSupplyActiveContentUM,
|
||||
isBalanceHidden: Boolean,
|
||||
onReadMoreClick: () -> Unit,
|
||||
chartComponent: ComposableContentComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
|
@ -61,16 +64,23 @@ internal fun YieldSupplyActiveContent(
|
|||
chartComponent.Content(Modifier.padding(bottom = 12.dp))
|
||||
}
|
||||
|
||||
AnimatedVisibility(state.notificationUM != null) {
|
||||
val wrappedNotification = remember(this) { requireNotNull(state.notificationUM) }
|
||||
Notification(
|
||||
config = wrappedNotification.config,
|
||||
iconTint = null,
|
||||
containerColor = TangemTheme.colors.background.action,
|
||||
)
|
||||
AnimatedVisibility(state.notifications.isNotEmpty()) {
|
||||
val notifications = remember(state.notifications) { state.notifications }
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
notifications.forEach { notificationUM ->
|
||||
Notification(
|
||||
config = notificationUM.config,
|
||||
containerColor = TangemTheme.colors.background.action,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
YieldSupplyActiveMyFunds(state = state, isBalanceHidden = isBalanceHidden)
|
||||
YieldSupplyActiveMyFunds(
|
||||
state = state,
|
||||
isBalanceHidden = isBalanceHidden,
|
||||
onReadMoreClick = onReadMoreClick,
|
||||
)
|
||||
|
||||
AnimatedVisibility(state.feeDescription != null) {
|
||||
Text(
|
||||
|
|
@ -81,12 +91,14 @@ internal fun YieldSupplyActiveContent(
|
|||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 12.dp),
|
||||
text = stringResourceSafe(R.string.yield_module_fee_policy_sheet_min_amount_note),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
AnimatedVisibility(state.minFeeDescription != null) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 12.dp),
|
||||
text = state.minFeeDescription?.resolveReference().orEmpty(),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +120,7 @@ private fun CurrentApy(apy: TextReference?, modifier: Modifier = Modifier) {
|
|||
TextShimmer(
|
||||
modifier = modifier.width(94.dp),
|
||||
text = "",
|
||||
style = TangemTheme.typography.head,
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
} else {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
|
|
@ -123,7 +135,7 @@ private fun CurrentApy(apy: TextReference?, modifier: Modifier = Modifier) {
|
|||
Text(
|
||||
modifier = modifier,
|
||||
text = apyText,
|
||||
style = TangemTheme.typography.body1,
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.accent,
|
||||
)
|
||||
}
|
||||
|
|
@ -134,7 +146,11 @@ private fun CurrentApy(apy: TextReference?, modifier: Modifier = Modifier) {
|
|||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM, isBalanceHidden: Boolean) {
|
||||
private fun YieldSupplyActiveMyFunds(
|
||||
state: YieldSupplyActiveContentUM,
|
||||
onReadMoreClick: () -> Unit,
|
||||
isBalanceHidden: Boolean,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
|
|
@ -164,7 +180,7 @@ private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM, isBalanc
|
|||
)
|
||||
}
|
||||
SpacerH8()
|
||||
DescriptionText(state = state)
|
||||
DescriptionText(state = state, onReadMoreClick = onReadMoreClick)
|
||||
SpacerH8()
|
||||
HorizontalDivider(
|
||||
thickness = 0.5.dp,
|
||||
|
|
@ -206,14 +222,14 @@ private fun YieldSupplyActiveMyFunds(state: YieldSupplyActiveContentUM, isBalanc
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun DescriptionText(state: YieldSupplyActiveContentUM) {
|
||||
private fun DescriptionText(state: YieldSupplyActiveContentUM, onReadMoreClick: () -> Unit) {
|
||||
val subtitle = annotatedReference {
|
||||
append(state.subtitle.resolveReference())
|
||||
appendSpace()
|
||||
withLink(
|
||||
LinkAnnotation.Clickable(
|
||||
tag = "LINK_TAG",
|
||||
linkInteractionListener = {},
|
||||
linkInteractionListener = { onReadMoreClick() },
|
||||
),
|
||||
{
|
||||
appendColored(
|
||||
|
|
@ -324,6 +340,7 @@ private fun YieldSupplyActiveBottomSheet_Preview(
|
|||
state = params,
|
||||
isBalanceHidden = true,
|
||||
chartComponent = ComposableContentComponent.EMPTY,
|
||||
onReadMoreClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -340,15 +357,31 @@ private class YieldSupplyActiveBottomSheetPreviewProvider : PreviewParameterProv
|
|||
wrappedList("USDT", "USDT"),
|
||||
),
|
||||
subtitleLink = resourceReference(R.string.common_read_more),
|
||||
notificationUM = NotificationUM.Error.InvalidAmount,
|
||||
apy = stringReference("5,14%"),
|
||||
notifications = persistentListOf(
|
||||
NotificationUM.Error.InvalidAmount,
|
||||
NotificationUM.Info(
|
||||
title = resourceReference(
|
||||
R.string.yield_module_amount_not_transfered_to_aave_title,
|
||||
wrappedList(
|
||||
"0,03",
|
||||
),
|
||||
),
|
||||
subtitle = TextReference.EMPTY,
|
||||
iconTint = NotificationConfig.IconTint.Accent,
|
||||
),
|
||||
),
|
||||
minAmount = stringReference("50 USDT"),
|
||||
isHighFee = true,
|
||||
currentFee = stringReference("30 USDT"),
|
||||
feeDescription = stringReference(
|
||||
"The network fee is currently too high to execute lending." +
|
||||
"Funds will be supplied once it drops to \$12 or below. ",
|
||||
),
|
||||
currentFee = stringReference("30 USDT"),
|
||||
apy = stringReference("5,14%"),
|
||||
isHighFee = true,
|
||||
minFeeDescription = stringReference(
|
||||
"The network fee is currently too high to execute lending." +
|
||||
"Funds will be supplied once it drops to \$12 or below. ",
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import com.tangem.core.decompose.model.ParamsContainer
|
|||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
|
|
@ -33,7 +32,7 @@ import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyAp
|
|||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsComponent
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.YieldSupplyNotificationsUpdateTrigger
|
||||
import com.tangem.features.yield.supply.impl.subcomponents.notifications.entity.YieldSupplyNotificationData
|
||||
import com.tangem.utils.StringsSigns.DOT
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.utils.TangemBlogUrlBuilder
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.transformer.update
|
||||
|
|
@ -220,7 +219,6 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
val feeFiatValue = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
|
||||
feeCryptoValue?.multiply(rate)
|
||||
}
|
||||
val cryptoFee = feeCryptoValue.format { crypto(feeCryptoCurrencyStatus.currency) }
|
||||
val fiatFee = feeFiatValue.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
uiState.update {
|
||||
|
|
@ -233,14 +231,11 @@ internal class YieldSupplyApproveModel @Inject constructor(
|
|||
transactionDataList = persistentListOf(
|
||||
approvalTransitionData.copy(fee = transactionFee.normal),
|
||||
),
|
||||
feeValue = combinedReference(
|
||||
stringReference(cryptoFee),
|
||||
stringReference(" $DOT "),
|
||||
stringReference(fiatFee),
|
||||
),
|
||||
currentNetworkFeeValue = TextReference.EMPTY,
|
||||
maxNetworkFeeValue = TextReference.EMPTY,
|
||||
minAmountFeeValue = TextReference.EMPTY,
|
||||
feeFiatValue = stringReference(fiatFee),
|
||||
tokenFeeFiatValue = TextReference.EMPTY,
|
||||
maxNetworkFeeFiatValue = TextReference.EMPTY,
|
||||
minTopUpFiatValue = TextReference.EMPTY,
|
||||
feeNoteValue = TextReference.EMPTY,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ internal class YieldSupplyFeePolicyComponent(
|
|||
YieldSupplyFeePolicyContent(
|
||||
yieldSupplyFeeUM = uiState.yieldSupplyFeeUM,
|
||||
tokenSymbol = params.cryptoCurrency.symbol,
|
||||
networkName = params.cryptoCurrency.network.name,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ import androidx.compose.foundation.layout.Column
|
|||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -34,7 +36,6 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
internal fun YieldSupplyFeePolicyContent(
|
||||
yieldSupplyFeeUM: YieldSupplyFeeUM,
|
||||
tokenSymbol: String,
|
||||
networkName: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
|
|
@ -62,68 +63,51 @@ internal fun YieldSupplyFeePolicyContent(
|
|||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
SpacerH24()
|
||||
FooterContainer(
|
||||
footer = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
|
||||
formatArgs = wrappedList(networkName),
|
||||
),
|
||||
paddingValues = PaddingValues(
|
||||
top = 8.dp,
|
||||
start = 12.dp,
|
||||
end = 12.dp,
|
||||
),
|
||||
) {
|
||||
val minAmount = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.minAmountFeeValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.yield_module_fee_policy_sheet_min_amount_title),
|
||||
value = minAmount,
|
||||
)
|
||||
}
|
||||
MinFeeNote(yieldSupplyFeeUM)
|
||||
SpacerH16()
|
||||
val feeNote = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.feeNoteValue
|
||||
YieldSupplyFeeUM.Error -> null
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
FooterContainer(
|
||||
footer = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_current_fee_note,
|
||||
formatArgs = wrappedList(networkName),
|
||||
),
|
||||
footer = feeNote,
|
||||
paddingValues = PaddingValues(
|
||||
top = 8.dp,
|
||||
start = 12.dp,
|
||||
end = 12.dp,
|
||||
),
|
||||
) {
|
||||
val currentFee = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.currentNetworkFeeValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(14.dp))
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
val currentFee = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.tokenFeeFiatValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.yield_module_fee_policy_sheet_current_fee_title),
|
||||
value = currentFee,
|
||||
modifier = Modifier.padding(vertical = 12.dp),
|
||||
)
|
||||
val maxFee = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.maxNetworkFeeFiatValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_title),
|
||||
value = maxFee,
|
||||
modifier = Modifier.padding(vertical = 12.dp),
|
||||
)
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.yield_module_fee_policy_sheet_current_fee_title),
|
||||
value = currentFee,
|
||||
)
|
||||
}
|
||||
SpacerH16()
|
||||
FooterContainer(
|
||||
footer = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_note),
|
||||
paddingValues = PaddingValues(
|
||||
top = 8.dp,
|
||||
start = 12.dp,
|
||||
end = 12.dp,
|
||||
),
|
||||
) {
|
||||
val maxFee = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.maxNetworkFeeValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_title),
|
||||
value = maxFee,
|
||||
)
|
||||
}
|
||||
SpacerH8()
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.yield_module_fee_policy_tangem_service_fee_title),
|
||||
style = TangemTheme.typography.caption2,
|
||||
|
|
@ -139,6 +123,38 @@ internal fun YieldSupplyFeePolicyContent(
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MinFeeNote(yieldSupplyFeeUM: YieldSupplyFeeUM) {
|
||||
val minFeeNote = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.minFeeNoteValue
|
||||
YieldSupplyFeeUM.Error -> null
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
FooterContainer(
|
||||
footer = minFeeNote,
|
||||
paddingValues = PaddingValues(
|
||||
top = 8.dp,
|
||||
start = 12.dp,
|
||||
end = 12.dp,
|
||||
),
|
||||
) {
|
||||
val minAmount = when (yieldSupplyFeeUM) {
|
||||
is YieldSupplyFeeUM.Content -> yieldSupplyFeeUM.minTopUpFiatValue
|
||||
YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN)
|
||||
YieldSupplyFeeUM.Loading -> null
|
||||
}
|
||||
YieldSupplyFeeRow(
|
||||
title = resourceReference(R.string.yield_module_fee_policy_sheet_min_amount_title),
|
||||
value = minAmount,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(14.dp))
|
||||
.background(TangemTheme.colors.background.action)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
|
|
@ -148,13 +164,28 @@ private fun YieldSupplyFeePolicyContent_Preview() {
|
|||
YieldSupplyFeePolicyContent(
|
||||
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
|
||||
transactionDataList = persistentListOf(),
|
||||
feeValue = stringReference("0.0001 ETH • \$1.45"),
|
||||
maxNetworkFeeValue = stringReference("8.50 USDT • \$8.50"),
|
||||
currentNetworkFeeValue = stringReference("1.45 USDT • \$1.45"),
|
||||
minAmountFeeValue = stringReference("50 USDT • \$50"),
|
||||
feeFiatValue = stringReference("$1.45"),
|
||||
maxNetworkFeeFiatValue = stringReference("$8.50"),
|
||||
tokenFeeFiatValue = stringReference("$1.45"),
|
||||
minTopUpFiatValue = stringReference("$50"),
|
||||
feeNoteValue = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_fee_note,
|
||||
formatArgs = wrappedList(
|
||||
stringReference("$1.45"),
|
||||
stringReference("1.46 USDT"),
|
||||
stringReference("$8.50"),
|
||||
stringReference("8.50 USDT"),
|
||||
),
|
||||
),
|
||||
minFeeNoteValue = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
|
||||
formatArgs = wrappedList(
|
||||
stringReference("$2.45"),
|
||||
stringReference("2.46 USDT"),
|
||||
),
|
||||
),
|
||||
),
|
||||
tokenSymbol = "USDT",
|
||||
networkName = "Ethereum",
|
||||
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
|||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyActivateUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyEstimateEnterFeeUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetTokenStatusUseCase
|
||||
|
|
@ -28,7 +30,6 @@ import com.tangem.domain.yield.supply.usecase.YieldSupplyStartEarningUseCase
|
|||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyAlertFactory
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyProtocolTrigger
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.transformer.YieldSupplyTransactionInProgressTransformer
|
||||
|
|
@ -66,7 +67,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
private val yieldSupplyActivateUseCase: YieldSupplyActivateUseCase,
|
||||
private val yieldSupplyGetTokenStatusUseCase: YieldSupplyGetTokenStatusUseCase,
|
||||
private val yieldSupplyMinAmountUseCase: YieldSupplyMinAmountUseCase,
|
||||
private val yieldSupplyProtocolTrigger: YieldSupplyProtocolTrigger,
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyStartEarningComponent.Params = paramsContainer.require()
|
||||
|
|
@ -252,7 +253,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
ifRight = {
|
||||
yieldSupplyProtocolTrigger.onEnterProtocol()
|
||||
yieldSupplyRepository.saveTokenProtocolStatus(cryptoCurrency, YieldSupplyEnterStatus.Enter)
|
||||
analytics.send(YieldSupplyAnalytics.FundsEarned)
|
||||
yieldSupplyActivateUseCase(cryptoCurrency)
|
||||
modelScope.launch {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
package com.tangem.features.yield.supply.impl.subcomponents.startearning.model.transformers
|
||||
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.core.ui.extensions.combinedReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.common.formatter.YieldSupplyAmountFormatter
|
||||
import com.tangem.utils.StringsSigns.DOT
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -29,30 +29,46 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
|
|||
) : Transformer<YieldSupplyActionUM> {
|
||||
override fun transform(prevState: YieldSupplyActionUM): YieldSupplyActionUM {
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val fiatRate = cryptoCurrencyStatus.value.fiatRate
|
||||
val tokenFiatRate = cryptoCurrencyStatus.value.fiatRate
|
||||
val feeFiatRate = feeCryptoCurrencyStatus.value.fiatRate
|
||||
|
||||
val crypto = feeValue.format { crypto(feeCryptoCurrencyStatus.currency) }
|
||||
val fiatFeeValue = feeFiatRate?.let(feeValue::multiply)
|
||||
val feeFiat = feeFiatRate?.let(feeValue::multiply)
|
||||
val feeFiatValueText = feeFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val fiat = fiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val tokenCryptoFeeValue = fiatRate?.let { rate ->
|
||||
fiatFeeValue?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
|
||||
val tokenCryptoFee = tokenFiatRate?.let { rate ->
|
||||
feeFiat?.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
|
||||
}
|
||||
val tokenCryptoFeeValueText = tokenCryptoFee.format { crypto(cryptoCurrency) }
|
||||
val tokenFiatFee = feeFiat // same fiat amount
|
||||
val tokenFiatFeeValueText = tokenFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val tokenCryptoFee = tokenCryptoFeeValue.format { crypto(cryptoCurrency) }
|
||||
|
||||
val maxCryptoFee = maxNetworkFee.format { crypto(cryptoCurrency) }
|
||||
val maxFiatFeeValue = fiatRate?.let { rate ->
|
||||
maxNetworkFee.divide(rate, cryptoCurrency.decimals, RoundingMode.HALF_UP)
|
||||
val maxFeeCryptoValueText = maxNetworkFee.format { crypto(cryptoCurrency) }
|
||||
val maxFiatFee = tokenFiatRate?.let { rate ->
|
||||
maxNetworkFee.multiply(rate)
|
||||
}
|
||||
val maxFiatFee = maxFiatFeeValue.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
val maxFiatFeeValueText = maxFiatFee.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val minAmountTextReference = YieldSupplyAmountFormatter(
|
||||
cryptoCurrency,
|
||||
appCurrency,
|
||||
).invoke(minAmount, cryptoCurrencyStatus.value.fiatRate)
|
||||
val minAmountCryptoText = minAmount.format { crypto(cryptoCurrency) }
|
||||
val minAmountFiat = tokenFiatRate?.let(minAmount::multiply)
|
||||
val minAmountFiatText = minAmountFiat.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
val feeNoteValue = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_fee_note,
|
||||
formatArgs = wrappedList(
|
||||
tokenFiatFeeValueText,
|
||||
tokenCryptoFeeValueText,
|
||||
maxFiatFeeValueText,
|
||||
maxFeeCryptoValueText,
|
||||
),
|
||||
)
|
||||
|
||||
val minFeeNoteValue = resourceReference(
|
||||
id = R.string.yield_module_fee_policy_sheet_min_amount_note,
|
||||
formatArgs = wrappedList(
|
||||
minAmountFiatText,
|
||||
minAmountCryptoText,
|
||||
),
|
||||
)
|
||||
|
||||
return if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading) {
|
||||
prevState.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading)
|
||||
|
|
@ -60,22 +76,12 @@ internal class YieldSupplyStartEarningFeeContentTransformer(
|
|||
prevState.copy(
|
||||
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
|
||||
transactionDataList = updatedTransactionList.toPersistentList(),
|
||||
feeValue = combinedReference(
|
||||
stringReference(crypto),
|
||||
stringReference(" $DOT "),
|
||||
stringReference(fiat),
|
||||
),
|
||||
currentNetworkFeeValue = combinedReference(
|
||||
stringReference(tokenCryptoFee),
|
||||
stringReference(" $DOT "),
|
||||
stringReference(fiat),
|
||||
),
|
||||
maxNetworkFeeValue = combinedReference(
|
||||
stringReference(maxCryptoFee),
|
||||
stringReference(" $DOT "),
|
||||
stringReference(maxFiatFee),
|
||||
),
|
||||
minAmountFeeValue = minAmountTextReference,
|
||||
feeFiatValue = stringReference(feeFiatValueText),
|
||||
tokenFeeFiatValue = stringReference(tokenFiatFeeValueText),
|
||||
maxNetworkFeeFiatValue = stringReference(maxFiatFeeValueText),
|
||||
minTopUpFiatValue = stringReference(minAmountFiatText),
|
||||
feeNoteValue = feeNoteValue,
|
||||
minFeeNoteValue = minFeeNoteValue,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,13 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.transaction.usecase.GetFeeUseCase
|
||||
import com.tangem.domain.transaction.usecase.SendTransactionUseCase
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyDeactivateUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyStopEarningUseCase
|
||||
import com.tangem.features.yield.supply.impl.R
|
||||
import com.tangem.features.yield.supply.api.analytics.YieldSupplyAnalytics
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyAlertFactory
|
||||
import com.tangem.features.yield.supply.impl.common.YieldSupplyProtocolTrigger
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.transformer.YieldSupplyTransactionInProgressTransformer
|
||||
|
|
@ -55,7 +56,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
private val yieldSupplyNotificationsUpdateTrigger: YieldSupplyNotificationsUpdateTrigger,
|
||||
private val yieldSupplyAlertFactory: YieldSupplyAlertFactory,
|
||||
private val yieldSupplyDeactivateUseCase: YieldSupplyDeactivateUseCase,
|
||||
private val yieldSupplyProtocolTrigger: YieldSupplyProtocolTrigger,
|
||||
private val yieldSupplyRepository: YieldSupplyRepository,
|
||||
) : Model(), YieldSupplyNotificationsComponent.ModelCallback {
|
||||
|
||||
private val params: YieldSupplyStopEarningComponent.Params = paramsContainer.require()
|
||||
|
|
@ -158,7 +159,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
ifRight = {
|
||||
yieldSupplyProtocolTrigger.onExitProtocol()
|
||||
yieldSupplyRepository.saveTokenProtocolStatus(cryptoCurrency, YieldSupplyEnterStatus.Exit)
|
||||
analytics.send(
|
||||
YieldSupplyAnalytics.FundsWithdrawn(
|
||||
token = cryptoCurrency.symbol,
|
||||
|
|
|
|||
|
|
@ -2,16 +2,13 @@ package com.tangem.features.yield.supply.impl.subcomponents.stopearning.model.tr
|
|||
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.combinedReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.format.bigdecimal.crypto
|
||||
import com.tangem.core.ui.format.bigdecimal.fiat
|
||||
import com.tangem.core.ui.format.bigdecimal.format
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyActionUM
|
||||
import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM
|
||||
import com.tangem.utils.StringsSigns.DOT
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import java.math.BigDecimal
|
||||
|
|
@ -24,11 +21,10 @@ internal class YieldSupplyStopEarningFeeContentTransformer(
|
|||
private val feeValue: BigDecimal,
|
||||
) : Transformer<YieldSupplyActionUM> {
|
||||
override fun transform(prevState: YieldSupplyActionUM): YieldSupplyActionUM {
|
||||
val feeFiatValue = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
|
||||
val feeFiatValueRaw = feeCryptoCurrencyStatus.value.fiatRate?.let { rate ->
|
||||
feeValue.multiply(rate)
|
||||
}
|
||||
val cryptoFee = feeValue.format { crypto(feeCryptoCurrencyStatus.currency) }
|
||||
val fiatFee = feeFiatValue.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
val fiatFeeText = feeFiatValueRaw.format { fiat(appCurrency.code, appCurrency.symbol) }
|
||||
|
||||
return if (cryptoCurrencyStatus.value is CryptoCurrencyStatus.Loading) {
|
||||
prevState.copy(yieldSupplyFeeUM = YieldSupplyFeeUM.Loading)
|
||||
|
|
@ -37,14 +33,11 @@ internal class YieldSupplyStopEarningFeeContentTransformer(
|
|||
isPrimaryButtonEnabled = true,
|
||||
yieldSupplyFeeUM = YieldSupplyFeeUM.Content(
|
||||
transactionDataList = transactions.toPersistentList(),
|
||||
feeValue = combinedReference(
|
||||
stringReference(cryptoFee),
|
||||
stringReference(" $DOT "),
|
||||
stringReference(fiatFee),
|
||||
),
|
||||
currentNetworkFeeValue = TextReference.EMPTY,
|
||||
maxNetworkFeeValue = TextReference.EMPTY,
|
||||
minAmountFeeValue = TextReference.EMPTY,
|
||||
feeFiatValue = stringReference(fiatFeeText),
|
||||
tokenFeeFiatValue = TextReference.EMPTY,
|
||||
maxNetworkFeeFiatValue = TextReference.EMPTY,
|
||||
minTopUpFiatValue = TextReference.EMPTY,
|
||||
feeNoteValue = TextReference.EMPTY,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ androidxWorkManager = "2.9.0"
|
|||
# endregion AndroidX
|
||||
|
||||
# region Compose
|
||||
compose-runtime = "1.7.4"
|
||||
compose-foundation = "1.7.4"
|
||||
compose-runtime = "1.7.8"
|
||||
compose-foundation = "1.7.8"
|
||||
compose-material3 = "1.3.1"
|
||||
compose-constraint = "1.0.1"
|
||||
compose-navigation = "2.7.7"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue