Updated on 2026-08-14
This commit is contained in:
parent
315d7c9d6c
commit
ab2f0f58bb
4 changed files with 85 additions and 12 deletions
|
|
@ -10,11 +10,16 @@ import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
|||
internal object WcAlertsFactory {
|
||||
|
||||
fun createCommonTransactionAppInfoAlertUM(alertType: WcTransactionRoutes.Alert.Type) = when (alertType) {
|
||||
is WcTransactionRoutes.Alert.Type.Verified -> createVerifiedDomainAlert(alertType.appName)
|
||||
is WcTransactionRoutes.Alert.Type.UnknownDomain -> createUnknownDomainAlert()
|
||||
is WcTransactionRoutes.Alert.Type.UnsafeDomain -> createUnsafeDomainAlert()
|
||||
is WcTransactionRoutes.Alert.Type.MaliciousDApp ->
|
||||
is WcTransactionRoutes.Alert.Type.Verified ->
|
||||
createVerifiedDomainAlert(alertType.appName)
|
||||
is WcTransactionRoutes.Alert.Type.UnknownDomain ->
|
||||
createUnknownDomainAlert()
|
||||
is WcTransactionRoutes.Alert.Type.UnsafeDomain ->
|
||||
createUnsafeDomainAlert()
|
||||
is WcTransactionRoutes.Alert.Type.MaliciousInfo ->
|
||||
createMaliciousDAppAlert(alertType.description, alertType.onClick)
|
||||
is WcTransactionRoutes.Alert.Type.UnknownError ->
|
||||
createUnknownErrorAlert(alertType.errorMessage, alertType.onDismiss)
|
||||
}
|
||||
|
||||
fun createUnknownDomainAlert(activeButtonOnClick: (() -> Unit)? = null): MessageBottomSheetUMV2 {
|
||||
|
|
@ -69,8 +74,32 @@ internal object WcAlertsFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createUnknownErrorAlert(errorMessage: String?, onDismiss: () -> Unit): MessageBottomSheetUMV2 {
|
||||
return messageBottomSheetUM {
|
||||
infoBlock {
|
||||
icon(R.drawable.img_attention_20) {
|
||||
type = MessageBottomSheetUMV2.Icon.Type.Warning
|
||||
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint
|
||||
}
|
||||
title = resourceReference(R.string.wc_alert_unknown_error_title)
|
||||
body = if (errorMessage.isNullOrEmpty()) {
|
||||
resourceReference(R.string.wc_alert_unknown_error_description_no_error_code)
|
||||
} else {
|
||||
resourceReference(
|
||||
R.string.wc_alert_unknown_error_description,
|
||||
wrappedList(errorMessage),
|
||||
)
|
||||
}
|
||||
}
|
||||
secondaryButton {
|
||||
text = resourceReference(R.string.balance_hidden_got_it_button)
|
||||
onClick { onDismiss() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMaliciousDAppAlert(
|
||||
description: String,
|
||||
description: String?,
|
||||
activeButtonOnClick: (() -> Unit),
|
||||
): MessageBottomSheetUMV2 {
|
||||
return messageBottomSheetUM {
|
||||
|
|
@ -80,7 +109,9 @@ internal object WcAlertsFactory {
|
|||
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.SameAsTint
|
||||
}
|
||||
title = resourceReference(R.string.security_alert_title)
|
||||
body = TextReference.Str(description)
|
||||
if (!description.isNullOrEmpty()) {
|
||||
body = TextReference.Str(description)
|
||||
}
|
||||
}
|
||||
primaryButton {
|
||||
text = resourceReference(R.string.common_cancel)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package com.tangem.features.walletconnect.transaction.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.Either
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.arkivanov.decompose.router.stack.pushNew
|
||||
import com.domain.blockaid.models.transaction.ValidationResult
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
|
|
@ -48,6 +51,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
val stackNavigation = StackNavigation<WcTransactionRoutes>()
|
||||
|
||||
private var wcApproval: WcApproval? = null
|
||||
private var sign: () -> Unit = {}
|
||||
|
||||
init {
|
||||
@Suppress("UnusedPrivateMember")
|
||||
|
|
@ -66,7 +70,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
.distinctUntilChanged()
|
||||
.collectLatest {
|
||||
val (signState, securityCheck) = it
|
||||
if (signingIsDone(signState)) return@collectLatest
|
||||
if (signingIsDone(signState, useCase)) return@collectLatest
|
||||
val signModel: Any = signState.signModel
|
||||
val isMutableFee = useCase is WcMutableFee
|
||||
val dAppFee = if (isMutableFee) useCase.dAppFee() else null
|
||||
|
|
@ -81,6 +85,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
var isApprovalMethod = isSecurityCheckContent &&
|
||||
securityCheck.content is BlockAidTransactionCheck.Result.Approval
|
||||
wcApproval = useCase as? WcApproval
|
||||
sign = { useCase.sign() }
|
||||
buildUiState(securityCheck, useCase, signState)
|
||||
}
|
||||
else -> unknownMethodRunnable()
|
||||
|
|
@ -107,7 +112,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
actions = WcTransactionActionsUM(
|
||||
onShowVerifiedAlert = ::showVerifiedAlert,
|
||||
onDismiss = { cancel(useCase) },
|
||||
onSign = useCase::sign,
|
||||
onSign = { onSign(securityCheck.getOrNull()) },
|
||||
onCopy = { copyData(useCase.rawSdkRequest.request.params) },
|
||||
),
|
||||
),
|
||||
|
|
@ -127,6 +132,14 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
stackNavigation.pushNew(WcTransactionRoutes.TransactionRequestInfo)
|
||||
}
|
||||
|
||||
private fun onSign(securityCheck: BlockAidTransactionCheck.Result?) {
|
||||
if (securityCheck?.result?.validation == ValidationResult.UNSAFE) {
|
||||
showMaliciousAlert(securityCheck.result.description)
|
||||
} else {
|
||||
sign()
|
||||
}
|
||||
}
|
||||
|
||||
fun onClickDoneCustomAllowance(value: BigDecimal, isUnlimited: Boolean) {
|
||||
val maxValue = if (isUnlimited) Double.MAX_VALUE.toBigDecimal() else value
|
||||
wcApproval?.getAmount()?.let { currentAmount ->
|
||||
|
|
@ -142,14 +155,36 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
stackNavigation.pushNew(WcTransactionRoutes.Alert(WcTransactionRoutes.Alert.Type.Verified(appName)))
|
||||
}
|
||||
|
||||
private fun signingIsDone(signState: WcSignState<*>): Boolean {
|
||||
private fun showMaliciousAlert(description: String?) {
|
||||
val type = WcTransactionRoutes.Alert.Type.MaliciousInfo(description = description, onClick = ::signFromAlert)
|
||||
stackNavigation.pushNew(WcTransactionRoutes.Alert(type))
|
||||
}
|
||||
|
||||
private fun signFromAlert() {
|
||||
stackNavigation.pop()
|
||||
sign()
|
||||
}
|
||||
|
||||
private fun signingIsDone(signState: WcSignState<*>, useCase: WcSignUseCase<*>): Boolean {
|
||||
(signState.domainStep as? WcSignStep.Result)?.result?.let {
|
||||
router.pop()
|
||||
handleSigningError(it, useCase)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun handleSigningError(result: Either<Throwable, Unit>, useCase: WcSignUseCase<*>) {
|
||||
if (result.isLeft()) {
|
||||
val error = WcTransactionRoutes.Alert.Type.UnknownError(
|
||||
errorMessage = result.leftOrNull()?.message,
|
||||
onDismiss = { cancel(useCase) },
|
||||
)
|
||||
stackNavigation.pushNew(WcTransactionRoutes.Alert(error))
|
||||
} else {
|
||||
router.pop()
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancel(useCase: WcSignUseCase<*>) {
|
||||
useCase.cancel()
|
||||
router.pop()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ internal sealed class WcTransactionRoutes : TangemBottomSheetConfigContent, Rout
|
|||
data class Verified(val appName: String) : Type()
|
||||
data object UnknownDomain : Type()
|
||||
data object UnsafeDomain : Type()
|
||||
data class MaliciousDApp(val description: String, val onClick: () -> Unit) : Type()
|
||||
data class MaliciousInfo(val description: String?, val onClick: () -> Unit) : Type()
|
||||
data class UnknownError(val errorMessage: String?, val onDismiss: () -> Unit) : Type()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import android.content.res.Configuration
|
|||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
|
|
@ -68,9 +69,14 @@ internal fun WcEstimatedWalletChangesItem(item: WcEstimatedWalletChangesUM, modi
|
|||
}
|
||||
|
||||
if (item.items.size > MAX_CHANGES_SIZE) {
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clickable { isExpanded = !isExpanded }
|
||||
.clickable(
|
||||
interactionSource = interactionSource,
|
||||
indication = null,
|
||||
onClick = { isExpanded = !isExpanded },
|
||||
)
|
||||
.padding(bottom = 12.dp, start = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue