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 615b1c3778..9a80508e7b 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
@@ -17,6 +17,7 @@ import com.tangem.features.disclaimer.api.components.DisclaimerComponent
import com.tangem.features.home.api.HomeComponent
import com.tangem.features.hotwallet.AddExistingWalletComponent
import com.tangem.features.hotwallet.CreateMobileWalletComponent
+import com.tangem.features.hotwallet.UpgradeWalletComponent
import com.tangem.features.hotwallet.WalletActivationComponent
import com.tangem.features.hotwallet.CreateWalletBackupComponent
import com.tangem.features.hotwallet.UpdateAccessCodeComponent
@@ -103,6 +104,7 @@ internal class ChildFactory @Inject constructor(
private val chooseManagedTokensComponentFactory: ChooseManagedTokensComponent.Factory,
private val createWalletSelectionComponentFactory: CreateWalletSelectionComponent.Factory,
private val createMobileWalletComponentFactory: CreateMobileWalletComponent.Factory,
+ private val upgradeWalletComponentFactory: UpgradeWalletComponent.Factory,
private val addExistingWalletComponentFactory: AddExistingWalletComponent.Factory,
private val walletActivationComponentFactory: WalletActivationComponent.Factory,
private val createWalletBackupComponentFactory: CreateWalletBackupComponent.Factory,
@@ -486,6 +488,15 @@ internal class ChildFactory @Inject constructor(
componentFactory = createMobileWalletComponentFactory,
)
}
+ is AppRoute.UpgradeWallet -> {
+ createComponentChild(
+ context = context,
+ params = UpgradeWalletComponent.Params(
+ userWalletId = route.userWalletId,
+ ),
+ componentFactory = upgradeWalletComponentFactory,
+ )
+ }
is AppRoute.AddExistingWallet -> {
createComponentChild(
context = context,
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 d0ffcca403..cfa1070c25 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
@@ -311,6 +311,11 @@ sealed class AppRoute(val path: String) : Route {
@Serializable
object CreateMobileWallet : AppRoute(path = "/create_mobile_wallet")
+ @Serializable
+ data class UpgradeWallet(
+ val userWalletId: UserWalletId,
+ ) : AppRoute(path = "/upgrade_wallet/${userWalletId.stringValue}")
+
@Serializable
object AddExistingWallet : AppRoute(path = "/add_existing_wallet")
diff --git a/core/ui/src/main/res/drawable/ic_knight_shield_24.xml b/core/ui/src/main/res/drawable/ic_knight_shield_24.xml
new file mode 100644
index 0000000000..1a058ff367
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_knight_shield_24.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_mobile_security_24.xml b/core/ui/src/main/res/drawable/ic_mobile_security_24.xml
new file mode 100644
index 0000000000..bbc69392d5
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_mobile_security_24.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_protect_24.xml b/core/ui/src/main/res/drawable/ic_protect_24.xml
new file mode 100644
index 0000000000..5ad478076f
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_protect_24.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/core/ui/src/main/res/drawable/ic_tangem_64.xml b/core/ui/src/main/res/drawable/ic_tangem_64.xml
new file mode 100644
index 0000000000..6c39da496c
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_tangem_64.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpgradeWalletComponent.kt b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpgradeWalletComponent.kt
new file mode 100644
index 0000000000..8a9b7f6c14
--- /dev/null
+++ b/features/hot-wallet/api/src/main/kotlin/com/tangem/features/hotwallet/UpgradeWalletComponent.kt
@@ -0,0 +1,14 @@
+package com.tangem.features.hotwallet
+
+import com.tangem.core.decompose.factory.ComponentFactory
+import com.tangem.core.ui.decompose.ComposableContentComponent
+import com.tangem.domain.models.wallet.UserWalletId
+
+interface UpgradeWalletComponent : ComposableContentComponent {
+
+ data class Params(
+ val userWalletId: UserWalletId,
+ )
+
+ interface Factory : ComponentFactory
+}
\ No newline at end of file
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt
new file mode 100644
index 0000000000..2f0e91d1de
--- /dev/null
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/DefaultUpgradeWalletComponent.kt
@@ -0,0 +1,39 @@
+package com.tangem.features.hotwallet.upgradewallet
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.tangem.core.decompose.context.AppComponentContext
+import com.tangem.core.decompose.model.getOrCreateModel
+import com.tangem.features.hotwallet.UpgradeWalletComponent
+import com.tangem.features.hotwallet.upgradewallet.ui.UpgradeWalletContent
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+@Suppress("UnusedPrivateMember")
+internal class DefaultUpgradeWalletComponent @AssistedInject constructor(
+ @Assisted private val context: AppComponentContext,
+ @Assisted private val params: UpgradeWalletComponent.Params,
+) : UpgradeWalletComponent, AppComponentContext by context {
+
+ private val model: UpgradeWalletModel = getOrCreateModel(params)
+
+ @Composable
+ override fun Content(modifier: Modifier) {
+ val state by model.uiState.collectAsStateWithLifecycle()
+ UpgradeWalletContent(
+ state = state,
+ modifier = modifier,
+ )
+ }
+
+ @AssistedFactory
+ interface Factory : UpgradeWalletComponent.Factory {
+ override fun create(
+ context: AppComponentContext,
+ params: UpgradeWalletComponent.Params,
+ ): DefaultUpgradeWalletComponent
+ }
+}
\ No newline at end of file
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt
new file mode 100644
index 0000000000..bc03e54e43
--- /dev/null
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/UpgradeWalletModel.kt
@@ -0,0 +1,41 @@
+package com.tangem.features.hotwallet.upgradewallet
+
+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.navigation.url.UrlOpener
+import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase
+import com.tangem.features.hotwallet.upgradewallet.entity.UpgradeWalletUM
+import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@ModelScoped
+internal class UpgradeWalletModel @Inject constructor(
+ override val dispatchers: CoroutineDispatcherProvider,
+ private val router: Router,
+ private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase,
+ private val urlOpener: UrlOpener,
+) : Model() {
+
+ internal val uiState: StateFlow
+ field = MutableStateFlow(
+ UpgradeWalletUM(
+ onBackClick = { router.pop() },
+ onBuyTangemWalletClick = ::onBuyTangemWalletClick,
+ onScanDeviceClick = ::onScanDeviceClick,
+ ),
+ )
+
+ private fun onBuyTangemWalletClick() {
+ modelScope.launch {
+ generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
+ }
+ }
+
+ private fun onScanDeviceClick() {
+ // TODO [REDACTED_TASK_KEY]
+ }
+}
\ No newline at end of file
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/di/UpgradeWalletModule.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/di/UpgradeWalletModule.kt
new file mode 100644
index 0000000000..3beb13bcab
--- /dev/null
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/di/UpgradeWalletModule.kt
@@ -0,0 +1,25 @@
+package com.tangem.features.hotwallet.upgradewallet.di
+
+import com.tangem.core.decompose.model.Model
+import com.tangem.features.hotwallet.UpgradeWalletComponent
+import com.tangem.features.hotwallet.upgradewallet.DefaultUpgradeWalletComponent
+import com.tangem.features.hotwallet.upgradewallet.UpgradeWalletModel
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+@InstallIn(SingletonComponent::class)
+internal interface UpgradeWalletModule {
+
+ @Binds
+ fun bindUpgradeWalletComponentFactory(impl: DefaultUpgradeWalletComponent.Factory): UpgradeWalletComponent.Factory
+
+ @Binds
+ @IntoMap
+ @ClassKey(UpgradeWalletModel::class)
+ fun bindUpgradeWalletModel(model: UpgradeWalletModel): Model
+}
\ No newline at end of file
diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/entity/UpgradeWalletUM.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/entity/UpgradeWalletUM.kt
new file mode 100644
index 0000000000..8f700a27b9
--- /dev/null
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/entity/UpgradeWalletUM.kt
@@ -0,0 +1,7 @@
+package com.tangem.features.hotwallet.upgradewallet.entity
+
+internal data class UpgradeWalletUM(
+ val onBackClick: () -> Unit,
+ val onBuyTangemWalletClick: () -> Unit,
+ val onScanDeviceClick: () -> Unit,
+)
\ No newline at end of file
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
new file mode 100644
index 0000000000..2ae6ae5d0c
--- /dev/null
+++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/upgradewallet/ui/UpgradeWalletContent.kt
@@ -0,0 +1,161 @@
+package com.tangem.features.hotwallet.upgradewallet.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.*
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.tangem.core.ui.R
+import com.tangem.core.ui.components.PrimaryButtonIconEnd
+import com.tangem.core.ui.components.SecondaryButton
+import com.tangem.core.ui.components.appbar.TangemTopAppBar
+import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.stringResourceSafe
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.hotwallet.upgradewallet.entity.UpgradeWalletUM
+
+@Suppress("LongMethod")
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun UpgradeWalletContent(state: UpgradeWalletUM, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier
+ .background(TangemTheme.colors.background.primary)
+ .fillMaxSize()
+ .systemBarsPadding(),
+ ) {
+ TangemTopAppBar(
+ modifier = Modifier
+ .statusBarsPadding(),
+ startButton = TopAppBarButtonUM.Back(state.onBackClick),
+ title = TextReference.EMPTY,
+ )
+ Column(
+ modifier = Modifier
+ .weight(1f)
+ .padding(
+ start = 16.dp,
+ top = 24.dp,
+ end = 16.dp,
+ ),
+ ) {
+ Icon(
+ modifier = Modifier
+ .fillMaxWidth(),
+ painter = painterResource(R.drawable.ic_tangem_64),
+ contentDescription = null,
+ tint = Color.Unspecified,
+ )
+ Text(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ start = 16.dp,
+ top = 20.dp,
+ end = 16.dp,
+ ),
+ text = stringResourceSafe(R.string.hw_upgrade_title),
+ style = TangemTheme.typography.h2,
+ color = TangemTheme.colors.text.primary1,
+ textAlign = TextAlign.Center,
+ )
+ 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,
+ )
+ 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,
+ )
+ 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),
+ iconRes = R.drawable.ic_protect_24,
+ )
+ }
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ ) {
+ SecondaryButton(
+ modifier = Modifier
+ .fillMaxWidth(),
+ text = stringResourceSafe(R.string.details_buy_wallet),
+ onClick = state.onBuyTangemWalletClick,
+ )
+ PrimaryButtonIconEnd(
+ modifier = Modifier
+ .fillMaxWidth(),
+ text = stringResourceSafe(R.string.hw_upgrade_scan_device),
+ onClick = state.onScanDeviceClick,
+ iconResId = R.drawable.ic_tangem_24,
+ )
+ }
+ }
+}
+
+@Composable
+private fun FeatureBlock(title: String, description: String, iconRes: Int, modifier: Modifier = Modifier) {
+ Row(
+ modifier = modifier,
+ ) {
+ Icon(
+ modifier = Modifier
+ .padding(horizontal = 12.dp),
+ painter = painterResource(iconRes),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.primary1,
+ )
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 8.dp),
+ ) {
+ Text(
+ text = title,
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.primary1,
+ )
+ Text(
+ modifier = Modifier
+ .padding(top = 4.dp),
+ text = description,
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.secondary,
+ )
+ }
+ }
+}
+
+@Preview(showBackground = true, widthDp = 360)
+@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun PreviewUpgradeWalletContent() {
+ TangemThemePreview {
+ UpgradeWalletContent(
+ state = UpgradeWalletUM(
+ onBackClick = {},
+ onBuyTangemWalletClick = {},
+ onScanDeviceClick = {},
+ ),
+ )
+ }
+}
\ No newline at end of file