Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-27 20:54:33 +05:00
parent 222b5d75d1
commit 81b030fd0d
7 changed files with 105 additions and 83 deletions

View file

@ -1,7 +1,6 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.serialization)
id("configuration")
}

View file

@ -7,7 +7,6 @@ import com.tangem.core.ui.extensions.TextReference
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.serialization.Serializable
@Immutable
data class MessageBottomSheetUMV2(
@ -25,7 +24,6 @@ data class MessageBottomSheetUMV2(
val closeScope = CloseScope()
@Immutable
@Serializable
sealed interface Element
@Immutable

View file

@ -5,12 +5,10 @@ import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetV2
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import kotlinx.collections.immutable.ImmutableList
internal class AlertsComponentV2(
appComponentContext: AppComponentContext,
private val elements: ImmutableList<MessageBottomSheetUMV2.Element>,
private val onDismissRequest: () -> Unit = {},
private val messageUM: MessageBottomSheetUMV2,
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
override fun dismiss() {
@ -19,9 +17,6 @@ internal class AlertsComponentV2(
@Composable
override fun BottomSheet() {
MessageBottomSheetV2(
state = MessageBottomSheetUMV2(elements = elements, onDismissRequest = onDismissRequest),
onDismissRequest = ::dismiss,
)
MessageBottomSheetV2(state = messageUM, onDismissRequest = ::dismiss)
}
}

View file

@ -12,12 +12,15 @@ import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.walletconnect.model.WcPairRequest
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.walletconnect.connections.model.WcPairModel
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes.Alert
import com.tangem.features.walletconnect.connections.utils.WcAlertsFactory
internal class WcPairComponent(
private val appComponentContext: AppComponentContext,
@ -75,9 +78,9 @@ internal class WcPairComponent(
onDismiss = ::dismiss,
model = model,
)
is WcAppInfoRoutes.Alert -> AlertsComponentV2(
is Alert -> AlertsComponentV2(
appComponentContext = appComponentContext,
elements = config.elements,
messageUM = createBottomSheetMessageUM(config.type),
)
is WcAppInfoRoutes.SelectNetworks -> WcSelectNetworksComponent(
appComponentContext = appComponentContext,
@ -102,5 +105,13 @@ internal class WcPairComponent(
}
}
private fun createBottomSheetMessageUM(alertType: Alert.Type): MessageBottomSheetUMV2 {
return when (alertType) {
is Alert.Type.Verified -> WcAlertsFactory.createVerifiedDomainAlert(alertType.appName)
Alert.Type.UnknownDomain -> WcAlertsFactory.createUnknownDomainAlert(model::connectFromAlert)
Alert.Type.UnsafeDomain -> WcAlertsFactory.createUnsafeDomainAlert(model::connectFromAlert)
}
}
data class Params(val userWalletId: UserWalletId, val wcUrl: String, val source: WcPairRequest.Source)
}

View file

@ -9,10 +9,6 @@ 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.ui.R
import com.tangem.core.ui.components.bottomsheets.message.*
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.domain.models.network.Network
import com.tangem.domain.walletconnect.model.WcPairRequest
import com.tangem.domain.walletconnect.model.WcSessionApprove
@ -133,6 +129,11 @@ internal class WcPairModel @Inject constructor(
wcPairUseCase.reject()
}
fun connectFromAlert() {
stackNavigation.pop()
connect()
}
private fun onConnect(securityStatus: CheckDAppResult) {
when (securityStatus) {
CheckDAppResult.SAFE -> connect()
@ -152,77 +153,16 @@ internal class WcPairModel @Inject constructor(
)
}
private fun connectFromAlert() {
stackNavigation.pop()
connect()
}
private fun showUnknownDomainAlert() {
val message = messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_knight_shield_32) {
type = MessageBottomSheetUMV2.Icon.Type.Attention
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint
}
title = resourceReference(R.string.security_alert_title)
body = resourceReference(R.string.wc_alert_domain_issues_description)
chip(resourceReference(R.string.wc_alert_audit_unknown_domain)) {
type = MessageBottomSheetUMV2.Chip.Type.Unspecified
}
}
primaryButton {
text = resourceReference(R.string.common_cancel)
onClick { closeBs() }
}
secondaryButton {
text = resourceReference(R.string.wc_alert_connect_anyway)
onClick { connectFromAlert() }
}
}
stackNavigation.pushNew(WcAppInfoRoutes.Alert(elements = message.elements))
stackNavigation.pushNew(WcAppInfoRoutes.Alert(WcAppInfoRoutes.Alert.Type.UnknownDomain))
}
private fun showSecurityRiskAlert() {
val message = messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_knight_shield_32) {
type = MessageBottomSheetUMV2.Icon.Type.Warning
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint
}
title = resourceReference(R.string.security_alert_title)
body = resourceReference(R.string.wc_alert_domain_issues_description)
chip(resourceReference(R.string.wc_alert_audit_unknown_domain)) {
type = MessageBottomSheetUMV2.Chip.Type.Warning
}
}
primaryButton {
text = resourceReference(R.string.common_cancel)
onClick { closeBs() }
}
secondaryButton {
text = resourceReference(R.string.wc_alert_connect_anyway)
onClick { connectFromAlert() }
}
}
stackNavigation.pushNew(WcAppInfoRoutes.Alert(elements = message.elements))
stackNavigation.pushNew(WcAppInfoRoutes.Alert(WcAppInfoRoutes.Alert.Type.UnsafeDomain))
}
private fun showVerifiedAlert(appName: String) {
val message = messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_approvale2_20) {
type = MessageBottomSheetUMV2.Icon.Type.Accent
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.Unspecified
}
title = resourceReference(R.string.wc_alert_verified_domain_title)
body = resourceReference(R.string.wc_alert_verified_domain_description, wrappedList(appName))
}
secondaryButton {
text = resourceReference(R.string.common_done)
onClick { closeBs() }
}
}
stackNavigation.pushNew(WcAppInfoRoutes.Alert(elements = message.elements))
stackNavigation.pushNew(WcAppInfoRoutes.Alert(WcAppInfoRoutes.Alert.Type.Verified(appName)))
}
override fun onWalletSelected(userWalletId: UserWalletId) {

View file

@ -3,10 +3,8 @@ package com.tangem.features.walletconnect.connections.routes
import androidx.compose.runtime.Immutable
import com.tangem.core.decompose.navigation.Route
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
import com.tangem.domain.models.network.Network
import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.serialization.Serializable
@Serializable
@ -28,5 +26,12 @@ internal sealed class WcAppInfoRoutes : TangemBottomSheetConfigContent, Route {
) : WcAppInfoRoutes()
@Serializable
data class Alert(val elements: ImmutableList<MessageBottomSheetUMV2.Element>) : WcAppInfoRoutes()
data class Alert(val type: Type) : WcAppInfoRoutes() {
@Serializable
sealed class Type {
data class Verified(val appName: String) : Type()
data object UnknownDomain : Type()
data object UnsafeDomain : Type()
}
}
}

View file

@ -0,0 +1,74 @@
package com.tangem.features.walletconnect.connections.utils
import com.tangem.core.ui.R
import com.tangem.core.ui.components.bottomsheets.message.*
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
internal object WcAlertsFactory {
fun createUnknownDomainAlert(onClick: () -> Unit): MessageBottomSheetUMV2 {
return messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_knight_shield_32) {
type = MessageBottomSheetUMV2.Icon.Type.Attention
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint
}
title = resourceReference(R.string.security_alert_title)
body = resourceReference(R.string.wc_alert_domain_issues_description)
chip(resourceReference(R.string.wc_alert_audit_unknown_domain)) {
type = MessageBottomSheetUMV2.Chip.Type.Unspecified
}
}
primaryButton {
text = resourceReference(R.string.common_cancel)
onClick { closeBs() }
}
secondaryButton {
text = resourceReference(R.string.wc_alert_connect_anyway)
onClick { onClick() }
}
}
}
fun createUnsafeDomainAlert(onClick: () -> Unit): MessageBottomSheetUMV2 {
return messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_knight_shield_32) {
type = MessageBottomSheetUMV2.Icon.Type.Warning
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint
}
title = resourceReference(R.string.security_alert_title)
body = resourceReference(R.string.wc_alert_domain_issues_description)
chip(resourceReference(R.string.wc_alert_audit_unknown_domain)) {
type = MessageBottomSheetUMV2.Chip.Type.Warning
}
}
primaryButton {
text = resourceReference(R.string.common_cancel)
onClick { closeBs() }
}
secondaryButton {
text = resourceReference(R.string.wc_alert_connect_anyway)
onClick { onClick() }
}
}
}
fun createVerifiedDomainAlert(appName: String): MessageBottomSheetUMV2 {
return messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_approvale2_20) {
type = MessageBottomSheetUMV2.Icon.Type.Accent
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.Unspecified
}
title = resourceReference(R.string.wc_alert_verified_domain_title)
body = resourceReference(R.string.wc_alert_verified_domain_description, wrappedList(appName))
}
secondaryButton {
text = resourceReference(R.string.common_done)
onClick { closeBs() }
}
}
}
}