From 587d356bf3554349e689fd5b9ccce650d38388db Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 7 Nov 2025 11:31:03 +0500 Subject: [PATCH 01/20] Updated on 2026-08-14 --- .../sendviaswap/confirm/SendWithSwapConfirmComponent.kt | 2 +- .../sendviaswap/confirm/model/SendWithSwapConfirmModel.kt | 3 ++- .../swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt | 6 ++++-- .../swap/converters/SavedSwapTransactionListConverter.kt | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt index 348a673fd5..0b4b6b742e 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/SendWithSwapConfirmComponent.kt @@ -189,6 +189,6 @@ internal class SendWithSwapConfirmComponent @AssistedInject constructor( } interface ModelCallback { - fun onResult(sendWithSwapUM: SendWithSwapUM) + fun onResult(route: SendWithSwapRoute, sendWithSwapUM: SendWithSwapUM) } } \ No newline at end of file diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt index c4961dabf6..58c4d854b7 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/confirm/model/SendWithSwapConfirmModel.kt @@ -424,7 +424,8 @@ internal class SendWithSwapConfirmModel @Inject constructor( val confirmUM = state.confirmUM val isReadyToSend = confirmUM is ConfirmUM.Content && !confirmUM.isTransactionInProcess params.callback.onResult( - state.copy( + route = SendWithSwapRoute.Confirm, + sendWithSwapUM = state.copy( navigationUM = NavigationUM.Content( title = resourceReference(id = R.string.send_with_swap_confirm_title), subtitle = null, diff --git a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt index 357ffacf9c..3d6968a554 100644 --- a/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt +++ b/features/swap-v2/impl/src/main/java/com/tangem/features/swap/v2/impl/sendviaswap/model/SendWithSwapModel.kt @@ -116,8 +116,10 @@ internal class SendWithSwapModel @Inject constructor( uiState.update { it.copy(destinationUM = destinationUM) } } - override fun onResult(sendWithSwapUM: SendWithSwapUM) { - uiState.value = sendWithSwapUM + override fun onResult(route: SendWithSwapRoute, sendWithSwapUM: SendWithSwapUM) { + if (currentRoute.value == route) { + uiState.value = sendWithSwapUM + } } override fun onNavigationResult(navigationUM: NavigationUM) { diff --git a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt index 261e5f675c..f890932dfe 100644 --- a/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt +++ b/features/swap/data/src/main/java/com/tangem/feature/swap/converters/SavedSwapTransactionListConverter.kt @@ -55,7 +55,7 @@ internal class SavedSwapTransactionListConverter( userWallet = userWallet, network = fromNetwork, ) ?: return null - val toNetwork = createSwapTransactionNetwork(fromToken, userWallet) ?: return null + val toNetwork = createSwapTransactionNetwork(toToken, userWallet) ?: return null val toCryptoCurrency = responseCryptoCurrenciesFactory.createCurrency( responseToken = toToken, userWallet = userWallet, From 6fcc50a39906ae2e5765dbddca2d3b7c91a77c3d Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 7 Nov 2025 16:48:35 +0500 Subject: [PATCH 02/20] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 47 ++++++++++++++++++- core/res/src/main/res/values-es/strings.xml | 7 ++- core/res/src/main/res/values-fr/strings.xml | 3 ++ core/res/src/main/res/values-ja/strings.xml | 10 ++-- core/res/src/main/res/values-ru/strings.xml | 2 +- .../src/main/res/values-uk-rUA/strings.xml | 2 + core/res/src/main/res/values/strings.xml | 17 +++++-- .../impl/main/ui/YieldSupplyBlockContent.kt | 2 +- .../impl/promo/ui/YieldSupplyPromoContent.kt | 2 +- .../ui/YieldSupplyFeePolicyContent.kt | 2 +- .../model/YieldSupplyStartEarningModel.kt | 2 +- 11 files changed, 83 insertions(+), 13 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 13d5401bc0..cbf3127021 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -258,7 +258,6 @@ Aktivieren Aktiviert Fehler - Netzwerkdienstgebühr Umtausch Erkunden Transaktionsverlauf einsehen @@ -574,11 +573,14 @@ Gehe zum Backup Bitte sicher Deine Wallet, bevor Du einen Zugangscode erstellst. Zuerst die Sicherung abschließen + Unvollständig Andere Methoden Physische Geräte, die Deine privaten Schlüssel sicher offline speichern. Wiederherstellungs-Phrase Um Deine Wallet auf Hardware umzustellen, erstelle vorher ein Backup. + Deine privaten Schlüssel sind sicher verschlüsselt und auf Deinem Telefon gespeichert. Schlüssel werden in der App gespeichert + Erstelle oder stelle Deine Wallet mithilfe einer Wiederherstellungsphrase wieder her – Deinem integrierten Backup. Sicherung der Seed-Phrase Mobile Wallet erstellen Vorhandene Wallet importieren @@ -966,6 +968,7 @@ %s min Erhältlich ab + Verfügbar bis zu Du erhältst Der Service wird von einem externen Anbieter bereitgestellt. \n Tangem übernimmt keine Verantwortung. Du kannst diesen Bildschirm schließen und den Transaktionsstatus auf dem Bildschirm mit den Token-Details überprüfen. @@ -1188,8 +1191,10 @@ Ein Staking-Konto ist ein spezielles Konto, auf dem eingesetzte SOL-Token gespeichert werden. Es wird erstellt, indem Sie Ihre Token an einen Validator delegieren, um an der Transaktionsvalidierung teilzunehmen und Belohnungen zu erhalten. Für die Einrichtung des Staking-Kontos wird eine geringe Gebühr erhoben, die nach Abschluss des Stakings zurückerstattet wird. Jährliche prozentuale Rendite Die jährliche prozentuale Rendite, die du durch die Teilnahme am Staking erzielen kannst. + Jährlicher prozentualer Ertrag APY zeigt den jährlichen prozentualen Ertrag des Validators basierend auf seiner Leistung Effektiver Jahreszins + Effektiver Jahreszins Belohnungen sammeln sich täglich automatisch in deinem Staking-Konto an. Verfügbar Durchschnittliche Belohnungsquote @@ -1365,6 +1370,8 @@ Ausstehend Die Bank hat diese Transaktionsanfrage abgelehnt. Diese Gebühr dient zur Deckung der Kosten für die Abwicklung Deiner Überweisung. + Nutze Dein Geld weiterhin. Du kannst es jederzeit einfrieren. + Karte entsperren? Abhebung Guthaben hinzufügen Aufladeoptionen @@ -1389,6 +1396,7 @@ Aufdecken Tausche beliebige Vermögenswerte in Deinem Portfolio gegen eine Karte. Kartendetails + Karte entsperren Konto erstellen und Karte ausstellen Tangem Pay Status anzeigen @@ -1491,20 +1499,37 @@ Wallet umbenennen Alle freischalten Alle mit %s freischalten + AML-geprüft + Verfügbar + Gesperrt + Schulden Grenzen + Andere (kein OTP) + Einzeltransaktion + Gesamt Verfügbar für %d Tag Verfügbar für %d Tage + Das verfügbare Guthaben ist das tatsächlich verfügbare Guthaben unter Berücksichtigung ausstehender Transaktionen, gesperrter Beträge und Sollsaldo, um Überziehungskredite zu vermeiden. + Verfügbar bis %1$s Guthaben und Limits + Fehlende Zahlungskontoinformationen. Bitte kontaktiere den Support. + Informationen zum Token konnten nicht geladen werden. + Die Informationen werden noch geladen, bitte warten. + Limits sind erforderlich, um Kosten zu kontrollieren, die Sicherheit zu verbessern und Risiken zu managen. Du kannst %1$s ausgeben, während des Zeitraums für Kartenzahlungen in Geschäften und %2$s für andere Transaktionen, z.B. Abos oder Schulden. + Der Zugangscode dient zur Verwaltung Deines Zahlungskontos und zum Schutz vor unbefugtem Zugriff. Zugangscode Aktivierung des Kontos Bitte wähle die Wallet aus, mit der Du den Registrierungsprozess gestartet hast, um die Transaktion zur Erstellung Deines Kontos auf der Blockchain zu signieren + Aktivierung abbrechen Möchtest Du den Vorgang wirklich beenden? Du kannst später dort fortfahren, wo Du aufgehört hast. Das wird nicht lange dauern. Wir richten gerade Dein Konto ein. Das wird nicht lange dauern. Wir schließen die Aktivierung ab. Alles wird vorbereitet! Andere Wallet + Richte einen 4-stelligen Code ein. \n Dieser wird für Zahlungen verwendet. + PIN-Code PIN-Code erstellen PIN wurde nicht akzeptiert. Versuche es erneut oder verwende einen anderen Code. Ungültige PIN: Sequenzen oder Wiederholungen vermeiden @@ -1513,11 +1538,31 @@ Tangem Wallet vorbereiten Du kannst Deine Verbindung \n auf der Website des Drittanbieters \n herstellen und zurück zur Tangem-App gelangen Zur Website gehen + Wallet-Verbindung Wallet wählen + Aktivierung fortsetzen Fahren wir mit der Einrichtung Deines Kontos fort. Willkommen zurück! + Aktivierung starten Folge den Schritten, um Dein Konto einzurichten. Willkommen! + Blockchain Betrag + Währungscode + Datum + Fehlercode + Transaktionsdetails + Händlerkategoriecode + Handelsstadt + Händler-Ländercode + Händlername + ID anfordern + Status + Transaktion + Transaktionsbetrag + Transaktions-Hash + Transaktionsanfrage + Transaktionsstatus + Typ Diese Transaktion anfechten Freischalten Scanne Deine Karte, um den Zugriff freizuschalten diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 558a2135a6..a84c13660c 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -194,6 +194,7 @@ Velocidad y tarifa Finalizar Sincronizar direcciones + Comenzar Ir al proveedor Ir al token Entendido @@ -984,6 +985,7 @@ Una cuenta de staking es una cuenta especial donde se almacenan los tokens SOL de staking. Se crea cuando delegas sus tokens a un validador para participar en la validación de transacciones y ganar recompensas. Se cobra una pequeña tarifa por crear la cuenta de staking, que se devuelve una vez que se completa el staking. Porcentaje de rendimiento anual El porcentaje de rendimiento anual que podrá ganar como participante en el staking. + APY muestra el porcentaje de rendimiento anual del validador en función de su rendimiento APR APY Las recompensas se acumulan automáticamente en su saldo de staking diariamente. @@ -1160,6 +1162,7 @@ El envío de fondos estará disponible una vez que se complete(n) la(s) transacción(es) pendiente(s) en la red %s Vender %s no es compatible con los proveedores actuales, pero estamos trabajando para agregar más opciones. El staking de %s no es compatible con los proveedores actuales, pero estamos trabajando para agregar más opciones. + Se ha revocado la aprobación. Sus fondos permanecen en modo de rendimiento. Para realizar acciones, vuelva al modo de rendimiento y otorgue el permiso nuevamente. Generar XPUB Ocultar Está a punto de ocultar este token de la pantalla principal. Puede volver a agregarlo en cualquier momento a través de la página de gestión de tokens. @@ -1549,6 +1552,7 @@ Al desactivar esto, retirará sus fondos de Aave a %s en su billetera y dejará de ganar recompensas. La comisión de red se deducirá del importe que retire. Desactivar el modo de rendimiento + Suministrar Suministro APY APY Los intereses se devengan automáticamente @@ -1560,5 +1564,6 @@ Deposite algo de %1$s %2$s para cubrir la tarifa de red para las transacciones No se puede cubrir la tarifa %s El servicio de intereses no está disponible en este momento. Vuelva a intentarlo más tarde. - Ganancias no disponibles + Modo de rendimiento no disponible + No se puede cargar el gráfico... diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 778dc97f1b..4d0bd4f6aa 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -172,6 +172,7 @@ Vitesse et frais Terminer Synchroniser les adresses + Commencer Aller au fournisseur Aller au jeton Compris @@ -949,6 +950,7 @@ Cela supprimera le portefeuille de l\'application. Le portefeuille lui-même peut être ajouté à nouveau. Nom Faites travailler votre jeton pour vous + Pour commencer à staker, votre compte TON doit être activé avec une transaction de 1 TON. Les fonds restent sur votre compte, car cette étape sert uniquement à l\'activer pour le staking. Le montant à staker doit être au moins %s Le montant du staking sera arrondi à %1$s TRX en raison des règles du réseau. Le montant d\'annulation du staking sera arrondi à %1$s TRX en raison des règles du réseau. @@ -1132,6 +1134,7 @@ L\'envoi de fonds sera disponible une fois la ou les transactions en attente dans le réseau %s terminées. L\'achat de %s n\'est pas pris en charge par les fournisseurs actuels mais nous travaillons à ajouter plus d\'options. Le staking de %s n\'est pas pris en charge par les fournisseurs actuels, mais nous travaillons à ajouter plus d\'options. + L’autorisation a été révoquée. Vos fonds restent en mode rendement. Pour effectuer des actions, accédez au mode rendement et accordez à nouveau l’autorisation. Générer XPUB Masquer Vous êtes sur le point de masquer ce jeton de l\'écran principal. Vous pouvez le rajouter à tout moment via la page de gestion des jetons. diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 74b96d49b9..77b2d58b3b 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -253,7 +253,6 @@ 有効にする 有効 エラー - ネットワークサービス手数料 スワップ 移動する 取引履歴を調べる @@ -949,6 +948,7 @@ %s分 利用可能: + 利用可能金額 以下が手に入ります。 サービスは外部プロバイダーによって提供されます。 \nTangemは責任を負いません。 この画面を閉じて、トークンの詳細画面で取引状況を確認できます。 @@ -1158,11 +1158,12 @@ 名前 トークンを活用しよう ネットワーク手数料とは、ブロックチェーン上で取引を処理し、承認するために支払う少額の料金です。 - ステーキングを始めるには、1 TONの自己取引によってTONアカウントを有効化する必要があります。資金はウォレット内にそのまま残ります。これは、ステーキング有効化のためのステップにすぎません。 + ステーキングを始めるには、1 TONを取引してTONアカウントを有効化する必要があります。資金はウォレット内にそのまま残ります。これは、ステーキング有効化のためのステップにすぎません。 アカウントの有効化 ステーキング金額は %s 以上である必要があります ネットワークルールにより、ステーキング金額は%1$s TRX に切り上げられます。 ネットワークルールにより、ステーキング解除の量は%1$s TRX に切り上げられます。 + APR %1$s% ステーキング解除分を請求する ステーキングアカウント手数料 ステーキングアカウントとは、ステーキングされたSOLが保管される特別なアカウントです。トークンをバリデーターに委任し、取引の検証に参加して報酬を受け取る際に作成されます。ステーキングアカウントの作成には少額の手数料がかかりますが、ステーキング完了後に返金されます。 @@ -1346,6 +1347,8 @@ 保留中 銀行がこの取引リクエストを拒否しました。 この手数料は、送金処理にかかるコストをカバーするためのものです。 + 資金は引き続き使用できます。いつでも一時停止できます。 + カードの一時停止を解除しますか? 出金 資金を追加 入金オプション @@ -1370,6 +1373,7 @@ 表示 ポートフォリオ内のあらゆる資産をカードと交換 カードの詳細 + カードの一時停止を解除 アカウントを作成してカードを発行 Tangem Pay ステータスを表示 @@ -1856,7 +1860,7 @@ 次回の入金は自動的にAaveに供給されます。 アクティブ 停止中 - 利回りモードを無効にする + 利回りモードを解除中 これをオフにすると、Aaveから資産が引き出され、ウォレット内の%sに変換され、利回りの発生が停止します。 出金金額からネットワーク手数料が差し引かれます。 利回りモードを無効にする diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 7e27e29ccb..a4f1af4013 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -186,7 +186,6 @@ Включить Включено Ошибка - Комиссия сети Обменять Обозреватель Посмотреть историю транзакций @@ -1318,6 +1317,7 @@ Переименование кошелька Разблокировать все Разблокировать все с %s + Активация аккаунта ПИН не принят. Попробуйте ещё раз или введите другой код. Что выбрать? Блокчейн недоступен. Попробуйте позже. diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index bb34e10eab..eb74113ec1 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -172,6 +172,7 @@ Швидкість та комісія Завершити Синхронізувати адреси + Почати Перейти до провайдера Перейти до токену Зrozуміло @@ -1138,6 +1139,7 @@ Надсилання коштів стане доступним після завершення транзакції(-ій) в мережі %s Наразі продаж %s недоступний. Слідкуйте за нашими оновленнями. Стейкінг %s зараз недоступний. Будь ласка, слідкуйте за нашими оновленнями. + Дозвіл скасовано. Ваші кошти залишаються в режимі прибутковості. Щоб виконати дії, перейдіть у режим прибутковості та надайте дозвіл знову. Згенерувати XPUB Приховати Ви збираєтеся приховати цей токен з головного екрану. Ви можете додати його назад будь-коли на сторінці керування токенами. diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 759d5737b1..9c03a1494f 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -258,7 +258,7 @@ Enable Enabled Error - Network service fee + Estimated fee Swap Explore Explore transaction history @@ -274,7 +274,7 @@ Free From Synchronize addresses - Get started + Learn more Get token Go to provider Go to token @@ -573,11 +573,13 @@ Upgrade current wallet Go to backup Please back up your wallet before creating an access code. + Finish Backup First Finalize backup first Incomplete Other methods Physical devices that securely store your private key offline. Recovery phrase + To secure your wallet with a Access Code, complete the backup first. To upgrade your wallet to hardware, back it up first. Your private keys are securely encrypted and stored on your phone Keys are stored in the app @@ -969,6 +971,7 @@ %s min Available from + Available up to You get Service is provided by an external provider. \nTangem is not responsible. You can close this screen and check the transaction status on the token details screen. @@ -1356,6 +1359,7 @@ You receive Choose token not available + Card frozen Deposit Dispute Explore transaction @@ -1363,13 +1367,19 @@ Fee Keep your money safe if your card is lost or stolen. You can unfreeze anytime. Freeze your card? + Failed to freeze the card. Try again later. Freeze + Your card is frozen. Get Help Completed Declined Pending The bank rejected this transaction request. This fee goes to cover the cost of handling your transfer. + Keep using your money. You can freeze anytime. + Unfreeze your card? + Failed to unfreeze the card. Try again later. + Your card is unfrozen. Withdrawal Add funds Top-up options @@ -1394,6 +1404,7 @@ Reveal Swap any asset in your portfolio for card Card details + Unfreeze Card Create account and issue a card Tangem Pay View Status @@ -1925,7 +1936,7 @@ When you top up, your funds will be automatically sent to Aave to start earning interest. %s will be deducted to cover the transaction fee. Supply assets Your %s will be supplied to Aave, but will remain manageable. - See fee policy + See top-up fee policy Your next top-ups will be automatically supplied to Aave. Active Paused diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt index 1cbf8f1cfe..1dc3b822c5 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt @@ -71,7 +71,7 @@ private fun SupplyAvailable(supplyUM: YieldSupplyUM.Available, modifier: Modifie modifier = modifier, button = { SecondaryButton( - text = stringResourceSafe(R.string.common_learn_more), + text = stringResourceSafe(R.string.common_get_started), onClick = supplyUM.onClick, size = TangemButtonSize.WideAction, modifier = Modifier.fillMaxWidth(), diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt index 12359bae82..5f3097807a 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt @@ -57,7 +57,7 @@ internal fun YieldSupplyPromoContent( onClick = clickIntents::onUrlClick, ) PrimaryButton( - text = stringResourceSafe(R.string.yield_module_start_earning), + text = stringResourceSafe(R.string.common_continue), onClick = clickIntents::onStartEarningClick, modifier = Modifier .padding( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt index ec32b8e52b..23b09ad7f7 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt @@ -91,7 +91,7 @@ internal fun YieldSupplyFeePolicyContent( YieldSupplyFeeUM.Loading -> null } YieldSupplyFeeRow( - title = resourceReference(R.string.yield_module_fee_policy_sheet_current_fee_title), + title = resourceReference(R.string.common_estimated_fee), value = currentFee, modifier = Modifier.padding(vertical = 12.dp), ) diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt index e890ae8bc5..95e7c4d6d1 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt @@ -144,7 +144,7 @@ internal class YieldSupplyStartEarningModel @Inject constructor( val transactionListData = yieldSupplyStartEarningUseCase( userWalletId = userWallet.walletId, cryptoCurrencyStatus = cryptoCurrencyStatus, - maxNetworkFee = maxFee.nativeMaxFee, + maxNetworkFee = maxFee.tokenMaxFee, ).getOrNull() if (transactionListData == null) { From 540d1382f11d3d5399ac505a475341d46a85af1a Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 10 Nov 2025 14:31:43 +0500 Subject: [PATCH 03/20] Updated on 2026-08-14 --- .../tangem/core/ui/components/label/Label.kt | 28 +++++++++++++------ .../ui/components/label/entity/LabelUM.kt | 1 + .../impl/apy/ui/YieldSupplyApyContent.kt | 7 ++++- .../impl/promo/ui/YieldSupplyPromoContent.kt | 13 +++++++-- .../active/ui/YieldSupplyActiveContent.kt | 15 +++++++--- .../ui/YieldSupplyFeePolicyContent.kt | 5 ++++ 6 files changed, 53 insertions(+), 16 deletions(-) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt b/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt index 951e6a5042..2cc6209978 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/label/Label.kt @@ -16,6 +16,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview @@ -68,9 +69,18 @@ fun Label(state: LabelUM, modifier: Modifier = Modifier) { horizontalArrangement = Arrangement.spacedBy(4.dp), modifier = modifier .padding(horizontal = 4.dp) - .background( - color = backgroundColor, - shape = TangemTheme.shapes.roundedCorners8, + .clip(TangemTheme.shapes.roundedCorners8) + .background(color = backgroundColor) + .then( + if (state.onClick != null) { + Modifier.clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = ripple(), + onClick = state.onClick, + ) + } else { + Modifier + }, ) .padding(horizontal = 8.dp, vertical = 4.dp), ) { @@ -86,11 +96,13 @@ fun Label(state: LabelUM, modifier: Modifier = Modifier) { imageVector = ImageVector.vectorResource(wrappedIcon), tint = iconColor, contentDescription = null, - modifier = Modifier.size(16.dp).clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = ripple(bounded = false), - onClick = { state.onIconClick?.invoke() }, - ), + modifier = Modifier + .size(16.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = ripple(bounded = false), + onClick = { state.onIconClick?.invoke() }, + ), ) } } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt index 1be654c994..9982a897b0 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/label/entity/LabelUM.kt @@ -8,6 +8,7 @@ data class LabelUM( val style: LabelStyle, @DrawableRes val icon: Int? = null, val onIconClick: (() -> Unit)? = null, + val onClick: (() -> Unit)? = null, ) enum class LabelStyle { diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt index 8d419ff256..ad2186300f 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/apy/ui/YieldSupplyApyContent.kt @@ -12,10 +12,12 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.appendInlineContent import androidx.compose.foundation.shape.CircleShape +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.res.painterResource import androidx.compose.ui.text.Placeholder import androidx.compose.ui.text.PlaceholderVerticalAlign @@ -114,7 +116,10 @@ internal fun YieldSupplyApyContent( ApyChart( isChartLoading = isLoading, chartComponent = chartComponent, - modifier = Modifier.padding(horizontal = 12.dp), + modifier = Modifier + .clip(RoundedCornerShape(14.dp)) + .background(TangemTheme.colors.background.action) + .padding(12.dp), ) SpacerH16() diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt index 5f3097807a..dc7127e226 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt @@ -4,13 +4,16 @@ import android.content.res.Configuration import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.Text +import androidx.compose.material3.ripple import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector @@ -106,7 +109,7 @@ private fun ColumnScope.Content(yieldSupplyPromoUM: YieldSupplyPromoUM, clickInt text = yieldSupplyPromoUM.subtitle, style = LabelStyle.REGULAR, icon = R.drawable.ic_information_24, - onIconClick = clickIntents::onApyInfoClick, + onClick = clickIntents::onApyInfoClick, ), ) SpacerH32() @@ -131,7 +134,11 @@ private fun YieldStatusAppBar(onBackClick: () -> Unit, onHowItWorksClick: () -> imageVector = ImageVector.vectorResource(R.drawable.ic_back_24), contentDescription = null, tint = TangemTheme.colors.icon.primary1, - modifier = Modifier.clickable(onClick = onBackClick), + modifier = Modifier.clickable( + onClick = onBackClick, + interactionSource = remember { MutableInteractionSource() }, + indication = ripple(bounded = false), + ), ) SpacerWMax() Text( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt index 0654981fee..689c77d719 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt @@ -26,7 +26,10 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider 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.SpacerH4 +import com.tangem.core.ui.components.SpacerH8 +import com.tangem.core.ui.components.SpacerWMax +import com.tangem.core.ui.components.TextShimmer import com.tangem.core.ui.components.notifications.Notification import com.tangem.core.ui.components.notifications.NotificationConfig import com.tangem.core.ui.decompose.ComposableContentComponent @@ -61,7 +64,7 @@ internal fun YieldSupplyActiveContent( .padding(12.dp), ) { CurrentApy(state.apy) - chartComponent.Content(Modifier.padding(bottom = 12.dp)) + chartComponent.Content(Modifier) } AnimatedVisibility(state.notifications.isNotEmpty()) { @@ -104,7 +107,7 @@ internal fun YieldSupplyActiveContent( @Composable private fun CurrentApy(apy: TextReference?, modifier: Modifier = Modifier) { - Column(modifier = modifier.padding(vertical = 12.dp)) { + Column(modifier = modifier) { Text( modifier = Modifier, text = stringResourceSafe(R.string.yield_module_earn_sheet_current_apy_title), @@ -156,7 +159,11 @@ private fun YieldSupplyActiveMyFunds( .clip(RoundedCornerShape(16.dp)) .background(TangemTheme.colors.background.action) .fillMaxWidth() - .padding(12.dp), + .padding( + top = 12.dp, + start = 12.dp, + end = 12.dp, + ), ) { Text( text = stringResourceSafe(R.string.yield_module_earn_sheet_my_funds_title), diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt index 23b09ad7f7..f00297a2f9 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/feepolicy/ui/YieldSupplyFeePolicyContent.kt @@ -7,6 +7,7 @@ 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.HorizontalDivider import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -100,6 +101,10 @@ internal fun YieldSupplyFeePolicyContent( YieldSupplyFeeUM.Error -> stringReference(StringsSigns.DASH_SIGN) YieldSupplyFeeUM.Loading -> null } + HorizontalDivider( + thickness = 0.5.dp, + color = TangemTheme.colors.stroke.primary, + ) YieldSupplyFeeRow( title = resourceReference(R.string.yield_module_fee_policy_sheet_max_fee_title), value = maxFee, From c54ca6134c0fdb322c79398a4a66e780e775832f Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 10 Nov 2025 16:27:16 +0500 Subject: [PATCH 04/20] Updated on 2026-08-14 --- .../common/ui/notifications/NotificationUM.kt | 18 +++++++-------- .../supply/impl/main/entity/YieldSupplyUM.kt | 1 + .../impl/main/model/YieldSupplyModel.kt | 6 +++-- .../impl/main/ui/YieldSupplyBlockContent.kt | 23 ++++++++++++++----- .../active/model/YieldSupplyActiveModel.kt | 2 +- .../active/ui/YieldSupplyActiveContent.kt | 5 ++++ 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt index 662a404f90..7425a7aa0f 100644 --- a/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt +++ b/common/ui/src/main/java/com/tangem/common/ui/notifications/NotificationUM.kt @@ -275,14 +275,6 @@ 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( @@ -301,7 +293,15 @@ sealed class NotificationUM(val config: NotificationConfig) { onCloseClick = onCloseClick, iconTint = iconTint, ), - ) + ) { + data class YieldSupplyNotAllAmountSupplied(val formattedAmount: String, val symbol: String) : Info( + title = resourceReference( + id = R.string.yield_module_amount_not_transfered_to_aave_title, + formatArgs = wrappedList(formattedAmount, symbol), + ), + subtitle = TextReference.EMPTY, + ) + } sealed interface Cardano { diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/entity/YieldSupplyUM.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/entity/YieldSupplyUM.kt index fab5e5aa21..a3ec2d930e 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/entity/YieldSupplyUM.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/entity/YieldSupplyUM.kt @@ -26,6 +26,7 @@ internal sealed class YieldSupplyUM { val rewardsApy: TextReference, val onClick: () -> Unit, val showWarningIcon: Boolean, + val showInfoIcon: Boolean, ) : YieldSupplyUM() @Immutable diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt index 2360b55d2d..4ae0cf1e53 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt @@ -253,8 +253,8 @@ internal class YieldSupplyModel @Inject constructor( private fun loadActiveState(cryptoCurrencyStatus: CryptoCurrencyStatus, yieldSupplyStatus: YieldSupplyStatus) { val cryptoCurrencyToken = cryptoCurrency as? CryptoCurrency.Token ?: return - val showWarningIcon = !yieldSupplyStatus.isAllowedToSpend || - cryptoCurrencyStatus.yieldSupplyNotAllAmountSupplied() + val showWarningIcon = !yieldSupplyStatus.isAllowedToSpend + val showInfoIcon = cryptoCurrencyStatus.yieldSupplyNotAllAmountSupplied() if (!yieldSupplyStatus.isAllowedToSpend) { analyticsEventsHandler.send( YieldSupplyAnalytics.NoticeApproveNeeded( @@ -282,6 +282,7 @@ internal class YieldSupplyModel @Inject constructor( ), onClick = ::onActiveClick, showWarningIcon = showWarningIcon, + showInfoIcon = showInfoIcon, apy = tokenStatus.apy.toString(), ) } @@ -298,6 +299,7 @@ internal class YieldSupplyModel @Inject constructor( rewardsApy = TextReference.EMPTY, onClick = ::onActiveClick, showWarningIcon = showWarningIcon, + showInfoIcon = showInfoIcon, apy = "", ) } diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt index 1dc3b822c5..d4414727ef 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt @@ -149,12 +149,21 @@ private fun SupplyContent(supplyUM: YieldSupplyUM.Content, modifier: Modifier = ) } SpacerW8() - AnimatedVisibility(supplyUM.showWarningIcon) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_alert_triangle_20), - contentDescription = null, - tint = TangemTheme.colors.icon.attention, - ) + AnimatedContent( + targetState = supplyUM, + ) { currentState -> + when { + currentState.showWarningIcon -> Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_alert_triangle_20), + contentDescription = null, + tint = TangemTheme.colors.icon.attention, + ) + currentState.showInfoIcon -> Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_alert_circle_red_20), + contentDescription = null, + tint = TangemTheme.colors.icon.accent, + ) + } } Icon( imageVector = ImageVector.vectorResource(R.drawable.ic_chevron_right_24), @@ -355,6 +364,7 @@ private class PreviewProvider : PreviewParameterProvider { onClick = {}, apy = "5.1", showWarningIcon = false, + showInfoIcon = true, ), YieldSupplyUM.Content( title = stringReference("Aave lending is active "), @@ -363,6 +373,7 @@ private class PreviewProvider : PreviewParameterProvider { onClick = {}, apy = "5.1", showWarningIcon = true, + showInfoIcon = false, ), YieldSupplyUM.Loading, YieldSupplyUM.Processing.Enter, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt index 070ec52cb7..414cd7a29d 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveModel.kt @@ -195,7 +195,7 @@ internal class YieldSupplyActiveModel @Inject constructor( blockchain = cryptoCurrency.network.name, ), ) - NotificationUM.Warning.YieldSupplyNotAllAmountSupplied( + NotificationUM.Info.YieldSupplyNotAllAmountSupplied( formattedAmount = formattedAmount, symbol = cryptoCurrency.symbol, ) diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt index 689c77d719..f303d4ae1e 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt @@ -74,6 +74,11 @@ internal fun YieldSupplyActiveContent( Notification( config = notificationUM.config, containerColor = TangemTheme.colors.background.action, + iconTint = if (notificationUM is NotificationUM.Info) { + TangemTheme.colors.icon.accent + } else { + null + }, ) } } From f88abf06b51cd2e78969c8b7620d1aa2fc80c421 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 11 Nov 2025 19:05:35 +0200 Subject: [PATCH 05/20] Updated on 2026-08-14 --- .gitignore | 1 + .../extension/AppExtensionConfigurations.kt | 11 +- .../plugin/configuration/model/AppConfig.kt | 2 - .../utils/VersionNameProvider.kt | 105 ++++++++++++++++++ 4 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionNameProvider.kt diff --git a/.gitignore b/.gitignore index cb56a9e269..345207b4eb 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ app/src/external/google-services.json # Kotlin Plugin .kotlin/ +find-latest-release-branch.output diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt index 88e9d25480..e60739fd69 100644 --- a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/configurations/extension/AppExtensionConfigurations.kt @@ -4,6 +4,7 @@ import com.android.build.gradle.AppExtension import com.tangem.plugin.configuration.model.AppConfig import com.tangem.plugin.configuration.model.BuildType import com.tangem.plugin.configuration.utils.BuildConfigFieldFactory +import com.tangem.plugin.configuration.utils.VersionNameProvider import org.gradle.api.Project import com.android.build.gradle.internal.dsl.BuildType as AndroidBuildType @@ -29,11 +30,11 @@ private fun AppExtension.configureDefaultConfig(project: Project) { AppConfig.versionCode } - versionName = if (project.hasProperty("versionName")) { - project.property("versionName") as String - } else { - AppConfig.versionName - } + // Get version name from property, git branch, or default config + val versionNameProvider = VersionNameProvider(project) + versionName = versionNameProvider.getVersionName() + + project.logger.lifecycle("Resolved versionName: $versionName") buildFeatures.buildConfig = true diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt index 5ddd7ba12d..25a86d101f 100644 --- a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/model/AppConfig.kt @@ -3,8 +3,6 @@ package com.tangem.plugin.configuration.model internal object AppConfig { const val packageName = "com.tangem.wallet" const val versionCode = 1 - const val versionName = "1.0.0-SNAPSHOT" - // const val versionName = "100.0.0-SNAPSHOT" //TODO: [REDACTED_JIRA] const val minSdkVersion = 24 const val targetSdkVersion = 35 const val compileSdkVersion = 35 diff --git a/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionNameProvider.kt b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionNameProvider.kt new file mode 100644 index 0000000000..905d2f12e4 --- /dev/null +++ b/plugins/configuration/src/main/kotlin/com/tangem/plugin/configuration/utils/VersionNameProvider.kt @@ -0,0 +1,105 @@ +package com.tangem.plugin.configuration.utils + +import org.gradle.api.Project +import org.gradle.api.provider.Provider + +/** + * Provides version name based on current git branch + */ +internal class VersionNameProvider( + private val project: Project, +) { + + /** + * Get version name for current branch. + * If -PversionName is provided, uses that value. + * Otherwise, derives version from git branch name. + */ + fun getVersionName(): String { + // Check if versionName is provided as gradle property + if (project.hasProperty("versionName")) { + return project.property("versionName") as String + } + + // Get current branch name using Provider API (configuration cache compatible) + val currentBranch = getCurrentBranchProvider().get() + + // Try to extract version from branch name (releases/X.Y) + val versionFromBranch = extractVersionFromBranch(currentBranch) + if (versionFromBranch != null) { + return versionFromBranch + } + + // For other branches (develop, feature/*), find latest release branch and increment minor + val latestReleaseBranch = findLatestReleaseBranch() + if (latestReleaseBranch != null) { + val versionFromLatest = extractVersionFromBranch(latestReleaseBranch) + if (versionFromLatest != null) { + return incrementMinorVersion(versionFromLatest) + } + } + + // Fallback to default if nothing works + return "1.0.0-SNAPSHOT" + } + + private fun getCurrentBranchProvider(): Provider { + return project.providers.exec { + commandLine("git", "rev-parse", "--abbrev-ref", "HEAD") + }.standardOutput.asText.map { it.trim() } + } + + private fun findLatestReleaseBranch(): String? { + val scriptPath = project.rootProject.file("tangem-android-tools/CI/shell_scripts/find-latest-release-branch.sh") + if (!scriptPath.exists()) { + project.logger.warn("Script not found: $scriptPath") + return null + } + + val currentBranch = getCurrentBranchProvider().get() + val outputFile = project.rootProject.file("find-latest-release-branch.output") + + return try { + project.providers.exec { + commandLine("sh", scriptPath.absolutePath, currentBranch) + }.standardOutput.asText.get() + + if (!outputFile.exists()) { + project.logger.warn("Script output file not found") + return null + } + + outputFile.readText().trim().also { result -> + project.logger.lifecycle("Found latest release branch: $result") + outputFile.delete() + } + } catch (e: Exception) { + project.logger.warn("Failed to execute script: ${e.message}") + outputFile.delete() + null + } + } + + private fun extractVersionFromBranch(branch: String): String? { + val regex = Regex("""^releases/(\d+)\.(\d+)(?:\.(\d+))?$""") + val matchResult = regex.find(branch) ?: return null + + val major = matchResult.groupValues[1] + val minor = matchResult.groupValues[2] + val patch = matchResult.groupValues[3].ifEmpty { "0" } + + return "$major.$minor.$patch" + } + + private fun incrementMinorVersion(version: String): String { + val parts = version.split(".") + if (parts.size < 2) return version + + val major = parts[0] + val minor = parts[1].toIntOrNull() ?: return version + val newMinor = minor + 1 + + return "$major.$newMinor.0" + } + +} \ No newline at end of file From c1a7434cbf7f05165621544fdff9b4bd11bdb72e Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 11 Nov 2025 23:15:40 +0200 Subject: [PATCH 06/20] Updated on 2026-08-14 --- .../staking/analytics/StakingAnalyticsEvent.kt | 12 +++++++++++- .../presentation/model/StakingClickIntents.kt | 3 +++ .../impl/presentation/model/StakingModel.kt | 18 ++++++++++++++++++ .../state/stub/StakingClickIntentsStub.kt | 2 ++ .../AddStakingNotificationsTransformer.kt | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt b/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt index 8279bb4189..42da91d04f 100644 --- a/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt +++ b/domain/staking/src/main/java/com/tangem/domain/staking/analytics/StakingAnalyticsEvent.kt @@ -160,10 +160,20 @@ sealed class StakingAnalyticsEvent( ), ) - data class UnitializedAddress(val token: String) : StakingAnalyticsEvent( + data class UninitializedAddress(val token: String) : StakingAnalyticsEvent( event = "Notice - Uninitialized Address", params = mapOf(AnalyticsParam.TOKEN_PARAM to token), ) + + data class UninitializedAddressScreen(val token: String) : StakingAnalyticsEvent( + event = "Uninitialized Address Screen", + params = mapOf(AnalyticsParam.TOKEN_PARAM to token), + ) + + data class ButtonActivate(val token: String) : StakingAnalyticsEvent( + event = "Button - Activate", + params = mapOf(AnalyticsParam.TOKEN_PARAM to token), + ) } enum class StakeScreenSource { diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingClickIntents.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingClickIntents.kt index 97e447a0f5..7e79b03b94 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingClickIntents.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingClickIntents.kt @@ -9,6 +9,7 @@ import com.tangem.features.staking.impl.presentation.state.BalanceState import com.tangem.features.staking.impl.presentation.state.bottomsheet.InfoType import java.math.BigDecimal +// TODO split this interface to click intents and other interaction events @Suppress("TooManyFunctions") internal interface StakingClickIntents : AmountScreenClickIntents { @@ -72,5 +73,7 @@ internal interface StakingClickIntents : AmountScreenClickIntents { fun onActivateTonAccountNotificationClick() + fun onActivateTonAccountNotificationShow() + fun onActivateTonAccountClick() } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt index 3ae4a70812..673c1398e0 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/model/StakingModel.kt @@ -943,6 +943,11 @@ internal class StakingModel @Inject constructor( } override fun onActivateTonAccountNotificationClick() { + analyticsEventHandler.send( + StakingAnalyticsEvent.UninitializedAddressScreen( + token = cryptoCurrencyStatus.currency.symbol, + ), + ) modelScope.launch { stateController.update( ShowTonInitializeBottomSheetTransformer( @@ -996,7 +1001,20 @@ internal class StakingModel @Inject constructor( } } + override fun onActivateTonAccountNotificationShow() { + analyticsEventHandler.send( + StakingAnalyticsEvent.UninitializedAddress( + token = cryptoCurrencyStatus.currency.symbol, + ), + ) + } + override fun onActivateTonAccountClick() { + analyticsEventHandler.send( + StakingAnalyticsEvent.ButtonActivate( + token = cryptoCurrencyStatus.currency.symbol, + ), + ) modelScope.launch { tonAccountInitializeTransaction?.let { transaction -> sendTransactionUseCase.invoke( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt index d7fac733a7..1b90c1dc49 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/stub/StakingClickIntentsStub.kt @@ -81,5 +81,7 @@ internal object StakingClickIntentsStub : StakingClickIntents { override fun onActivateTonAccountNotificationClick() {} + override fun onActivateTonAccountNotificationShow() {} + override fun onActivateTonAccountClick() {} } \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt index b4daf2050b..66d3c56eac 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/notifications/AddStakingNotificationsTransformer.kt @@ -295,6 +295,7 @@ internal class AddStakingNotificationsTransformer( val cryptoCurrencyNetworkIdValue = cryptoCurrencyStatusProvider().currency.network.rawId if (isTon(cryptoCurrencyNetworkIdValue) && !isAccountInitialized) { + prevState.clickIntents.onActivateTonAccountNotificationShow() add( StakingNotification.Warning.InitializeTonAccount( onInitializeClick = prevState.clickIntents::onActivateTonAccountNotificationClick, From 0fb5081daf9b9189231e315bdec290519e857cef Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 13 Nov 2025 13:00:46 +0500 Subject: [PATCH 07/20] Updated on 2026-08-14 --- ...TransactionDataToTxHistoryItemConverter.kt | 57 ++++++++++++++----- data/yield-supply/build.gradle.kts | 1 + .../supply/DefaultYieldSupplyRepository.kt | 50 +++++++++++++++- .../yield/supply/YieldSupplyRepository.kt | 19 ++++++- .../impl/main/model/YieldSupplyModel.kt | 36 ++++++++---- gradle/tangem_dependencies.toml | 2 +- 6 files changed, 133 insertions(+), 32 deletions(-) diff --git a/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/utils/TransactionDataToTxHistoryItemConverter.kt b/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/utils/TransactionDataToTxHistoryItemConverter.kt index 5701b7eb2e..dae65d3ec7 100644 --- a/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/utils/TransactionDataToTxHistoryItemConverter.kt +++ b/data/wallet-manager/src/main/java/com/tangem/data/walletmanager/utils/TransactionDataToTxHistoryItemConverter.kt @@ -1,10 +1,13 @@ package com.tangem.data.walletmanager.utils import com.tangem.blockchain.blockchains.ethereum.EthereumTransactionExtras +import com.tangem.blockchain.blockchains.ethereum.tokenmethods.ApprovalERC20TokenCallData import com.tangem.blockchain.common.* import com.tangem.blockchain.yieldsupply.providers.ethereum.factory.EthereumYieldSupplyDeployCallData import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyEnterCallData import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyExitCallData +import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyInitTokenCallData +import com.tangem.blockchain.yieldsupply.providers.ethereum.yield.EthereumYieldSupplyReactivateTokenCallData import com.tangem.blockchainsdk.models.UpdateWalletManagerResult.Address import com.tangem.domain.models.network.TxInfo import com.tangem.utils.converter.Converter @@ -37,25 +40,12 @@ internal class TransactionDataToTxHistoryItemConverter( addressType = TxInfo.AddressType.User(value.destinationAddress), ), sourceType = TxInfo.SourceType.Single(value.sourceAddress), - interactionAddressType = TxInfo.InteractionAddressType.User( - address = if (isOutgoing) value.destinationAddress else value.sourceAddress, - ), + interactionAddressType = getInteractionAddressType(value, isOutgoing), status = when (value.status) { TransactionStatus.Confirmed -> TxInfo.TransactionStatus.Confirmed TransactionStatus.Unconfirmed -> TxInfo.TransactionStatus.Unconfirmed }, - type = when (val extras = value.extras) { - is EthereumTransactionExtras -> { - when (extras.callData) { - is EthereumYieldSupplyDeployCallData, - is EthereumYieldSupplyEnterCallData, - -> TxInfo.TransactionType.YieldSupply.Enter - is EthereumYieldSupplyExitCallData -> TxInfo.TransactionType.YieldSupply.Exit - else -> TxInfo.TransactionType.Transfer - } - } - else -> TxInfo.TransactionType.Transfer - }, + type = getTransactionType(value.extras), amount = amount, ) } @@ -89,4 +79,41 @@ internal class TransactionDataToTxHistoryItemConverter( return amountToken.contractAddress.equals(feeToken.contractAddress, ignoreCase = true) && amountToken.symbol.equals(feeToken.symbol, ignoreCase = true) } + + private fun getInteractionAddressType( + value: TransactionData.Uncompiled, + isOutgoing: Boolean, + ): TxInfo.InteractionAddressType = when (val extras = value.extras) { + is EthereumTransactionExtras -> { + when (val callData = extras.callData) { + is ApprovalERC20TokenCallData -> TxInfo.InteractionAddressType.Contract( + address = callData.spenderAddress, + ) + else -> TxInfo.InteractionAddressType.User( + address = if (isOutgoing) value.destinationAddress else value.sourceAddress, + ) + } + } + else -> TxInfo.InteractionAddressType.User( + address = if (isOutgoing) value.destinationAddress else value.sourceAddress, + ) + } + + private fun getTransactionType(extras: TransactionExtras?): TxInfo.TransactionType { + return when (extras) { + is EthereumTransactionExtras -> { + when (extras.callData) { + is EthereumYieldSupplyDeployCallData, + is EthereumYieldSupplyReactivateTokenCallData, + is EthereumYieldSupplyInitTokenCallData, + is EthereumYieldSupplyEnterCallData, + -> TxInfo.TransactionType.YieldSupply.Enter + is EthereumYieldSupplyExitCallData -> TxInfo.TransactionType.YieldSupply.Exit + is ApprovalERC20TokenCallData -> TxInfo.TransactionType.Approve + else -> TxInfo.TransactionType.Transfer + } + } + else -> TxInfo.TransactionType.Transfer + } + } } \ No newline at end of file diff --git a/data/yield-supply/build.gradle.kts b/data/yield-supply/build.gradle.kts index 73b4ac8ab2..b53babcf05 100644 --- a/data/yield-supply/build.gradle.kts +++ b/data/yield-supply/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { implementation(projects.domain.yieldSupply.models) implementation(projects.domain.walletManager) implementation(projects.domain.legacy) + implementation(projects.domain.txhistory.models) implementation(projects.libs.blockchainSdk) diff --git a/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt b/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt index cdc6d867fc..48badf6ec8 100644 --- a/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt +++ b/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt @@ -12,6 +12,8 @@ import com.tangem.datasource.api.tangemTech.YieldSupplyApi import com.tangem.datasource.api.tangemTech.models.YieldSupplyChangeTokenStatusBody import com.tangem.datasource.local.yieldsupply.YieldMarketsStore 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.wallet.UserWalletId import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.yield.supply.YieldSupplyRepository @@ -109,16 +111,21 @@ internal class DefaultYieldSupplyRepository( override suspend fun saveTokenProtocolStatus( userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, - yieldSupplyEnterStatus: YieldSupplyEnterStatus, + yieldSupplyEnterStatus: YieldSupplyEnterStatus?, ) { - statusMap["${userWalletId}_${cryptoCurrency.id.value}"] = yieldSupplyEnterStatus + val key = getTokenProtocolStatusKey(userWalletId, cryptoCurrency) + if (yieldSupplyEnterStatus != null) { + statusMap[key] = yieldSupplyEnterStatus + } else { + statusMap.remove(key) + } } override fun getTokenProtocolStatus( userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, ): YieldSupplyEnterStatus? { - return statusMap["${userWalletId}_${cryptoCurrency.id.value}"] + return statusMap[getTokenProtocolStatusKey(userWalletId, cryptoCurrency)] } private fun List.enrichNetworkIds(): List { @@ -127,4 +134,41 @@ internal class DefaultYieldSupplyRepository( token.copy(backendId = chainIdMap[token.chainId]) } } + + override suspend fun getTokenPendingStatus( + userWalletId: UserWalletId, + cryptoCurrencyStatus: CryptoCurrencyStatus, + ): YieldSupplyEnterStatus? { + val cryptoCurrency = cryptoCurrencyStatus.currency + val walletManager = walletManagersFacade.getOrCreateWalletManager( + userWalletId = userWalletId, + blockchain = cryptoCurrency.network.toBlockchain(), + derivationPath = cryptoCurrency.network.derivationPath.value, + ) ?: error("Wallet manager not found") + + val pendingTxs = cryptoCurrencyStatus.value.pendingTransactions + + val yieldAddress = walletManager.calculateYieldModuleAddress() + val hasRecentYieldEnterTxs = pendingTxs.hasYieldEnterTransactions(yieldAddress) + val hasRecentYieldExitTxs = pendingTxs.hasYieldExitTransactions() + + return when { + hasRecentYieldEnterTxs -> YieldSupplyEnterStatus.Enter + hasRecentYieldExitTxs -> YieldSupplyEnterStatus.Exit + else -> null + } + } + + private fun Set.hasYieldEnterTransactions(yieldAddress: String) = any { + it.type == TxInfo.TransactionType.YieldSupply.Enter || + it.type == TxInfo.TransactionType.Approve && + (it.interactionAddressType as? TxInfo.InteractionAddressType.Contract)?.address == yieldAddress + } + + private fun Set.hasYieldExitTransactions() = any { + it.type == TxInfo.TransactionType.YieldSupply.Exit + } + + private fun getTokenProtocolStatusKey(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): String = + "${userWalletId}_${cryptoCurrency.id.value}" } \ No newline at end of file diff --git a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/YieldSupplyRepository.kt b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/YieldSupplyRepository.kt index 7fbbc6d543..8ab13bbac1 100644 --- a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/YieldSupplyRepository.kt +++ b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/YieldSupplyRepository.kt @@ -1,6 +1,7 @@ package com.tangem.domain.yield.supply import com.tangem.domain.models.currency.CryptoCurrency +import com.tangem.domain.models.currency.CryptoCurrencyStatus import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.yield.supply.models.YieldMarketToken import com.tangem.domain.yield.supply.models.YieldSupplyEnterStatus @@ -76,7 +77,7 @@ interface YieldSupplyRepository { suspend fun saveTokenProtocolStatus( userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency, - yieldSupplyEnterStatus: YieldSupplyEnterStatus, + yieldSupplyEnterStatus: YieldSupplyEnterStatus?, ) /** @@ -91,4 +92,20 @@ interface YieldSupplyRepository { * @return the last action intent or null if nothing has been recorded */ fun getTokenProtocolStatus(userWalletId: UserWalletId, cryptoCurrency: CryptoCurrency): YieldSupplyEnterStatus? + + /** + * Get the pending status of the yield protocol action for the given wallet and 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. The value is + * transient (in‑memory only) and is not persisted across app restarts. + * + * @param userWalletId the wallet to query + * @param cryptoCurrencyStatus the currency status to query + * @return the pending action intent or null if nothing has been recorded + */ + suspend fun getTokenPendingStatus( + userWalletId: UserWalletId, + cryptoCurrencyStatus: CryptoCurrencyStatus, + ): YieldSupplyEnterStatus? } \ No newline at end of file diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt index 4ae0cf1e53..d83e344df8 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt @@ -35,9 +35,9 @@ 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 import com.tangem.utils.coroutines.DelayedWork -import com.tangem.utils.transformer.update import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn +import com.tangem.utils.transformer.update import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* @@ -193,42 +193,54 @@ internal class YieldSupplyModel @Inject constructor( } @Suppress("MaximumLineLength") - private fun onCryptoCurrencyStatusUpdated(cryptoCurrencyStatus: CryptoCurrencyStatus) { + private fun onCryptoCurrencyStatusUpdated(cryptoCurrencyStatus: CryptoCurrencyStatus) = modelScope.launch { val yieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus val tokenProtocolStatus = yieldSupplyRepository.getTokenProtocolStatus( userWallet.walletId, cryptoCurrency, ) + val tokenPendingStatus = yieldSupplyRepository.getTokenPendingStatus( + userWallet.walletId, + cryptoCurrencyStatus, + ) + val isActive = yieldSupplyStatus?.isActive == true val isCryptoCurrencyStatusFromCache = cryptoCurrencyStatus.value.sources.networkSource != StatusSource.ACTUAL val processing = uiState.value is YieldSupplyUM.Processing Timber.d( - "currentUiState ${uiState.value.javaClass} \n" + - "yieldSupplyStatus $yieldSupplyStatus" + + "YIELD " + + "yieldSupplyStatus $yieldSupplyStatus " + "tokenProtocolStatus $tokenProtocolStatus " + + "tokenPendingStatus $tokenPendingStatus " + "isActive $isActive " + "processing $processing " + "isCryptoCurrencyStatusFromCache $isCryptoCurrencyStatusFromCache", ) if (isCryptoCurrencyStatusFromCache && processing) { - return + return@launch } when { - !isActive && tokenProtocolStatus == YieldSupplyEnterStatus.Enter -> { - uiState.update { YieldSupplyUM.Processing.Enter } - fetchCurrencyWithDelay() - } - isActive && tokenProtocolStatus == YieldSupplyEnterStatus.Exit -> { - uiState.update { YieldSupplyUM.Processing.Exit } + tokenProtocolStatus != null && tokenPendingStatus != null -> { + uiState.update { + when (tokenPendingStatus) { + YieldSupplyEnterStatus.Enter -> YieldSupplyUM.Processing.Enter + YieldSupplyEnterStatus.Exit -> YieldSupplyUM.Processing.Exit + } + } fetchCurrencyWithDelay() } else -> { + yieldSupplyRepository.saveTokenProtocolStatus( + userWalletId = userWallet.walletId, + cryptoCurrency = cryptoCurrency, + yieldSupplyEnterStatus = null, + ) sendInfoAboutProtocolStatus(cryptoCurrencyStatus) if (isActive) { loadActiveState( cryptoCurrencyStatus = cryptoCurrencyStatus, - yieldSupplyStatus = requireNotNull(yieldSupplyStatus), + yieldSupplyStatus = yieldSupplyStatus, ) } else { loadTokenStatus() diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 852b769c33..4e7835869e 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,7 +5,7 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.30-1299" +tangemBlockchainSdk = "releases-5.30-1305" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "releases-5.30-567" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ From 314526cbbd7b73e0b15ed44ee7b6f1739728d8b3 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 13 Nov 2025 13:38:19 +0500 Subject: [PATCH 08/20] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 5 ++- core/res/src/main/res/values-es/strings.xml | 1 + core/res/src/main/res/values-fr/strings.xml | 1 + core/res/src/main/res/values-ja/strings.xml | 32 ++++++++++----- core/res/src/main/res/values-ru/strings.xml | 3 +- .../src/main/res/values-uk-rUA/strings.xml | 1 + core/res/src/main/res/values/strings.xml | 39 +++++++++++++------ .../supply/DefaultYieldSupplyRepository.kt | 8 +++- .../domain/GetMultiWalletWarningsFactory.kt | 36 ++++++++--------- .../impl/main/model/YieldSupplyModel.kt | 10 ++++- .../impl/main/ui/YieldSupplyBlockContent.kt | 2 +- 11 files changed, 92 insertions(+), 46 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index cbf3127021..ddf5455028 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -258,6 +258,7 @@ Aktivieren Aktiviert Fehler + Geschätzte Gebühr Umtausch Erkunden Transaktionsverlauf einsehen @@ -1194,7 +1195,7 @@ Jährlicher prozentualer Ertrag APY zeigt den jährlichen prozentualen Ertrag des Validators basierend auf seiner Leistung Effektiver Jahreszins - Effektiver Jahreszins + APY Belohnungen sammeln sich täglich automatisch in deinem Staking-Konto an. Verfügbar Durchschnittliche Belohnungsquote @@ -1384,12 +1385,14 @@ Google Wallet öffnen Richte Tangem Pay mit wenigen Klicks ein und bezahlen mit Google Pay. Karte zu Google Pay hinzufügen + Karte zu Apple Pay hinzufügen Google Wallet öffnen Tippe auf „Karte hinzufügen“. Gebe die Kartendaten manuell ein Verifiziere die Karte mit dem Einmalpasswort (OPT), das an Dein Gerät gesendet wird. Alles erledigt! Deine Karte ist einsatzbereit. Karte zu Google Pay hinzufügen + Karte zu Apple Pay hinzufügen Teile Deine Adresse mit oder zeig den QR-Code. Es wurden technische Probleme festgestellt. Bitte versuche es später erneut oder kontaktiere den Support. Empfangen ist jetzt nicht verfügbar diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index a84c13660c..1a1ad0aad3 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -182,6 +182,7 @@ Activar Activado Error + Comisión de red por recarga Intercambiar Explore Explore historial de transacciones diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 4d0bd4f6aa..1da9dfb319 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -160,6 +160,7 @@ Activer Activé Erreur + Frais estimés Echanger Explorez Explorez l\'historique des transactions diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 77b2d58b3b..9a4215ccc4 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -253,6 +253,7 @@ 有効にする 有効 エラー + ネットワーク手数料 スワップ 移動する 取引履歴を調べる @@ -268,7 +269,7 @@ 無料 送信元 アドレスを同期する - はじめる + もっと詳しく トークンを取得 プロバイダーへ移動 トークンへ移動 @@ -369,6 +370,7 @@ 利用可能なネットワーク このトークンの導出パスが%1$sの導出パスと一致しています。トークンはこのアカウントに追加されます。 導出パスは別のアカウントに属します。 + トークンが%1$sアカウントに追加されました コントラクトアドレス コントラクトアドレスが無効です ネットワークを選択してください @@ -564,10 +566,12 @@ 現在のウォレットをアップグレードする バックアップへ移動 アクセスコードを作成する前にウォレットをバックアップしてください。 + まずバックアップを完了する まずバックアップを完了する その他の方法 秘密鍵をオフラインで安全に保存する物理デバイス。 リカバリーフレーズ + アクセスコードを使用してウォレットを保護するには、まずバックアップを完了してください。 ウォレットをハードウェアにアップグレードするには、まずバックアップしてください。 鍵はアプリに保存されます シードフレーズのバックアップ @@ -1333,6 +1337,7 @@ 受け取る トークンを選択 利用不可 + カードが凍結されています 入金 異議申し立て 取引を表示 @@ -1340,15 +1345,20 @@ 手数料 カードを紛失したり盗まれたりしても、資金を安全に保てます。一時停止はいつでも解除できます。 カードを一時停止しますか? + カードを凍結できませんでした。しばらくしてからもう一度お試しください。 一時停止 + カードが凍結されています サポートを受ける 完了 拒否 保留中 + 利用規約・手数料・利用制限 銀行がこの取引リクエストを拒否しました。 この手数料は、送金処理にかかるコストをカバーするためのものです。 資金は引き続き使用できます。いつでも一時停止できます。 カードの一時停止を解除しますか? + カードの凍結解除に失敗しました。しばらくしてからもう一度お試しください。 + カードの凍結が解除されました 出金 資金を追加 入金オプション @@ -1361,12 +1371,14 @@ Googleウォレットを開く 数回タップするだけでTangem Payの設定完了。Google Payですぐに支払いを始めましょう。 Google Payにカードを追加する + Apple Payにカードを追加する Googleウォレットを開く 「カードを追加」をタップします カードの詳細を手動で入力してください お使いの端末に送信されたワンタイムパスワード(OTP)でカードを認証してください。 準備完了!カードはすぐに使用できます。 Google Payにカードを追加する + Apple Payにカードを追加する アドレスを共有するか、QRコードを表示してください。 技術的な問題が検出されました。しばらくしてからもう一度お試しいただくか、サポートにお問い合わせください。 現在、受け取りは利用できません @@ -1379,12 +1391,12 @@ ステータスを表示 Tangem PayのKYC手続き進行中 カードをGET - ウォレットに追加して、どこでもスマートフォンで支払いができます。 - Apple Pay & Google Pay - USDC残高を使用して、毎日のお買い物をシームレスに支払います。 - 日常の買い物 - カードの詳細は保護されており、アプリ内で完全に制御できます。 - 内蔵セキュリティ + どこでも暗号資産を使える + Apple PayとGoogle Payに対応したデジタルカード付き + 購入時に追加手数料はかかりません。 + 余計な費用なしで、表示金額のみを支払う + あなたの住所や資産を開示することなく、個別の支払い用アカウントが作成されます。 + 他に類を見ないプライバシー 無料のCryptoカード\nを数分で入手しましょう Tangem Pay これは私のウォレットです @@ -1800,7 +1812,7 @@ 利息モードを有効にすると、このアドレスへの今後のすべての入金はAaveに送られます。ただし、資金の管理は引き続き自由に行えます。 %sはAaveに供給されています Aaveへの%1$s %2$sの供給は保留中です - 承認する + 承認 トークンの承認は取り消されました。サービス機能を再開するには、再度承認を行ってください。 承認が必要 手数料が差し引かれ、あなたの資産は再び貸し出されます。 @@ -1829,7 +1841,7 @@ 最大手数料 最小金額は、ネットワーク手数料がチャージ額の4%を超えないように現在の手数料に基づいて計算されます。その結果、最小金額は%1$s(%2$s)となります。 最低入金額 - 手数料ポリシー + 入金手数料ポリシー Tangemはまた、得られた利回りに対して15%のサービス手数料を差し引きます。 ネットワーク手数料が下がるか、残高が最低必要額に達すると、資金は自動的にAaveに供給されます。 過去のリターン @@ -1856,7 +1868,7 @@ 入金すると、資金は自動的にAaveに送金され、利息が付き始めます。%sが取引手数料として差し引かれます。 資産を供給する %sはAaveに供給されますが、管理可能な状態のままになります。 - 手数料ポリシーを見る + 入金手数料ポリシーを見る 次回の入金は自動的にAaveに供給されます。 アクティブ 停止中 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index a4f1af4013..1df2916b57 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -186,6 +186,7 @@ Включить Включено Ошибка + Комиссия сети Обменять Обозреватель Посмотреть историю транзакций @@ -1615,7 +1616,7 @@ Максимальная комиссия Минимальная сумма рассчитывается исходя из текущей комиссии сети, чтобы она не превышала 4%% от суммы пополнения, что составляет минимум %1$s (%2$s). Минимальный депозит - Политика комиссий + Политика комиссий за пополнение Tangem взимает комиссию за обслуживание в размере 15% от полученного дохода. Ваши средства будут автоматически переведены в Aave, как только комиссия сети снизится или баланс достигнет минимально необходимой суммы. Историческая доходность diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index eb74113ec1..35f9ffc00b 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -160,6 +160,7 @@ Увімкнути Увімкнено Помилка + Комісія мережі за поповнення Обміняти Оглядач Переглянути історію транзакцій diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 9c03a1494f..11fdaf6304 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -258,7 +258,7 @@ Enable Enabled Error - Estimated fee + Top-up network fee Swap Explore Explore transaction history @@ -274,7 +274,7 @@ Free From Synchronize addresses - Learn more + Get started Get token Go to provider Go to token @@ -378,6 +378,7 @@ Available networks Derivation of your token matches the derivation of %1$s. Your token will be added to this account. Derivation belongs to another account. + Token added to %1$s account Contract address Contract address is invalid Please select the network @@ -1360,6 +1361,7 @@ Choose token not available Card frozen + Card payment Deposit Dispute Explore transaction @@ -1371,9 +1373,11 @@ Freeze Your card is frozen. Get Help + Other Completed Declined Pending + Terms, Fees & Limits The bank rejected this transaction request. This fee goes to cover the cost of handling your transfer. Keep using your money. You can freeze anytime. @@ -1383,25 +1387,36 @@ Withdrawal Add funds Top-up options + Card Number Change PIN The card is fully ready for payments. PIN code created + CVC Failed to load data. Try again later. + Expiry Freeze Card + Hide details Hide Open Google Wallet Set up Tangem Pay in a few taps and start paying with Google Pay. Add your card to Google Pay + Add your card to Apple Pay Open Google Wallet + Tap “+” button on the top right + Open + Apple Wallet Tap “Add a card” + Tap “Debit or Credit Card” Enter the card details manually Verify card using the OTP sent to your device. All set! Your card is ready to use. Add card to Google Pay + Add card to Apple Pay Share your address or show QR-code Technical issues detected. Please try again later or contact support. Receive unavailable now Reveal + Show details Swap any asset in your portfolio for card Card details Unfreeze Card @@ -1410,13 +1425,15 @@ View Status KYC in progress for Tangem Pay Get card - Add to your wallet and pay with your phone anywhere. - Apple Pay & Google Pay - Use your USDC balance to pay for everyday purchases seamlessly. - Everyday purchases - Your card details are protected — full control in the app. - Built-in security + Spend your crypto anywhere + With digital card that works with Apple Pay and Google Pay + There are no additional fees for purchases + Pay exactly what you see + A separate payment account will be created without disclosing your addresses and assets + Unrivaled privacy Get your free Crypto Card\nin minutes + We’re fixing a technical issue. Please try again later. + Service temporarily unavailable Tangem Pay This is my wallet Balances hidden @@ -1880,7 +1897,7 @@ With Yield mode active, all future deposits to this address will go to Aave. You can still manage your funds freely. Your %s is supplied to Aave Supplying %1$s %2$s to Aave is pending - Give Approve + Approve Your token’s approval has been revoked. Grant it again to resume service functionality. Approve needed The fee will be taken out, and your assets will be lent again. @@ -1909,7 +1926,7 @@ Maximum fee The minimum amount is calculated based on the current network fee so that it does not exceed 4%% of the top-up amount, which makes the minimum %1$s (%2$s). Minimum top-up - Fee policy + Top-up fee policy Tangem also takes a 15% service fee on yield earned. Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount. Historical returns @@ -1950,7 +1967,7 @@ Interest accrues automatically. Interest accrues automatically Yield mode - Processing your deposit + Processing your top-up Yield Mode Automatic Deposit some %1$s %2$s to cover the network fee for transactions diff --git a/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt b/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt index 48badf6ec8..75f2634213 100644 --- a/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt +++ b/data/yield-supply/src/main/java/com/tangem/data/yield/supply/DefaultYieldSupplyRepository.kt @@ -24,6 +24,7 @@ import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.withContext +import timber.log.Timber import java.util.concurrent.ConcurrentHashMap internal class DefaultYieldSupplyRepository( @@ -138,7 +139,7 @@ internal class DefaultYieldSupplyRepository( override suspend fun getTokenPendingStatus( userWalletId: UserWalletId, cryptoCurrencyStatus: CryptoCurrencyStatus, - ): YieldSupplyEnterStatus? { + ): YieldSupplyEnterStatus? = try { val cryptoCurrency = cryptoCurrencyStatus.currency val walletManager = walletManagersFacade.getOrCreateWalletManager( userWalletId = userWalletId, @@ -152,11 +153,14 @@ internal class DefaultYieldSupplyRepository( val hasRecentYieldEnterTxs = pendingTxs.hasYieldEnterTransactions(yieldAddress) val hasRecentYieldExitTxs = pendingTxs.hasYieldExitTransactions() - return when { + when { hasRecentYieldEnterTxs -> YieldSupplyEnterStatus.Enter hasRecentYieldExitTxs -> YieldSupplyEnterStatus.Exit else -> null } + } catch (e: Exception) { + Timber.e(e, "Failed to get pending yield supply status") + null } private fun Set.hasYieldEnterTransactions(yieldAddress: String) = any { diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt index 108d706b1d..e21b971fe1 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt @@ -36,7 +36,6 @@ import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.presentation.account.AccountDependencies import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification -import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles import com.tangem.lib.crypto.BlockchainUtils.isBitcoin import com.tangem.utils.extensions.addIf import com.tangem.utils.extensions.isPositive @@ -62,7 +61,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( private val onrampSepaAvailableUseCase: OnrampSepaAvailableUseCase, private val getOnrampCountryUseCase: GetOnrampCountryUseCase, private val notificationsRepository: NotificationsRepository, - private val yieldSupplyFeatureToggles: YieldSupplyFeatureToggles, private val accountDependencies: AccountDependencies, ) { @@ -134,7 +132,8 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( !notificationsRepository.isUserAllowToSubscribeOnPushNotifications(), ) - addYieldSupplyNotifications(flattenCurrencies) + // Remove in first iteration of yield supply feature + // addYieldSupplyNotifications(flattenCurrencies) val hasCriticalOrWarning = any { notification -> notification is WalletNotification.Critical || notification is WalletNotification.Warning @@ -319,14 +318,14 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( ) } - private fun MutableList.addYieldSupplyNotifications( - flattenCurrencies: Lce>, - ) { - addIf( - element = WalletNotification.Warning.YeildSupplyApprove, - condition = flattenCurrencies.hasTokensWithActivatedSupplyWithoutApprove(), - ) - } + // private fun MutableList.addYieldSupplyNotifications( + // flattenCurrencies: Lce>, + // ) { + // addIf( + // element = WalletNotification.Warning.YeildSupplyApprove, + // condition = flattenCurrencies.hasTokensWithActivatedSupplyWithoutApprove(), + // ) + // } private fun MutableList.addWarningNotifications( cardTypesResolver: CardTypesResolver?, @@ -371,13 +370,14 @@ internal class GetMultiWalletWarningsFactory @Inject constructor( return flattenCurrencies.any { it.value is CryptoCurrencyStatus.Unreachable } } - private fun Lce>.hasTokensWithActivatedSupplyWithoutApprove(): Boolean { - val flattenCurrencies = getOrNull(isPartialContentAccepted = false) ?: return false - val yieldSupplyEnabled = yieldSupplyFeatureToggles.isYieldSupplyFeatureEnabled - return yieldSupplyEnabled && flattenCurrencies.any { - it.value.yieldSupplyStatus?.isAllowedToSpend == false - } - } + // Remove in first iteration of yield supply feature + // private fun Lce>.hasTokensWithActivatedSupplyWithoutApprove(): Boolean { + // val flattenCurrencies = getOrNull(isPartialContentAccepted = false) ?: return false + // val yieldSupplyEnabled = yieldSupplyFeatureToggles.isYieldSupplyFeatureEnabled + // return yieldSupplyEnabled && flattenCurrencies.any { + // it.value.yieldSupplyStatus?.isAllowedToSpend == false + // } + // } private fun MutableList.addRateTheAppNotification( isReadyToShowRating: Boolean, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt index d83e344df8..f73b643b1b 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt @@ -72,6 +72,7 @@ internal class YieldSupplyModel @Inject constructor( val bottomSheetNavigation: SlotNavigation = SlotNavigation() + private val handleNavigation = params.handleNavigation private val cryptoCurrency = params.cryptoCurrency var userWallet: UserWallet by Delegates.notNull() @@ -91,8 +92,13 @@ internal class YieldSupplyModel @Inject constructor( init { checkIfYieldSupplyIsAvailable() - params.handleNavigation?.let { handle -> - if (handle) { + + val protocolStatus = yieldSupplyRepository.getTokenProtocolStatus( + userWalletId = params.userWalletId, + cryptoCurrency = cryptoCurrency, + ) + if (handleNavigation != null && protocolStatus == null) { + if (handleNavigation) { modelScope.launch { delay(timeMillis = 1000) bottomSheetNavigation.activate(Unit) diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt index d4414727ef..df2c84d279 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt @@ -71,7 +71,7 @@ private fun SupplyAvailable(supplyUM: YieldSupplyUM.Available, modifier: Modifie modifier = modifier, button = { SecondaryButton( - text = stringResourceSafe(R.string.common_get_started), + text = stringResourceSafe(R.string.common_learn_more), onClick = supplyUM.onClick, size = TangemButtonSize.WideAction, modifier = Modifier.fillMaxWidth(), From c4bbacd9c3956132c5261713fa2409bed52ccf85 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 13 Nov 2025 20:21:10 +0500 Subject: [PATCH 09/20] Updated on 2026-08-14 --- .../impl/main/model/YieldSupplyModel.kt | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt index f73b643b1b..a6ab368dc5 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/model/YieldSupplyModel.kt @@ -1,5 +1,6 @@ package com.tangem.features.yield.supply.impl.main.model +import android.os.SystemClock import com.arkivanov.decompose.router.slot.SlotNavigation import com.arkivanov.decompose.router.slot.activate import com.tangem.common.routing.AppRoute.YieldSupplyPromo @@ -46,7 +47,7 @@ import timber.log.Timber import javax.inject.Inject import kotlin.properties.Delegates -@Suppress("LongParameterList") +@Suppress("LongParameterList", "LargeClass") @ModelScoped internal class YieldSupplyModel @Inject constructor( paramsContainer: ParamsContainer, @@ -90,6 +91,8 @@ internal class YieldSupplyModel @Inject constructor( private var lastYieldSupplyStatus: YieldSupplyStatus? = null private val fetchCurrencyJobHolder = JobHolder() + private var lastStatusCheckTimestamp = 0L + init { checkIfYieldSupplyIsAvailable() @@ -228,22 +231,51 @@ internal class YieldSupplyModel @Inject constructor( when { tokenProtocolStatus != null && tokenPendingStatus != null -> { - uiState.update { - when (tokenPendingStatus) { - YieldSupplyEnterStatus.Enter -> YieldSupplyUM.Processing.Enter - YieldSupplyEnterStatus.Exit -> YieldSupplyUM.Processing.Exit + showProcessing(tokenPendingStatus) + lastStatusCheckTimestamp = 0L + } + tokenProtocolStatus == YieldSupplyEnterStatus.Exit && isActive || + tokenProtocolStatus == YieldSupplyEnterStatus.Enter && !isActive -> { + if (lastStatusCheckTimestamp != 0L) { + if (SystemClock.elapsedRealtime() - lastStatusCheckTimestamp > MAX_STATUS_CHECK_LIMIT) { + loadStatus(cryptoCurrencyStatus) + lastStatusCheckTimestamp = 0L + } else { + showProcessing(tokenProtocolStatus) } + } else { + showProcessing(tokenProtocolStatus) + lastStatusCheckTimestamp = SystemClock.elapsedRealtime() } - fetchCurrencyWithDelay() } else -> { + loadStatus(cryptoCurrencyStatus) + lastStatusCheckTimestamp = 0L + } + } + } + + private fun showProcessing(status: YieldSupplyEnterStatus) { + uiState.update { + when (status) { + YieldSupplyEnterStatus.Enter -> YieldSupplyUM.Processing.Enter + YieldSupplyEnterStatus.Exit -> YieldSupplyUM.Processing.Exit + } + } + fetchCurrencyWithDelay() + } + + private fun loadStatus(cryptoCurrencyStatus: CryptoCurrencyStatus) { + val yieldSupplyStatus = cryptoCurrencyStatus.value.yieldSupplyStatus + modelScope + .launch { yieldSupplyRepository.saveTokenProtocolStatus( userWalletId = userWallet.walletId, cryptoCurrency = cryptoCurrency, yieldSupplyEnterStatus = null, ) sendInfoAboutProtocolStatus(cryptoCurrencyStatus) - if (isActive) { + if (yieldSupplyStatus?.isActive == true) { loadActiveState( cryptoCurrencyStatus = cryptoCurrencyStatus, yieldSupplyStatus = yieldSupplyStatus, @@ -252,7 +284,6 @@ internal class YieldSupplyModel @Inject constructor( loadTokenStatus() } } - } } private fun fetchCurrencyWithDelay() { @@ -348,5 +379,6 @@ internal class YieldSupplyModel @Inject constructor( private companion object { const val PROCESSING_UPDATE_DELAY = 10_000L + const val MAX_STATUS_CHECK_LIMIT = 10_000L } } \ No newline at end of file From d293f60a6de8310962f125114bc26ecb390b0f7b Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 12:44:16 +0500 Subject: [PATCH 10/20] Updated on 2026-08-14 --- .../bottomsheets/TangemBottomSheetConfig.kt | 7 ++++++- .../modal/TangemModalBottomSheetWithFooter.kt | 12 +++++++++++- .../tangem/domain/yield/supply/FeeExtensions.kt | 2 +- .../YieldSupplyEstimateEnterFeeUseCaseTest.kt | 12 ++++++------ .../active/YieldSupplyActiveEntryComponent.kt | 4 +++- .../active/model/YieldSupplyActiveEntryModel.kt | 15 ++++++++++++++- .../ui/YieldSupplyActiveEntryBottomSheet.kt | 2 ++ .../approve/YieldSupplyApproveComponent.kt | 1 + .../approve/model/YieldSupplyApproveModel.kt | 3 +++ .../YieldSupplyStartEarningEntryComponent.kt | 3 +++ .../model/YieldSupplyStartEarningEntryModel.kt | 6 ++++-- .../ui/YieldSupplyStartEarningBottomSheet.kt | 2 ++ .../YieldSupplyStopEarningComponent.kt | 1 + .../model/YieldSupplyStopEarningModel.kt | 3 +++ 14 files changed, 60 insertions(+), 13 deletions(-) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheetConfig.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheetConfig.kt index 002cecf115..d99aefacb5 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheetConfig.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/TangemBottomSheetConfig.kt @@ -10,10 +10,15 @@ package com.tangem.core.ui.components.bottomsheets data class TangemBottomSheetConfig( val isShown: Boolean, val onDismissRequest: () -> Unit, + val dismissOnClickOutside: () -> Boolean = { true }, val content: TangemBottomSheetConfigContent, ) { companion object { - val Empty = TangemBottomSheetConfig(false, {}, TangemBottomSheetConfigContent.Empty) + val Empty = TangemBottomSheetConfig( + isShown = false, + onDismissRequest = {}, + content = TangemBottomSheetConfigContent.Empty, + ) } } \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/modal/TangemModalBottomSheetWithFooter.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/modal/TangemModalBottomSheetWithFooter.kt index 6506a16d14..8b2c012fc1 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/modal/TangemModalBottomSheetWithFooter.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/modal/TangemModalBottomSheetWithFooter.kt @@ -88,7 +88,17 @@ inline fun DefaultModalBottomSheetW noinline footer: @Composable (BoxScope.(T) -> Unit)?, ) { var isVisible by remember { mutableStateOf(value = config.isShown) } - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = skipPartiallyExpanded) + val sheetState = rememberModalBottomSheetState( + skipPartiallyExpanded = skipPartiallyExpanded, + confirmValueChange = { sheetValue -> + if (config.dismissOnClickOutside().not()) { + // Ignore transitions to hidden (prevents dismiss on outside click/back press) + sheetValue != SheetValue.Hidden + } else { + true + } + }, + ) if (isVisible && config.content is T) { BasicModalBottomSheetWithFooter( diff --git a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/FeeExtensions.kt b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/FeeExtensions.kt index 799506d8f2..6df54ae127 100644 --- a/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/FeeExtensions.kt +++ b/domain/yield-supply/src/main/java/com/tangem/domain/yield/supply/FeeExtensions.kt @@ -6,7 +6,7 @@ import java.math.BigInteger import java.math.RoundingMode private val HUNDRED_PERCENT = 100.toBigInteger() // base 100% -val INCREASE_GAS_LIMIT_FOR_SUPPLY = 112.toBigInteger() // 12% increase +val INCREASE_GAS_LIMIT_FOR_SUPPLY = 120.toBigInteger() // 20% increase fun Fee.fixFee(cryptoCurrency: CryptoCurrency, gasLimit: BigInteger): Fee = when (this) { is Fee.Ethereum.Legacy -> copy( diff --git a/domain/yield-supply/src/test/java/com/tangem/domain/yield/supply/YieldSupplyEstimateEnterFeeUseCaseTest.kt b/domain/yield-supply/src/test/java/com/tangem/domain/yield/supply/YieldSupplyEstimateEnterFeeUseCaseTest.kt index 20c7619b9e..38e789a341 100644 --- a/domain/yield-supply/src/test/java/com/tangem/domain/yield/supply/YieldSupplyEstimateEnterFeeUseCaseTest.kt +++ b/domain/yield-supply/src/test/java/com/tangem/domain/yield/supply/YieldSupplyEstimateEnterFeeUseCaseTest.kt @@ -314,9 +314,9 @@ class YieldSupplyEstimateEnterFeeUseCaseTest { val deployFee = txs.first().fee as Fee.Ethereum.EIP1559 val approveFee = txs[1].fee as Fee.Ethereum.EIP1559 val enterFee = txs.last().fee as Fee.Ethereum.EIP1559 - Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_120)) - Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_240)) - Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_360)) + Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_200)) + Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_400)) + Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_600)) } @Test @@ -353,9 +353,9 @@ class YieldSupplyEstimateEnterFeeUseCaseTest { val deployFee = txs.first().fee as Fee.Ethereum.Legacy val approveFee = txs[1].fee as Fee.Ethereum.Legacy val enterFee = txs.last().fee as Fee.Ethereum.Legacy - Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_120)) - Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_240)) - Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_360)) + Truth.assertThat(deployFee.gasLimit).isEqualTo(BigInteger.valueOf(1_200)) + Truth.assertThat(approveFee.gasLimit).isEqualTo(BigInteger.valueOf(2_400)) + Truth.assertThat(enterFee.gasLimit).isEqualTo(BigInteger.valueOf(3_600)) } private fun getDeployTx() = uncompiled( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveEntryComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveEntryComponent.kt index 59616762c7..89dcded7bf 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveEntryComponent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveEntryComponent.kt @@ -2,6 +2,7 @@ package com.tangem.features.yield.supply.impl.subcomponents.active import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.arkivanov.decompose.extensions.compose.subscribeAsState import com.arkivanov.decompose.router.stack.StackNavigation import com.arkivanov.decompose.router.stack.childStack @@ -59,9 +60,10 @@ internal class YieldSupplyActiveEntryComponent( @Composable override fun BottomSheet() { val stackState by innerStack.subscribeAsState() - + val isTransactionInProgress by model.isTransactionInProgressFlow.collectAsStateWithLifecycle() YieldSupplyActiveEntryBottomSheet( stackState = stackState, + dismissOnClickOutside = { !isTransactionInProgress }, onDismiss = ::dismiss, ) } diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveEntryModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveEntryModel.kt index 02fc956678..9f7ca52491 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveEntryModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/model/YieldSupplyActiveEntryModel.kt @@ -11,6 +11,9 @@ import com.tangem.features.yield.supply.impl.subcomponents.approve.YieldSupplyAp import com.tangem.features.yield.supply.impl.subcomponents.stopearning.YieldSupplyStopEarningComponent import com.tangem.utils.TangemBlogUrlBuilder import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.update import javax.inject.Inject @ModelScoped @@ -25,15 +28,25 @@ internal class YieldSupplyActiveEntryModel @Inject constructor( private val params = paramsContainer.require() + val isTransactionInProgressFlow: StateFlow + field = MutableStateFlow(false) + override fun onStopEarning() { router.push(YieldSupplyActiveRoute.Exit) } override fun onBackClick() { - router.pop() + if (!isTransactionInProgressFlow.value) { + router.pop() + } + } + + override fun onTransactionProgress(inProgress: Boolean) { + isTransactionInProgressFlow.update { inProgress } } override fun onTransactionSent() { + isTransactionInProgressFlow.update { false } params.onDismiss() } diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveEntryBottomSheet.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveEntryBottomSheet.kt index 124b736fa4..e4f47efa5e 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveEntryBottomSheet.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveEntryBottomSheet.kt @@ -14,12 +14,14 @@ import com.tangem.features.yield.supply.impl.subcomponents.active.model.YieldSup @Composable internal fun YieldSupplyActiveEntryBottomSheet( stackState: ChildStack, + dismissOnClickOutside: () -> Boolean, onDismiss: () -> Unit, ) { TangemModalBottomSheetWithFooter( config = TangemBottomSheetConfig( isShown = true, onDismissRequest = onDismiss, + dismissOnClickOutside = dismissOnClickOutside, content = TangemBottomSheetConfigContent.Empty, ), containerColor = TangemTheme.colors.background.tertiary, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/YieldSupplyApproveComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/YieldSupplyApproveComponent.kt index 3c1de839bb..c712301a01 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/YieldSupplyApproveComponent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/YieldSupplyApproveComponent.kt @@ -106,6 +106,7 @@ internal class YieldSupplyApproveComponent( interface ModelCallback { fun onBackClick() + fun onTransactionProgress(inProgress: Boolean) fun onTransactionSent() } } \ No newline at end of file diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt index bb92b7315b..e2c89da4c0 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/approve/model/YieldSupplyApproveModel.kt @@ -117,6 +117,8 @@ internal class YieldSupplyApproveModel @Inject constructor( } fun onClick() { + params.callback.onTransactionProgress(true) + val yieldSupplyFeeUM = uiState.value.yieldSupplyFeeUM as? YieldSupplyFeeUM.Content ?: return uiState.update(YieldSupplyTransactionInProgressTransformer) @@ -153,6 +155,7 @@ internal class YieldSupplyApproveModel @Inject constructor( } }, ) + params.callback.onTransactionProgress(false) }, ifRight = { val event = AnalyticsParam.TxSentFrom.Earning( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/YieldSupplyStartEarningEntryComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/YieldSupplyStartEarningEntryComponent.kt index 77763ea8fc..850ee680cd 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/YieldSupplyStartEarningEntryComponent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/YieldSupplyStartEarningEntryComponent.kt @@ -2,6 +2,7 @@ package com.tangem.features.yield.supply.impl.subcomponents.startearning import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.arkivanov.decompose.extensions.compose.subscribeAsState import com.arkivanov.decompose.router.stack.StackNavigation import com.arkivanov.decompose.router.stack.childStack @@ -56,9 +57,11 @@ internal class YieldSupplyStartEarningEntryComponent( @Composable override fun BottomSheet() { val stackState by innerStack.subscribeAsState() + val uiState by model.uiState.collectAsStateWithLifecycle() YieldSupplyStartEarningBottomSheet( stackState = stackState, + dismissOnClickOutside = { !uiState.isTransactionSending }, onDismiss = ::dismiss, ) } diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt index 2037750020..696f86af29 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt @@ -8,8 +8,8 @@ import com.tangem.core.decompose.navigation.Router import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList -import com.tangem.features.yield.supply.impl.R 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.entity.YieldSupplyActionUM import com.tangem.features.yield.supply.impl.common.entity.YieldSupplyFeeUM import com.tangem.features.yield.supply.impl.subcomponents.feepolicy.YieldSupplyFeePolicyComponent @@ -54,7 +54,9 @@ internal class YieldSupplyStartEarningEntryModel @Inject constructor( } override fun onBackClick() { - router.pop() + if (!uiState.value.isTransactionSending) { + router.pop() + } } override fun onFeePolicyClick() { diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/ui/YieldSupplyStartEarningBottomSheet.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/ui/YieldSupplyStartEarningBottomSheet.kt index aba821a580..6a7550515c 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/ui/YieldSupplyStartEarningBottomSheet.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/ui/YieldSupplyStartEarningBottomSheet.kt @@ -14,12 +14,14 @@ import com.tangem.features.yield.supply.impl.subcomponents.startearning.YieldSup @Composable internal fun YieldSupplyStartEarningBottomSheet( stackState: ChildStack, + dismissOnClickOutside: () -> Boolean, onDismiss: () -> Unit, ) { TangemModalBottomSheetWithFooter( config = TangemBottomSheetConfig( isShown = true, onDismissRequest = onDismiss, + dismissOnClickOutside = dismissOnClickOutside, content = TangemBottomSheetConfigContent.Empty, ), containerColor = TangemTheme.colors.background.tertiary, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/YieldSupplyStopEarningComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/YieldSupplyStopEarningComponent.kt index 2379649d45..e74a248197 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/YieldSupplyStopEarningComponent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/YieldSupplyStopEarningComponent.kt @@ -107,6 +107,7 @@ internal class YieldSupplyStopEarningComponent( interface ModelCallback { fun onBackClick() + fun onTransactionProgress(inProgress: Boolean) fun onTransactionSent() } } \ No newline at end of file diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt index c9dc0ec5fd..13daef75cc 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/stopearning/model/YieldSupplyStopEarningModel.kt @@ -126,6 +126,8 @@ internal class YieldSupplyStopEarningModel @Inject constructor( } fun onClick() { + params.callback.onTransactionProgress(true) + val yieldSupplyFeeUM = uiState.value.yieldSupplyFeeUM as? YieldSupplyFeeUM.Content ?: return analytics.send( YieldSupplyAnalytics.ButtonStopEarning( @@ -163,6 +165,7 @@ internal class YieldSupplyStopEarningModel @Inject constructor( } }, ) + params.callback.onTransactionProgress(false) }, ifRight = { onStopEarningTransactionSuccess() From e17996366a9d7d5534f57f90c5e146b4e02316de Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 14:04:37 +0500 Subject: [PATCH 11/20] Updated on 2026-08-14 --- .../impl/subcomponents/active/ui/YieldSupplyActiveContent.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt index f303d4ae1e..70282dca3f 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/ui/YieldSupplyActiveContent.kt @@ -226,7 +226,7 @@ private fun YieldSupplyActiveMyFunds( color = TangemTheme.colors.stroke.primary, ) HighComissionInfoRow( - title = resourceReference(R.string.common_network_fee_title), + title = resourceReference(R.string.common_estimated_fee), info = state.currentFee, isHighComission = state.isHighFee, ) From 804ea2b1b0cf0328df01f8d0c97d568a9f1ff1ed Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 14:58:48 +0500 Subject: [PATCH 12/20] Updated on 2026-08-14 --- core/res/src/main/res/values-fr/strings.xml | 10 ++-- core/res/src/main/res/values-ja/strings.xml | 16 +++++- core/res/src/main/res/values-ru/strings.xml | 4 +- core/res/src/main/res/values/strings.xml | 57 +++++++++++---------- 4 files changed, 52 insertions(+), 35 deletions(-) diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 1da9dfb319..2a30362217 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -1484,7 +1484,7 @@ 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. Mes fonds 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. - Gagner + Mode Rendement Total des gains Transferts vers Aave Découvrez Aave @@ -1500,7 +1500,7 @@ Tangem prélève également des frais de service de 15% sur les revenus générés. 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. Rendements historiques - L\'autorisation pour votre token en mode Yield a été révoquée. Ouvrez le token pour accorder à nouveau l\'autorisation. + L\'autorisation pour votre token en mode Rendement a été révoquée. Ouvrez le token pour accorder à nouveau l\'autorisation. Approbations de tokens nécessaires Vérifiez votre connexion réseau. Informations sur les frais de réseau inaccessibles @@ -1535,12 +1535,12 @@ APY Les intérêts sont cumulés automatiquement. Les intérêts sont cumulés automatiquement. - Mode de rendement + Mode Rendement Traitement de votre dépôt Mode Rendement Automatique Déposez %1$s %2$s pour couvrir les frais de réseau liés aux transactions. Impossible de couvrir les frais %s - Le service d\'intérêt n\'est pas disponible pour le moment. Veuillez réessayer plus tard. - Gains indisponibles + Le mode rendement n\'est pas disponible pour le moment. Veuillez réessayer plus tard. + Le mode Rendement est indisponible diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 9a4215ccc4..6b9eb2fcce 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -54,6 +54,8 @@ 新しいアカウントを破棄してもよろしいですか? 編集内容を破棄してもよろしいですか? 保存されていない変更 + 一部のカスタムトークンは、その派生がそのアカウントに属しているため、「 %1$s 」から「 %2$s 」に移動されました。 + 一部のカスタムトークンが移動されました トークンが見つかりませんか?メインページのマーケットセクションに移動し、ポートフォリオに追加して買付できるようにします。 トークンが見つかりませんか?メインページのマーケットセクションに移動し、ポートフォリオに追加して売却できるようにします。 売却 @@ -269,7 +271,7 @@ 無料 送信元 アドレスを同期する - もっと詳しく + はじめる トークンを取得 プロバイダーへ移動 トークンへ移動 @@ -1338,6 +1340,7 @@ トークンを選択 利用不可 カードが凍結されています + カード決済 入金 異議申し立て 取引を表示 @@ -1362,18 +1365,26 @@ 出金 資金を追加 入金オプション + カード番号 PINを変更する カードは支払いの準備が整いました。 PINコードを作成しました + CVC データの読み込みに失敗しました。しばらくしてからもう一度お試しください。 + 有効期限 カードの一時停止 + 詳細を隠す 非表示 Googleウォレットを開く 数回タップするだけでTangem Payの設定完了。Google Payですぐに支払いを始めましょう。 Google Payにカードを追加する Apple Payにカードを追加する Googleウォレットを開く + 右上の「+」ボタンをタップ + 開く + Apple Wallet 「カードを追加」をタップします + 「デビットカードまたはクレジットカード」をタップ カードの詳細を手動で入力してください お使いの端末に送信されたワンタイムパスワード(OTP)でカードを認証してください。 準備完了!カードはすぐに使用できます。 @@ -1383,6 +1394,7 @@ 技術的な問題が検出されました。しばらくしてからもう一度お試しいただくか、サポートにお問い合わせください。 現在、受け取りは利用できません 表示 + 詳細を表示 ポートフォリオ内のあらゆる資産をカードと交換 カードの詳細 カードの一時停止を解除 @@ -1398,6 +1410,8 @@ あなたの住所や資産を開示することなく、個別の支払い用アカウントが作成されます。 他に類を見ないプライバシー 無料のCryptoカード\nを数分で入手しましょう + 技術的な問題を修正しています。後でもう一度お試しください。 + サービスは一時的に利用できません Tangem Pay これは私のウォレットです 残高非表示 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 1df2916b57..9995970f79 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1620,7 +1620,7 @@ Tangem взимает комиссию за обслуживание в размере 15% от полученного дохода. Ваши средства будут автоматически переведены в Aave, как только комиссия сети снизится или баланс достигнет минимально необходимой суммы. Историческая доходность - Разрешение для вашего токена в Yield сервисе было отозвано. Откройте токен, чтобы выдать разрешение снова. + Разрешение для вашего токена в режиме доходности было отозвано. Откройте токен, чтобы выдать разрешение снова. Необходимо разрешение для токена Проверьте ваше интернет соединение Информация о комиссии недоступна @@ -1662,7 +1662,7 @@ Автоматически Внесите немного %1$s %2$s, чтобы покрыть комиссию сети за транзакции. Невозможно покрыть комиссию в %s - Сервис доходности в данный момент недоступен. Пожалуйста, попробуйте позже. + Режим доходности в данный момент недоступен. Пожалуйста, попробуйте позже. Режим доходности недоступен Невозможно загрузить график diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 11fdaf6304..dfd30b29a3 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -54,6 +54,8 @@ Are you sure you want to discard new account? Are you sure you want to discard edits? Unsaved Changes + Some custom tokens were moved from “%1$s” to “%2$s” as their derivation belongs to that account. + Some custom tokens were moved Can’t find your token? Go to the Market section on the main page and add it to your portfolio for purchase Can’t find your token? Go to the Market section on the main page and add it to your portfolio for selling. Sell @@ -1378,6 +1380,7 @@ Declined Pending Terms, Fees & Limits + Terms and Limits The bank rejected this transaction request. This fee goes to cover the cost of handling your transfer. Keep using your money. You can freeze anytime. @@ -1894,63 +1897,63 @@ No, send all Reduce by %s XTZ To avoid paying an increased commission the next time you top up your wallet, reduce the amount by %s XTZ - With Yield mode active, all future deposits to this address will go to Aave. You can still manage your funds freely. + When Yield Mode is active, all future top-ups to this address will be supplied to Aave. You can still manage your funds freely. Your %s is supplied to Aave Supplying %1$s %2$s to Aave is pending Approve - Your token’s approval has been revoked. Grant it again to resume service functionality. + Your token\'s approval has been revoked. Grant it again to resume the service\'s functionality. Approve needed - The fee will be taken out, and your assets will be lent again. - To continue earning, approval is required. + The fee will be deducted, and your assets will be resupplied. + To continue generating yield, approval is required. Confirm approval Your funds are currently supplied to the Aave protocol, but you can manage them at any time. - Your %s is deposited in Aave + Your %s is supplied to Aave Unable to load chart... - Supplying %1$s %2$s to Aave is pending. + Supply of %1$s %2$s to Aave is pending. APY %1$s%% Available Current APY When topping up for lending, a network fee not exceeding %1$s will be deducted from the balance. The network fee is currently too high to execute lending. Funds will be supplied once it drops to %1$s or below. My funds - Your %1$s is now deployed to Aave and earning yield. You hold %2$s tokens, which represent your balance and accrue yield automatically. When you top up, funds are added to Aave to earn more yield, minus fees. - Yield mode - Total earnings + Your %1$s is now deployed to Aave and generating yield. You hold %2$s tokens, representing your balance and accruing yield automatically. When you top up, the funds are supplied to Aave to generate more yield, after fees are deducted. + Yield Mode + Total yield Transfers to Aave Explore Aave This is the current supply fee on %s. The actual cost will be shown on the activation tab. Current fee - All future %s deposits will be supplied to Aave automatically, with the transaction fee deducted. - 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. - If network fees rise above maximum fee, the transaction won’t go through until they decrease. You can change this limit later. + All future %s top-ups will be supplied to Aave automatically, after the transaction fee is deducted. + 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. + If network fees rise above the maximum fee, the transaction won\'t go through until they decrease. You can change this limit later. Maximum fee - The minimum amount is calculated based on the current network fee so that it does not exceed 4%% of the top-up amount, which makes the minimum %1$s (%2$s). + The minimum amount is calculated based on the current network fee, ensuring it doesn\'t exceed 4% of the top-up amount, which equals the minimum %1$s (%2$s). Minimum top-up Top-up fee policy - Tangem also takes a 15% service fee on yield earned. + Tangem also takes a 15% service fee on yield generated. Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount. Historical returns - Approval for your token in the Yield mode has been revoked. Open the token to grant permission again. + Approval for your token in Yield Mode has been revoked. Open the token to grant permission again. Token approval needed Check your network connection Network fee info unreachable - Every deposit you make will be supplied to Aave automatically. - Auto-Transfer to Aave + Every top-up will be supplied to Aave automatically. + Auto-supply to Aave Send, swap, or sell your funds instantly, anytime you want. Access your funds anytime How it works? Aave is a decentralized protocol managing over $61 billion in total value. Decentralized and self-custodial By using this service, you agree with provider\n%1$s and %2$s - Connect Aave + Connect to Aave Aave %1$s%% • Variable Interest Rate Aave Avg %s Last year\'s returns - Current interest rate is always variable and automatically computed by the Aave on-chain smart-contract, based on real-time supply and demand. + The current interest rate is always variable and automatically computed by Aave\'s on-chain smart contract, based on real-time supply and demand. Powered by Interest rate is variable - When you top up, your funds will be automatically sent to Aave to start earning interest. %s will be deducted to cover the transaction fee. + When you top up, your funds will be automatically supplied to Aave to start generating yield. %s will be deducted to cover the transaction fee. Supply assets Your %s will be supplied to Aave, but will remain manageable. See top-up fee policy @@ -1960,19 +1963,19 @@ Disabling Yield Mode Turning this off will withdraw your assets from Aave, convert them back to %s in your wallet, and stop yield accrual. The network fee will be deducted from the amount you withdraw. - Disable yield mode + Disable Yield Mode Supply Supply APY APY - Interest accrues automatically. - Interest accrues automatically - Yield mode + Yield accrues automatically. + Yield accrues automatically + Yield Mode Processing your top-up Yield Mode Automatic - Deposit some %1$s %2$s to cover the network fee for transactions + Add some %1$s %2$s to cover the network fee for transactions. Unable to cover %s fee - The Yield mode service isn’t available at the moment. Please try again later. - Yield mode unavailable + Yield Mode isn\'t available at the moment. Please try again later. + Yield Mode unavailable Unable to load chart... From 4e10a0c4cae14a3b3e85d6944be57adbae4d97f2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 18:25:36 +0500 Subject: [PATCH 13/20] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 7 +++++-- core/res/src/main/res/values-es/strings.xml | 7 +++++-- core/res/src/main/res/values-fr/strings.xml | 7 +++++-- core/res/src/main/res/values-ja/strings.xml | 5 ++++- core/res/src/main/res/values-ru/strings.xml | 8 ++++++-- core/res/src/main/res/values-uk-rUA/strings.xml | 7 +++++-- core/res/src/main/res/values/strings.xml | 11 +++++++---- .../impl/common/ui/YieldSupplyActionContent.kt | 8 ++++++-- .../impl/main/ui/YieldSupplyBlockContent.kt | 17 +++-------------- .../impl/promo/entity/YieldSupplyPromoUM.kt | 1 + .../impl/promo/model/YieldSupplyPromoModel.kt | 1 + .../impl/promo/ui/YieldSupplyPromoContent.kt | 10 +++++++--- .../active/YieldSupplyActiveComponent.kt | 2 +- .../model/YieldSupplyStartEarningEntryModel.kt | 5 ++++- .../model/YieldSupplyStartEarningModel.kt | 7 +++++-- 15 files changed, 65 insertions(+), 38 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index ddf5455028..7de8b4b57e 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1884,6 +1884,7 @@ Deine%s ist in Aave hinterlegt Chart konnte nicht geladen werden... Das Bereitstellen von %1$s %2$s bei Aave steht aus. + Deaktiviere den Yield-Modus APY %1$s%% Verfügbar Aktueller effektiver Jahreszins @@ -1912,11 +1913,12 @@ Prüfe Deine Netzwerkverbindung Informationen zu den Netzwerkgebühren nicht erreichbar Jede Einzahlung, die Du tätigst, wird automatisch an Aave weitergeleitet. + Alle %1$s auf Ihrem Konto werden automatisch an Aave bereitgestellt. Automatische Übertragung zu Aave Senden, tauschen oder verkaufen Deine Gelder sofort, wann immer Du willst. - Jederzeit Zugriff auf Dein Geld + Sofort verfügbar Wie funktioniert das? - Aave ist ein dezentrales Protokoll, das ein Gesamtvermögen von über 61 Milliarden Dollar verwaltet. + Aave ist ein On-Chain-Protokoll zur Erstellung von nicht-kustodialen Liquiditätsmärkten, um Zinsen mit variablem Satz zu verdienen. Dezentral und selbstverwahrend Durch die Nutzung dieses Dienstes erklärst Du Dich mit provider\n%1$s und %2$s einverstanden Mit Aave verbinden @@ -1932,6 +1934,7 @@ Dein %s wird an Aave übermittelt, bleibt aber verwaltbar. Siehe Gebührenrichtlinie Deine nächste Aufladung wird automatisch an Aave weitergeleitet. + Alle Ihre zukünftigen eingehenden %1$s-Einlagen werden automatisch an Aave bereitgestellt. Aktiv Pausiert Deaktiviere den Yield-Modus diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 1a1ad0aad3..8379c45b32 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -1499,6 +1499,7 @@ Su %s está depositado en Aave No se puede cargar el gráfico... El suministro de %1$s %2$s a Aave está pendiente. + Desactivar el modo de rendimiento APY %1$s%% Disponible APY actual @@ -1527,11 +1528,12 @@ Compruebe su conexión de red Información de tarifas de red inaccesible Cada depósito que realice se suministrará a Aave automáticamente. + Todos los %1$s en tu cuenta se suministrarán automáticamente a Aave. Transferencia automática a Aave Envíe, intercambie o venda sus fondos al instante, cuando quiera. - Acceda a sus fondos en cualquier momento + Acceso inmediato ¿Cómo funciona? - Aave es un protocolo descentralizado que administra más de 61 billones de dólares en valor total. + Aave es un protocolo on-chain para crear mercados de liquidez no custodiales y ganar intereses a tasa variable. Descentralizado y autocustodiado Al utilizar este servicio, usted acepta que el proveedor\n%1$s y %2$s Conectar Aave @@ -1547,6 +1549,7 @@ Su %s se suministrará a Aave, pero seguirá siendo gestionable. Ver política de tarifas Sus próximas recargas se suministrarán automáticamente a Aave. + Todos tus futuros depósitos %1$s se suministrarán automáticamente a Aave. Activo En pausa Desactivación del modo de rendimiento diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 2a30362217..3c836280ec 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -1477,6 +1477,7 @@ Vos %s sont déposés dans Aave. Impossible de charger le graphique... L’approvisionnement de %1$s %2$s sur Aave est en attente. + Désactiver le mode rendement APY %1$s%% Disponible APY actuel @@ -1505,11 +1506,12 @@ Vérifiez votre connexion réseau. Informations sur les frais de réseau inaccessibles Chaque dépôt que vous effectuez sera automatiquement transféré à Aave. + Tous les %1$s de votre compte seront automatiquement fournis à Aave. Transfert automatique vers Aave Envoyez, échangez ou vendez vos fonds instantanément, quand vous le souhaitez. - Accédez à vos fonds à tout moment + Accès immédiat Comment ça marche ? - Aave est un protocole décentralisé qui gère plus de 61 milliards de dollars en valeur totale. + Aave est un protocole on-chain permettant de créer des marchés de liquidité non dépositaire pour gagner des intérêts à taux variable. Décentralisé et auto-détenu En utilisant ce service, vous acceptez les conditions générales du fournisseur %1$s et %2$s. Connecter Aave @@ -1525,6 +1527,7 @@ Vos %s seront fournis à Aave, mais resteront gérables. Voir la politique tarifaire Vos prochains dépôts seront automatiquement transférés vers Aave. + Tous vos futurs dépôts %1$s seront automatiquement fournis à Aave. Actif En pause Désactivation du mode de rendement diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 6b9eb2fcce..1ff1d4fbaf 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -1836,6 +1836,7 @@ あなたの%sはAaveに預けられています チャートを読み込めません・・ Aaveへの%1$s %2$sの供給は保留中です。 + 利回りモードを無効にする 年利%1$s%% 利用可能 現在のAPY @@ -1864,9 +1865,10 @@ ネットワーク接続を確認してください ネットワーク手数料についての情報にアクセスできません あなたが行うすべての入金は、自動的にAaveへ供給されます。 + アカウントのすべての %1$s は自動的に Aave に供給されます。 Aaveへの自動送金 いつでも、即座に資金を送信、交換、売却できます。 - いつでも資金にアクセス可能 + すぐに利用可能 使い方 Aaveは、総額610億ドル以上の資産を管理する分散型プロトコルです。 分散型・自己管理型 @@ -1884,6 +1886,7 @@ %sはAaveに供給されますが、管理可能な状態のままになります。 入金手数料ポリシーを見る 次回の入金は自動的にAaveに供給されます。 + 今後のすべての %1$s 入金は自動的に Aave に供給されます。 アクティブ 停止中 利回りモードを解除中 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 9995970f79..e12c0def79 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -179,6 +179,7 @@ дней Удалить + Отключить Отключено Отключить Готово @@ -1597,6 +1598,7 @@ Ваш %s внесён в Aave Невозможно загрузить график Отправка %1$s %2$s на Aave ожидает выполнения. + Завершить режим доходности APY %1$s%% Доступно Текущий APY @@ -1625,11 +1627,12 @@ Проверьте ваше интернет соединение Информация о комиссии недоступна Каждое пополнение вашего адреса автоматически будет отправляться в Aave. + Все %1$s на вашем счёте будут автоматически переданы в Aave. Автоперевод в AAVE Отправляйте, обменивайте или продавайте свои средства мгновенно, когда захотите. - Мгновенный вывод средств + Свободный доступ Как это работает? - Aave — децентрализованный протокол, управляющий активами на сумму более $61 млрд. + Aave — это ончейн-протокол для создания некостодиальных рынков ликвидности, позволяющий получать доход с переменной ставкой. Децентрализованный и некастодиальный Используя сервис, вы соглашаетесь с условиями провайдера %1$s и %2$s Подключить Aave @@ -1645,6 +1648,7 @@ Ваш %s будет передан в Aave и останется всегда доступным. Политика комиссий Следующие пополнения вашего счёта автоматически поступят в Aave. + Все ваши будущие поступления %1$s будут автоматически направляться в Aave. Активен На паузе Завершение режима доходности diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 35f9ffc00b..05d849f93f 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -1453,6 +1453,7 @@ Ваш %s внесений у Aave Неможливо завантажити графік Поповнення %1$s %2$s на Aave очікує виконання. + Завершити заробіток APY %1$s%% Доступно Поточний APY @@ -1481,11 +1482,12 @@ Перевірте підключення до мережі Інформація про комісію недоступна Кожен ваш депозит буде автоматично надходити до Aave. + Всі %1$s на вашому рахунку будуть автоматично передані в Aave. Автопереказ до AAVE Відправляйте, обмінюйте або продавайте свої кошти миттєво, в будь-який час. - Миттєвий вивід коштів + Вільний доступ Як це працює? - Aave — децентралізований протокол, що керує активами на понад $61 млрд. + Aave — це ончейн-протокол для створення некостодіальних ринків ліквідності, що дозволяє отримувати дохід з змінною ставкою. Децентралізований та некастодіальний Використовуючи сервіс, ви погоджуєтесь з умовами провайдера %1$s та %2$s Підключити Aave @@ -1501,6 +1503,7 @@ Ваш %s буде передано до Aave, і залишиться завжди доступним. Політика комісій Ваші наступні поповнення рахунку автоматично надходитимуть до Aave. + Всі ваші майбутні надходження %1$s будуть автоматично спрямовані в Aave. Активний На паузі Вимкнення режиму прибутковості diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index dfd30b29a3..9cb5e7b0a8 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1910,6 +1910,7 @@ Your %s is supplied to Aave Unable to load chart... Supply of %1$s %2$s to Aave is pending. + Disable Yield Mode APY %1$s%% Available Current APY @@ -1927,7 +1928,7 @@ 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. If network fees rise above the maximum fee, the transaction won\'t go through until they decrease. You can change this limit later. Maximum fee - The minimum amount is calculated based on the current network fee, ensuring it doesn\'t exceed 4% of the top-up amount, which equals the minimum %1$s (%2$s). + The minimum amount is calculated based on the current network fee, ensuring it doesn\'t exceed 4%% of the top-up amount, which equals the minimum %1$s (%2$s). Minimum top-up Top-up fee policy Tangem also takes a 15% service fee on yield generated. @@ -1938,11 +1939,12 @@ Check your network connection Network fee info unreachable Every top-up will be supplied to Aave automatically. + All %1$s on your account will be supplied to Aave automatically. Auto-supply to Aave Send, swap, or sell your funds instantly, anytime you want. - Access your funds anytime + No lock-ups How it works? - Aave is a decentralized protocol managing over $61 billion in total value. + Aave is an on-chain protocol that offers non-custodial liquidity markets, enabling users to accrue yield at variable rates. Decentralized and self-custodial By using this service, you agree with provider\n%1$s and %2$s Connect to Aave @@ -1955,9 +1957,10 @@ Interest rate is variable When you top up, your funds will be automatically supplied to Aave to start generating yield. %s will be deducted to cover the transaction fee. Supply assets - Your %s will be supplied to Aave, but will remain manageable. + Your %s will be supplied to Aave with no lock-ups and will remain fully accessible. See top-up fee policy Your next top-ups will be automatically supplied to Aave. + All your future incoming %1$s deposits will be automatically supplied to Aave. Active Paused Disabling Yield Mode diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/common/ui/YieldSupplyActionContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/common/ui/YieldSupplyActionContent.kt index 177149a2f3..d2b8c520de 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/common/ui/YieldSupplyActionContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/common/ui/YieldSupplyActionContent.kt @@ -94,7 +94,8 @@ internal fun YieldSupplyActionContent( YieldSupplyFeeRow( title = resourceReference(R.string.common_network_fee_title), value = fee, - modifier = Modifier.fillMaxWidth() + modifier = Modifier + .fillMaxWidth() .clip(RoundedCornerShape(14.dp)) .background(TangemTheme.colors.background.action) .padding(horizontal = 16.dp, vertical = 12.dp), @@ -139,7 +140,10 @@ private class YieldSupplyActionContentPreviewProvider : PreviewParameterProvider R.string.yield_module_start_earning_sheet_description, wrappedList("USDT"), ), - footer = resourceReference(R.string.yield_module_start_earning_sheet_next_deposits), + footer = resourceReference( + R.string.yield_module_start_earning_sheet_next_deposits_v2, + wrappedList("USDT"), + ), footerLink = resourceReference(R.string.yield_module_start_earning_sheet_fee_policy), currencyIconState = CurrencyIconState.Loading, yieldSupplyFeeUM = YieldSupplyFeeUM.Content( diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt index df2c84d279..08381eab85 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/main/ui/YieldSupplyBlockContent.kt @@ -55,8 +55,9 @@ internal fun YieldSupplyBlockContent(yieldSupplyUM: YieldSupplyUM, modifier: Mod resourceReference(R.string.yield_module_stop_earning), modifier, ) - YieldSupplyUM.Unavailable -> SupplyUnavailable(modifier) - YieldSupplyUM.Initial -> Unit + YieldSupplyUM.Unavailable, + YieldSupplyUM.Initial, + -> Unit } } } @@ -80,18 +81,6 @@ private fun SupplyAvailable(supplyUM: YieldSupplyUM.Available, modifier: Modifie ) } -@Composable -private fun SupplyUnavailable(modifier: Modifier = Modifier) { - SupplyInfo( - title = resourceReference(R.string.yield_module_unavailable_title), - subtitle = resourceReference(R.string.yield_module_unavailable_subtitle), - rewardsApy = null, - iconTint = TangemTheme.colors.icon.inactive, - button = null, - modifier = modifier, - ) -} - @Suppress("LongMethod") @Composable private fun SupplyContent(supplyUM: YieldSupplyUM.Content, modifier: Modifier = Modifier) { diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/entity/YieldSupplyPromoUM.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/entity/YieldSupplyPromoUM.kt index fca29d33ea..e10b365bf0 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/entity/YieldSupplyPromoUM.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/entity/YieldSupplyPromoUM.kt @@ -7,4 +7,5 @@ data class YieldSupplyPromoUM( val policyLink: String, val title: TextReference, val subtitle: TextReference, + val tokenSymbol: String, ) \ No newline at end of file diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/model/YieldSupplyPromoModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/model/YieldSupplyPromoModel.kt index 09c57f0305..2c01ceb12d 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/model/YieldSupplyPromoModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/model/YieldSupplyPromoModel.kt @@ -34,6 +34,7 @@ internal class YieldSupplyPromoModel @Inject constructor( val uiState: YieldSupplyPromoUM = YieldSupplyPromoUM( tosLink = TangemBlogUrlBuilder.YIELD_SUPPLY_TOS_URL, policyLink = TangemBlogUrlBuilder.YIELD_SUPPLY_PRIVACY_URL, + tokenSymbol = params.currency.symbol, title = resourceReference(R.string.yield_module_promo_screen_title), subtitle = resourceReference( R.string.yield_module_promo_screen_variable_rate_info, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt index dc7127e226..24eac0bb13 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/promo/ui/YieldSupplyPromoContent.kt @@ -113,7 +113,7 @@ private fun ColumnScope.Content(yieldSupplyPromoUM: YieldSupplyPromoUM, clickInt ), ) SpacerH32() - PromoItems() + PromoItems(yieldSupplyPromoUM.tokenSymbol) } SpacerH32() } @@ -151,7 +151,7 @@ private fun YieldStatusAppBar(onBackClick: () -> Unit, onHowItWorksClick: () -> } @Composable -private fun PromoItems() { +private fun PromoItems(tokenSymbol: String) { PromoItem( icon = R.drawable.ic_flash_new_24, title = resourceReference(R.string.yield_module_promo_screen_cash_out_title), @@ -161,7 +161,10 @@ private fun PromoItems() { PromoItem( icon = R.drawable.ic_repeat_24, title = resourceReference(R.string.yield_module_promo_screen_auto_balance_title), - subtitle = resourceReference(R.string.yield_module_promo_screen_auto_balance_subtitle), + subtitle = resourceReference( + R.string.yield_module_promo_screen_auto_balance_subtitle_v2, + wrappedList(tokenSymbol), + ), ) SpacerH24() PromoItem( @@ -258,6 +261,7 @@ private fun YieldSupplyPromoContent_Preview() { tosLink = "https://tangem.com/terms-of-service/", policyLink = "https://tangem.com/privacy-policy/", title = resourceReference(R.string.yield_module_promo_screen_title), + tokenSymbol = "USDT", subtitle = resourceReference(R.string.yield_module_promo_screen_variable_rate_info, wrappedList("5.3")), ), clickIntents = object : YieldSupplyPromoClickIntents { diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveComponent.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveComponent.kt index 0dccc9df82..18d339bb5c 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveComponent.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/active/YieldSupplyActiveComponent.kt @@ -58,7 +58,7 @@ internal class YieldSupplyActiveComponent( @Composable override fun Footer() { SecondaryButton( - text = stringResourceSafe(R.string.yield_module_stop_earning), + text = stringResourceSafe(R.string.yield_module_disable_button), onClick = params.callback::onStopEarning, modifier = Modifier .fillMaxWidth() diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt index 696f86af29..88108f3a9d 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningEntryModel.kt @@ -40,7 +40,10 @@ internal class YieldSupplyStartEarningEntryModel @Inject constructor( R.string.yield_module_start_earning_sheet_description, wrappedList(params.cryptoCurrency.symbol), ), - footer = resourceReference(R.string.yield_module_start_earning_sheet_next_deposits), + footer = resourceReference( + R.string.yield_module_start_earning_sheet_next_deposits_v2, + wrappedList(params.cryptoCurrency.symbol), + ), footerLink = resourceReference(R.string.yield_module_start_earning_sheet_fee_policy), currencyIconState = CryptoCurrencyToIconStateConverter().convert(params.cryptoCurrency), yieldSupplyFeeUM = YieldSupplyFeeUM.Loading, diff --git a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt index 95e7c4d6d1..3446144179 100644 --- a/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt +++ b/features/yield-supply/impl/src/main/java/com/tangem/features/yield/supply/impl/subcomponents/startearning/model/YieldSupplyStartEarningModel.kt @@ -45,7 +45,7 @@ import java.math.BigDecimal import javax.inject.Inject import kotlin.properties.Delegates -@Suppress("LongParameterList") +@Suppress("LongParameterList", "LargeClass") @ModelScoped internal class YieldSupplyStartEarningModel @Inject constructor( override val dispatchers: CoroutineDispatcherProvider, @@ -96,7 +96,10 @@ internal class YieldSupplyStartEarningModel @Inject constructor( R.string.yield_module_start_earning_sheet_description, wrappedList(cryptoCurrency.symbol), ), - footer = resourceReference(R.string.yield_module_start_earning_sheet_next_deposits), + footer = resourceReference( + R.string.yield_module_start_earning_sheet_next_deposits_v2, + wrappedList(cryptoCurrency.symbol), + ), footerLink = resourceReference(R.string.yield_module_start_earning_sheet_fee_policy), currencyIconState = CryptoCurrencyToIconStateConverter().convert(params.cryptoCurrency), yieldSupplyFeeUM = YieldSupplyFeeUM.Loading, From 5446f4af6b7ad15a768ca189ca266bdd215ca143 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 19:51:16 +0500 Subject: [PATCH 14/20] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 4 ++-- core/res/src/main/res/values-es/strings.xml | 5 +++-- core/res/src/main/res/values-fr/strings.xml | 4 +++- core/res/src/main/res/values-ja/strings.xml | 4 ++-- core/res/src/main/res/values-ru/strings.xml | 5 +++-- core/res/src/main/res/values-uk-rUA/strings.xml | 4 +++- core/res/src/main/res/values/strings.xml | 8 ++++---- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 7de8b4b57e..84032764f8 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1191,9 +1191,9 @@ Gebühr für das Staking-Konto Ein Staking-Konto ist ein spezielles Konto, auf dem eingesetzte SOL-Token gespeichert werden. Es wird erstellt, indem Sie Ihre Token an einen Validator delegieren, um an der Transaktionsvalidierung teilzunehmen und Belohnungen zu erhalten. Für die Einrichtung des Staking-Kontos wird eine geringe Gebühr erhoben, die nach Abschluss des Stakings zurückerstattet wird. Jährliche prozentuale Rendite - Die jährliche prozentuale Rendite, die du durch die Teilnahme am Staking erzielen kannst. + APR: Zeigt den Zinssatz, den Sie in einem Jahr ohne Zinseszins verdienen könnten. Die verdienten Zinsen werden nicht zu Ihrem Kontostand hinzugefügt, sodass Sie auf diese Zinsen keine zusätzlichen Zinsen erhalten. Jährlicher prozentualer Ertrag - APY zeigt den jährlichen prozentualen Ertrag des Validators basierend auf seiner Leistung + APY: Zeigt die gesamten Zinsen, die Sie in einem Jahr mit Zinseszins verdienen könnten. Zinseszins bedeutet, dass die verdienten Zinsen Ihrem Kontostand hinzugefügt werden, sodass Sie auch auf diese Zinsen Zinsen erhalten. Effektiver Jahreszins APY Belohnungen sammeln sich täglich automatisch in deinem Staking-Konto an. diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 8379c45b32..f4ed196991 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -985,8 +985,8 @@ Tarifa de staking de la cuenta Una cuenta de staking es una cuenta especial donde se almacenan los tokens SOL de staking. Se crea cuando delegas sus tokens a un validador para participar en la validación de transacciones y ganar recompensas. Se cobra una pequeña tarifa por crear la cuenta de staking, que se devuelve una vez que se completa el staking. Porcentaje de rendimiento anual - El porcentaje de rendimiento anual que podrá ganar como participante en el staking. - APY muestra el porcentaje de rendimiento anual del validador en función de su rendimiento + APR: Muestra el interés que podrías ganar en un año sin capitalización. Los intereses ganados no se añaden a tu saldo, por lo que no ganas intereses adicionales sobre ellos. + APY: Muestra el total de intereses que podrías ganar en un año con capitalización. La capitalización significa que los intereses ganados se añaden a tu saldo, por lo que también ganas intereses sobre esos intereses. APR APY Las recompensas se acumulan automáticamente en su saldo de staking diariamente. @@ -1076,6 +1076,7 @@ Mensual Semanal Recompensas + Las recompensas en Solana se agregan automáticamente a tu saldo de staking y no pueden mostrarse por separado. El stake está bloqueado Hacer más staking Al hacer staking de %1$s, se realiza sobre todo su saldo de %2$s. Cualquier %2$s adicional que deposite en su billetera Tangem también se pondrá en staking automáticamente. diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index 3c836280ec..d20290dd58 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -959,7 +959,8 @@ Frais de staking du compte Un compte de staking est un compte spécial où sont stockés les jetons SOL stakés. Il est créé lorsque vous déléguez vos jetons à un validateur pour participer à la validation des transactions et gagner des récompenses. Des frais minimes sont facturés pour la création du compte de staking, qui sont restitués une fois le staking terminé. Pourcentage de rendement annuel - Le pourcentage de rendement annuel que vous pouvez gagner en participant au staking. + APR : Montre le taux d’intérêt que vous pourriez gagner en un an sans capitalisation. Les intérêts gagnés ne sont pas ajoutés à votre solde, donc vous ne gagnez pas d’intérêts supplémentaires dessus. + APY : Montre le total des intérêts que vous pourriez gagner en un an avec capitalisation. La capitalisation signifie que les intérêts gagnés sont ajoutés à votre solde, et vous gagnez également des intérêts sur ces intérêts. APR APY Les récompenses s\'accumulent automatiquement sur votre solde de staking quotidiennement. @@ -1049,6 +1050,7 @@ Mois Semaine Récompenses + Les récompenses sur Solana sont automatiquement ajoutées à votre solde de staking et ne peuvent pas être affichées séparément. Stake verrouillé Staker plus Lorsque vous stakez %1$s, la totalité de votre solde %2$s est stakeée. Tout dépôt supplémentaire de %2$s sur votre portefeuille Tangem sera également staké automatiquement. diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 1ff1d4fbaf..2ff08e525e 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -1174,8 +1174,8 @@ ステーキングアカウント手数料 ステーキングアカウントとは、ステーキングされたSOLが保管される特別なアカウントです。トークンをバリデーターに委任し、取引の検証に参加して報酬を受け取る際に作成されます。ステーキングアカウントの作成には少額の手数料がかかりますが、ステーキング完了後に返金されます。 年率 - ステーキングに参加することで得られる年間収益率。 - APYは、バリデータのパフォーマンスに基づいた年間利回りを示します。 + APR:1年間で得られる利息を単利で表示します。得た利息は残高に加算されず、その利息にはさらに利息がつきません。 + APY:1年間で得られる合計利息を複利込みで表示します。複利とは、得た利息が残高に加算され、その利息にもさらに利息がつくことを意味します。 APR APY 報酬は毎日自動的にステーキング残高に蓄積されます。 diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index e12c0def79..27e98d406f 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1069,7 +1069,8 @@ Комиссия за стейкинг аккаунт Стейкинг аккаунт — это специальный счет, на котором хранятся застейканные токены SOL. Он создается при делегировании ваших токенов валидатору для участия в подтверждении транзакций и получении наград. За создание стейкинг аккаунта взимается небольшая комиссия, которая возвращается после завершения стейкинга. Процентная ставка - Годовой процентный доход, который вы можете получить от участия в стейкинге. + APR: Показывает процент, который вы можете заработать за год без учёта сложного процента. Начисленные проценты не добавляются к балансу, поэтому на них не начисляются дополнительные проценты. + APY: Показывает общий процент, который вы можете заработать за год с учётом сложного процента. Сложный процент означает, что начисленные проценты добавляются к вашему балансу, и на них тоже начисляются проценты. APR APY Награда автоматически аккумулируется на вашем стейкинг балансе. @@ -1661,7 +1662,7 @@ Проценты начисляются автоматически. Проценты начисляются автоматически. Режим доходности - Отправка ваших средств + Включение режима доходности Режим доходности Автоматически Внесите немного %1$s %2$s, чтобы покрыть комиссию сети за транзакции. diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 05d849f93f..7924d3ce64 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -964,7 +964,8 @@ Комісія за стейкінг-акаунт Стейкінг-акаунт — це спеціальний рахунок, на якому зберігаються застейкані SOL токени. Він створюється, коли ви делегуєте свої токени валідатору для участі у перевірці транзакцій та отримання винагород. За створення стейкінг-акаунту стягується невелика комісія, яка повертається після завершення стейкінгу. Процентна ставка - Річний відсоток, який ви можете отримати, беручи участь у стейкінгу. + APR: Показує відсоток, який ви можете заробити за рік без урахування складного відсотка. Нараховані відсотки не додаються до вашого балансу, тому на них не нараховуються додаткові відсотки. + APY: Показує загальний відсоток, який ви можете заробити за рік з урахуванням складного відсотка. Складний відсоток означає, що нараховані відсотки додаються до вашого балансу, і на них також нараховуються відсотки. APR APY Винагороди автоматично накопичуються на вашому балансі щодня. @@ -1054,6 +1055,7 @@ Місяць Потижнево Винагороди + Нагороди на Solana автоматично додаються до вашого стейкінг-балансу і не можуть відображатися окремо. Стейкінг закрито Застейкати більше При стейкінгу %1$s, весь ваш %2$s Баланс застейкний. Будь-які додаткові %2$s поповнены на Ваш гаманець Tangem буде також автоматично застейкано. diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 9cb5e7b0a8..f3ef5c6cfe 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1196,9 +1196,9 @@ Stake account fee A staking account is a special account where staked SOL tokens are stored. It is created when you delegate your tokens to a validator to participate in transaction validation and receive rewards. A small fee is charged for creating the staking account, which is returned after the staking is completed. Annual percentage rate - The annual percentage return you can earn from participating in staking. + APR: Shows the interest rate you could earn in a year without compounding. Your earned interest is not added to your balance, so your earnings don’t grow on themselves. Annual percentage yield - APY shows the validator’s annual percentage yield based on its performance + APY: Shows the total interest you could earn in a year with compounding. Compounding means your earned interest is added to your balance, so you also earn interest on that interest. APR APY Rewards automatically accumulate in your staking balance daily. @@ -1434,7 +1434,7 @@ Pay exactly what you see A separate payment account will be created without disclosing your addresses and assets Unrivaled privacy - Get your free Crypto Card\nin minutes + Get your free Tangem Pay Card in minutes We’re fixing a technical issue. Please try again later. Service temporarily unavailable Tangem Pay @@ -1973,7 +1973,7 @@ Yield accrues automatically. Yield accrues automatically Yield Mode - Processing your top-up + Enabling Yield Mode Yield Mode Automatic Add some %1$s %2$s to cover the network fee for transactions. From 5810d3221be2a3334cf4b4fda8f705fdadc2c293 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 21:28:01 +0500 Subject: [PATCH 15/20] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 2 +- core/res/src/main/res/values-es/strings.xml | 2 +- core/res/src/main/res/values-fr/strings.xml | 2 +- core/res/src/main/res/values-ja/strings.xml | 2 +- core/res/src/main/res/values-ru/strings.xml | 4 ++-- core/res/src/main/res/values-uk-rUA/strings.xml | 2 +- core/res/src/main/res/values/strings.xml | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index 84032764f8..7ada2a897d 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1939,7 +1939,7 @@ Pausiert Deaktiviere den Yield-Modus Wenn Du diese Option deaktivierst, werden Deine Vermögenswerte von Aave abgezogen, in Deiner Wallet wieder in %s umgewandelt und die Zinsgutschrift gestoppt. - Die Netzwerkgebühr wird von dem Betrag, den Du abhebst, abgezogen. + Eine Netzwerkgebühr wird von der Blockchain erhoben, wenn Sie den Yield-Modus verlassen. Deaktiviere den Yield-Modus Angebot Effektiver Jahreszins für Versorgung diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index f4ed196991..d036fbae09 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -1555,7 +1555,7 @@ En pausa Desactivación del modo de rendimiento Al desactivar esto, retirará sus fondos de Aave a %s en su billetera y dejará de ganar recompensas. - La comisión de red se deducirá del importe que retire. + Se cobra una comisión de red por la blockchain al salir del modo Yield. Desactivar el modo de rendimiento Suministrar Suministro APY diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index d20290dd58..bdf1ca0a6b 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -1534,7 +1534,7 @@ En pause Désactivation du mode de rendement En désactivant cela, vos fonds seront retirés d\'Aave vers %s dans votre portefeuille et vous ne gagnerez plus de récompenses. - Les frais de réseau seront déduits du montant que vous retirez. + Des frais de réseau sont prélevés par la blockchain lorsque vous quittez le mode Yield. Désactiver le mode rendement Rendement annuel brut (APY) APY diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 2ff08e525e..a437982f8e 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -1891,7 +1891,7 @@ 停止中 利回りモードを解除中 これをオフにすると、Aaveから資産が引き出され、ウォレット内の%sに変換され、利回りの発生が停止します。 - 出金金額からネットワーク手数料が差し引かれます。 + ネットワーク手数料とは、ブロックチェーン上で取引を処理して承認するためにユーザーが支払う料金のことです。 利回りモードを無効にする 供給 供給APY diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 27e98d406f..b57ccc750c 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1598,7 +1598,7 @@ Ваши средства в данный момент размещены в протоколе Aave, но вы можете воспользоваться ими в любое время. Ваш %s внесён в Aave Невозможно загрузить график - Отправка %1$s %2$s на Aave ожидает выполнения. + Отправка %1$s %2$s в Aave. Завершить режим доходности APY %1$s%% Доступно @@ -1654,7 +1654,7 @@ На паузе Завершение режима доходности Выключив эту функцию, вы выведёте средства из Aave, получите их обратно в %s в своем кошельке и перестанете зарабатывать награды. - Комиссия сети будет вычтена из суммы вашего вывода. + Комиссия сети взимается блокчейном при выходе из режима доходности. Завершить режим доходности Внесение Годовая доходность (APY) diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 7924d3ce64..11f6debacd 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -1510,7 +1510,7 @@ На паузі Вимкнення режиму прибутковості Вимкнення цієї опції виведе ваші активи з Aave, отримаєте їх назад у %s у вашому гаманці і зупинить накопичення нагород. - Комісія мережі буде вирахувана з суми, яку ви знімаєте. + Комісію мережі стягує блокчейн при виході з режиму доходності. Завершити заробіток Річна прибутковість (APY) APY diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index f3ef5c6cfe..21f5246f51 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1909,7 +1909,7 @@ Your funds are currently supplied to the Aave protocol, but you can manage them at any time. Your %s is supplied to Aave Unable to load chart... - Supply of %1$s %2$s to Aave is pending. + Supplying %1$s %2$s to Aave. Disable Yield Mode APY %1$s%% Available @@ -1965,13 +1965,13 @@ Paused Disabling Yield Mode Turning this off will withdraw your assets from Aave, convert them back to %s in your wallet, and stop yield accrual. - The network fee will be deducted from the amount you withdraw. + A network fee is charged by the blockchain when you exit Yield Mode. Disable Yield Mode Supply Supply APY APY - Yield accrues automatically. - Yield accrues automatically + Interest accrues automatically + Interest accrues automatically Yield Mode Enabling Yield Mode Yield Mode From 3b04938e54197598903e767880367a980592657b Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Nov 2025 23:34:51 +0500 Subject: [PATCH 16/20] Updated on 2026-08-14 --- core/res/src/main/res/values-ru/strings.xml | 12 ++++++------ core/res/src/main/res/values-uk-rUA/strings.xml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index b57ccc750c..eb34b26afd 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1606,7 +1606,7 @@ При пополнении в режиме доходности с баланса будет удержана комиссия сети, не превышающая %1$s. Сейчас комиссия сети слишком высока для выполнения операции. Средства будут отправлены, как только она снизится до %1$s или ниже. Мои средства - Ваши %1$s теперь внесён в Aave и приносит проценты. У вас есть токен %2$s, который отражает ваш баланс и со временем увеличивается. При пополнении средства автоматически направляются в Aave для получения процентов за вычетом комиссии за транзакцию. + Ваши %1$s теперь внесены в Aave и приносят проценты. У вас есть токен %2$s, который отражает ваш баланс и со временем увеличивается. При пополнении средства автоматически направляются в Aave для получения процентов за вычетом комиссии за транзакцию. Режим доходности Итоговый доход Переводы в Aave @@ -1628,14 +1628,14 @@ Проверьте ваше интернет соединение Информация о комиссии недоступна Каждое пополнение вашего адреса автоматически будет отправляться в Aave. - Все %1$s на вашем счёте будут автоматически переданы в Aave. + Все %1$s на вашем аккаунте будут автоматически переданы в Aave. Автоперевод в AAVE Отправляйте, обменивайте или продавайте свои средства мгновенно, когда захотите. Свободный доступ Как это работает? - Aave — это ончейн-протокол для создания некостодиальных рынков ликвидности, позволяющий получать доход с переменной ставкой. - Децентрализованный и некастодиальный - Используя сервис, вы соглашаетесь с условиями провайдера %1$s и %2$s + Aave — ончейн-протокол для некостодиальных рынков ликвидности, позволяющий получать доход с переменной ставкой. + Децентрализованный и некостодиальный + Используя сервис, вы соглашаетесь с %1$s и %2$s Подключить Aave Aave %1$s%% • Плавающая ставка Aave @@ -1646,7 +1646,7 @@ Ставка может меняться При пополнении ваши средства автоматически отправляются в Aave для начала начисления процентов. Для покрытия комиссии с вас будет удержана небольшая плата в размере %s. Начать зарабатывать - Ваш %s будет передан в Aave и останется всегда доступным. + Ваши %s будет переданы в Aave и останутся всегда доступными. Политика комиссий Следующие пополнения вашего счёта автоматически поступят в Aave. Все ваши будущие поступления %1$s будут автоматически направляться в Aave. diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 11f6debacd..e86e8f9877 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -1462,7 +1462,7 @@ При поповненні для кредитування з балансу буде вирахувано комісію мережі, що не перевищує %1$s. Наразі мережева комісія є занадто високою, щоб здійснювати кредитування. Кошти будуть надані, як тільки вона знизиться до %1$s або нижче. Мої кошти - Ваші %1$s тепер розміщено в Aave і приносить дохід. У вас є токен %2$s, який представляє ваш баланс і з часом збільшується. При поповненні кошти автоматично направляються в Aave для отримання процентів з вирахуванням комісії за транзакцію. + Ваші %1$s тепер розміщені в Aave і приносять дохід. У вас є токен %2$s, який представляє ваш баланс і з часом збільшується. При поповненні кошти автоматично направляються в Aave для отримання процентів з вирахуванням комісії за транзакцію. Режим дохідності Підсумковий дохід Перекази в Aave From 00cd18ee69ad0d7dfd7f0fe60fad404be128dda5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 17 Nov 2025 07:26:59 +0000 Subject: [PATCH 17/20] Updated on 2026-08-14 --- gradle/tangem_dependencies.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 4e7835869e..e06f0759db 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,9 +5,9 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "releases-5.30-1305" +tangemBlockchainSdk = "develop-1306" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds -tangemCardSdk = "releases-5.30-567" +tangemCardSdk = "develop-564" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^ tangemVico = "2.0.0-alpha.25-tangem12" #tangemVico = "0.0.1" # Keep it! - used for local builds ^ From 30011acc2e53dfaebcafe88e7bdc5a37d1789312 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 17 Nov 2025 10:58:19 +0300 Subject: [PATCH 18/20] Updated on 2026-08-14 --- core/res/src/main/res/values-de/strings.xml | 13 ++-- core/res/src/main/res/values-es/strings.xml | 14 +++-- core/res/src/main/res/values/strings.xml | 69 +++++++++++---------- tangem-android-tools | 2 +- 4 files changed, 54 insertions(+), 44 deletions(-) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index ddf5455028..7ada2a897d 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1191,9 +1191,9 @@ Gebühr für das Staking-Konto Ein Staking-Konto ist ein spezielles Konto, auf dem eingesetzte SOL-Token gespeichert werden. Es wird erstellt, indem Sie Ihre Token an einen Validator delegieren, um an der Transaktionsvalidierung teilzunehmen und Belohnungen zu erhalten. Für die Einrichtung des Staking-Kontos wird eine geringe Gebühr erhoben, die nach Abschluss des Stakings zurückerstattet wird. Jährliche prozentuale Rendite - Die jährliche prozentuale Rendite, die du durch die Teilnahme am Staking erzielen kannst. + APR: Zeigt den Zinssatz, den Sie in einem Jahr ohne Zinseszins verdienen könnten. Die verdienten Zinsen werden nicht zu Ihrem Kontostand hinzugefügt, sodass Sie auf diese Zinsen keine zusätzlichen Zinsen erhalten. Jährlicher prozentualer Ertrag - APY zeigt den jährlichen prozentualen Ertrag des Validators basierend auf seiner Leistung + APY: Zeigt die gesamten Zinsen, die Sie in einem Jahr mit Zinseszins verdienen könnten. Zinseszins bedeutet, dass die verdienten Zinsen Ihrem Kontostand hinzugefügt werden, sodass Sie auch auf diese Zinsen Zinsen erhalten. Effektiver Jahreszins APY Belohnungen sammeln sich täglich automatisch in deinem Staking-Konto an. @@ -1884,6 +1884,7 @@ Deine%s ist in Aave hinterlegt Chart konnte nicht geladen werden... Das Bereitstellen von %1$s %2$s bei Aave steht aus. + Deaktiviere den Yield-Modus APY %1$s%% Verfügbar Aktueller effektiver Jahreszins @@ -1912,11 +1913,12 @@ Prüfe Deine Netzwerkverbindung Informationen zu den Netzwerkgebühren nicht erreichbar Jede Einzahlung, die Du tätigst, wird automatisch an Aave weitergeleitet. + Alle %1$s auf Ihrem Konto werden automatisch an Aave bereitgestellt. Automatische Übertragung zu Aave Senden, tauschen oder verkaufen Deine Gelder sofort, wann immer Du willst. - Jederzeit Zugriff auf Dein Geld + Sofort verfügbar Wie funktioniert das? - Aave ist ein dezentrales Protokoll, das ein Gesamtvermögen von über 61 Milliarden Dollar verwaltet. + Aave ist ein On-Chain-Protokoll zur Erstellung von nicht-kustodialen Liquiditätsmärkten, um Zinsen mit variablem Satz zu verdienen. Dezentral und selbstverwahrend Durch die Nutzung dieses Dienstes erklärst Du Dich mit provider\n%1$s und %2$s einverstanden Mit Aave verbinden @@ -1932,11 +1934,12 @@ Dein %s wird an Aave übermittelt, bleibt aber verwaltbar. Siehe Gebührenrichtlinie Deine nächste Aufladung wird automatisch an Aave weitergeleitet. + Alle Ihre zukünftigen eingehenden %1$s-Einlagen werden automatisch an Aave bereitgestellt. Aktiv Pausiert Deaktiviere den Yield-Modus Wenn Du diese Option deaktivierst, werden Deine Vermögenswerte von Aave abgezogen, in Deiner Wallet wieder in %s umgewandelt und die Zinsgutschrift gestoppt. - Die Netzwerkgebühr wird von dem Betrag, den Du abhebst, abgezogen. + Eine Netzwerkgebühr wird von der Blockchain erhoben, wenn Sie den Yield-Modus verlassen. Deaktiviere den Yield-Modus Angebot Effektiver Jahreszins für Versorgung diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 1a1ad0aad3..d036fbae09 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -985,8 +985,8 @@ Tarifa de staking de la cuenta Una cuenta de staking es una cuenta especial donde se almacenan los tokens SOL de staking. Se crea cuando delegas sus tokens a un validador para participar en la validación de transacciones y ganar recompensas. Se cobra una pequeña tarifa por crear la cuenta de staking, que se devuelve una vez que se completa el staking. Porcentaje de rendimiento anual - El porcentaje de rendimiento anual que podrá ganar como participante en el staking. - APY muestra el porcentaje de rendimiento anual del validador en función de su rendimiento + APR: Muestra el interés que podrías ganar en un año sin capitalización. Los intereses ganados no se añaden a tu saldo, por lo que no ganas intereses adicionales sobre ellos. + APY: Muestra el total de intereses que podrías ganar en un año con capitalización. La capitalización significa que los intereses ganados se añaden a tu saldo, por lo que también ganas intereses sobre esos intereses. APR APY Las recompensas se acumulan automáticamente en su saldo de staking diariamente. @@ -1076,6 +1076,7 @@ Mensual Semanal Recompensas + Las recompensas en Solana se agregan automáticamente a tu saldo de staking y no pueden mostrarse por separado. El stake está bloqueado Hacer más staking Al hacer staking de %1$s, se realiza sobre todo su saldo de %2$s. Cualquier %2$s adicional que deposite en su billetera Tangem también se pondrá en staking automáticamente. @@ -1499,6 +1500,7 @@ Su %s está depositado en Aave No se puede cargar el gráfico... El suministro de %1$s %2$s a Aave está pendiente. + Desactivar el modo de rendimiento APY %1$s%% Disponible APY actual @@ -1527,11 +1529,12 @@ Compruebe su conexión de red Información de tarifas de red inaccesible Cada depósito que realice se suministrará a Aave automáticamente. + Todos los %1$s en tu cuenta se suministrarán automáticamente a Aave. Transferencia automática a Aave Envíe, intercambie o venda sus fondos al instante, cuando quiera. - Acceda a sus fondos en cualquier momento + Acceso inmediato ¿Cómo funciona? - Aave es un protocolo descentralizado que administra más de 61 billones de dólares en valor total. + Aave es un protocolo on-chain para crear mercados de liquidez no custodiales y ganar intereses a tasa variable. Descentralizado y autocustodiado Al utilizar este servicio, usted acepta que el proveedor\n%1$s y %2$s Conectar Aave @@ -1547,11 +1550,12 @@ Su %s se suministrará a Aave, pero seguirá siendo gestionable. Ver política de tarifas Sus próximas recargas se suministrarán automáticamente a Aave. + Todos tus futuros depósitos %1$s se suministrarán automáticamente a Aave. Activo En pausa Desactivación del modo de rendimiento Al desactivar esto, retirará sus fondos de Aave a %s en su billetera y dejará de ganar recompensas. - La comisión de red se deducirá del importe que retire. + Se cobra una comisión de red por la blockchain al salir del modo Yield. Desactivar el modo de rendimiento Suministrar Suministro APY diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index 433f57b894..21f5246f51 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1196,9 +1196,9 @@ Stake account fee A staking account is a special account where staked SOL tokens are stored. It is created when you delegate your tokens to a validator to participate in transaction validation and receive rewards. A small fee is charged for creating the staking account, which is returned after the staking is completed. Annual percentage rate - The annual percentage return you can earn from participating in staking. + APR: Shows the interest rate you could earn in a year without compounding. Your earned interest is not added to your balance, so your earnings don’t grow on themselves. Annual percentage yield - APY shows the validator’s annual percentage yield based on its performance + APY: Shows the total interest you could earn in a year with compounding. Compounding means your earned interest is added to your balance, so you also earn interest on that interest. APR APY Rewards automatically accumulate in your staking balance daily. @@ -1897,85 +1897,88 @@ No, send all Reduce by %s XTZ To avoid paying an increased commission the next time you top up your wallet, reduce the amount by %s XTZ - With Yield mode active, all future deposits to this address will go to Aave. You can still manage your funds freely. + When Yield Mode is active, all future top-ups to this address will be supplied to Aave. You can still manage your funds freely. Your %s is supplied to Aave Supplying %1$s %2$s to Aave is pending Approve - Your token’s approval has been revoked. Grant it again to resume service functionality. + Your token\'s approval has been revoked. Grant it again to resume the service\'s functionality. Approve needed - The fee will be taken out, and your assets will be lent again. - To continue earning, approval is required. + The fee will be deducted, and your assets will be resupplied. + To continue generating yield, approval is required. Confirm approval Your funds are currently supplied to the Aave protocol, but you can manage them at any time. - Your %s is deposited in Aave + Your %s is supplied to Aave Unable to load chart... - Supplying %1$s %2$s to Aave is pending. + Supplying %1$s %2$s to Aave. + Disable Yield Mode APY %1$s%% Available Current APY When topping up for lending, a network fee not exceeding %1$s will be deducted from the balance. The network fee is currently too high to execute lending. Funds will be supplied once it drops to %1$s or below. My funds - Your %1$s is now deployed to Aave and earning yield. You hold %2$s tokens, which represent your balance and accrue yield automatically. When you top up, funds are added to Aave to earn more yield, minus fees. - Yield mode - Total earnings + Your %1$s is now deployed to Aave and generating yield. You hold %2$s tokens, representing your balance and accruing yield automatically. When you top up, the funds are supplied to Aave to generate more yield, after fees are deducted. + Yield Mode + Total yield Transfers to Aave Explore Aave This is the current supply fee on %s. The actual cost will be shown on the activation tab. Current fee - All future %s deposits will be supplied to Aave automatically, with the transaction fee deducted. - 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. - If network fees rise above maximum fee, the transaction won’t go through until they decrease. You can change this limit later. + All future %s top-ups will be supplied to Aave automatically, after the transaction fee is deducted. + 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. + If network fees rise above the maximum fee, the transaction won\'t go through until they decrease. You can change this limit later. Maximum fee - The minimum amount is calculated based on the current network fee so that it does not exceed 4%% of the top-up amount, which makes the minimum %1$s (%2$s). + The minimum amount is calculated based on the current network fee, ensuring it doesn\'t exceed 4%% of the top-up amount, which equals the minimum %1$s (%2$s). Minimum top-up Top-up fee policy - Tangem also takes a 15% service fee on yield earned. + Tangem also takes a 15% service fee on yield generated. Your funds will be automatically supplied to Aave once network fees are lower or your balance meets the minimum required amount. Historical returns - Approval for your token in the Yield mode has been revoked. Open the token to grant permission again. + Approval for your token in Yield Mode has been revoked. Open the token to grant permission again. Token approval needed Check your network connection Network fee info unreachable - Every deposit you make will be supplied to Aave automatically. - Auto-Transfer to Aave + Every top-up will be supplied to Aave automatically. + All %1$s on your account will be supplied to Aave automatically. + Auto-supply to Aave Send, swap, or sell your funds instantly, anytime you want. - Access your funds anytime + No lock-ups How it works? - Aave is a decentralized protocol managing over $61 billion in total value. + Aave is an on-chain protocol that offers non-custodial liquidity markets, enabling users to accrue yield at variable rates. Decentralized and self-custodial By using this service, you agree with provider\n%1$s and %2$s - Connect Aave + Connect to Aave Aave %1$s%% • Variable Interest Rate Aave Avg %s Last year\'s returns - Current interest rate is always variable and automatically computed by the Aave on-chain smart-contract, based on real-time supply and demand. + The current interest rate is always variable and automatically computed by Aave\'s on-chain smart contract, based on real-time supply and demand. Powered by Interest rate is variable - When you top up, your funds will be automatically sent to Aave to start earning interest. %s will be deducted to cover the transaction fee. + When you top up, your funds will be automatically supplied to Aave to start generating yield. %s will be deducted to cover the transaction fee. Supply assets - Your %s will be supplied to Aave, but will remain manageable. + Your %s will be supplied to Aave with no lock-ups and will remain fully accessible. See top-up fee policy Your next top-ups will be automatically supplied to Aave. + All your future incoming %1$s deposits will be automatically supplied to Aave. Active Paused Disabling Yield Mode Turning this off will withdraw your assets from Aave, convert them back to %s in your wallet, and stop yield accrual. - The network fee will be deducted from the amount you withdraw. - Disable yield mode + A network fee is charged by the blockchain when you exit Yield Mode. + Disable Yield Mode Supply Supply APY APY - Interest accrues automatically. + Interest accrues automatically Interest accrues automatically - Yield mode - Processing your top-up + Yield Mode + Enabling Yield Mode Yield Mode Automatic - Deposit some %1$s %2$s to cover the network fee for transactions + Add some %1$s %2$s to cover the network fee for transactions. Unable to cover %s fee - The Yield mode service isn’t available at the moment. Please try again later. - Yield mode unavailable + Yield Mode isn\'t available at the moment. Please try again later. + Yield Mode unavailable Unable to load chart... diff --git a/tangem-android-tools b/tangem-android-tools index 005d624edb..92c1bfd312 160000 --- a/tangem-android-tools +++ b/tangem-android-tools @@ -1 +1 @@ -Subproject commit 005d624edbb899bb8fae1c9444ea34b6eac86603 +Subproject commit 92c1bfd3123f0b2fd9e5a80b9d69bbc17a6e1160 From 01c539a1117ac32216aafaf26dffb44ee4195de8 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 17 Nov 2025 11:20:04 +0300 Subject: [PATCH 19/20] Updated on 2026-08-14 --- .../java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt | 1 + app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt | 2 +- .../com/tangem/tap/features/details/redux/DetailsMiddleware.kt | 1 + .../onboarding/products/wallet/redux/BackupMiddleware.kt | 1 + .../java/com/tangem/tap/proxy/redux/DaggerGraphMiddleware.kt | 1 + core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt | 2 +- .../src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt | 2 +- .../java/com/tangem/blockchainsdk/utils/ExcludedBlockchains.kt | 1 + .../src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt | 2 +- 9 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index 637030995e..c847cb4a50 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* import org.rekotlin.Middleware +@Suppress("MemberNameEqualsClassName") internal object LegacyMiddleware { private val prepareDetailsScreenJobHolder = JobHolder() diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 76f033a638..72762cb7a0 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -30,7 +30,7 @@ class TapWalletManager( // ensuring that only one job is active at any given time. loadUserWalletDataJob = CoroutineScope(dispatchers.io) .launch { loadUserWalletData(userWallet) } - .also { it.join() } + .apply { join() } } private suspend fun loadUserWalletData(userWallet: UserWallet) { diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index bc49d31e9d..3a4901f8e3 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -34,6 +34,7 @@ import org.rekotlin.Action import org.rekotlin.Middleware import timber.log.Timber +@Suppress("MemberNameEqualsClassName") class DetailsMiddleware { private val appSettingsMiddleware = AppSettingsMiddleware() val detailsMiddleware: Middleware = { _, stateProvider -> diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt index 2433af1e95..e0e8bd6b12 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/BackupMiddleware.kt @@ -14,6 +14,7 @@ import com.tangem.tap.store import kotlinx.coroutines.launch import org.rekotlin.Middleware +@Suppress("MemberNameEqualsClassName") class BackupMiddleware { val backupMiddleware: Middleware = { dispatch, state -> { next -> diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphMiddleware.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphMiddleware.kt index ee884e4e2a..0e822a4edc 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphMiddleware.kt @@ -3,6 +3,7 @@ package com.tangem.tap.proxy.redux import com.tangem.tap.common.redux.AppState import org.rekotlin.Middleware +@Suppress("MemberNameEqualsClassName") object DaggerGraphMiddleware { val daggerGraphMiddleware: Middleware = { _, _ -> { next -> diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt index 9c862a5c77..85535f739b 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt @@ -66,7 +66,7 @@ fun TangemTheme( ) { val themeColors = if (isDark) darkThemeColors() else lightThemeColors() val rememberedColors = remember { themeColors } - .also { it.update(themeColors) } + .apply { update(themeColors) } val systemUiController = rememberSystemUiController() val systemBarsIconsController = remember(systemUiController) { SystemBarsIconsController(systemUiController) } diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt index 7a93d0463c..476a412a20 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemThemeRedesign.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.* fun TangemThemeRedesign(content: @Composable () -> Unit) { val themeColors = if (LocalIsInDarkTheme.current) darkThemeColors() else lightThemeColors(redesign = true) val rememberedColors = remember { themeColors } - .also { it.update(themeColors) } + .apply { update(themeColors) } val rootBackgroundColor = rememberedColors.background.secondary MaterialTheme( diff --git a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/ExcludedBlockchains.kt b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/ExcludedBlockchains.kt index e2d3d72ea2..18125a1152 100644 --- a/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/ExcludedBlockchains.kt +++ b/libs/blockchain-sdk/src/main/java/com/tangem/blockchainsdk/utils/ExcludedBlockchains.kt @@ -5,6 +5,7 @@ import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager import org.jetbrains.annotations.TestOnly import javax.inject.Inject +@Suppress("MemberNameEqualsClassName") class ExcludedBlockchains @Inject internal constructor( private val excludedBlockchainsManager: ExcludedBlockchainsManager, ) : Set { diff --git a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt index 936f54845e..f27fd2b825 100644 --- a/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt +++ b/libs/tangem-sdk-api/src/main/kotlin/com/tangem/sdk/api/di/CardSdkModule.kt @@ -26,7 +26,7 @@ internal object CardSdkModule { artworksDirectory = File( context.getExternalFilesDir(null) ?: context.filesDir, "card_artworks", - ).also { it.mkdirs() }, + ).apply { mkdirs() }, ) } } \ No newline at end of file From 315ff5aa6fd1919b298e27d6705b1325ff7ec0a2 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 17 Nov 2025 11:59:24 +0300 Subject: [PATCH 20/20] Updated on 2026-08-14 --- app/src/main/java/com/tangem/tap/MainActivity.kt | 4 +++- .../common/pushes/PushNotificationDelegate.kt | 9 ++++++--- .../com/tangem/tap/common/redux/AppReducer.kt | 1 + .../main/java/com/tangem/tap/di/HapticModule.kt | 10 +++++++--- .../tap/domain/scanCard/LegacyScanProcessor.kt | 16 +++++++--------- .../domain/sdk/impl/DefaultTangemSdkManager.kt | 11 +++-------- .../domain/tasks/visa/VisaCardActivationTask.kt | 2 +- .../BiometricUserWalletsListManager.kt | 10 +++++----- .../RuntimeUserWalletsListManager.kt | 10 +++++----- .../exchangeServices/moonpay/MoonPayService.kt | 6 +++--- tangem-android-tools | 2 +- 11 files changed, 42 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 0ef437226d..8db7434ef7 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -302,7 +302,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { } private fun createAppThemeModeFlow(): SharedFlow { - val tangemApplication = application as TangemApplication + val tangemApplication = requireNotNull(application as? TangemApplication) { + "Application is null" + } return tangemApplication.getAppThemeModeUseCase() .filterNotNull() diff --git a/app/src/main/java/com/tangem/tap/common/pushes/PushNotificationDelegate.kt b/app/src/main/java/com/tangem/tap/common/pushes/PushNotificationDelegate.kt index a04f41db40..cde6e78a86 100644 --- a/app/src/main/java/com/tangem/tap/common/pushes/PushNotificationDelegate.kt +++ b/app/src/main/java/com/tangem/tap/common/pushes/PushNotificationDelegate.kt @@ -54,8 +54,8 @@ class PushNotificationDelegate(private val context: Context) { .setContentIntent(pendingIntent) .setVibrate(vibratePattern) .apply { - imageUrl?.let { uri -> - val bitmap = getBitmapImageFromUrl(uri) + if (imageUrl != null) { + val bitmap = getBitmapImageFromUrl(imageUrl) setStyle( NotificationCompat .BigPictureStyle() @@ -64,7 +64,10 @@ class PushNotificationDelegate(private val context: Context) { } } - val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + val service = context.getSystemService(Context.NOTIFICATION_SERVICE) + val notificationManager = requireNotNull(service as? NotificationManager) { + "NotificationManager not available" + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationChannel = NotificationChannel( diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt index 6099bad60a..71fcd29497 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt @@ -6,6 +6,7 @@ import com.tangem.tap.features.welcome.redux.WelcomeReducer import com.tangem.tap.proxy.redux.DaggerGraphReducer import org.rekotlin.Action +@Suppress("CanBeNonNullable") fun appReducer(action: Action, state: AppState?): AppState { requireNotNull(state) if (action is AppAction.RestoreState) return action.state diff --git a/app/src/main/java/com/tangem/tap/di/HapticModule.kt b/app/src/main/java/com/tangem/tap/di/HapticModule.kt index dc04a3ce72..3db66d0e6e 100644 --- a/app/src/main/java/com/tangem/tap/di/HapticModule.kt +++ b/app/src/main/java/com/tangem/tap/di/HapticModule.kt @@ -4,9 +4,9 @@ import android.content.Context import android.os.Build import android.os.Vibrator import android.os.VibratorManager -import com.tangem.tap.common.haptic.DefaultVibratorHapticManager import com.tangem.core.ui.haptic.TangemHapticEffect import com.tangem.core.ui.haptic.VibratorHapticManager +import com.tangem.tap.common.haptic.DefaultVibratorHapticManager import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -22,10 +22,14 @@ class HapticModule { @Singleton fun provideHapticManager(@ApplicationContext context: Context): VibratorHapticManager { val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + val service = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) + val vibratorManager = requireNotNull(service as? VibratorManager) { + "VibratorManager not available" + } vibratorManager.defaultVibrator } else { - context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + val service = context.getSystemService(Context.VIBRATOR_SERVICE) + requireNotNull(service as? Vibrator) { "Vibrator service not available" } } return if (vibrator.hasVibrator()) { diff --git a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt index 06178511a5..ac18c8b943 100644 --- a/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt +++ b/app/src/main/java/com/tangem/tap/domain/scanCard/LegacyScanProcessor.kt @@ -120,16 +120,14 @@ internal class LegacyScanProcessor @Inject constructor( } } - private fun sendAnalytics(analyticsEvent: AnalyticsEvent?, scanResponse: ScanResponse) { - analyticsEvent?.let { event -> - // this workaround needed to send CardWasScannedEvent without adding a context - val interceptor = CardContextInterceptor(scanResponse) - val params = event.params.toMutableMap() - interceptor.intercept(params) - event.params = params.toMap() + private fun sendAnalytics(analyticsEvent: AnalyticsEvent, scanResponse: ScanResponse) { + // this workaround needed to send CardWasScannedEvent without adding a context + val interceptor = CardContextInterceptor(scanResponse) + val params = analyticsEvent.params.toMutableMap() + interceptor.intercept(params) + analyticsEvent.params = params.toMap() - Analytics.send(event) - } + Analytics.send(analyticsEvent) } // TODO: [REDACTED_JIRA] diff --git a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt index 32f0e5b105..89c571cd1e 100644 --- a/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/sdk/impl/DefaultTangemSdkManager.kt @@ -23,11 +23,7 @@ import com.tangem.domain.card.repository.CardSdkConfigRepository import com.tangem.domain.models.scan.CardDTO import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.visa.model.TangemPayInitialCredentials -import com.tangem.domain.visa.model.VisaActivationInput -import com.tangem.domain.visa.model.VisaDataForApprove -import com.tangem.domain.visa.model.VisaSignedDataByCustomerWallet -import com.tangem.domain.visa.model.sign +import com.tangem.domain.visa.model.* import com.tangem.domain.wallets.derivations.derivationStyleProvider import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.operations.ScanTask @@ -82,13 +78,12 @@ internal class DefaultTangemSdkManager( secureStorage = tangemSdk.secureStorage, ) } + override val needEnrollBiometrics: Boolean + get() = tangemSdk.authenticationManager.needEnrollBiometrics override val canUseBiometry: Boolean get() = tangemSdk.authenticationManager.canAuthenticate || needEnrollBiometrics - override val needEnrollBiometrics: Boolean - get() = tangemSdk.authenticationManager.needEnrollBiometrics - override val keystoreManager: KeystoreManager get() = tangemSdk.keystoreManager diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt index 547876b22f..27f82f9b3b 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/visa/VisaCardActivationTask.kt @@ -177,7 +177,7 @@ class VisaCardActivationTask @AssistedInject constructor( .getOrElse { raise(it.tangemError) } if (remoteState !is VisaActivationRemoteState.CardWalletSignatureRequired) { - return raise(VisaActivationError.WrongRemoteState.tangemError) + raise(VisaActivationError.WrongRemoteState.tangemError) } visaActivationRepository.getCardWalletAcceptanceData( diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt index ae13a2ec94..85b958f1d1 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/BiometricUserWalletsListManager.kt @@ -36,11 +36,6 @@ internal class BiometricUserWalletsListManager( .mapLatest { it.userWallets } .distinctUntilChanged() - override val savedWalletsCount: Flow - get() = state - .mapLatest { walletsCount } - .distinctUntilChanged() - override val userWalletsSync: List get() = state.value.userWallets @@ -71,6 +66,11 @@ internal class BiometricUserWalletsListManager( override val walletsCount: Int get() = state.value.userWallets.size + override val savedWalletsCount: Flow + get() = state + .mapLatest { walletsCount } + .distinctUntilChanged() + override suspend fun unlock(type: UnlockType): CompletionResult { return unlockAndSetSelectedUserWallet(type) .mapFailure { error -> diff --git a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt index 31ad6301f0..8ee8847ffa 100644 --- a/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/userWalletList/implementation/RuntimeUserWalletsListManager.kt @@ -20,11 +20,6 @@ internal class RuntimeUserWalletsListManager : UserWalletsListManager { .mapLatest { listOfNotNull(it.userWallet) } .distinctUntilChanged() - override val savedWalletsCount: Flow - get() = state - .mapLatest { walletsCount } - .distinctUntilChanged() - override val selectedUserWallet: Flow get() = state .mapLatest { it.userWallet } @@ -46,6 +41,11 @@ internal class RuntimeUserWalletsListManager : UserWalletsListManager { override val walletsCount: Int get() = if (hasUserWallets) 1 else 0 + override val savedWalletsCount: Flow + get() = state + .mapLatest { walletsCount } + .distinctUntilChanged() + override suspend fun select(userWalletId: UserWalletId): CompletionResult = catching { state.value.userWallet ?.takeIf { it.walletId == userWalletId } diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt index 0e5af5e7c0..60491ab4c7 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/moonpay/MoonPayService.kt @@ -33,12 +33,12 @@ class MoonPayService( private val userWalletProvider: () -> UserWallet?, ) : SellService { - override val initializationStatus: StateFlow - get() = _initializationStatus - private val _initializationStatus: MutableStateFlow = MutableStateFlow(value = lceLoading()) + override val initializationStatus: StateFlow + get() = _initializationStatus + private var status: MoonPayStatus? = null override suspend fun update() { diff --git a/tangem-android-tools b/tangem-android-tools index 92c1bfd312..193db8a024 160000 --- a/tangem-android-tools +++ b/tangem-android-tools @@ -1 +1 @@ -Subproject commit 92c1bfd3123f0b2fd9e5a80b9d69bbc17a6e1160 +Subproject commit 193db8a0247a1f33574dcdd5f9ec4dab2c28ea73