diff --git a/features/walletconnect/impl/build.gradle.kts b/features/walletconnect/impl/build.gradle.kts index 0bf16b6415..1d3a97b3a6 100644 --- a/features/walletconnect/impl/build.gradle.kts +++ b/features/walletconnect/impl/build.gradle.kts @@ -16,13 +16,16 @@ dependencies { implementation(projects.features.walletconnect.api) implementation(projects.features.sendV2.api) - /** Core */ - implementation(projects.core.configToggles) - implementation(projects.core.decompose) - implementation(projects.core.ui) + /** Common */ implementation(projects.common.routing) implementation(projects.common.ui) + + /** Core */ implementation(projects.core.analytics) + implementation(projects.core.configToggles) + implementation(projects.core.decompose) + implementation(projects.core.navigation) + implementation(projects.core.ui) /** Domain models */ implementation(projects.domain.appCurrency.models) diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/approve/WcSpendAllowanceUM.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/approve/WcSpendAllowanceUM.kt index 0bdad0e725..57aef929c4 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/approve/WcSpendAllowanceUM.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/approve/WcSpendAllowanceUM.kt @@ -11,4 +11,5 @@ internal data class WcSpendAllowanceUM( val tokenSymbol: String, val tokenImageUrl: String?, val networkIconRes: Int?, + val onLearnMoreClicked: () -> Unit, ) : TangemBottomSheetConfigContent \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt index 8d36bbe2c6..8b201362c2 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSendTransactionModel.kt @@ -16,6 +16,7 @@ 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.decompose.ui.UiMessageSender +import com.tangem.core.navigation.url.UrlOpener import com.tangem.core.ui.clipboard.ClipboardManager import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2 import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2.Icon.Type @@ -55,6 +56,7 @@ import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransacti import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes import com.tangem.features.walletconnect.transaction.ui.blockaid.WcSendAndReceiveBlockAidUiConverter import com.tangem.features.walletconnect.utils.WcNotificationsFactory +import com.tangem.utils.SupportedLanguages import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch @@ -74,11 +76,11 @@ internal class WcSendTransactionModel @Inject constructor( private val clipboardManager: ClipboardManager, private val useCaseFactory: WcRequestUseCaseFactory, private val converter: WcSendTransactionUMConverter, - private val blockAidUiConverter: WcSendAndReceiveBlockAidUiConverter, private val getFeeUseCase: GetFeeUseCase, private val getNetworkCoinUseCase: GetNetworkCoinStatusUseCase, private val notificationsFactory: WcNotificationsFactory, private val analytics: AnalyticsEventHandler, + private val urlOpener: UrlOpener, ) : Model(), WcCommonTransactionModel, FeeSelectorModelCallback { private val params = paramsContainer.require() @@ -94,6 +96,7 @@ internal class WcSendTransactionModel @Inject constructor( private var signState: WcSignState<*> by Delegates.notNull() private var wcApproval: WcApproval? = null private var sign: () -> Unit = {} + private val blockAidUiConverter = WcSendAndReceiveBlockAidUiConverter() private val feeReloadState = MutableStateFlow(false) private val signatureReceivedAnalyticsSendState = MutableStateFlow(false) private val securityStatusState = @@ -243,8 +246,9 @@ internal class WcSendTransactionModel @Inject constructor( val blockAidState = when (securityCheck) { is Lce.Content -> blockAidUiConverter.convert( WcSendAndReceiveBlockAidUiConverter.Input( - securityCheck.content.result, - if (isApproval) wcApproval?.getAmount() else null, + result = securityCheck.content.result, + approvedAmount = if (isApproval) wcApproval?.getAmount() else null, + onApproveLearnMoreClick = ::onApproveLearnMoreClick, ), ) is Lce.Error -> WcSendReceiveTransactionCheckResultsUM(isLoading = false) @@ -291,6 +295,15 @@ internal class WcSendTransactionModel @Inject constructor( stackNavigation.pop() } + private fun onApproveLearnMoreClick() { + val code = SupportedLanguages.getCurrentSupportedLanguageCode() + .takeIf { it == SupportedLanguages.RUSSIAN } + ?: SupportedLanguages.ENGLISH + + val url = "https://tangem.com/$code/blog/post/give-revoke-permission/" + urlOpener.openUrl(url) + } + private fun isMultipleSignRequired(useCase: WcSignUseCase<*>): Boolean { return if (useCase is SignRequirements) { useCase.isMultipleSignRequired() diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/approve/WcCustomAllowanceContent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/approve/WcCustomAllowanceContent.kt index 60c4fc70c2..a4e431c1a1 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/approve/WcCustomAllowanceContent.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/approve/WcCustomAllowanceContent.kt @@ -255,6 +255,7 @@ private class WcCustomAllowanceStateProvider : CollectionPreviewParameterProvide amountValue = BigDecimal("100"), tokenSymbol = "ETH", isUnlimited = false, + onLearnMoreClicked = {}, ), ), ) \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/TransactionCheckResultsItem.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/TransactionCheckResultsItem.kt index 2b7aca4340..92dbcdd661 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/TransactionCheckResultsItem.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/TransactionCheckResultsItem.kt @@ -3,25 +3,29 @@ package com.tangem.features.walletconnect.transaction.ui.blockaid import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.text.LinkAnnotation +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.withLink import androidx.compose.ui.tooling.preview.Devices import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp -import com.tangem.core.ui.extensions.TextReference -import com.tangem.core.ui.extensions.isNullOrEmpty -import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.* import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.walletconnect.impl.R +import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM import com.tangem.features.walletconnect.transaction.entity.blockaid.BlockAidNotificationUM import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangeUM import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangesUM import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM import com.tangem.features.walletconnect.transaction.ui.approve.WcSpendAllowanceItem import kotlinx.collections.immutable.persistentListOf +import java.math.BigDecimal @Composable internal fun TransactionCheckResultsItem( @@ -29,11 +33,7 @@ internal fun TransactionCheckResultsItem( onClickAllowToSpend: () -> Unit, modifier: Modifier = Modifier, ) { - Column( - modifier = modifier - .fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { + Column(modifier = modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(12.dp)) { if (item.isLoading) { WcEstimatedWalletChangesLoadingItem() } else { @@ -44,6 +44,10 @@ internal fun TransactionCheckResultsItem( WcEstimatedWalletChangesItem(item.estimatedWalletChanges) } else if (item.spendAllowance != null) { WcSpendAllowanceItem(item.spendAllowance, onClickAllowToSpend) + ApproveDescription( + modifier = Modifier.padding(bottom = 6.dp, start = 12.dp, end = 12.dp), + onLearnMoreClick = item.spendAllowance.onLearnMoreClicked, + ) } else if (!item.additionalNotification.isNullOrEmpty()) { WcEstimatedWalletChangesNotificationItem(description = item.additionalNotification) } else { @@ -53,6 +57,29 @@ internal fun TransactionCheckResultsItem( } } +@Composable +private fun ApproveDescription(modifier: Modifier = Modifier, onLearnMoreClick: () -> Unit) { + val linkText = stringResourceSafe(R.string.common_learn_more) + val fullString = stringResourceSafe(R.string.wc_approve_description) + val defaultColor = TangemTheme.colors.text.tertiary + val linkColor = TangemTheme.colors.text.accent + Text( + modifier = modifier, + style = TangemTheme.typography.caption2, + text = buildAnnotatedString { + appendColored(fullString, defaultColor) + appendSpace() + withLink( + link = LinkAnnotation.Clickable( + tag = "WC_APPROVE_LEARN_MORE_TAG", + linkInteractionListener = { onLearnMoreClick() }, + ), + block = { appendColored(text = linkText, color = linkColor) }, + ) + }, + ) +} + @Composable @Preview(showBackground = true, device = Devices.PIXEL_7_PRO) @Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES) @@ -95,5 +122,22 @@ private class TransactionCheckResultsItemProvider : PreviewParameterProvider { override fun convert(value: Input): WcEstimatedWalletChangeUM { diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSendAndReceiveBlockAidUiConverter.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSendAndReceiveBlockAidUiConverter.kt index 3ef6afbf4c..e8777d39f3 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSendAndReceiveBlockAidUiConverter.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSendAndReceiveBlockAidUiConverter.kt @@ -20,15 +20,16 @@ import com.tangem.utils.converter.Converter import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import java.math.BigDecimal -import javax.inject.Inject private const val DECIMALS_AMOUNT = 2 @Suppress("CyclomaticComplexMethod", "LongMethod") -internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor( - private val estimatedWalletChangeUMConverter: WcEstimatedWalletChangeUMConverter, - private val spendAllowanceUMConverter: WcSpendAllowanceUMConverter, -) : Converter { +internal class WcSendAndReceiveBlockAidUiConverter : + Converter { + + private val estimatedWalletChangeUMConverter = WcEstimatedWalletChangeUMConverter() + private val spendAllowanceUMConverter = WcSpendAllowanceUMConverter() + override fun convert(value: Input): WcSendReceiveTransactionCheckResultsUM { val description = value.result.description?.let { if (it.isNotEmpty()) TextReference.Str(it) else null } val simulation = value.result.simulation @@ -118,7 +119,12 @@ internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor( when (data) { is SimulationData.SendAndReceive, SimulationData.NoWalletChangesDetected -> null is SimulationData.Approve -> value.approvedAmount?.let { - spendAllowanceUMConverter.convert(it) + spendAllowanceUMConverter.convert( + WcSpendAllowanceUMConverter.Input( + approvedAmount = it, + onLearnMoreClick = value.onApproveLearnMoreClick, + ), + ) } } }, @@ -128,6 +134,7 @@ internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor( data class Input( val result: CheckTransactionResult, val approvedAmount: WcApprovedAmount?, + val onApproveLearnMoreClick: () -> Unit, ) } diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSpendAllowanceUMConverter.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSpendAllowanceUMConverter.kt index 4f7bf34268..e79abdf12d 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSpendAllowanceUMConverter.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/blockaid/WcSpendAllowanceUMConverter.kt @@ -6,24 +6,26 @@ import com.tangem.domain.walletconnect.model.WcApprovedAmount import com.tangem.features.walletconnect.impl.R import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM import com.tangem.utils.converter.Converter -import javax.inject.Inject -internal class WcSpendAllowanceUMConverter @Inject constructor() : Converter { +internal class WcSpendAllowanceUMConverter : Converter { - override fun convert(value: WcApprovedAmount): WcSpendAllowanceUM { - val amount = value.amount?.value ?: 0.0.toBigDecimal() - val isUnlimited = value.amount?.value == null + override fun convert(value: Input): WcSpendAllowanceUM { + val amount = value.approvedAmount.amount?.value ?: 0.0.toBigDecimal() + val isUnlimited = value.approvedAmount.amount?.value == null return WcSpendAllowanceUM( amountValue = amount, - amountText = if (value.amount?.value == null) { + amountText = if (value.approvedAmount.amount?.value == null) { TextReference.Res(R.string.wc_common_unlimited) } else { TextReference.Str(amount.amountText()) }, isUnlimited = isUnlimited, - tokenSymbol = value.amount?.currencySymbol ?: "", - tokenImageUrl = value.logoUrl, - networkIconRes = value.chainId?.toString()?.let { getActiveIconRes(it) }, + tokenSymbol = value.approvedAmount.amount?.currencySymbol ?: "", + tokenImageUrl = value.approvedAmount.logoUrl, + networkIconRes = value.approvedAmount.chainId?.toString()?.let { getActiveIconRes(it) }, + onLearnMoreClicked = value.onLearnMoreClick, ) } + + data class Input(val approvedAmount: WcApprovedAmount, val onLearnMoreClick: () -> Unit) } \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/send/WcSendTransactionModalBottomSheet.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/send/WcSendTransactionModalBottomSheet.kt index a1d574e005..1f02216d53 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/send/WcSendTransactionModalBottomSheet.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/send/WcSendTransactionModalBottomSheet.kt @@ -37,6 +37,7 @@ import com.tangem.features.walletconnect.connections.entity.VerifiedDAppState import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem import com.tangem.features.walletconnect.impl.R import com.tangem.features.walletconnect.transaction.components.PreviewFeeSelectorBlockComponent +import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM import com.tangem.features.walletconnect.transaction.entity.blockaid.BlockAidNotificationUM import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangeUM import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangesUM @@ -51,6 +52,7 @@ import com.tangem.features.walletconnect.transaction.ui.common.WcSmallTitleItem import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestButtons import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestItem import kotlinx.collections.immutable.persistentListOf +import java.math.BigDecimal @Suppress("LongParameterList", "LongMethod") @Composable @@ -316,5 +318,34 @@ private class WcSendTransactionStateProvider : CollectionPreviewParameterProvide ), transactionValidationResult = ValidationResult.SAFE, ), + WcSendTransactionItemUM( + onDismiss = {}, + onSend = {}, + appInfo = WcTransactionAppInfoContentUM( + appName = "React App", + appIcon = "", + verifiedState = VerifiedDAppState.Verified {}, + appSubtitle = "react-app.walletconnect.com", + ), + estimatedWalletChanges = WcSendReceiveTransactionCheckResultsUM( + isLoading = false, + spendAllowance = WcSpendAllowanceUM( + amountValue = BigDecimal.ZERO, + isUnlimited = false, + amountText = stringReference("0.00 WPOL"), + tokenSymbol = "", + tokenImageUrl = "", + networkIconRes = 0, + onLearnMoreClicked = {}, + ), + ), + walletName = "Tangem 2.0", + networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), + feeState = WcTransactionFeeState.None, + address = "0xdac17f958d2ee523a2206206994597c13d831ec7", + sendEnabled = true, + feeErrorNotification = null, + transactionValidationResult = ValidationResult.SAFE, + ), ), ) \ No newline at end of file