diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt
index 19f07cabf5..d7f3a0cc33 100644
--- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt
+++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt
@@ -190,6 +190,7 @@ internal class ChildFactory @Inject constructor(
context = context,
params = WalletBackupComponent.Params(
userWalletId = route.userWalletId,
+ isColdWalletOptionShown = route.isColdWalletOptionShown,
),
componentFactory = walletBackupComponentFactory,
)
diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt
index e5bdf4dad1..7242c08646 100644
--- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt
+++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt
@@ -231,7 +231,8 @@ sealed class AppRoute(val path: String) : Route {
@Serializable
data class WalletBackup(
val userWalletId: UserWalletId,
- ) : AppRoute(path = "/wallet_backup/${userWalletId.stringValue}")
+ val isColdWalletOptionShown: Boolean,
+ ) : AppRoute(path = "/wallet_backup/${userWalletId.stringValue}/$isColdWalletOptionShown")
@Serializable
data class WalletHardwareBackup(
diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
index 1cb7bb7d24..94775b09a4 100644
--- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
+++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json
@@ -35,6 +35,10 @@
"name": "HOT_WALLET_ENABLED",
"version": "5.32.0"
},
+ {
+ "name": "HOT_WALLET_CREATION_RESTRICTION_ENABLED",
+ "version": "5.32.0"
+ },
{
"name": "TANGEM_PAY_ENABLED",
"version": "5.31.0"
diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml
index db29c44fbe..0a5f0530a8 100644
--- a/core/res/src/main/res/values-de/strings.xml
+++ b/core/res/src/main/res/values-de/strings.xml
@@ -1767,7 +1767,7 @@
Importiere eine bestehende Wallet mit Deiner Wiederherstellungsphrase.
Wallet importieren
Wiederherstellungsphrase eingeben
- Du hast Deine Wallet erfolgreich gesichert.
+ Du hast Deine Wallet erfolgreich importiert.
Wallet importieren
Import abgeschlossen
Wallet importieren
diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml
index 785a92204c..565f5cf8f8 100644
--- a/core/res/src/main/res/values-ja/strings.xml
+++ b/core/res/src/main/res/values-ja/strings.xml
@@ -322,6 +322,7 @@
今
わかりました
ブラウザで開く
+ または
プライマリーカード
プライマリーリング
パスフレーズ
@@ -430,6 +431,7 @@
このメカニズムは、カードまたはリングに対する近接攻撃から保護します。コマンドの受信と実行の間に遅延を強制します。
パスコード
カードの状態の変更を伴うコマンドを実行する前に、パスコードを入力する必要があります。
+ ハードウェアウォレットにアップグレード
NFT
紹介プログラム
デバイスの画面を下に向けると、残高をすばやく非表示にしたり表示したりできます。
@@ -443,6 +445,7 @@
署名済み
フィードバックを送信
詳細
+ モバイルウォレットは同時に1つのみ利用できます。Tangemコールドウォレットにアップグレードすることも、新しいコールドウォレットと併用することも可能です。
インターネット接続を確認するか、別のネットワークに切り替えてください。
利用規約
デフォルトアドレス
@@ -552,7 +555,8 @@
Tangemへのフィードバック
取引を送信できません
コインの説明エラー
- ガス代不要の取引手数料
+ 残高不足
+ 取引手数料
エラーが発生しました
エラーが発生しました。コード: %s 。
メモが必要
@@ -564,10 +568,10 @@
続行するには、%1sスマートコントラクトに%2sを使用する権限を付与してください
許可を与える
無制限
- バックアップは2〜3枚のTangemカードを使用して作成されます。紛失や破損に備え、カードはそれぞれ安全な別の場所に保管してください。シードフレーズは不要です。
- 複数のカードでバックアップ
+ ハードウェアウォレット内に新しいアドレスが自動生成され、安全にすぐ利用できる状態になります。
+ 新しいアドレス
Tangemウォレットを追加
- あなたの秘密鍵はTangemカード内部で直接生成され、決してカードの外に出ることはありません。
+ 秘密鍵はTangemカード内部で直接生成され、外部に出ることは一切ありません。
鍵生成
すべての暗号処理は、複製や物理的な改ざんに対する認証を受けたセキュアチップ内で行われます。
ハードウェアレベルのセキュリティ
@@ -602,15 +606,20 @@
まずバックアップを完了する
未完了
その他の方法
+ リカバリーフレーズは安全な場所に保管し、他人に知られないようにしてください。あわせて、資産をさらに強力に保護するためにアクセスコードを設定してください。
資金を保護するため、リカバリーフレーズは安全な場所に保管し、他人に知られないようにしてください。
リカバリーフレーズ
アクセスコードでウォレットを保護するには、バックアップの手続きを完了してください。
ハードウェアウォレットにアップグレードするには、バックアップの手続きを完了してください。
+ 業界最高レベルのセキュリティを実現するため、モバイルウォレットをTangemハードウェアウォレットにアップグレードしましょう。既存のウォレットをインポートするか、新しいウォレットへ資産を移行できます。
+ コールドウォレットにアップグレード
秘密鍵は安全に暗号化され、スマートフォン上に保存されています
秘密鍵はデバイス上に保持されます
リカバリーフレーズを使ってウォレットを作成または復元してください。
シードフレーズのバックアップ
モバイルウォレットを作成する
+ モバイルウォレットは、いつでも安全にTangemカードまたはリングへ移行できます。
+ ハードウェアウォレットにアップグレード
既存のウォレットをインポートする
このリカバリーフレーズはすでにインポートされています。
モバイルウォレット
@@ -628,14 +637,14 @@
ウォレットを削除する前にバックアップを行っていない場合、ウォレットへのアクセスを失うことを理解しています。
ウォレットを削除しても中身自体が消えるわけではなく、このデバイスから表示が消えるだけであることを理解しています。
アップグレード
- シードフレーズは不要です。Tangemカードまたはリングが安全なバックアップとなります。
- Tangemでバックアップ
+ モバイルウォレットをTangemカードまたはリングにアップグレードしても、すべてのアドレスと残高は引き続き完全に利用できます。
+ 同じアドレス
アップグレードできません。このデバイスにはすでにウォレットが存在します。
別のデバイスを選択してください。このデバイスはアップグレードに使用できません。
操作中にエラーが発生しました。
処理中も、資金は安全に保たれ、常にアクセス可能です。
資金へのアクセス
- ウォレット情報はアプリから削除され、ハードウェアウォレットに保存されます
+ アップグレード後、モバイルウォレットはアプリから削除され、ハードウェアウォレットに保存されます。リカバリーフレーズは引き続きご自身で管理してください。
セキュリティ全般
秘密鍵はアプリからTangemハードウェアウォレットへ移行されます
キーの移行
@@ -1225,6 +1234,11 @@
設定したいカードまたはリングをスキャンするために準備してください。
ウォレット削除
これにより、ウォレットがアプリから削除されます。ウォレットは再度追加できます。
+ シンプルな操作
+ 暗号資産をオフラインで厳重保管。カードサイズで、金庫以上の安心を。
+ シードフレーズ不要
+ 業界最高水準のハードウェアウォレット
+ Tangemコールドウォレット
名前
トークンを活用しよう
ネットワーク手数料とは、ブロックチェーン上で取引を処理し、承認するために支払う少額の料金です。
@@ -1391,6 +1405,7 @@
手間がかからず直感的に操作でき、数回タップするだけでトークンを交換できます。
とにかく便利
プロバイダー経由のスワップ
+ 資産
この金額には以下が含まれます:\n- サービスプロバイダーの手数料\n- 取引所からユーザーのアドレスに%s を送り返すためのネットワーク手数料。
金額には以下が含まれます: \n • サービス プロバイダーの手数料\n • 取引所からユーザーのアドレスに%1$sを送金するためのネットワーク手数料。 \n\nプロバイダーのスリッページは最大%2$sです
この金額には、サービスプロバイダーの手数料が含まれています。
@@ -1405,6 +1420,7 @@
残高不足
許可を与える
スワップ
+ スワップ中…
受け取る
トークンを選択
利用不可
@@ -1531,6 +1547,8 @@
Tangem Payは現在一時的に利用できません。
Tangem Pay
下のボタンをクリックしてアクセスを復元してください
+ 現在引き出せるのは、保留中の取引分を差し引いたオンチェーンアドレス上のUSDC(Polygon)のみです。以前に返金や購入のキャンセルを行った場合、暗号資産アカウントの残高は2営業日以内に更新されます。
+ ご注意ください
PINコード
これは私のウォレットです
残高非表示
@@ -1602,6 +1620,7 @@
エラーが発生しました。エラー コード:%s。サポートにお問い合わせください。
%sを使用するか、カード / リングをスキャンしてウォレットにアクセスしてください
接続に失敗しました:このdAppは、サポートされていないWallet Connectバージョン1.0を使用しています。正常に接続するには、dAppがWallet Connectバージョン2.0をサポートしていることを確認してください。
+ ハードウェアウォレットにアップグレード
最新の機能とニュースをお届けします
取引・スワップ・重要な更新に関するリアルタイム通知。
取引アラート
@@ -1925,6 +1944,7 @@
迅速な配送
ワンタップで開始
シームレスで安全
+ シードフレーズ不要
シンプルな操作
Tangemでハードウェアウォレットを作成しよう。キャッシュカードのようにスリムで、金庫のように安全。
ソフトウェアウォレットを作成またはインポート
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index 20c4204701..ef16028c2d 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -325,7 +325,7 @@
- %d сеть
- %d сети
- %d сетей
- - %d сети
+ - %d сетях
Новый адрес
Новости
@@ -334,10 +334,12 @@
Нет
Нет адреса
Не добавлено
+ Не доступно
Не сейчас
Сейчас
OK
Открыть в браузере
+ или
Основная карта
Основное кольцо
Парольная фраза
@@ -450,6 +452,7 @@
Этот механизм защищает карту или кольцо от бесконтактных атак. Между сканированием и выполнением команды будет добавлена задержка.
Пароль
Перед выполнением любой команды, влекущей за собой изменение состояния карты, вам необходимо будет ввести пароль.
+ Апгрейд до аппаратного кошелька
NFT
Реферальная программа
Переверните экран вашего устройства вниз, чтобы быстро скрыть и отобразить балансы
@@ -463,6 +466,7 @@
Подписано
Отправить отзыв
Подробности
+ Одновременно у вас может быть только один мобильный кошелек. Его можно апгрейдить до Tangem cold wallet или использовать вместе с новым холодным кошельком.
Проверьте подключение с интернетом или переключитесь на другую сеть
Условия использования
Основной адрес
@@ -569,6 +573,8 @@
Обращение в поддержку Tangem
Не могу отправить транзакцию
Ошибка в описании монеты
+ Недостаточно средств
+ Комиссия за транзакцию
Произошла ошибка
Произошла ошибка. Код: %s.
Требуется memo
@@ -580,10 +586,10 @@
Чтобы продолжить, вам нужно разрешить смарт-контракту %1s использовать ваш %2s
Дать разрешение
Безлимитно
- Резервная копия создаётся на 2–3 картах Tangem. Храните их отдельно для безопасности — seed-фраза не нужна.
- Бэкап на несколько карт
+ Новые адреса будут сгенерированы прямо в вашем аппаратном кошельке, готовы к использованию и полностью защищены.
+ Новые адреса
Добавить кошелек Tangem
- Ваш приватный ключ генерируется на карте Tangem и никогда не покидает её.
+ Ваш приватный ключ будет сгенерирован на карте Tangem и никогда не покинет её.
Генерация ключа
Операции с криптографией выполняются внутри защищённого чипа, устойчивого к клонированию и физическому взлому.
Аппаратная безопасность
@@ -618,15 +624,20 @@
Сначала завершите создание резервной копии
Не завершено
Другие способы
+ Сохраните фразу восстановления в надежном месте и держите её в секрете, чтобы защитить свои средства, а также установите код доступа для дополнительной безопасности.
Сохраните фразу восстановления в безопасном месте и держите её в секрете.
Фраза восстановления
Чтобы защитить ваш кошелёк с помощью кода доступа, сначала завершите резервное копирование.
Чтобы улучшить кошелёк до аппаратного, сначала создайте резервную копию.
+ Перенесите свой мобильный кошелек на аппаратный кошелек Tangem для максимальной безопасности. Импортируйте существующий кошелек или переведите средства на новый.
+ Апгрейд до холодного кошелька
Ваши приватные ключи надёжно зашифрованы и хранятся на вашем телефоне
Ключи хранятся в приложении
Создайте или импортируйте кошелёк с помощью вашей фразы восстановления.
Резервная копия
Создать мобильный кошелек
+ Перенесите свой мобильный кошелек на Tangem-карту или кольцо в любое время.
+ Апгрейд до аппаратного кошелька
Импортировать существующий
Эта фраза восстановления уже была импортирована
Мобильный кошелек
@@ -644,14 +655,14 @@
Я понимаю, что если я не создал резервную копию кошелька перед его удалением, я могу потерять к нему доступ.
Я понимаю, что удаление моего кошелька не стирает его — оно просто удаляет его с моего устройства.
Апгрейд
- Фраза восстановления больше не нужна — ваша карта или кольцо Tangem становятся вашей надёжной резервной копией.
- Резервное копирование
+ Все ваши адреса и балансы остаются полностью доступными при апгрейде мобильного кошелька на Tangem-карту или кольцо.
+ Те же адреса
Это устройство не может быть использовано для апгрейда, оно уже содержит другой кошелек.
Выберите другое устройство. Это нельзя использовать для обновления.
Во время операции произошла ошибка.
Ваши средства остаются в безопасности и полностью доступны в процессе.
Доступ к средствам
- Данные вашего кошелька будут удалены из приложения и сохранены на вашем устройстве Tangem.
+ После апгрейда ваш мобильный кошелек будет удалён из приложения и сохранён на аппаратном кошельке; фраза восстановления остаётся у вас.
Общая безопасность
Приватные ключи будут перемещены из приложения в вашу Tangem карту или кольцо
Миграция ключей
@@ -1277,6 +1288,11 @@
Подготовьтесь к сканированию кольца или карты, которую вы хотите настроить.
Забыть кошелек
Это приведет к удалению кошелька из приложения. Сам кошелек можно добавить снова.
+ Прост в использовании
+ Хранит вашу криптовалюту в безопасности и офлайн. Тонкий, как кредитная карта, надежнее банковского сейфа.
+ Без seed-фразы
+ Лучший в своём классе аппаратный кошелек
+ Холодный кошелек Tangem
Имя
Заставьте ваш токен работать
Сетевая комиссия — это небольшая плата за обработку и подтверждение вашей транзакции в блокчейне.
@@ -1442,6 +1458,7 @@
Интуитивный обмен в пару касаний — без сложностей и ожидания
Проще простого
Обмен через провайдера
+ Ваши средства
В сумму включено: \n• комиссия провайдера сервиса\n• комиссия сети за отправку %s от биржи обратно на адрес пользователя.
В сумму включено: \n• комиссия провайдера сервиса\n• комиссия сети за отправку %1$s от биржи обратно на адрес пользователя \n\nПроскальзывание провайдера составляет до %2$s
В сумму включена комиссия провайдера сервиса.
@@ -1456,6 +1473,7 @@
Недостаточно средств
Дать разрешение
Обменять
+ Обмен…
Вы получите
Выберите токен
не доступен
@@ -1646,6 +1664,7 @@
Произошла ошибка. Код ошибки: %s. Попробуйте, пожалуйста, снова. Если проблема будет продолжать возникать — обратитесь в службу поддержки.
Используйте %s или отсканируйте карту/кольцо, чтобы получить доступ к своему кошельку
Соединение не удалось: это dApp использует Wallet Connect версии 1.0, которая не поддерживается. Убедитесь, что dApp поддерживает Wallet Connect версии 2.0 для успешного подключения.
+ Апгрейд до аппаратного кошелька
Будьте в курсе новых функций и новостей
Мгновенные уведомления о транзакциях, обменах и важных обновлениях.
Уведомления о транзакциях
@@ -1957,6 +1976,7 @@
Быстрая доставка
Начните в один клик
Просто и надёжно
+ Без seed-фразы
Интуитивно понятный
Создайте аппаратный кошелёк с Tangem. Тонкий, как банковская карта, безопасный, как банковский сейф.
Создать или импортировать мобильный кошелёк
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 59177b2da4..f7732464c2 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -328,6 +328,7 @@
Now
OK
Open in Browser
+ or
Primary card
Primary ring
Passphrase
@@ -438,7 +439,6 @@
This mechanism protects against proximity attacks on a card or ring. It will enforce a delay between reception and execution of a command.
Passcode
Before executing any command entailing a change of the card state, you will have to enter the passcode.
- You can have either one mobile wallet or hardware wallet at the same time. Upgrade you wallet or delete it from the app to start using a Tangem cold wallet.
Upgrade to hardware wallet
NFT
Referral program
@@ -453,6 +453,7 @@
Signed
Send feedback
Details
+ You can have only one mobile wallet at a time. It can be upgraded to a Tangem cold wallet or used alongside a new cold wallet.
Check your internet connection or switch to a different network
Terms of service
Default Address
@@ -563,7 +564,7 @@
Can\'t send a transaction
Coin description error
Not enough funds
- Gasless transaction fee
+ Transaction fee
An error occurred
An error occurred. Code: %s.
Requires memo
@@ -575,10 +576,10 @@
To continue, grant %1s smart contracts permission to use your %2s
Give Permission
Unlimited
- A backup is created using 2–3 Tangem cards. Store them separately in secure locations to protect against loss or damage. No seed phrase needed.
- Backup With Multiple Cards
+ New addresses will be generated for you inside your hardware wallet, ready for use and fully secure.
+ New Addresses
Add Tangem Wallet
- Your private key is generated directly inside the Tangem card and never leaves it.
+ Your private key will be generated directly inside the Tangem card and will never leave it.
Key Generation
All cryptographic operations happen inside the secure chip, certified against cloning and physical tampering.
Hardware-Level Security
@@ -613,15 +614,20 @@
Finalize backup first
Incomplete
Other methods
+ Save your recovery phrase in a secure place and keep it private to protect your funds, and set up an access code for additional security.
Save your recovery phrase in a secure place and keep it private to protect your funds.
Recovery phrase
To secure your wallet with an access code, complete the backup process.
To upgrade to a hardware wallet, complete the backup process.
+ Upgrade your mobile wallet to a Tangem hardware wallet for the highest security. Import your wallet or transfer funds to a new one.
+ Upgrade to cold wallet
Your private keys are securely encrypted and stored on your phone
Private keys stay on your device
Create or restore your wallet with a recovery phrase.
Seed phrase backup
Create Mobile Wallet
+ Transfer your mobile wallet to a Tangem card or ring anytime, securely.
+ Upgrade to hardware wallet
Import existing wallet
This recovery phrase has already been imported
Mobile Wallet
@@ -639,14 +645,14 @@
I understand that if I haven\'t backed up my wallet before removing it, I will lose access to it.
I understand that removing my wallet does not delete it, only removes it from my device.
Upgrade
- Seed phrase not required. Your Tangem card or ring becomes your secure backup.
- Backup With Tangem
+ All your addresses and balances stay fully accessible when upgrading your mobile wallet to a Tangem card or ring.
+ Same Addresses
Can\'t upgrade. A wallet already exists on this device.
Pick another device. This one can\'t be used for the upgrade.
An error occurred during the operation.
Your funds remain safe and fully accessible during the process
Access to funds
- Your wallet information will be erased from the app and stored on your hardware wallet
+ After upgrading, your mobile wallet will be removed from the app and stored on your hardware wallet; your recovery phrase stays with you.
General security
Private keys will be moved from the app to your Tangem hardware wallet
Key migration
@@ -1420,6 +1426,7 @@
Hassle-free and intuitive, allowing you to swap tokens in just a few taps
Simply Convenient
Swap via provider
+ Your assets
The amount includes:\n• service provider\'s fee\n• network fee for sending %s from the exchange back to the user\'s address.
The amount includes:\n• service provider\'s fee\n• network fee for sending %1$s from the exchange back to the user\'s address. \n\nProvider slippage is up to %2$s
The amount includes the service provider\'s fee.
@@ -1434,6 +1441,7 @@
Insufficient funds
Give Permission
Swap
+ Swapping...
You receive
Choose token
not available
@@ -1560,6 +1568,8 @@
Tangem Pay is temporarily unreachable
Tangem Pay
Click the button below to restore access
+ You can only withdraw USDC (Polygon) currently available on your on‑chain address balance, taking into account pending transactions. If you previously made a refund or cancelled a purchase, your crypto account balance will update within 2 business days.
+ Please note
Your PIN code
This is my wallet
Balances hidden
@@ -1631,7 +1641,7 @@
We\'ve encountered an error. Error code: %s. Please contact our support.
Use %s or scan a card/ring to have access to your wallet
Connection failed: This dApp uses Wallet Connect version 1.0, which is not supported. Please ensure the dApp supports Wallet Connect version 2.0 to connect successfully.
- Upgrade to a hardware wallet
+ Upgrade to hardware wallet
Stay up to date with the latest features and news
Real-time alerts for transactions, exchanges, and critical updates.
Transaction Alerts
@@ -2002,6 +2012,7 @@
Fast delivery
Start in one tap
Seamless and secure
+ No seed phrase
Simple to use
Create a hardware wallet with Tangem. Slim as a bank card, secure as a bank vault.
Create or import a software wallet
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/block/BlockItem.kt b/core/ui/src/main/java/com/tangem/core/ui/components/block/BlockItem.kt
index 66cf54df35..be7f8f5b2c 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/block/BlockItem.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/block/BlockItem.kt
@@ -27,16 +27,18 @@ fun BlockItem(model: BlockUM, modifier: Modifier = Modifier) {
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12, Alignment.Start),
) {
- Icon(
- modifier = Modifier.size(TangemTheme.dimens.size24),
- painter = painterResource(id = model.iconRes),
- tint = when (model.accentType) {
- BlockUM.AccentType.NONE -> TangemTheme.colors.icon.secondary
- BlockUM.AccentType.ACCENT -> TangemTheme.colors.text.accent
- BlockUM.AccentType.WARNING -> TangemTheme.colors.text.warning
- },
- contentDescription = null,
- )
+ if (model.iconRes != null) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = model.iconRes),
+ tint = when (model.accentType) {
+ BlockUM.AccentType.NONE -> TangemTheme.colors.icon.secondary
+ BlockUM.AccentType.ACCENT -> TangemTheme.colors.text.accent
+ BlockUM.AccentType.WARNING -> TangemTheme.colors.text.warning
+ },
+ contentDescription = null,
+ )
+ }
Text(
modifier = Modifier.weight(1f),
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/block/model/BlockUM.kt b/core/ui/src/main/java/com/tangem/core/ui/components/block/model/BlockUM.kt
index 4988f72eff..f0079ad959 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/block/model/BlockUM.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/block/model/BlockUM.kt
@@ -7,7 +7,7 @@ import javax.annotation.concurrent.Immutable
data class BlockUM(
val text: TextReference,
- @DrawableRes val iconRes: Int,
+ @DrawableRes val iconRes: Int?,
val onClick: () -> Unit,
val accentType: AccentType = AccentType.NONE,
val endContent: EndContent = EndContent.None,
diff --git a/core/ui/src/main/res/drawable/ic_backup_repeat_24.xml b/core/ui/src/main/res/drawable/ic_backup_repeat_24.xml
new file mode 100644
index 0000000000..3579504b2c
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_backup_repeat_24.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_double_star_24.xml b/core/ui/src/main/res/drawable/ic_double_star_24.xml
new file mode 100644
index 0000000000..78ca302987
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_double_star_24.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_mobile_security_2_24.xml b/core/ui/src/main/res/drawable/ic_mobile_security_2_24.xml
new file mode 100644
index 0000000000..20f8ba11fa
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_mobile_security_2_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_seed_phrase_24.xml b/core/ui/src/main/res/drawable/ic_seed_phrase_24.xml
new file mode 100644
index 0000000000..7ec0b491f4
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_seed_phrase_24.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_smartphone_24.xml b/core/ui/src/main/res/drawable/ic_smartphone_24.xml
new file mode 100644
index 0000000000..eb4558d24b
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_smartphone_24.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_tangem_card_24.xml b/core/ui/src/main/res/drawable/ic_tangem_card_24.xml
new file mode 100644
index 0000000000..2f4eabe10a
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_tangem_card_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt
index 8c7bb0d2eb..2183fc05a0 100644
--- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt
+++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/CreateWalletStartModel.kt
@@ -92,7 +92,7 @@ internal class CreateWalletStartModel @Inject constructor(
onPrimaryButtonClick = ::onBuyClick,
primaryButtonText = resourceReference(R.string.details_buy_wallet),
otherMethodTitle = resourceReference(R.string.welcome_create_wallet_mobile_title),
- otherMethodDescription = resourceReference(R.string.welcome_create_wallet_mobile_description),
+ otherMethodDescription = null,
otherMethodClick = ::onStartWithMobileWalletClick,
onBackClick = { router.pop() },
onScanClick = ::onScanClick,
diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt
index b45777a20a..bce2d230b2 100644
--- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt
+++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/entity/CreateWalletStartUM.kt
@@ -12,7 +12,7 @@ internal data class CreateWalletStartUM(
val shouldShowScanSecondaryButton: Boolean,
val primaryButtonText: TextReference,
val onPrimaryButtonClick: () -> Unit,
- val otherMethodDescription: TextReference,
+ val otherMethodDescription: TextReference?,
val otherMethodTitle: TextReference,
val otherMethodClick: () -> Unit,
val onScanClick: () -> Unit,
diff --git a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt
index ecf741b0f0..e113e454a5 100644
--- a/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt
+++ b/features/create-wallet-start/impl/src/main/kotlin/com/tangem/features/createwalletstart/ui/CreateWalletStartContent.kt
@@ -181,7 +181,7 @@ internal fun CreateWalletStartContent(state: CreateWalletStartUM, modifier: Modi
.height(16.dp),
)
Text(
- text = stringResourceSafe(R.string.welcome_create_wallet_other_method),
+ text = stringResourceSafe(R.string.common_or),
style = TangemTheme.typography.caption1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
@@ -193,19 +193,21 @@ internal fun CreateWalletStartContent(state: CreateWalletStartUM, modifier: Modi
.scale(scaleX = -1f, scaleY = 1f),
)
}
- Text(
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- start = 16.dp,
- top = 16.dp,
- end = 16.dp,
- ),
- text = state.otherMethodDescription.resolveReference(),
- style = TangemTheme.typography.subtitle2,
- color = TangemTheme.colors.text.tertiary,
- textAlign = TextAlign.Center,
- )
+ if (state.otherMethodDescription != null) {
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ start = 16.dp,
+ top = 16.dp,
+ end = 16.dp,
+ ),
+ text = state.otherMethodDescription.resolveReference(),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ textAlign = TextAlign.Center,
+ )
+ }
Row(
modifier = Modifier
.wrapContentWidth()
@@ -429,9 +431,7 @@ private class CreateWalletStartStateProvider : CollectionPreviewParameterProvide
onPrimaryButtonClick = { },
primaryButtonText = resourceReference(R.string.details_buy_wallet),
otherMethodTitle = resourceReference(R.string.welcome_create_wallet_mobile_title),
- otherMethodDescription = resourceReference(
- R.string.welcome_create_wallet_mobile_description,
- ),
+ otherMethodDescription = null,
otherMethodClick = { },
onBackClick = { },
onScanClick = { },
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt
index 0a9a273352..45c7cd73ca 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt
@@ -12,6 +12,7 @@ import com.tangem.features.details.entity.DetailsUM
import com.tangem.features.details.ui.DetailsScreen
import com.tangem.features.details.utils.ItemsBuilder
import com.tangem.features.details.utils.SocialsBuilder
+import com.tangem.features.hotwallet.HotWalletFeatureToggles
import kotlinx.coroutines.runBlocking
internal class PreviewDetailsComponent : DetailsComponent {
@@ -19,9 +20,14 @@ internal class PreviewDetailsComponent : DetailsComponent {
private val previewBlocks = runBlocking {
ItemsBuilder(
router = DummyRouter(),
+ hotWalletFeatureToggles = object : HotWalletFeatureToggles {
+ override val isHotWalletEnabled: Boolean = true
+ override val isWalletCreationRestrictionEnabled: Boolean = true
+ },
).buildAll(
isWalletConnectAvailable = true,
isSupportChatAvailable = true,
+ hasAnyMobileWallet = true,
userWalletId = UserWalletId(""),
onSupportEmailClick = {},
onSupportChatClick = {},
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt
index 86ecb2a42f..e56710ead0 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt
@@ -50,6 +50,7 @@ internal class PreviewUserWalletListComponent : UserWalletListComponent {
),
addNewWalletText = resourceReference(R.string.user_wallet_list_add_button),
isWalletSavingInProgress = true,
+ addNewWalletIconRes = R.drawable.ic_plus_24,
onAddNewWalletClick = {},
),
)
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt
index 99c416a63a..5e7ebe0773 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt
@@ -2,6 +2,7 @@ package com.tangem.features.details.entity
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.block.model.BlockUM
+import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
@Immutable
@@ -27,4 +28,9 @@ internal sealed class DetailsItemUM {
data object UserWalletList : DetailsItemUM() {
override val id: String = "user_wallet_list"
}
+
+ data class UnderSectionText(
+ override val id: String,
+ val text: TextReference,
+ ) : DetailsItemUM()
}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt
index a8ef5eb141..bc4baf7d42 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt
@@ -1,5 +1,6 @@
package com.tangem.features.details.entity
+import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
import com.tangem.core.ui.extensions.TextReference
@@ -10,5 +11,6 @@ internal data class UserWalletListUM(
val userWallets: ImmutableList,
val isWalletSavingInProgress: Boolean,
val addNewWalletText: TextReference,
+ @DrawableRes val addNewWalletIconRes: Int?,
val onAddNewWalletClick: () -> Unit,
)
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt
index 1c4c53f372..9d316e6c90 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt
@@ -97,6 +97,7 @@ internal class DetailsModel @Inject constructor(
itemsBuilder.buildAll(
isWalletConnectAvailable = isWalletConnectAvailable,
isSupportChatAvailable = feedbackFeatureToggles.isUsedeskEnabled,
+ hasAnyMobileWallet = getWalletsUseCase.invokeSync().any { it is UserWallet.Hot },
userWalletId = params.userWalletId,
onSupportEmailClick = ::sendFeedback,
onSupportChatClick = ::openUseDesk,
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt
index badebd605e..0a0dd71c89 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/UserWalletListModel.kt
@@ -60,6 +60,7 @@ internal class UserWalletListModel @Inject constructor(
isWalletSavingInProgress = false,
addNewWalletText = TextReference.EMPTY,
onAddNewWalletClick = ::onAddNewWalletClick,
+ addNewWalletIconRes = R.drawable.ic_plus_24,
),
)
@@ -81,10 +82,11 @@ internal class UserWalletListModel @Inject constructor(
value.copy(
userWallets = userWallets,
isWalletSavingInProgress = isWalletSavingInProgress,
- addNewWalletText = if (shouldSaveUserWallets || hotWalletFeatureToggles.isHotWalletEnabled) {
- resourceReference(R.string.user_wallet_list_add_button)
- } else {
- resourceReference(R.string.scan_card_settings_button)
+ addNewWalletText = when {
+ shouldSaveUserWallets || hotWalletFeatureToggles.isHotWalletEnabled -> {
+ resourceReference(R.string.user_wallet_list_add_button)
+ }
+ else -> resourceReference(R.string.scan_card_settings_button)
},
)
}
@@ -92,7 +94,14 @@ internal class UserWalletListModel @Inject constructor(
private fun onAddNewWalletClick() {
if (hotWalletFeatureToggles.isHotWalletEnabled) {
analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.Settings))
- router.push(AppRoute.CreateWalletSelection)
+
+ if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) {
+ withProgress(isWalletSavingInProgress) {
+ userWalletSaver.scanAndSaveUserWallet(modelScope)
+ }
+ } else {
+ router.push(AppRoute.CreateWalletSelection)
+ }
} else {
withProgress(isWalletSavingInProgress) {
userWalletSaver.scanAndSaveUserWallet(modelScope)
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt
index 6be90f525b..0afe3711b2 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt
@@ -5,6 +5,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
@@ -18,10 +19,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.tangem.core.ui.components.SpacerH16
import com.tangem.core.ui.components.appbar.TangemTopAppBar
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
import com.tangem.core.ui.components.block.BlockItem
import com.tangem.core.ui.decompose.ComposableContentComponent
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@@ -68,7 +73,7 @@ private fun Content(
) {
LazyColumn(
modifier = modifier.testTag(DetailsScreenTestTags.SCREEN_CONTAINER),
- verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
+ verticalArrangement = Arrangement.SpaceBetween,
contentPadding = PaddingValues(
top = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing16,
@@ -94,6 +99,7 @@ private fun Content(
}
item(key = "footer") {
+ SpacerH16()
Footer(
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing12),
model = state.footer,
@@ -108,6 +114,16 @@ private fun Block(
userWalletListBlockContent: ComposableContentComponent,
modifier: Modifier = Modifier,
) {
+ if (model is DetailsItemUM.UnderSectionText) {
+ UnderSectionTextBlock(
+ modifier = Modifier.fillMaxWidth(),
+ text = model.text,
+ )
+ return
+ }
+
+ SpacerH16()
+
Column(
modifier = modifier
.fillMaxWidth()
@@ -142,10 +158,21 @@ private fun Block(
is DetailsItemUM.UserWalletList -> {
userWalletListBlockContent.Content(modifier = itemModifier)
}
+ is DetailsItemUM.UnderSectionText -> { /* Handled above */ }
}
}
}
+@Composable
+private fun UnderSectionTextBlock(text: TextReference, modifier: Modifier = Modifier) {
+ Text(
+ modifier = modifier.padding(horizontal = 30.dp, vertical = 8.dp),
+ text = text.resolveReference(),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+}
+
@Composable
private fun Footer(model: DetailsFooterUM, modifier: Modifier = Modifier) {
Column(
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt
index ec27900868..f06856c4df 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt
@@ -1,6 +1,7 @@
package com.tangem.features.details.ui
import android.content.res.Configuration
+import androidx.annotation.DrawableRes
import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.CircularProgressIndicator
@@ -23,7 +24,6 @@ import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.details.component.UserWalletListComponent
import com.tangem.features.details.component.preview.PreviewUserWalletListComponent
import com.tangem.features.details.entity.UserWalletListUM
-import com.tangem.features.details.impl.R
@Composable
internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = Modifier) {
@@ -42,6 +42,7 @@ internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = M
text = state.addNewWalletText,
isInProgress = state.isWalletSavingInProgress,
onClick = state.onAddNewWalletClick,
+ icon = state.addNewWalletIconRes,
)
}
}
@@ -49,6 +50,7 @@ internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = M
@Composable
private fun AddWalletButton(
text: TextReference,
+ @DrawableRes icon: Int?,
isInProgress: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
@@ -65,23 +67,25 @@ private fun AddWalletButton(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
- AnimatedContent(
- modifier = Modifier.size(TangemTheme.dimens.size24),
- targetState = isInProgress,
- label = "Add wallet progress",
- ) { isInProgress ->
- if (isInProgress) {
- CircularProgressIndicator(
- modifier = Modifier.size(TangemTheme.dimens.size24),
- color = TangemTheme.colors.icon.accent,
- )
- } else {
- Icon(
- modifier = Modifier.size(TangemTheme.dimens.size24),
- painter = painterResource(id = R.drawable.ic_plus_24),
- tint = TangemTheme.colors.icon.accent,
- contentDescription = null,
- )
+ if (icon != null) {
+ AnimatedContent(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ targetState = isInProgress,
+ label = "Add wallet progress",
+ ) { isInProgress ->
+ if (isInProgress) {
+ CircularProgressIndicator(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ color = TangemTheme.colors.icon.accent,
+ )
+ } else {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = icon),
+ tint = TangemTheme.colors.icon.accent,
+ contentDescription = null,
+ )
+ }
}
}
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt
index 7ee2b6eccd..9746070c35 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt
@@ -8,6 +8,7 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.details.entity.DetailsItemUM
import com.tangem.features.details.impl.R
+import com.tangem.features.hotwallet.HotWalletFeatureToggles
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
@@ -17,12 +18,16 @@ import javax.inject.Inject
private const val TANGEM_PAY_ITEM_ID = "get_tangem_pay"
@ModelScoped
-internal class ItemsBuilder @Inject constructor(private val router: Router) {
+internal class ItemsBuilder @Inject constructor(
+ private val router: Router,
+ private val hotWalletFeatureToggles: HotWalletFeatureToggles,
+) {
@Suppress("LongParameterList")
fun buildAll(
isWalletConnectAvailable: Boolean,
isSupportChatAvailable: Boolean,
+ hasAnyMobileWallet: Boolean,
userWalletId: UserWalletId,
onSupportEmailClick: () -> Unit,
onSupportChatClick: () -> Unit,
@@ -30,6 +35,14 @@ internal class ItemsBuilder @Inject constructor(private val router: Router) {
): ImmutableList = buildList {
buildWalletConnectBlock(isWalletConnectAvailable, userWalletId)?.let(::add)
buildUserWalletListBlock().let(::add)
+
+ if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled && hasAnyMobileWallet) {
+ DetailsItemUM.UnderSectionText(
+ id = "only_one_mobile_wallet_explanation",
+ text = resourceReference(R.string.only_one_mobile_wallet_explanation),
+ ).let(::add)
+ }
+
buildShopBlock(onBuyClick).let(::add)
buildSettingsBlock().let(::add)
buildSupportBlock(
diff --git a/features/hot-wallet/api/build.gradle.kts b/features/hot-wallet/api/build.gradle.kts
index a51cd40254..7e7bd837fd 100644
--- a/features/hot-wallet/api/build.gradle.kts
+++ b/features/hot-wallet/api/build.gradle.kts
@@ -9,6 +9,7 @@ android {
}
dependencies {
+ implementation(projects.common.routing)
/* Project - Domain */
implementation(projects.domain.models)
diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt
index f8ecf58ffe..c0526863e1 100644
--- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt
+++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/HotWalletFeatureToggles.kt
@@ -2,4 +2,5 @@ package com.tangem.features.hotwallet
interface HotWalletFeatureToggles {
val isHotWalletEnabled: Boolean
+ val isWalletCreationRestrictionEnabled: Boolean
}
\ No newline at end of file
diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/WalletBackupComponent.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/WalletBackupComponent.kt
index c5c270623f..0d4df73fb4 100644
--- a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/WalletBackupComponent.kt
+++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/WalletBackupComponent.kt
@@ -8,6 +8,7 @@ interface WalletBackupComponent : ComposableContentComponent {
data class Params(
val userWalletId: UserWalletId,
+ val isColdWalletOptionShown: Boolean,
)
interface Factory : ComponentFactory
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt
index cadb09331f..b635ab78db 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/DefaultHotWalletFeatureToggles.kt
@@ -7,4 +7,7 @@ internal class DefaultHotWalletFeatureToggles(
) : HotWalletFeatureToggles {
override val isHotWalletEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_ENABLED")
+ override val isWalletCreationRestrictionEnabled: Boolean
+ get() = isHotWalletEnabled &&
+ featureTogglesManager.isFeatureEnabled(name = "HOT_WALLET_CREATION_RESTRICTION_ENABLED")
}
\ No newline at end of file
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/common/ui/OptionBlock.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/common/ui/OptionBlock.kt
index bcc2a2c440..168491ff06 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/common/ui/OptionBlock.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/common/ui/OptionBlock.kt
@@ -26,11 +26,11 @@ private const val DISABLED_COLORS_ALPHA = 0.5f
internal fun OptionBlock(
title: String,
description: String,
- badge: (@Composable () -> Unit)?,
onClick: (() -> Unit)?,
- enabled: Boolean,
- backgroundColor: Color,
modifier: Modifier = Modifier,
+ backgroundColor: Color = TangemTheme.colors.background.primary,
+ badge: (@Composable () -> Unit)? = null,
+ enabled: Boolean = true,
) {
Column(
modifier = modifier
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt
index 095790c30a..08afdafd30 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createhardwarewallet/ui/CreateHardwareWalletContent.kt
@@ -66,7 +66,7 @@ internal fun CreateHardwareWalletContent(state: CreateHardwareWalletUM, modifier
top = 20.dp,
end = 16.dp,
),
- text = stringResourceSafe(R.string.wallet_create_common_title),
+ text = stringResourceSafe(R.string.hardware_wallet_create_title),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
@@ -74,22 +74,22 @@ internal fun CreateHardwareWalletContent(state: CreateHardwareWalletUM, modifier
FeatureBlock(
modifier = Modifier
.padding(top = 32.dp),
- title = stringResourceSafe(R.string.hw_upgrade_key_migration_title),
- description = stringResourceSafe(R.string.hw_upgrade_key_migration_description),
- iconRes = R.drawable.ic_mobile_security_24,
+ title = stringResourceSafe(R.string.hardware_wallet_key_feature_title),
+ description = stringResourceSafe(R.string.hardware_wallet_key_feature_description),
+ iconRes = R.drawable.ic_mobile_security_2_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
- title = stringResourceSafe(R.string.hw_upgrade_funds_access_title),
- description = stringResourceSafe(R.string.hw_upgrade_funds_access_description),
- iconRes = R.drawable.ic_knight_shield_24,
+ title = stringResourceSafe(R.string.hardware_wallet_backup_feature_title),
+ description = stringResourceSafe(R.string.hardware_wallet_backup_feature_description),
+ iconRes = R.drawable.ic_double_star_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
- title = stringResourceSafe(R.string.hw_upgrade_general_security_title),
- description = stringResourceSafe(R.string.hw_upgrade_general_security_description),
+ title = stringResourceSafe(R.string.hardware_wallet_security_feature_title),
+ description = stringResourceSafe(R.string.hardware_wallet_security_feature_description),
iconRes = R.drawable.ic_protect_24,
)
}
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt
index e6916bdcfd..bf0f02e9b8 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/createmobilewallet/ui/CreateMobileWalletContent.kt
@@ -75,14 +75,21 @@ internal fun CreateMobileWalletContent(state: CreateMobileWalletUM, modifier: Mo
.padding(top = 32.dp),
title = stringResourceSafe(R.string.hw_create_keys_title),
description = stringResourceSafe(R.string.hw_create_keys_description),
- iconRes = R.drawable.ic_lock_24,
+ iconRes = R.drawable.ic_protect_24,
)
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
title = stringResourceSafe(R.string.hw_create_seed_title),
description = stringResourceSafe(R.string.hw_create_seed_description),
- iconRes = R.drawable.ic_settings_24,
+ iconRes = R.drawable.ic_seed_phrase_24,
+ )
+ FeatureBlock(
+ modifier = Modifier
+ .padding(top = 24.dp),
+ title = stringResourceSafe(R.string.hw_create_upgrade_title),
+ description = stringResourceSafe(R.string.hw_create_upgrade_description),
+ iconRes = R.drawable.ic_tangem_card_24,
)
}
SecondaryButton(
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt
index a643ee75e0..7dc3ca93cf 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt
@@ -83,9 +83,9 @@ internal fun UpgradeWalletContent(state: UpgradeWalletUM, modifier: Modifier = M
FeatureBlock(
modifier = Modifier
.padding(top = 24.dp),
- title = stringResourceSafe(R.string.hw_upgrade_funds_access_title),
- description = stringResourceSafe(R.string.hw_upgrade_funds_access_description),
- iconRes = R.drawable.ic_knight_shield_24,
+ title = stringResourceSafe(R.string.hw_upgrade_backup_title),
+ description = stringResourceSafe(R.string.hw_upgrade_backup_description),
+ iconRes = R.drawable.ic_smartphone_24,
)
FeatureBlock(
modifier = Modifier
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/viewphrase/model/ViewPhraseModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/viewphrase/model/ViewPhraseModel.kt
index a0b991c0a4..808f1df0b6 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/viewphrase/model/ViewPhraseModel.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/viewphrase/model/ViewPhraseModel.kt
@@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
+import timber.log.Timber
import javax.inject.Inject
@Stable
@@ -48,19 +49,19 @@ internal class ViewPhraseModel @Inject constructor(
private fun loadSeedPhrase() {
val userWallet = getUserWalletUseCase(params.userWalletId)
.getOrElse { error("User wallet with id ${params.userWalletId} not found") }
- if (userWallet is UserWallet.Hot) {
- modelScope.launch {
- val words = exportSeedPhraseUseCase.invoke(userWallet.hotWalletId)
- .getOrElse { error("Unable to export seed phrase for wallet with id ${params.userWalletId}") }
- .mnemonic
- .mnemonicComponents
- uiState.update {
- it.copy(
- words = words.mapIndexed { index, s ->
- EnumeratedTwoColumnGridItem(index + 1, s)
- }.toImmutableList(),
- )
- }
+ as? UserWallet.Hot ?: return
+
+ modelScope.launch {
+ val words = exportSeedPhraseUseCase.invoke(userWallet.hotWalletId)
+ .getOrElse { error -> Timber.e(error); throw error }
+ .mnemonic.mnemonicComponents
+
+ uiState.update {
+ it.copy(
+ words = words.mapIndexed { index, s ->
+ EnumeratedTwoColumnGridItem(index + 1, s)
+ }.toImmutableList(),
+ )
}
}
}
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/entity/WalletBackupUM.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/entity/WalletBackupUM.kt
index 9afce42e0d..a1219ed46a 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/entity/WalletBackupUM.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/entity/WalletBackupUM.kt
@@ -8,7 +8,6 @@ internal data class WalletBackupUM(
val recoveryPhraseOption: LabelUM?,
val googleDriveOption: LabelUM?,
val googleDriveStatus: BackupStatus,
- val onBuyClick: () -> Unit,
val onRecoveryPhraseClick: () -> Unit,
val onGoogleDriveClick: () -> Unit,
val onHardwareWalletClick: () -> Unit,
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt
index bdc95378ca..7c284f9cef 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/model/WalletBackupModel.kt
@@ -2,21 +2,17 @@ package com.tangem.features.hotwallet.walletbackup.model
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.api.AnalyticsEventHandler
-import com.tangem.core.analytics.models.AnalyticsParam
-import com.tangem.core.analytics.models.Basic
import com.tangem.core.analytics.utils.TrackingContextProxy
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
-import com.tangem.core.navigation.url.UrlOpener
import com.tangem.core.ui.R
import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
-import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase
import com.tangem.features.hotwallet.WalletBackupComponent
@@ -36,8 +32,6 @@ internal class WalletBackupModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val getUserWalletUseCase: GetUserWalletUseCase,
private val unlockHotWalletContextualUseCase: UnlockHotWalletContextualUseCase,
- private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase,
- private val urlOpener: UrlOpener,
private val router: Router,
private val trackingContextProxy: TrackingContextProxy,
private val analyticsEventHandler: AnalyticsEventHandler,
@@ -54,7 +48,7 @@ internal class WalletBackupModel @Inject constructor(
hardwareWalletOption = LabelUM(
text = resourceReference(R.string.common_recommended),
style = LabelStyle.ACCENT,
- ),
+ ).takeIf { params.isColdWalletOptionShown },
recoveryPhraseOption = LabelUM(
text = resourceReference(R.string.hw_backup_no_backup),
style = LabelStyle.WARNING,
@@ -64,7 +58,6 @@ internal class WalletBackupModel @Inject constructor(
style = LabelStyle.REGULAR,
),
googleDriveStatus = BackupStatus.ComingSoon,
- onBuyClick = ::onBuyClick,
onRecoveryPhraseClick = ::onRecoveryPhraseClick,
onGoogleDriveClick = { },
onHardwareWalletClick = ::onHardwareWalletClick,
@@ -129,14 +122,6 @@ internal class WalletBackupModel @Inject constructor(
backedUp = userWallet.backedUp,
)
- private fun onBuyClick() {
- analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Backup))
- modelScope.launch {
- generateBuyTangemCardLinkUseCase
- .invoke(GenerateBuyTangemCardLinkUseCase.Source.Backup).let { urlOpener.openUrl(it) }
- }
- }
-
private fun onRecoveryPhraseClick() {
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonRecoveryPhrase())
if (uiState.value.backedUp) {
@@ -157,10 +142,9 @@ internal class WalletBackupModel @Inject constructor(
)
} else {
router.push(
- AppRoute.CreateWalletBackup(
+ AppRoute.WalletActivation(
userWalletId = params.userWalletId,
- analyticsSource = AnalyticsParam.ScreensSources.Backup.value,
- analyticsAction = WalletSettingsAnalyticEvents.RecoveryPhraseScreenAction.Backup.value,
+ isBackupExists = false,
),
)
}
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/ui/WalletBackupContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/ui/WalletBackupContent.kt
index d3e452bab2..dc2787f9c6 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/ui/WalletBackupContent.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/walletbackup/ui/WalletBackupContent.kt
@@ -1,36 +1,25 @@
package com.tangem.features.hotwallet.walletbackup.ui
import android.content.res.Configuration
-import androidx.annotation.DrawableRes
-import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R
-import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.components.label.Label
import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.components.rows.NetworkTitle
-import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
-import com.tangem.core.ui.res.ForceDarkTheme
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.common.ui.OptionBlock
@@ -61,33 +50,31 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
end = 16.dp,
),
) {
- Banner(state)
+ if (state.hardwareWalletOption != null) {
+ OptionBlock(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 8.dp),
+ title = stringResourceSafe(R.string.hw_backup_upgrade_title),
+ description = stringResourceSafe(R.string.hw_backup_upgrade_description),
+ badge = { Label(state.hardwareWalletOption) },
+ onClick = state.onHardwareWalletClick,
+ enabled = true,
+ backgroundColor = TangemTheme.colors.background.primary,
+ )
- OptionBlock(
- modifier = Modifier
- .fillMaxWidth()
- .padding(top = 8.dp),
- title = stringResourceSafe(R.string.hw_backup_hardware_title),
- description = stringResourceSafe(R.string.hw_backup_hardware_description),
- badge = {
- state.hardwareWalletOption?.let { Label(it) }
- },
- onClick = state.onHardwareWalletClick,
- enabled = true,
- backgroundColor = TangemTheme.colors.background.primary,
- )
- NetworkTitle(
- modifier = Modifier
- .padding(top = 8.dp),
- title = {
- Text(
- modifier = Modifier,
- text = stringResourceSafe(R.string.onboarding_create_wallet_options_button_options),
- style = TangemTheme.typography.subtitle2,
- color = TangemTheme.colors.text.tertiary,
- )
- },
- )
+ NetworkTitle(
+ modifier = Modifier.padding(top = 8.dp),
+ title = {
+ Text(
+ modifier = Modifier,
+ text = stringResourceSafe(R.string.onboarding_create_wallet_options_button_options),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ },
+ )
+ }
OptionBlock(
modifier = Modifier,
title = stringResourceSafe(R.string.hw_backup_seed_title),
@@ -116,120 +103,6 @@ internal fun WalletBackupContent(state: WalletBackupUM, modifier: Modifier = Mod
}
}
-@Suppress("LongMethod")
-@OptIn(ExperimentalLayoutApi::class)
-@Composable
-private fun Banner(state: WalletBackupUM, modifier: Modifier = Modifier) {
- ForceDarkTheme {
- Column(
- modifier = modifier
- .background(
- color = TangemTheme.colors.background.primary,
- shape = RoundedCornerShape(16.dp),
- ),
- ) {
- Column(
- modifier = Modifier
- .padding(
- start = 12.dp,
- top = 20.dp,
- end = 12.dp,
- ),
- ) {
- Text(
- modifier = Modifier
- .fillMaxWidth(),
- text = "Tangem Wallet",
- style = TangemTheme.typography.h3,
- color = TangemTheme.colors.text.primary1,
- textAlign = TextAlign.Center,
- )
-
- Text(
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- top = 4.dp,
- ),
- text = "Keeps your crypto safe and offline. Slim as a credit card, safer than a bank vault.",
- style = TangemTheme.typography.body2,
- color = TangemTheme.colors.text.tertiary,
- textAlign = TextAlign.Center,
- )
-
- FlowRow(
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- start = 24.dp,
- top = 16.dp,
- end = 24.dp,
- ),
- horizontalArrangement = Arrangement.Center,
- verticalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- FeatureItem(
- iconResId = R.drawable.ic_shield_check_16,
- text = resourceReference(R.string.welcome_create_wallet_feature_class),
- )
- FeatureItem(
- iconResId = R.drawable.ic_flash_16,
- text = resourceReference(R.string.welcome_create_wallet_feature_delivery),
- )
- FeatureItem(
- iconResId = R.drawable.ic_sparkles_16,
- text = resourceReference(R.string.welcome_create_wallet_feature_use),
- )
- }
-
- Box(
- modifier = Modifier
- .padding(
- start = 8.dp,
- top = 12.dp,
- end = 8.dp,
- bottom = 20.dp,
- ),
- ) {
- Image(
- painter = painterResource(id = R.drawable.img_tangem_cards_vertical),
- contentDescription = null,
- )
- SecondaryButton(
- modifier = Modifier
- .fillMaxWidth()
- .align(Alignment.BottomCenter),
- text = stringResourceSafe(R.string.details_buy_wallet),
- onClick = state.onBuyClick,
- )
- }
- }
- }
- }
-}
-
-@Composable
-private fun FeatureItem(@DrawableRes iconResId: Int, text: TextReference) {
- Row(
- modifier = Modifier
- .wrapContentWidth()
- .padding(horizontal = 8.dp),
- horizontalArrangement = Arrangement.spacedBy(6.dp),
- ) {
- Icon(
- modifier = Modifier.size(16.dp),
- painter = painterResource(iconResId),
- tint = TangemTheme.colors.icon.accent,
- contentDescription = null,
- )
- Text(
- text = text.resolveReference(),
- style = TangemTheme.typography.caption1,
- color = TangemTheme.colors.text.secondary,
- )
- }
-}
-
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@@ -256,7 +129,6 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider,
val onBackClick: () -> Unit,
val onBuyClick: () -> Unit,
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt
index efcd39aa14..ae34bf84a6 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/model/WalletHardwareBackupModel.kt
@@ -32,10 +32,8 @@ import com.tangem.features.hotwallet.wallethardwarebackup.entity.WalletHardwareB
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.collections.immutable.persistentListOf
-import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@@ -119,7 +117,6 @@ internal class WalletHardwareBackupModel @Inject constructor(
init {
trackingContextProxy.addHotWalletContext()
analyticsEventHandler.send(WalletSettingsAnalyticEvents.HardwareBackupScreenOpened())
- showPurchaseBlockWithDelay()
}
override fun onDestroy() {
@@ -127,13 +124,6 @@ internal class WalletHardwareBackupModel @Inject constructor(
super.onDestroy()
}
- private fun showPurchaseBlockWithDelay() {
- modelScope.launch {
- delay(SHOW_PURCHASE_BLOCK_DELAY)
- uiState.update { it.copy(showPurchaseBlock = true) }
- }
- }
-
private fun onCreateNewWalletClick() {
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonCreateNewWallet())
router.push(AppRoute.CreateHardwareWallet)
@@ -175,8 +165,4 @@ internal class WalletHardwareBackupModel @Inject constructor(
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Backup).let { urlOpener.openUrl(it) }
}
}
-
- companion object {
- private const val SHOW_PURCHASE_BLOCK_DELAY = 3000L
- }
}
\ No newline at end of file
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/ui/WalletHardwareBackupContent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/ui/WalletHardwareBackupContent.kt
index 8e4eafbf78..41073ffc50 100644
--- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/ui/WalletHardwareBackupContent.kt
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/wallethardwarebackup/ui/WalletHardwareBackupContent.kt
@@ -1,26 +1,26 @@
package com.tangem.features.hotwallet.wallethardwarebackup.ui
import android.content.res.Configuration
-import androidx.compose.animation.AnimatedVisibility
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.SecondaryButton
-import com.tangem.core.ui.components.buttons.common.TangemButtonSize
import com.tangem.core.ui.components.label.Label
import com.tangem.core.ui.components.label.entity.LabelStyle
import com.tangem.core.ui.components.label.entity.LabelUM
-import com.tangem.core.ui.extensions.resolveReference
-import com.tangem.core.ui.extensions.resourceReference
-import com.tangem.core.ui.extensions.stringReference
-import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.extensions.*
+import com.tangem.core.ui.res.ForceDarkTheme
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.hotwallet.common.ui.OptionBlock
@@ -71,6 +71,8 @@ internal fun WalletHardwareBackupContent(state: WalletHardwareBackupUM, modifier
end = 16.dp,
),
) {
+ Banner(onBuyClick = state.onBuyClick)
+
state.blocks.forEach { block ->
OptionBlock(
modifier = Modifier
@@ -86,45 +88,119 @@ internal fun WalletHardwareBackupContent(state: WalletHardwareBackupUM, modifier
)
}
}
- AnimatedVisibility(state.showPurchaseBlock) {
- PurchaseBlock(
- onBuyClick = state.onBuyClick,
- )
+ }
+}
+
+@Suppress("LongMethod")
+@OptIn(ExperimentalLayoutApi::class)
+@Composable
+private fun Banner(onBuyClick: () -> Unit, modifier: Modifier = Modifier) {
+ ForceDarkTheme {
+ Column(
+ modifier = modifier
+ .background(
+ color = TangemTheme.colors.background.primary,
+ shape = RoundedCornerShape(16.dp),
+ ),
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(
+ start = 12.dp,
+ top = 20.dp,
+ end = 12.dp,
+ ),
+ ) {
+ Text(
+ modifier = Modifier
+ .fillMaxWidth(),
+ text = stringResourceSafe(R.string.common_tangem_wallet),
+ style = TangemTheme.typography.h3,
+ color = TangemTheme.colors.text.primary1,
+ textAlign = TextAlign.Center,
+ )
+
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ top = 4.dp,
+ ),
+ text = stringResourceSafe(R.string.hw_backup_banner_description),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.tertiary,
+ textAlign = TextAlign.Center,
+ )
+
+ FlowRow(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ start = 24.dp,
+ top = 16.dp,
+ end = 24.dp,
+ ),
+ horizontalArrangement = Arrangement.Center,
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ FeatureItem(
+ iconResId = R.drawable.ic_shield_check_16,
+ text = resourceReference(R.string.welcome_create_wallet_feature_class),
+ )
+ FeatureItem(
+ iconResId = R.drawable.ic_flash_16,
+ text = resourceReference(R.string.welcome_create_wallet_feature_delivery),
+ )
+ FeatureItem(
+ iconResId = R.drawable.ic_sparkles_16,
+ text = resourceReference(R.string.welcome_create_wallet_feature_seedphrase),
+ )
+ }
+
+ Box(
+ modifier = Modifier
+ .padding(
+ start = 8.dp,
+ top = 12.dp,
+ end = 8.dp,
+ bottom = 20.dp,
+ ),
+ ) {
+ Image(
+ painter = painterResource(id = R.drawable.img_tangem_cards_vertical),
+ contentDescription = null,
+ )
+ SecondaryButton(
+ modifier = Modifier
+ .fillMaxWidth()
+ .align(Alignment.BottomCenter),
+ text = stringResourceSafe(R.string.details_buy_wallet),
+ onClick = onBuyClick,
+ )
+ }
+ }
}
}
}
@Composable
-private fun PurchaseBlock(onBuyClick: () -> Unit, modifier: Modifier = Modifier) {
+private fun FeatureItem(@DrawableRes iconResId: Int, text: TextReference) {
Row(
- modifier = modifier
- .fillMaxWidth()
- .padding(16.dp)
- .background(
- color = TangemTheme.colors.background.primary,
- shape = TangemTheme.shapes.roundedCornersXMedium,
- )
- .padding(
- horizontal = 20.dp,
- vertical = 16.dp,
- ),
- verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .wrapContentWidth()
+ .padding(horizontal = 8.dp),
+ horizontalArrangement = Arrangement.spacedBy(6.dp),
) {
- Text(
- modifier = Modifier
- .weight(1f)
- .padding(end = 16.dp),
- text = stringResourceSafe(R.string.wallet_add_hardware_purchase),
- style = TangemTheme.typography.button,
- color = TangemTheme.colors.text.primary1,
- maxLines = 3,
- overflow = TextOverflow.Ellipsis,
+ Icon(
+ modifier = Modifier.size(16.dp),
+ painter = painterResource(iconResId),
+ tint = TangemTheme.colors.icon.accent,
+ contentDescription = null,
)
-
- SecondaryButton(
- text = stringResourceSafe(R.string.wallet_import_buy_title),
- onClick = onBuyClick,
- size = TangemButtonSize.RoundedAction,
+ Text(
+ text = text.resolveReference(),
+ style = TangemTheme.typography.caption1,
+ color = TangemTheme.colors.text.secondary,
)
}
}
@@ -156,7 +232,6 @@ private fun PreviewWalletHardwareBackupContent() {
onClick = { },
),
),
- showPurchaseBlock = true,
onBuyClick = { },
),
)
diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt
index 34449ac010..4fa7a53f60 100644
--- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt
+++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/component/preview/PreviewWalletSettingsComponent.kt
@@ -65,7 +65,6 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
onNotificationsDescriptionClick = {},
isNotificationsPermissionGranted = false,
onAccessCodeClick = {},
- onUpgradeWalletClick = {},
onBackupClick = {},
onCardSettingsClick = {},
accountsUM = previewAccounts(),
diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt
index a495db9417..d9ff609d19 100644
--- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt
+++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/entity/WalletSettingsItemUM.kt
@@ -31,6 +31,7 @@ internal sealed class WalletSettingsItemUM {
val text: TextReference,
val isEnabled: Boolean,
val imageState: ImageState,
+ val additionalBlock: BlockUM? = null,
val onClick: () -> Unit,
) : WalletSettingsItemUM()
@@ -46,13 +47,6 @@ internal sealed class WalletSettingsItemUM {
val title: TextReference,
val description: TextReference,
) : WalletSettingsItemUM()
-
- data class UpgradeWallet(
- override val id: String,
- val title: TextReference,
- val description: TextReference,
- val onClick: () -> Unit,
- ) : WalletSettingsItemUM()
}
@Immutable
diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt
index 8e97fb4927..f817314f14 100644
--- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt
+++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/model/WalletSettingsModel.kt
@@ -96,7 +96,10 @@ internal class WalletSettingsModel @Inject constructor(
val params: WalletSettingsComponent.Params = paramsContainer.require()
val dialogNavigation = SlotNavigation()
val bottomSheetNavigation: SlotNavigation = SlotNavigation()
- private val walletCardItemDelegate = walletCardItemDelegateFactory.create(dialogNavigation)
+ private val walletCardItemDelegate = walletCardItemDelegateFactory.create(
+ dialogNavigation = dialogNavigation,
+ onUpgradeHotWalletClick = ::onUpgradeWalletClick,
+ )
val state: MutableStateFlow = MutableStateFlow(
value = WalletSettingsUM(
@@ -249,7 +252,6 @@ internal class WalletSettingsModel @Inject constructor(
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
onAccessCodeClick = { onAccessCodeClick(userWallet) },
- onUpgradeWalletClick = { onUpgradeWalletClick() },
onBackupClick = ::onBackupClick,
onCardSettingsClick = ::onCardSettingsClick,
accountsUM = accountList,
@@ -374,10 +376,7 @@ internal class WalletSettingsModel @Inject constructor(
val isCodeSet = userWallet.hotWalletId.authType != HotWalletId.AuthType.NoPassword
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonAccessCode(isCodeSet))
if (!state.value.isWalletBackedUp) {
- showMakeBackupAtFirstAlertBS(
- isUpgradeFlow = false,
- action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.AccessCode,
- )
+ showMakeBackupAtFirstAlertBS()
} else {
unlockWalletIfNeedAndProceed { authorizationRequired ->
router.push(
@@ -392,35 +391,28 @@ internal class WalletSettingsModel @Inject constructor(
}
private fun onUpgradeWalletClick() {
- if (!state.value.isWalletBackedUp) {
- showMakeBackupAtFirstAlertBS(
- isUpgradeFlow = true,
- action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.Upgrade,
- )
- } else {
- unlockWalletIfNeedAndProceed {
- router.push(AppRoute.UpgradeWallet(userWalletId = params.userWalletId))
- }
- }
+ router.push(AppRoute.WalletHardwareBackup(userWalletId = params.userWalletId))
}
private fun onBackupClick() {
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonBackup())
- router.push(AppRoute.WalletBackup(params.userWalletId))
+ router.push(
+ AppRoute.WalletBackup(
+ userWalletId = params.userWalletId,
+ isColdWalletOptionShown = false,
+ ),
+ )
}
private fun onCardSettingsClick() {
router.push(AppRoute.CardSettings(params.userWalletId))
}
- private fun showMakeBackupAtFirstAlertBS(
- action: WalletSettingsAnalyticEvents.NoticeBackupFirst.Action,
- isUpgradeFlow: Boolean,
- ) {
+ private fun showMakeBackupAtFirstAlertBS() {
analyticsEventHandler.send(
event = WalletSettingsAnalyticEvents.NoticeBackupFirst(
source = AnalyticsParam.ScreensSources.WalletSettings.value,
- action = action,
+ action = WalletSettingsAnalyticEvents.NoticeBackupFirst.Action.AccessCode,
),
)
val message = bottomSheetMessage {
@@ -438,14 +430,10 @@ internal class WalletSettingsModel @Inject constructor(
router.push(
AppRoute.CreateWalletBackup(
userWalletId = params.userWalletId,
- isUpgradeFlow = isUpgradeFlow,
+ isUpgradeFlow = false,
shouldSetAccessCode = true,
analyticsSource = AnalyticsParam.ScreensSources.WalletSettings.value,
- analyticsAction = if (isUpgradeFlow) {
- RecoveryPhraseScreenAction.Upgrade.value
- } else {
- RecoveryPhraseScreenAction.AccessCode.value
- },
+ analyticsAction = RecoveryPhraseScreenAction.AccessCode.value,
),
)
closeBs()
diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt
index 7f9cb9d418..6590758780 100644
--- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt
+++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/ui/WalletSettingsScreen.kt
@@ -42,7 +42,6 @@ import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
-import com.tangem.core.ui.extensions.stringReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@@ -153,10 +152,6 @@ private fun Content(state: WalletSettingsUM, modifier: Modifier = Modifier) {
modifier = itemModifier,
model = item,
)
- is WalletSettingsItemUM.UpgradeWallet -> UpgradeWalletBlock(
- modifier = itemModifier,
- model = item,
- )
is WalletSettingsAccountsUM.Header -> AccountsHeader(item, itemModifier)
is WalletSettingsAccountsUM.Account -> AccountItem(
model = item,
@@ -211,35 +206,54 @@ private fun CardBlock(model: WalletSettingsItemUM.CardBlock, modifier: Modifier
enabled = model.isEnabled,
onClick = model.onClick,
) {
- Row(
- modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
- horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
- verticalAlignment = Alignment.CenterVertically,
- ) {
- CardImage(model.imageState)
- Column(modifier = Modifier.weight(1f)) {
- Text(
- text = model.title.resolveReference(),
- color = TangemTheme.colors.text.tertiary,
- style = TangemTheme.typography.caption2,
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- )
- Text(
- text = model.text.resolveReference(),
- color = TangemTheme.colors.text.primary1,
- style = TangemTheme.typography.subtitle1,
- overflow = TextOverflow.Ellipsis,
- maxLines = 1,
+ Column {
+ Row(
+ modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
+ horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ CardImage(model.imageState)
+ Column(modifier = Modifier.weight(1f)) {
+ Text(
+ text = model.title.resolveReference(),
+ color = TangemTheme.colors.text.tertiary,
+ style = TangemTheme.typography.caption2,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ Text(
+ text = model.text.resolveReference(),
+ color = TangemTheme.colors.text.primary1,
+ style = TangemTheme.typography.subtitle1,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ )
+ }
+ SecondarySmallButton(
+ config = SmallButtonConfig(
+ isEnabled = model.isEnabled,
+ text = resourceReference(R.string.common_rename),
+ onClick = model.onClick,
+ ),
)
}
- SecondarySmallButton(
- config = SmallButtonConfig(
- isEnabled = model.isEnabled,
- text = resourceReference(R.string.common_rename),
- onClick = model.onClick,
- ),
- )
+
+ if (model.additionalBlock != null) {
+ Column {
+ HorizontalDivider(
+ thickness = TangemTheme.dimens.size0_5,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = TangemTheme.dimens.spacing12),
+ color = TangemTheme.colors.stroke.primary,
+ )
+
+ BlockItem(
+ modifier = Modifier.fillMaxWidth(),
+ model = model.additionalBlock,
+ )
+ }
+ }
}
}
}
@@ -272,21 +286,6 @@ private fun SwitchBlock(model: WalletSettingsItemUM.WithSwitch, modifier: Modifi
}
}
-@Composable
-private fun UpgradeWalletBlock(model: WalletSettingsItemUM.UpgradeWallet, modifier: Modifier = Modifier) {
- Notification(
- config = NotificationConfig(
- title = model.title,
- subtitle = model.description,
- iconResId = R.drawable.ic_hardware_backup_36,
- iconSize = 36.dp,
- onClick = model.onClick,
- shouldShowArrowIcon = false,
- ),
- modifier = modifier,
- )
-}
-
@Composable
private fun NotificationAlertBlock(model: WalletSettingsItemUM.NotificationPermission, modifier: Modifier = Modifier) {
Notification(
@@ -480,20 +479,4 @@ private fun Preview_WalletSettingsScreen() {
PreviewWalletSettingsComponent().Content(modifier = Modifier.fillMaxSize())
}
}
-
-@Composable
-@Preview(showBackground = true, widthDp = 360)
-@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
-private fun Preview_WalletSettingsScreen1() {
- TangemThemePreview {
- UpgradeWalletBlock(
- model = WalletSettingsItemUM.UpgradeWallet(
- id = "upgrade_wallet",
- title = stringReference("Upgrade wallet with a hardware backup"),
- description = stringReference("Keep your crypto safe with Tangem’s best-in-class hardware wallet."),
- onClick = {},
- ),
- )
- }
-}
// endregion Preview
\ No newline at end of file
diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt
index 86b1637320..a103dee2de 100644
--- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt
+++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/ItemsBuilder.kt
@@ -38,17 +38,10 @@ internal class ItemsBuilder @Inject constructor() {
onReferralClick: () -> Unit,
onManageTokensClick: () -> Unit,
onAccessCodeClick: () -> Unit,
- onUpgradeWalletClick: () -> Unit,
onBackupClick: () -> Unit,
onCardSettingsClick: () -> Unit,
): PersistentList = persistentListOf()
.add(cardItem)
- .addAll(
- buildUpgradeWalletItem(
- userWallet = userWallet,
- onUpgradeWalletClick = onUpgradeWalletClick,
- ),
- )
.addAll(buildAccessCodeItem(userWallet, onAccessCodeClick))
.addAll(accountsUM)
.add(
@@ -116,21 +109,6 @@ internal class ItemsBuilder @Inject constructor() {
onCheckedChange = onCheckedNFTChange,
)
- private fun buildUpgradeWalletItem(
- userWallet: UserWallet,
- onUpgradeWalletClick: () -> Unit,
- ): List = when (userWallet) {
- is UserWallet.Cold -> emptyList()
- is UserWallet.Hot -> listOf(
- WalletSettingsItemUM.UpgradeWallet(
- id = "upgrade_wallet",
- title = resourceReference(id = R.string.hw_upgrade_to_cold_banner_title),
- description = resourceReference(id = R.string.hw_upgrade_to_cold_banner_description),
- onClick = onUpgradeWalletClick,
- ),
- )
- }
-
private fun buildNotificationsPermissionItem() = WalletSettingsItemUM.NotificationPermission(
id = "notifications_permission",
title = resourceReference(id = R.string.transaction_notifications_warning_title),
diff --git a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt
index 18d1546028..8162044ed2 100644
--- a/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt
+++ b/features/wallet-settings/impl/src/main/kotlin/com/tangem/feature/walletsettings/utils/WalletCardItemDelegate.kt
@@ -2,6 +2,7 @@ package com.tangem.feature.walletsettings.utils
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
+import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.models.wallet.UserWallet
@@ -24,6 +25,7 @@ internal class WalletCardItemDelegate @AssistedInject constructor(
private val getShouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
private val walletImageFetcher: UserWalletImageFetcher,
@Assisted private val dialogNavigation: SlotNavigation,
+ @Assisted private val onUpgradeHotWalletClick: () -> Unit,
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
) {
@@ -43,10 +45,20 @@ internal class WalletCardItemDelegate @AssistedInject constructor(
isEnabled = isRenameAvailable,
onClick = { openRenameWalletDialog(wallet) },
imageState = imageState,
+ additionalBlock = buildUpgradeToHardwareWalletBlockOrNull(wallet),
)
},
)
+ private fun buildUpgradeToHardwareWalletBlockOrNull(wallet: UserWallet): BlockUM? {
+ return BlockUM(
+ text = resourceReference(R.string.upgrade_to_hardware_wallet_button_title),
+ iconRes = null,
+ onClick = onUpgradeHotWalletClick,
+ accentType = BlockUM.AccentType.ACCENT,
+ ).takeIf { wallet is UserWallet.Hot }
+ }
+
private fun openRenameWalletDialog(userWallet: UserWallet) {
val config = DialogConfig.RenameWallet(
userWalletId = userWallet.walletId,
@@ -57,6 +69,9 @@ internal class WalletCardItemDelegate @AssistedInject constructor(
@AssistedFactory
interface Factory {
- fun create(dialogNavigation: SlotNavigation): WalletCardItemDelegate
+ fun create(
+ dialogNavigation: SlotNavigation,
+ onUpgradeHotWalletClick: () -> Unit,
+ ): WalletCardItemDelegate
}
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt
index 8d1c6bd283..ed19a09083 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/WalletWarningsClickIntents.kt
@@ -477,7 +477,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
override fun onFinishWalletActivationClick(isBackupExists: Boolean) {
analyticsEventHandler.send(MainScreen.ButtonFinalizeActivation())
val userWalletId = stateHolder.getSelectedWalletId()
- appRouter.push(WalletActivation(userWalletId, isBackupExists))
+ val route = if (isBackupExists) {
+ WalletActivation(userWalletId = userWalletId, isBackupExists = true)
+ } else {
+ WalletBackup(
+ userWalletId = userWalletId,
+ isColdWalletOptionShown = true,
+ )
+ }
+
+ appRouter.push(route)
}
override fun onAllowPermissions() {
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsSingleEventSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsSingleEventSender.kt
index 69b492660a..4b4227a657 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsSingleEventSender.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletWarningsSingleEventSender.kt
@@ -1,6 +1,6 @@
package com.tangem.feature.wallet.presentation.wallet.analytics.utils
-import com.tangem.common.routing.AppRoute.WalletActivation
+import com.tangem.common.routing.AppRoute.WalletBackup
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
@@ -93,7 +93,12 @@ internal class WalletWarningsSingleEventSender @Inject constructor(
primaryButton {
text = resourceReference(R.string.hw_activation_need_backup)
onClick {
- router.push(WalletActivation(userWallet.walletId, userWallet.backedUp))
+ router.push(
+ WalletBackup(
+ userWalletId = userWalletId,
+ isColdWalletOptionShown = true,
+ ),
+ )
closeBs()
}
}
diff --git a/features/welcome/impl/build.gradle.kts b/features/welcome/impl/build.gradle.kts
index 7557118256..09713985c8 100644
--- a/features/welcome/impl/build.gradle.kts
+++ b/features/welcome/impl/build.gradle.kts
@@ -14,6 +14,7 @@ android {
dependencies {
implementation(projects.features.welcome.api)
implementation(projects.features.wallet.api)
+ implementation(projects.features.hotWallet.api)
/** Core */
implementation(projects.core.configToggles)
diff --git a/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt b/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt
index b5b89566f2..4179ffefe8 100644
--- a/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt
+++ b/features/welcome/impl/src/main/kotlin/com/tangem/features/welcome/impl/model/WelcomeModel.kt
@@ -12,14 +12,22 @@ import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.message.SnackbarMessage
+import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.common.wallets.UserWalletsListRepository
+import com.tangem.domain.common.wallets.error.SaveWalletError
import com.tangem.domain.common.wallets.error.UnlockWalletError
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isLocked
import com.tangem.domain.settings.CanUseBiometryUseCase
+import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
import com.tangem.domain.wallets.repository.WalletsRepository
import com.tangem.domain.wallets.usecase.NonBiometricUnlockWalletUseCase
+import com.tangem.domain.wallets.usecase.SaveWalletUseCase
+import com.tangem.features.hotwallet.HotWalletFeatureToggles
import com.tangem.features.wallet.utils.UserWalletsFetcher
import com.tangem.features.welcome.impl.ui.state.WelcomeUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@@ -40,10 +48,15 @@ internal class WelcomeModel @Inject constructor(
private val userWalletsListRepository: UserWalletsListRepository,
private val nonBiometricUnlockWalletUseCase: NonBiometricUnlockWalletUseCase,
private val canUseBiometryUseCase: CanUseBiometryUseCase,
+ private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
+ private val saveWalletUseCase: SaveWalletUseCase,
private val walletsRepository: WalletsRepository,
private val trackingContextProxy: TrackingContextProxy,
private val analyticsEventHandler: AnalyticsEventHandler,
userWalletsFetcherFactory: UserWalletsFetcher.Factory,
+ private val hotWalletFeatureToggles: HotWalletFeatureToggles,
+ private val scanCardProcessor: ScanCardProcessor,
+ private val messageSender: UiMessageSender,
) : Model() {
val uiState: StateFlow
@@ -168,7 +181,50 @@ internal class WelcomeModel @Inject constructor(
private fun addWalletClick() {
analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.SignIn))
- router.push(AppRoute.CreateWalletSelection)
+ if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) {
+ scanCard()
+ } else {
+ router.push(AppRoute.CreateWalletSelection)
+ }
+ }
+
+ private fun scanCard() {
+ modelScope.launch {
+ scanCardProcessor.scan(
+ analyticsSource = AnalyticsParam.ScreensSources.SignIn,
+ onWalletNotCreated = {},
+ disclaimerWillShow = { router.pop() },
+ onSuccess = { scanResponse ->
+ val userWallet =
+ coldUserWalletBuilderFactory.create(scanResponse = scanResponse).build() ?: return@scan
+ saveWalletUseCase.invoke(userWallet)
+ .onLeft { error ->
+ if (error is SaveWalletError.WalletAlreadySaved) {
+ userWalletsListRepository.unlock(
+ userWallet.walletId,
+ unlockMethod = UserWalletsListRepository.UnlockMethod.Scan(scanResponse),
+ ).onRight {
+ userWalletsListRepository.select(userWallet.walletId)
+ router.replaceAll(AppRoute.Wallet)
+ }
+ }
+ }
+ .onRight {
+ router.replaceAll(AppRoute.Wallet)
+ }
+ },
+ onCancel = {},
+ onFailure = { tangemError ->
+ if (!tangemError.silent) {
+ val message = tangemError.messageResId
+ ?.let(::resourceReference)
+ ?: stringReference(tangemError.customMessage)
+
+ messageSender.send(SnackbarMessage(message))
+ }
+ },
+ )
+ }
}
private suspend fun onlyOneHotWalletWithAccessCode(): Boolean {
diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml
index 9f09031069..370da97987 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.32-1335"
+tangemBlockchainSdk = "releases-5.32-1382"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "releases-5.32-574"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^