Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-11 12:15:16 +04:00
parent 86f832d859
commit 77eed4f146
18 changed files with 179 additions and 235 deletions

View file

@ -5,7 +5,7 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class Trace( data class Trace(
@Json(name = "exposed") val exposed: Exposed, @Json(name = "exposed") val exposed: Exposed?,
@Json(name = "asset") val asset: NftAsset, @Json(name = "asset") val asset: NftAsset,
) )

View file

@ -49,7 +49,9 @@ internal object WcEthTxHelper {
.hexToBigDecimal() .hexToBigDecimal()
.movePointLeft(blockchain.decimals()) .movePointLeft(blockchain.decimals())
val callData = CompiledSmartContractCallData(txParams.data.removePrefix(HEX_PREFIX).hexToBytes()) val callData = txParams.data?.removePrefix(HEX_PREFIX)?.hexToBytes()?.let {
CompiledSmartContractCallData(it)
}
return TransactionData.Uncompiled( return TransactionData.Uncompiled(
amount = Amount(value, blockchain), amount = Amount(value, blockchain),
fee = dAppFee, fee = dAppFee,
@ -62,10 +64,10 @@ internal object WcEthTxHelper {
) )
} }
fun getApprovedAmount(txData: String, result: CheckTransactionResult): ApprovedAmount? { fun getApprovedAmount(txData: String?, result: CheckTransactionResult): ApprovedAmount? {
val approvalMethodId = ApprovalERC20TokenCallData("", null).methodId val approvalMethodId = ApprovalERC20TokenCallData("", null).methodId
val isApprovalWcMethod = txData.startsWith(approvalMethodId) val isApprovalWcMethod = txData?.startsWith(approvalMethodId)
if (!isApprovalWcMethod) return null if (isApprovalWcMethod != true) return null
val simulation = result.simulation as? SimulationResult.Success val simulation = result.simulation as? SimulationResult.Success
?: return null ?: return null
val approves = (simulation.data as? SimulationData.Approve)?.approvedAmounts val approves = (simulation.data as? SimulationData.Approve)?.approvedAmounts

View file

@ -12,7 +12,7 @@ data class WcEthTransactionParams(
val to: String?, val to: String?,
@Json(name = "data") @Json(name = "data")
val data: String, val data: String?,
@Json(name = "gas") @Json(name = "gas")
val gas: String?, val gas: String?,

View file

@ -8,23 +8,40 @@ import com.tangem.features.walletconnect.transaction.entity.common.WcTransaction
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoItemUM
import com.tangem.utils.converter.Converter import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import org.json.JSONArray
import javax.inject.Inject import javax.inject.Inject
private const val DATA_FIELD = "data"
internal class WcTransactionRequestBlockUMConverter @Inject constructor() : internal class WcTransactionRequestBlockUMConverter @Inject constructor() :
Converter<WcTransactionRequestBlockUMConverter.Input, WcTransactionRequestBlockUM> { Converter<WcTransactionRequestBlockUMConverter.Input, WcTransactionRequestBlockUM> {
override fun convert(value: Input) = WcTransactionRequestBlockUM( override fun convert(value: Input): WcTransactionRequestBlockUM {
persistentListOf( val params = value.rawSdkRequest.request.params
WcTransactionRequestInfoItemUM( return WcTransactionRequestBlockUM(
title = resourceReference(R.string.wc_signature_type), persistentListOf(
description = value.rawSdkRequest.request.method, WcTransactionRequestInfoItemUM(
title = resourceReference(R.string.wc_signature_type),
description = value.rawSdkRequest.request.method,
),
WcTransactionRequestInfoItemUM(
title = resourceReference(R.string.wc_contents),
description = value.signModel?.humanMsg ?: params.tryExtractData() ?: params,
),
), ),
WcTransactionRequestInfoItemUM( )
title = resourceReference(R.string.wc_contents), }
description = value.signModel?.humanMsg ?: value.rawSdkRequest.request.params,
), private fun String.tryExtractData() = try {
), val array = JSONArray(this)
) if (array.length() > 0 && array.getJSONObject(0).has(DATA_FIELD)) {
array.getJSONObject(0).getString(DATA_FIELD)
} else {
null
}
} catch (ignore: Exception) {
null
}
data class Input( data class Input(
val rawSdkRequest: WcSdkSessionRequest, val rawSdkRequest: WcSdkSessionRequest,

View file

@ -1,31 +0,0 @@
package com.tangem.features.walletconnect.transaction.entity.approve
import androidx.annotation.DrawableRes
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionAppInfoContentUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
internal data class WcApproveTransactionUM(
val transaction: WcApproveTransactionItemUM,
val transactionRequestInfo: WcTransactionRequestInfoUM,
val customAllowance: WcCustomAllowanceUM,
)
internal data class WcApproveTransactionItemUM(
val onDismiss: () -> Unit,
val onSend: () -> Unit,
val appInfo: WcTransactionAppInfoContentUM,
val spendAllowance: WcSpendAllowanceUM? = null,
val walletName: String,
val networkInfo: WcNetworkInfoUM,
val networkFee: String? = null,
val isLoading: Boolean = false,
) : TangemBottomSheetConfigContent
internal data class WcCustomAllowanceUM(
@DrawableRes val networkIconRes: Int,
val tokenIconUrl: String,
val amountText: String,
val isUnlimited: Boolean,
) : TangemBottomSheetConfigContent

View file

@ -0,0 +1,11 @@
package com.tangem.features.walletconnect.transaction.entity.approve
import androidx.annotation.DrawableRes
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
internal data class WcCustomAllowanceUM(
@DrawableRes val networkIconRes: Int,
val tokenIconUrl: String,
val amountText: String,
val isUnlimited: Boolean,
) : TangemBottomSheetConfigContent

View file

@ -1,6 +1,9 @@
package com.tangem.features.walletconnect.transaction.entity.approve package com.tangem.features.walletconnect.transaction.entity.approve
import com.tangem.core.ui.extensions.TextReference
internal data class WcSpendAllowanceUM( internal data class WcSpendAllowanceUM(
val amountText: String, val amountText: TextReference,
val tokenImageUrl: String, val tokenSymbol: String,
val tokenImageUrl: String?,
) )

View file

@ -1,9 +1,11 @@
package com.tangem.features.walletconnect.transaction.entity.blockaid package com.tangem.features.walletconnect.transaction.entity.blockaid
import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.TextReference
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
internal data class WcSendReceiveTransactionCheckResultsUM( internal data class WcSendReceiveTransactionCheckResultsUM(
val estimatedWalletChanges: WcEstimatedWalletChangesUM? = null, val estimatedWalletChanges: WcEstimatedWalletChangesUM? = null,
val spendAllowance: WcSpendAllowanceUM? = null,
val notificationText: TextReference? = null, val notificationText: TextReference? = null,
val isLoading: Boolean = true, val isLoading: Boolean = true,
) )

View file

@ -1,133 +0,0 @@
package com.tangem.features.walletconnect.transaction.ui.approve
import android.content.res.Configuration
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.divider.DividerWithPadding
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
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.entity.approve.WcApproveTransactionItemUM
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionAppInfoContentUM
import com.tangem.features.walletconnect.transaction.ui.common.*
@Composable
internal fun WcApproveTransactionModalBottomSheetContent(
state: WcApproveTransactionItemUM,
onClickTransactionRequest: () -> Unit,
) {
Column(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16),
) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
.background(color = TangemTheme.colors.background.action)
.fillMaxWidth()
.animateContentSize(),
) {
WcSmallTitleItem(R.string.wc_request_from)
WcAppInfoItem(
iconUrl = state.appInfo.appIcon,
title = state.appInfo.appName,
subtitle = state.appInfo.appSubtitle,
verifiedDAppState = state.appInfo.verifiedState,
)
DividerWithPadding(start = 0.dp, end = 0.dp)
WcTransactionRequestItem(
iconRes = R.drawable.ic_doc_new_24,
modifier = Modifier
.fillMaxWidth()
.clickable { onClickTransactionRequest() }
.padding(TangemTheme.dimens.spacing12),
)
}
Column(modifier = Modifier.padding(top = TangemTheme.dimens.spacing16)) {
if (state.spendAllowance != null) {
WcSpendAllowanceItem(state.spendAllowance)
Spacer(Modifier.height(TangemTheme.dimens.spacing16))
}
WcSendTransactionItems(
walletName = state.walletName,
networkInfo = state.networkInfo,
networkFee = state.networkFee,
)
WcTransactionRequestButtons(
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16),
onDismiss = state.onDismiss,
onClickActiveButton = state.onSend,
activeButtonText = resourceReference(R.string.common_send),
isLoading = state.isLoading,
)
}
}
}
@Composable
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun WcApproveTransactionBottomSheetPreview(
@PreviewParameter(WcApproveTransactionStateProvider::class) state: WcApproveTransactionItemUM,
) {
TangemThemePreview {
TangemModalBottomSheet<WcApproveTransactionItemUM>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = {},
content = state,
),
containerColor = TangemTheme.colors.background.tertiary,
title = {
TangemModalBottomSheetTitle(
title = resourceReference(R.string.wallet_connect_title),
endIconRes = R.drawable.ic_close_24,
onEndClick = {},
startIconRes = null,
onStartClick = {},
)
},
content = {
WcApproveTransactionModalBottomSheetContent(state = state, onClickTransactionRequest = {})
},
)
}
}
private class WcApproveTransactionStateProvider : CollectionPreviewParameterProvider<WcApproveTransactionItemUM>(
listOf(
WcApproveTransactionItemUM(
onDismiss = {},
onSend = {},
appInfo = WcTransactionAppInfoContentUM(
appName = "React App",
appIcon = "",
verifiedState = VerifiedDAppState.Verified {},
appSubtitle = "react-app.walletconnect.com",
),
spendAllowance = WcSpendAllowanceUM(amountText = "Unlimited USDT", tokenImageUrl = ""),
walletName = "Tangem 2.0",
networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22),
networkFee = "~ 0.22 $",
),
),
)

View file

@ -13,7 +13,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import com.tangem.features.walletconnect.impl.R import com.tangem.features.walletconnect.impl.R
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
@ -23,17 +25,14 @@ import com.tangem.features.walletconnect.transaction.ui.common.WcSmallTitleItem
internal fun WcSpendAllowanceItem(spendAllowance: WcSpendAllowanceUM, modifier: Modifier = Modifier) { internal fun WcSpendAllowanceItem(spendAllowance: WcSpendAllowanceUM, modifier: Modifier = Modifier) {
Column( Column(
modifier = modifier modifier = modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius14)) .clip(RoundedCornerShape(14.dp))
.background(TangemTheme.colors.background.action) .background(TangemTheme.colors.background.action)
.fillMaxWidth() .fillMaxWidth()
.padding( .padding(end = 12.dp, bottom = 12.dp),
end = TangemTheme.dimens.spacing12,
bottom = TangemTheme.dimens.spacing12,
),
) { ) {
WcSmallTitleItem(R.string.wc_allow_to_spend) WcSmallTitleItem(R.string.wc_allow_to_spend)
Spacer(modifier = Modifier.height(TangemTheme.dimens.spacing8)) Spacer(modifier = Modifier.height(8.dp))
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
@ -46,15 +45,16 @@ internal fun WcSpendAllowanceItem(spendAllowance: WcSpendAllowanceUM, modifier:
AsyncImage( AsyncImage(
model = spendAllowance.tokenImageUrl, model = spendAllowance.tokenImageUrl,
modifier = Modifier modifier = Modifier
.size(TangemTheme.dimens.size24) .padding(start = 12.dp)
.size(24.dp)
.clip(CircleShape), .clip(CircleShape),
contentDescription = null, contentDescription = null,
) )
Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing12)) Spacer(modifier = Modifier.width(8.dp))
AnimatedContent( AnimatedContent(
targetState = spendAllowance.amountText, targetState = "${spendAllowance.amountText.resolveReference()} ${spendAllowance.tokenSymbol}",
label = "Animate Spend allowance text", label = "Animate Spend allowance text",
) { amount -> ) { amount ->
Text( Text(
@ -75,7 +75,7 @@ internal fun WcSpendAllowanceItem(spendAllowance: WcSpendAllowanceUM, modifier:
color = TangemTheme.colors.text.tertiary, color = TangemTheme.colors.text.tertiary,
) )
Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing8)) Spacer(modifier = Modifier.width(8.dp))
Icon( Icon(
painter = painterResource(id = R.drawable.ic_edit_new_12), painter = painterResource(id = R.drawable.ic_edit_new_12),

View file

@ -19,12 +19,11 @@ import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangeUM 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.WcEstimatedWalletChangesUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
import com.tangem.features.walletconnect.transaction.ui.approve.WcSpendAllowanceItem
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@Composable @Composable
internal fun TransactionCheckResultsItem(item: WcSendReceiveTransactionCheckResultsUM, modifier: Modifier = Modifier) { internal fun TransactionCheckResultsItem(item: WcSendReceiveTransactionCheckResultsUM, modifier: Modifier = Modifier) {
if (item.notificationText == null && item.estimatedWalletChanges == null) return
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth(), .fillMaxWidth(),
@ -38,6 +37,8 @@ internal fun TransactionCheckResultsItem(item: WcSendReceiveTransactionCheckResu
} }
if (item.estimatedWalletChanges != null) { if (item.estimatedWalletChanges != null) {
WcEstimatedWalletChangesItem(item.estimatedWalletChanges) WcEstimatedWalletChangesItem(item.estimatedWalletChanges)
} else if (item.spendAllowance != null) {
WcSpendAllowanceItem(item.spendAllowance)
} else { } else {
WcEstimatedWalletChangesNotLoadedItem() WcEstimatedWalletChangesNotLoadedItem()
} }

View file

@ -63,7 +63,7 @@ internal fun WcEstimatedWalletChangeRow(item: WcEstimatedWalletChangeUM, modifie
} }
} }
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(8.dp))
AsyncImage( AsyncImage(
model = item.tokenIconUrl, model = item.tokenIconUrl,

View file

@ -0,0 +1,40 @@
package com.tangem.features.walletconnect.transaction.ui.blockaid
import com.domain.blockaid.models.transaction.simultation.AmountInfo
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangeUM
import com.tangem.utils.converter.Converter
import java.math.BigDecimal
import javax.inject.Inject
internal class WcEstimatedWalletChangeUMConverter @Inject constructor() :
Converter<WcEstimatedWalletChangeUMConverter.Input, WcEstimatedWalletChangeUM> {
override fun convert(value: Input): WcEstimatedWalletChangeUM {
return when (val amountInfo = value.amountInfo) {
is AmountInfo.FungibleTokens -> WcEstimatedWalletChangeUM(
iconRes = value.iconRes,
title = resourceReference(value.titleRes),
description = "${value.sign} ${amountInfo.amount.amountText()} ${amountInfo.token.symbol}",
tokenIconUrl = amountInfo.token.logoUrl,
)
is AmountInfo.NonFungibleTokens -> WcEstimatedWalletChangeUM(
iconRes = value.iconRes,
title = resourceReference(value.titleRes),
description = amountInfo.name,
tokenIconUrl = amountInfo.logoUrl,
)
}
}
private fun BigDecimal.amountText() = format { crypto("", DECIMALS_AMOUNT) }
data class Input(
val amountInfo: AmountInfo,
val iconRes: Int,
val titleRes: Int,
val sign: String? = null,
)
}

View file

@ -36,7 +36,7 @@ internal fun WcEstimatedWalletChangesLoadingItem(modifier: Modifier = Modifier)
Row( Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(bottom = 14.dp), modifier = Modifier.padding(start = 12.dp, end = 12.dp, bottom = 14.dp),
) { ) {
CircularProgressIndicator( CircularProgressIndicator(
color = TangemTheme.colors.icon.accent, color = TangemTheme.colors.icon.accent,
@ -45,7 +45,8 @@ internal fun WcEstimatedWalletChangesLoadingItem(modifier: Modifier = Modifier)
) )
Text( Text(
modifier = modifier modifier = modifier
.fillMaxWidth(), .fillMaxWidth()
.padding(start = 8.dp),
text = stringResourceSafe(R.string.wc_common_loading), text = stringResourceSafe(R.string.wc_common_loading),
color = TangemTheme.colors.text.disabled, color = TangemTheme.colors.text.disabled,
style = TangemTheme.typography.body2, style = TangemTheme.typography.body2,

View file

@ -35,7 +35,7 @@ internal fun WcEstimatedWalletChangesNotLoadedItem(modifier: Modifier = Modifier
Text( Text(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(start = 12.dp, bottom = 14.dp), .padding(start = 12.dp, end = 12.dp, bottom = 14.dp),
text = stringResourceSafe(R.string.wc_estimated_wallet_changes_not_simulated), text = stringResourceSafe(R.string.wc_estimated_wallet_changes_not_simulated),
color = TangemTheme.colors.text.tertiary, color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.body2, style = TangemTheme.typography.body2,

View file

@ -6,28 +6,34 @@ import com.domain.blockaid.models.transaction.ValidationResult
import com.domain.blockaid.models.transaction.simultation.AmountInfo import com.domain.blockaid.models.transaction.simultation.AmountInfo
import com.domain.blockaid.models.transaction.simultation.SimulationData import com.domain.blockaid.models.transaction.simultation.SimulationData
import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.format.bigdecimal.crypto import com.tangem.core.ui.format.bigdecimal.crypto
import com.tangem.core.ui.format.bigdecimal.format import com.tangem.core.ui.format.bigdecimal.format
import com.tangem.features.walletconnect.impl.R import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcEstimatedWalletChangeUM 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.WcEstimatedWalletChangesUM
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
import com.tangem.utils.StringsSigns
import com.tangem.utils.converter.Converter import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import java.math.BigDecimal
import javax.inject.Inject import javax.inject.Inject
private const val DECIMALS_AMOUNT = 2 internal const val DECIMALS_AMOUNT = 2
internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor() : internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor(
private val estimatedWalletChangeUMConverter: WcEstimatedWalletChangeUMConverter,
private val spendAllowanceUMConverter: WcSpendAllowanceUMConverter,
) :
Converter<CheckTransactionResult, WcSendReceiveTransactionCheckResultsUM> { Converter<CheckTransactionResult, WcSendReceiveTransactionCheckResultsUM> {
override fun convert(value: CheckTransactionResult): WcSendReceiveTransactionCheckResultsUM { override fun convert(value: CheckTransactionResult): WcSendReceiveTransactionCheckResultsUM {
return WcSendReceiveTransactionCheckResultsUM( return WcSendReceiveTransactionCheckResultsUM(
isLoading = false, isLoading = false,
notificationText = when (value.validation) { notificationText = when (value.validation) {
ValidationResult.SAFE, ValidationResult.FAILED_TO_VALIDATE -> null ValidationResult.SAFE, ValidationResult.FAILED_TO_VALIDATE -> null
ValidationResult.UNSAFE -> TextReference.Str("") // TODO("Add text after approve with designer") // TODO("Add text after approve with designer")
ValidationResult.UNSAFE ->
TextReference.Str("The transaction approves tokens to a known malicious address")
}, },
estimatedWalletChanges = (value.simulation as? SimulationResult.Success)?.data?.let { data -> estimatedWalletChanges = (value.simulation as? SimulationResult.Success)?.data?.let { data ->
when (data) { when (data) {
@ -36,24 +42,38 @@ internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor() :
val items: ImmutableList<WcEstimatedWalletChangeUM> = ( val items: ImmutableList<WcEstimatedWalletChangeUM> = (
data.send.map { data.send.map {
when (it) { when (it) {
is AmountInfo.FungibleTokens -> it.toUM( is AmountInfo.FungibleTokens -> estimatedWalletChangeUMConverter.convert(
iconRes = R.drawable.ic_send_new_24, WcEstimatedWalletChangeUMConverter.Input(
titleRes = R.string.common_send, amountInfo = it,
iconRes = R.drawable.ic_receive_new_24,
titleRes = R.string.common_send,
sign = StringsSigns.MINUS,
),
) )
is AmountInfo.NonFungibleTokens -> it.toUM( is AmountInfo.NonFungibleTokens -> estimatedWalletChangeUMConverter.convert(
iconRes = R.drawable.ic_send_new_24, WcEstimatedWalletChangeUMConverter.Input(
titleRes = R.string.common_send, amountInfo = it,
iconRes = R.drawable.ic_send_new_24,
titleRes = R.string.common_send,
),
) )
} }
} + data.receive.map { } + data.receive.map {
when (it) { when (it) {
is AmountInfo.FungibleTokens -> it.toUM( is AmountInfo.FungibleTokens -> estimatedWalletChangeUMConverter.convert(
iconRes = R.drawable.ic_receive_new_24, WcEstimatedWalletChangeUMConverter.Input(
titleRes = R.string.common_receive, amountInfo = it,
iconRes = R.drawable.ic_receive_new_24,
titleRes = R.string.common_receive,
sign = StringsSigns.PLUS,
),
) )
is AmountInfo.NonFungibleTokens -> it.toUM( is AmountInfo.NonFungibleTokens -> estimatedWalletChangeUMConverter.convert(
iconRes = R.drawable.ic_receive_new_24, WcEstimatedWalletChangeUMConverter.Input(
titleRes = R.string.common_receive, amountInfo = it,
iconRes = R.drawable.ic_receive_new_24,
titleRes = R.string.common_receive,
),
) )
} }
} }
@ -62,25 +82,15 @@ internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor() :
} }
} }
}, },
spendAllowance = (value.simulation as? SimulationResult.Success)?.data?.let { data ->
when (data) {
is SimulationData.SendAndReceive -> null
is SimulationData.Approve -> data.approvedAmounts.map { spendAllowanceUMConverter.convert(it) }
.firstOrNull()
}
},
) )
} }
} }
private fun AmountInfo.FungibleTokens.toUM(iconRes: Int, titleRes: Int): WcEstimatedWalletChangeUM { internal fun BigDecimal.amountText() = format { crypto("", DECIMALS_AMOUNT) }
val amountText = amount.format { crypto(token.symbol, DECIMALS_AMOUNT) }
return WcEstimatedWalletChangeUM(
iconRes = iconRes,
title = resourceReference(titleRes),
description = "- $amountText",
tokenIconUrl = token.logoUrl,
)
}
private fun AmountInfo.NonFungibleTokens.toUM(iconRes: Int, titleRes: Int): WcEstimatedWalletChangeUM {
return WcEstimatedWalletChangeUM(
iconRes = iconRes,
title = resourceReference(titleRes),
description = name,
tokenIconUrl = logoUrl,
)
}

View file

@ -0,0 +1,21 @@
package com.tangem.features.walletconnect.transaction.ui.blockaid
import com.domain.blockaid.models.transaction.simultation.ApprovedAmount
import com.tangem.core.ui.extensions.TextReference
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<ApprovedAmount, WcSpendAllowanceUM> {
override fun convert(value: ApprovedAmount) = WcSpendAllowanceUM(
amountText = if (value.isUnlimited) {
TextReference.Res(R.string.wc_common_unlimited)
} else {
TextReference.Str(value.approvedAmount.amountText())
},
tokenSymbol = value.tokenInfo.symbol,
tokenImageUrl = value.tokenInfo.logoUrl,
)
}

View file

@ -15,7 +15,7 @@ fun WcSmallTitleItem(@StringRes textRex: Int, modifier: Modifier = Modifier) {
Text( Text(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 12.dp, start = 12.dp), .padding(top = 12.dp, start = 12.dp, end = 12.dp),
text = stringResourceSafe(textRex), text = stringResourceSafe(textRex),
color = TangemTheme.colors.text.tertiary, color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.subtitle2, style = TangemTheme.typography.subtitle2,