Updated on 2026-08-14
This commit is contained in:
parent
717b8e2df2
commit
422e406d15
21 changed files with 258 additions and 112 deletions
|
|
@ -7,4 +7,5 @@ import com.squareup.moshi.JsonClass
|
||||||
data class ValidationResponse(
|
data class ValidationResponse(
|
||||||
@Json(name = "status") val status: String,
|
@Json(name = "status") val status: String,
|
||||||
@Json(name = "result_type") val resultType: String,
|
@Json(name = "result_type") val resultType: String,
|
||||||
|
@Json(name = "description") val description: String?,
|
||||||
)
|
)
|
||||||
|
|
@ -39,6 +39,7 @@ internal object BlockAidMapper {
|
||||||
} else {
|
} else {
|
||||||
mapSimulationSuccessResult(from.simulation.accountSummary)
|
mapSimulationSuccessResult(from.simulation.accountSummary)
|
||||||
},
|
},
|
||||||
|
description = from.validation.description,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class BlockAidMapperTest {
|
||||||
spenders = mapOf("spender" to spenderDetails),
|
spenders = mapOf("spender" to spenderDetails),
|
||||||
)
|
)
|
||||||
val response = TransactionScanResponse(
|
val response = TransactionScanResponse(
|
||||||
validation = ValidationResponse(status = "Success", resultType = "Benign"),
|
validation = ValidationResponse(status = "Success", resultType = "Benign", description = ""),
|
||||||
simulation = SimulationResponse(
|
simulation = SimulationResponse(
|
||||||
status = "Success",
|
status = "Success",
|
||||||
accountSummary = AccountSummaryResponse(
|
accountSummary = AccountSummaryResponse(
|
||||||
|
|
@ -79,7 +79,7 @@ class BlockAidMapperTest {
|
||||||
outTransfer = listOf(Transfer(value = "1.5", rawValue = "0x2")),
|
outTransfer = listOf(Transfer(value = "1.5", rawValue = "0x2")),
|
||||||
)
|
)
|
||||||
val response = TransactionScanResponse(
|
val response = TransactionScanResponse(
|
||||||
validation = ValidationResponse(status = "Success", resultType = "Benign"),
|
validation = ValidationResponse(status = "Success", resultType = "Benign", description = ""),
|
||||||
simulation = SimulationResponse(
|
simulation = SimulationResponse(
|
||||||
status = "Success",
|
status = "Success",
|
||||||
accountSummary = AccountSummaryResponse(
|
accountSummary = AccountSummaryResponse(
|
||||||
|
|
@ -105,7 +105,7 @@ class BlockAidMapperTest {
|
||||||
@Test
|
@Test
|
||||||
fun `when response error validation rhen returns failed to validate`() {
|
fun `when response error validation rhen returns failed to validate`() {
|
||||||
val response = TransactionScanResponse(
|
val response = TransactionScanResponse(
|
||||||
validation = ValidationResponse(status = "Error", resultType = "Benign"),
|
validation = ValidationResponse(status = "Error", resultType = "Benign", description = ""),
|
||||||
simulation = SimulationResponse(
|
simulation = SimulationResponse(
|
||||||
status = "Success",
|
status = "Success",
|
||||||
accountSummary = AccountSummaryResponse(emptyList(), emptyList(), null),
|
accountSummary = AccountSummaryResponse(emptyList(), emptyList(), null),
|
||||||
|
|
@ -120,7 +120,7 @@ class BlockAidMapperTest {
|
||||||
@Test
|
@Test
|
||||||
fun `when response not benign then returns validation unsafe`() {
|
fun `when response not benign then returns validation unsafe`() {
|
||||||
val response = TransactionScanResponse(
|
val response = TransactionScanResponse(
|
||||||
validation = ValidationResponse(status = "Success", resultType = "Phishing"),
|
validation = ValidationResponse(status = "Success", resultType = "Phishing", description = ""),
|
||||||
simulation = SimulationResponse(
|
simulation = SimulationResponse(
|
||||||
status = "Success",
|
status = "Success",
|
||||||
accountSummary = AccountSummaryResponse(emptyList(), emptyList(), null),
|
accountSummary = AccountSummaryResponse(emptyList(), emptyList(), null),
|
||||||
|
|
@ -134,7 +134,7 @@ class BlockAidMapperTest {
|
||||||
@Test
|
@Test
|
||||||
fun `when response simulation not success then returns simulation failed ro simulate`() {
|
fun `when response simulation not success then returns simulation failed ro simulate`() {
|
||||||
val response = TransactionScanResponse(
|
val response = TransactionScanResponse(
|
||||||
validation = ValidationResponse(status = "Success", resultType = "Benign"),
|
validation = ValidationResponse(status = "Success", resultType = "Benign", description = ""),
|
||||||
simulation = SimulationResponse(
|
simulation = SimulationResponse(
|
||||||
status = "Error",
|
status = "Error",
|
||||||
accountSummary = AccountSummaryResponse(emptyList(), emptyList(), null),
|
accountSummary = AccountSummaryResponse(emptyList(), emptyList(), null),
|
||||||
|
|
@ -148,7 +148,7 @@ class BlockAidMapperTest {
|
||||||
@Test
|
@Test
|
||||||
fun `when response simulation is empty then returns failed to simulate`() {
|
fun `when response simulation is empty then returns failed to simulate`() {
|
||||||
val txResponse = TransactionScanResponse(
|
val txResponse = TransactionScanResponse(
|
||||||
validation = ValidationResponse(status = "Success", resultType = "Benign"),
|
validation = ValidationResponse(status = "Success", resultType = "Benign", description = ""),
|
||||||
simulation = SimulationResponse(
|
simulation = SimulationResponse(
|
||||||
status = "Success",
|
status = "Success",
|
||||||
accountSummary = AccountSummaryResponse(
|
accountSummary = AccountSummaryResponse(
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ internal class WcEthSendTransactionUseCase @AssistedInject constructor(
|
||||||
emitAll(delegate.invoke(transactionData))
|
emitAll(delegate.invoke(transactionData))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getAmount(): Amount? {
|
override fun getAmount(): Amount? {
|
||||||
return approvalAmount
|
return approvalAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ internal class WcEthSignTransactionUseCase @AssistedInject constructor(
|
||||||
return dAppFee
|
return dAppFee
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getAmount(): Amount? {
|
override fun getAmount(): Amount? {
|
||||||
return approvalAmount
|
return approvalAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ package com.domain.blockaid.models.transaction
|
||||||
*/
|
*/
|
||||||
data class CheckTransactionResult(
|
data class CheckTransactionResult(
|
||||||
val validation: ValidationResult,
|
val validation: ValidationResult,
|
||||||
|
val description: String? = null,
|
||||||
val simulation: SimulationResult,
|
val simulation: SimulationResult,
|
||||||
)
|
)
|
||||||
|
|
@ -44,6 +44,6 @@ interface WcMutableFee {
|
||||||
* [updateAmount] triggered a new [TransactionData] emit
|
* [updateAmount] triggered a new [TransactionData] emit
|
||||||
*/
|
*/
|
||||||
interface WcApproval {
|
interface WcApproval {
|
||||||
suspend fun getAmount(): Amount?
|
fun getAmount(): Amount?
|
||||||
fun updateAmount(amount: Amount?)
|
fun updateAmount(amount: Amount?)
|
||||||
}
|
}
|
||||||
|
|
@ -60,6 +60,7 @@ internal abstract class WcCommonTransactionComponentDelegate(
|
||||||
is WcTransactionRoutes.Transaction,
|
is WcTransactionRoutes.Transaction,
|
||||||
is WcTransactionRoutes.TransactionRequestInfo,
|
is WcTransactionRoutes.TransactionRequestInfo,
|
||||||
is WcTransactionRoutes.Alert,
|
is WcTransactionRoutes.Alert,
|
||||||
|
is WcTransactionRoutes.CustomAllowance,
|
||||||
-> stackNavigation?.pop()
|
-> stackNavigation?.pop()
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import com.tangem.core.decompose.context.AppComponentContext
|
||||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
import com.tangem.features.walletconnect.connections.components.AlertsComponentV2
|
import com.tangem.features.walletconnect.connections.components.AlertsComponentV2
|
||||||
import com.tangem.features.walletconnect.connections.utils.WcAlertsFactory.createCommonTransactionAppInfoAlertUM
|
import com.tangem.features.walletconnect.connections.utils.WcAlertsFactory.createCommonTransactionAppInfoAlertUM
|
||||||
|
import com.tangem.features.walletconnect.transaction.components.send.WcCustomAllowanceComponent
|
||||||
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionModel
|
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionModel
|
||||||
|
import com.tangem.features.walletconnect.transaction.model.WcSendTransactionModel
|
||||||
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
|
||||||
|
|
||||||
internal fun getWcCommonScreen(
|
internal fun getWcCommonScreen(
|
||||||
|
|
@ -23,5 +25,12 @@ internal fun getWcCommonScreen(
|
||||||
appComponentContext = appComponentContext,
|
appComponentContext = appComponentContext,
|
||||||
model = model,
|
model = model,
|
||||||
)
|
)
|
||||||
|
is WcTransactionRoutes.CustomAllowance -> WcCustomAllowanceComponent(
|
||||||
|
appComponentContext = appComponentContext,
|
||||||
|
model = model,
|
||||||
|
onClickDoneCustomAllowance = { value, isUnlimited ->
|
||||||
|
(model as? WcSendTransactionModel)?.onClickDoneCustomAllowance(value, isUnlimited)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.tangem.features.walletconnect.transaction.components.send
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import com.tangem.core.decompose.context.AppComponentContext
|
||||||
|
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||||
|
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionModel
|
||||||
|
import com.tangem.features.walletconnect.transaction.entity.send.WcSendTransactionUM
|
||||||
|
import com.tangem.features.walletconnect.transaction.ui.approve.WcCustomAllowanceContent
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
internal class WcCustomAllowanceComponent(
|
||||||
|
private val appComponentContext: AppComponentContext,
|
||||||
|
private val model: WcCommonTransactionModel,
|
||||||
|
private val onClickDoneCustomAllowance: (BigDecimal, Boolean) -> Unit,
|
||||||
|
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
|
||||||
|
|
||||||
|
override fun dismiss() {
|
||||||
|
model.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun BottomSheet() {
|
||||||
|
val content by model.uiState.collectAsStateWithLifecycle()
|
||||||
|
val spendAllowance = (content as? WcSendTransactionUM)?.spendAllowance
|
||||||
|
if (spendAllowance != null) {
|
||||||
|
WcCustomAllowanceContent(
|
||||||
|
state = spendAllowance,
|
||||||
|
onClickDone = { value, isUnlimited ->
|
||||||
|
router.pop()
|
||||||
|
onClickDoneCustomAllowance(value, isUnlimited)
|
||||||
|
},
|
||||||
|
onBack = router::pop,
|
||||||
|
onDismiss = ::dismiss,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,6 +27,7 @@ internal class WcSendTransactionComponent(
|
||||||
onClickTransactionRequest = model::showTransactionRequest,
|
onClickTransactionRequest = model::showTransactionRequest,
|
||||||
onBack = router::pop,
|
onBack = router::pop,
|
||||||
onDismiss = ::dismiss,
|
onDismiss = ::dismiss,
|
||||||
|
onClickAllowToSpend = model::onClickAllowToSpend,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
package com.tangem.features.walletconnect.transaction.entity.approve
|
package com.tangem.features.walletconnect.transaction.entity.approve
|
||||||
|
|
||||||
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
internal data class WcSpendAllowanceUM(
|
internal data class WcSpendAllowanceUM(
|
||||||
|
val amountValue: BigDecimal,
|
||||||
|
val isUnlimited: Boolean,
|
||||||
val amountText: TextReference,
|
val amountText: TextReference,
|
||||||
val tokenSymbol: String,
|
val tokenSymbol: String,
|
||||||
val tokenImageUrl: String?,
|
val tokenImageUrl: String?,
|
||||||
)
|
val networkIconRes: Int?,
|
||||||
|
) : TangemBottomSheetConfigContent
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.tangem.features.walletconnect.transaction.entity.send
|
package com.tangem.features.walletconnect.transaction.entity.send
|
||||||
|
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||||
|
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
|
||||||
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
|
import com.tangem.features.walletconnect.transaction.entity.blockaid.WcSendReceiveTransactionCheckResultsUM
|
||||||
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionUM
|
import com.tangem.features.walletconnect.transaction.entity.common.WcCommonTransactionUM
|
||||||
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
import com.tangem.features.walletconnect.transaction.entity.common.WcNetworkInfoUM
|
||||||
|
|
@ -10,6 +11,7 @@ import com.tangem.features.walletconnect.transaction.entity.common.WcTransaction
|
||||||
internal data class WcSendTransactionUM(
|
internal data class WcSendTransactionUM(
|
||||||
val transaction: WcSendTransactionItemUM,
|
val transaction: WcSendTransactionItemUM,
|
||||||
override val transactionRequestInfo: WcTransactionRequestInfoUM,
|
override val transactionRequestInfo: WcTransactionRequestInfoUM,
|
||||||
|
val spendAllowance: WcSpendAllowanceUM? = null,
|
||||||
) : WcCommonTransactionUM
|
) : WcCommonTransactionUM
|
||||||
|
|
||||||
internal data class WcSendTransactionItemUM(
|
internal data class WcSendTransactionItemUM(
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import com.tangem.features.walletconnect.transaction.ui.blockaid.WcSendAndReceiv
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.math.BigDecimal
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@Suppress("LongParameterList")
|
@Suppress("LongParameterList")
|
||||||
|
|
@ -46,6 +47,8 @@ internal class WcSendTransactionModel @Inject constructor(
|
||||||
|
|
||||||
val stackNavigation = StackNavigation<WcTransactionRoutes>()
|
val stackNavigation = StackNavigation<WcTransactionRoutes>()
|
||||||
|
|
||||||
|
private var wcApproval: WcApproval? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@Suppress("UnusedPrivateMember")
|
@Suppress("UnusedPrivateMember")
|
||||||
modelScope.launch {
|
modelScope.launch {
|
||||||
|
|
@ -77,6 +80,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
||||||
val isSecurityCheckContent = securityCheck is Lce.Content
|
val isSecurityCheckContent = securityCheck is Lce.Content
|
||||||
var isApprovalMethod = isSecurityCheckContent &&
|
var isApprovalMethod = isSecurityCheckContent &&
|
||||||
securityCheck.content is BlockAidTransactionCheck.Result.Approval
|
securityCheck.content is BlockAidTransactionCheck.Result.Approval
|
||||||
|
wcApproval = useCase as? WcApproval
|
||||||
buildUiState(securityCheck, useCase, signState)
|
buildUiState(securityCheck, useCase, signState)
|
||||||
}
|
}
|
||||||
else -> unknownMethodRunnable()
|
else -> unknownMethodRunnable()
|
||||||
|
|
@ -90,7 +94,9 @@ internal class WcSendTransactionModel @Inject constructor(
|
||||||
signState: WcSignState<*>,
|
signState: WcSignState<*>,
|
||||||
) {
|
) {
|
||||||
val blockAidState = when (securityCheck) {
|
val blockAidState = when (securityCheck) {
|
||||||
is Lce.Content -> blockAidUiConverter.convert(securityCheck.content.result)
|
is Lce.Content -> blockAidUiConverter.convert(
|
||||||
|
WcSendAndReceiveBlockAidUiConverter.Input(securityCheck.content.result, wcApproval?.getAmount()),
|
||||||
|
)
|
||||||
is Lce.Error -> WcSendReceiveTransactionCheckResultsUM(isLoading = false)
|
is Lce.Error -> WcSendReceiveTransactionCheckResultsUM(isLoading = false)
|
||||||
is Lce.Loading -> WcSendReceiveTransactionCheckResultsUM(isLoading = true)
|
is Lce.Loading -> WcSendReceiveTransactionCheckResultsUM(isLoading = true)
|
||||||
}
|
}
|
||||||
|
|
@ -108,6 +114,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
||||||
) as? WcSendTransactionUM
|
) as? WcSendTransactionUM
|
||||||
transactionUM = transactionUM?.copy(
|
transactionUM = transactionUM?.copy(
|
||||||
transaction = transactionUM.transaction.copy(estimatedWalletChanges = blockAidState),
|
transaction = transactionUM.transaction.copy(estimatedWalletChanges = blockAidState),
|
||||||
|
spendAllowance = blockAidState.spendAllowance,
|
||||||
)
|
)
|
||||||
_uiState.emit(transactionUM)
|
_uiState.emit(transactionUM)
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +127,17 @@ internal class WcSendTransactionModel @Inject constructor(
|
||||||
stackNavigation.pushNew(WcTransactionRoutes.TransactionRequestInfo)
|
stackNavigation.pushNew(WcTransactionRoutes.TransactionRequestInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onClickDoneCustomAllowance(value: BigDecimal, isUnlimited: Boolean) {
|
||||||
|
val maxValue = if (isUnlimited) Double.MAX_VALUE.toBigDecimal() else value
|
||||||
|
wcApproval?.getAmount()?.let { currentAmount ->
|
||||||
|
wcApproval?.updateAmount(currentAmount.copy(maxValue = maxValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onClickAllowToSpend() {
|
||||||
|
wcApproval?.let { stackNavigation.pushNew(WcTransactionRoutes.CustomAllowance) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun showVerifiedAlert(appName: String) {
|
private fun showVerifiedAlert(appName: String) {
|
||||||
stackNavigation.pushNew(WcTransactionRoutes.Alert(WcTransactionRoutes.Alert.Type.Verified(appName)))
|
stackNavigation.pushNew(WcTransactionRoutes.Alert(WcTransactionRoutes.Alert.Type.Verified(appName)))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ internal sealed class WcTransactionRoutes : TangemBottomSheetConfigContent, Rout
|
||||||
@Serializable
|
@Serializable
|
||||||
data object TransactionRequestInfo : WcTransactionRoutes()
|
data object TransactionRequestInfo : WcTransactionRoutes()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data object CustomAllowance : WcTransactionRoutes()
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Alert(val type: Type) : WcTransactionRoutes() {
|
data class Alert(val type: Type) : WcTransactionRoutes() {
|
||||||
@Serializable
|
@Serializable
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.material3.TextFieldDefaults
|
import androidx.compose.material3.TextFieldDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
|
@ -23,91 +23,126 @@ import androidx.compose.ui.tooling.preview.Devices
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.tangem.core.ui.components.PrimaryButton
|
import com.tangem.core.ui.components.PrimaryButton
|
||||||
import com.tangem.core.ui.components.TangemSwitch
|
import com.tangem.core.ui.components.TangemSwitch
|
||||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||||
|
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
|
||||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||||
|
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
|
||||||
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
import com.tangem.core.ui.extensions.resourceReference
|
import com.tangem.core.ui.extensions.resourceReference
|
||||||
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.core.ui.res.TangemThemePreview
|
import com.tangem.core.ui.res.TangemThemePreview
|
||||||
import com.tangem.features.walletconnect.impl.R
|
import com.tangem.features.walletconnect.impl.R
|
||||||
import com.tangem.features.walletconnect.transaction.entity.approve.WcCustomAllowanceUM
|
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WcCustomAllowanceContent(
|
internal fun WcCustomAllowanceContent(
|
||||||
allowance: WcCustomAllowanceUM,
|
state: WcSpendAllowanceUM,
|
||||||
onAmountChange: (String) -> Unit,
|
onClickDone: (BigDecimal, Boolean) -> Unit,
|
||||||
onToggleChange: (Boolean) -> Unit,
|
onBack: () -> Unit,
|
||||||
onClickDone: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
) {
|
) {
|
||||||
Column(
|
var amountText by remember { mutableStateOf(state.amountValue.toPlainString()) }
|
||||||
modifier = modifier
|
var isUnlimited by remember { mutableStateOf(state.isUnlimited) }
|
||||||
.background(TangemTheme.colors.background.tertiary)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(TangemTheme.dimens.size16),
|
|
||||||
) {
|
|
||||||
AmountTextField(
|
|
||||||
allowance = allowance,
|
|
||||||
onAmountChange = onAmountChange,
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(TangemTheme.dimens.spacing16))
|
val amount: BigDecimal by remember(amountText) {
|
||||||
|
mutableStateOf(amountText.toBigDecimalOrNull() ?: state.amountValue)
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
modifier = Modifier
|
|
||||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
|
||||||
.background(color = TangemTheme.colors.background.action)
|
|
||||||
.padding(TangemTheme.dimens.spacing16)
|
|
||||||
.fillMaxWidth(),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResourceSafe(R.string.wc_unlimited_amount),
|
|
||||||
style = TangemTheme.typography.body1,
|
|
||||||
color = TangemTheme.colors.text.primary1,
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
)
|
|
||||||
TangemSwitch(
|
|
||||||
checked = allowance.isUnlimited,
|
|
||||||
onCheckedChange = onToggleChange,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(TangemTheme.dimens.spacing60))
|
|
||||||
|
|
||||||
PrimaryButton(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
text = stringResourceSafe(R.string.common_done),
|
|
||||||
onClick = onClickDone,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
|
||||||
|
config = TangemBottomSheetConfig(
|
||||||
|
isShown = true,
|
||||||
|
onDismissRequest = onDismiss,
|
||||||
|
content = TangemBottomSheetConfigContent.Empty,
|
||||||
|
),
|
||||||
|
containerColor = TangemTheme.colors.background.tertiary,
|
||||||
|
onBack = onBack,
|
||||||
|
title = {
|
||||||
|
TangemModalBottomSheetTitle(
|
||||||
|
title = resourceReference(R.string.wc_custom_allowance_title),
|
||||||
|
startIconRes = R.drawable.ic_back_24,
|
||||||
|
onStartClick = onBack,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(TangemTheme.colors.background.tertiary)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
) {
|
||||||
|
AmountTextField(
|
||||||
|
amountText = amountText,
|
||||||
|
onAmountChange = { amountText = it },
|
||||||
|
isEnabled = !isUnlimited,
|
||||||
|
tokenImageUrl = state.tokenImageUrl,
|
||||||
|
networkIconRes = state.networkIconRes,
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier
|
||||||
|
.clip(RoundedCornerShape(14.dp))
|
||||||
|
.background(TangemTheme.colors.background.action)
|
||||||
|
.padding(16.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResourceSafe(R.string.wc_unlimited_amount),
|
||||||
|
style = TangemTheme.typography.body1,
|
||||||
|
color = TangemTheme.colors.text.primary1,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
TangemSwitch(
|
||||||
|
checked = isUnlimited,
|
||||||
|
onCheckedChange = { isUnlimited = it },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(60.dp))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
footer = {
|
||||||
|
PrimaryButton(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.fillMaxWidth(),
|
||||||
|
text = stringResourceSafe(R.string.common_done),
|
||||||
|
onClick = { onClickDone(amount, isUnlimited) },
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AmountTextField(
|
private fun AmountTextField(
|
||||||
allowance: WcCustomAllowanceUM,
|
amountText: String,
|
||||||
onAmountChange: (String) -> Unit,
|
onAmountChange: (String) -> Unit,
|
||||||
|
isEnabled: Boolean,
|
||||||
|
tokenImageUrl: String?,
|
||||||
|
@DrawableRes networkIconRes: Int?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
.clip(RoundedCornerShape(14.dp))
|
||||||
.background(color = TangemTheme.colors.background.action)
|
.background(TangemTheme.colors.background.action)
|
||||||
.padding(
|
.padding(end = 8.dp, top = 4.dp, bottom = 4.dp)
|
||||||
end = TangemTheme.dimens.size8,
|
|
||||||
top = TangemTheme.dimens.size4,
|
|
||||||
bottom = TangemTheme.dimens.size4,
|
|
||||||
)
|
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
TextField(
|
TextField(
|
||||||
value = allowance.amountText,
|
value = amountText,
|
||||||
onValueChange = onAmountChange,
|
onValueChange = onAmountChange,
|
||||||
|
enabled = isEnabled,
|
||||||
label = {
|
label = {
|
||||||
Text(
|
Text(
|
||||||
text = stringResourceSafe(R.string.send_amount_label),
|
text = stringResourceSafe(R.string.send_amount_label),
|
||||||
|
|
@ -127,6 +162,9 @@ private fun AmountTextField(
|
||||||
unfocusedTextColor = TangemTheme.colors.text.primary1,
|
unfocusedTextColor = TangemTheme.colors.text.primary1,
|
||||||
focusedPlaceholderColor = TangemTheme.colors.text.disabled,
|
focusedPlaceholderColor = TangemTheme.colors.text.disabled,
|
||||||
unfocusedPlaceholderColor = TangemTheme.colors.text.disabled,
|
unfocusedPlaceholderColor = TangemTheme.colors.text.disabled,
|
||||||
|
disabledContainerColor = Color.Transparent,
|
||||||
|
disabledTextColor = TangemTheme.colors.text.disabled,
|
||||||
|
disabledIndicatorColor = Color.Transparent,
|
||||||
focusedIndicatorColor = Color.Transparent,
|
focusedIndicatorColor = Color.Transparent,
|
||||||
unfocusedIndicatorColor = Color.Transparent,
|
unfocusedIndicatorColor = Color.Transparent,
|
||||||
cursorColor = TangemTheme.colors.icon.primary1,
|
cursorColor = TangemTheme.colors.icon.primary1,
|
||||||
|
|
@ -134,40 +172,44 @@ private fun AmountTextField(
|
||||||
)
|
)
|
||||||
|
|
||||||
TokenWithNetworkIcon(
|
TokenWithNetworkIcon(
|
||||||
tokenIconUrl = allowance.tokenIconUrl,
|
tokenIconUrl = tokenImageUrl,
|
||||||
networkIconRes = allowance.networkIconRes,
|
networkIconRes = networkIconRes,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun TokenWithNetworkIcon(
|
private fun TokenWithNetworkIcon(
|
||||||
tokenIconUrl: String,
|
tokenIconUrl: String?,
|
||||||
@DrawableRes networkIconRes: Int,
|
@DrawableRes networkIconRes: Int?,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier.size(48.dp),
|
||||||
.size(TangemTheme.dimens.size48),
|
|
||||||
) {
|
) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
|
model = tokenIconUrl,
|
||||||
|
contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.align(Alignment.Center)
|
.align(Alignment.Center)
|
||||||
.padding(TangemTheme.dimens.spacing8),
|
.padding(8.dp),
|
||||||
model = tokenIconUrl,
|
placeholder = painterResource(R.drawable.ic_nft_placeholder_20),
|
||||||
contentDescription = null,
|
error = painterResource(R.drawable.ic_nft_placeholder_20),
|
||||||
)
|
|
||||||
Image(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopEnd)
|
|
||||||
.size(TangemTheme.dimens.size18)
|
|
||||||
.border(TangemTheme.dimens.size2, TangemTheme.colors.background.action, CircleShape)
|
|
||||||
.padding(TangemTheme.dimens.spacing2),
|
|
||||||
painter = painterResource(id = networkIconRes),
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (networkIconRes != null) {
|
||||||
|
Image(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.size(18.dp)
|
||||||
|
.border(2.dp, TangemTheme.colors.background.action, CircleShape)
|
||||||
|
.padding(2.dp),
|
||||||
|
painter = painterResource(networkIconRes),
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,10 +217,10 @@ private fun TokenWithNetworkIcon(
|
||||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO)
|
||||||
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
internal fun PreviewWcCustomAllowanceContent(
|
internal fun PreviewWcCustomAllowanceContent(
|
||||||
@PreviewParameter(WcCustomAllowanceStateProvider::class) state: WcCustomAllowanceUM,
|
@PreviewParameter(WcCustomAllowanceStateProvider::class) state: WcSpendAllowanceUM,
|
||||||
) {
|
) {
|
||||||
TangemThemePreview {
|
TangemThemePreview {
|
||||||
TangemModalBottomSheet<WcCustomAllowanceUM>(
|
TangemModalBottomSheet<WcSpendAllowanceUM>(
|
||||||
config = TangemBottomSheetConfig(
|
config = TangemBottomSheetConfig(
|
||||||
isShown = true,
|
isShown = true,
|
||||||
onDismissRequest = {},
|
onDismissRequest = {},
|
||||||
|
|
@ -196,22 +238,24 @@ internal fun PreviewWcCustomAllowanceContent(
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
WcCustomAllowanceContent(
|
WcCustomAllowanceContent(
|
||||||
allowance = state,
|
state = state,
|
||||||
onAmountChange = {},
|
onClickDone = { _, _ -> },
|
||||||
onToggleChange = {},
|
onBack = {},
|
||||||
onClickDone = {},
|
onDismiss = {},
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WcCustomAllowanceStateProvider : CollectionPreviewParameterProvider<WcCustomAllowanceUM>(
|
private class WcCustomAllowanceStateProvider : CollectionPreviewParameterProvider<WcSpendAllowanceUM>(
|
||||||
listOf(
|
listOf(
|
||||||
WcCustomAllowanceUM(
|
WcSpendAllowanceUM(
|
||||||
networkIconRes = R.drawable.img_eth_22,
|
networkIconRes = R.drawable.img_eth_22,
|
||||||
tokenIconUrl = "https://tangem.com",
|
tokenImageUrl = "https://tangem.com",
|
||||||
amountText = "100",
|
amountText = TextReference.Str("100"),
|
||||||
|
amountValue = BigDecimal("100"),
|
||||||
|
tokenSymbol = "ETH",
|
||||||
isUnlimited = false,
|
isUnlimited = false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.walletconnect.transaction.ui.approve
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
|
@ -22,13 +23,18 @@ import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllow
|
||||||
import com.tangem.features.walletconnect.transaction.ui.common.WcSmallTitleItem
|
import com.tangem.features.walletconnect.transaction.ui.common.WcSmallTitleItem
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WcSpendAllowanceItem(spendAllowance: WcSpendAllowanceUM, modifier: Modifier = Modifier) {
|
internal fun WcSpendAllowanceItem(
|
||||||
|
spendAllowance: WcSpendAllowanceUM,
|
||||||
|
onClickAllowToSpend: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.clip(RoundedCornerShape(14.dp))
|
.clip(RoundedCornerShape(14.dp))
|
||||||
.background(TangemTheme.colors.background.action)
|
.background(TangemTheme.colors.background.action)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(end = 12.dp, bottom = 12.dp),
|
.padding(end = 12.dp, bottom = 12.dp)
|
||||||
|
.clickable { onClickAllowToSpend() },
|
||||||
) {
|
) {
|
||||||
WcSmallTitleItem(R.string.wc_allow_to_spend)
|
WcSmallTitleItem(R.string.wc_allow_to_spend)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,11 @@ import com.tangem.features.walletconnect.transaction.ui.approve.WcSpendAllowance
|
||||||
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,
|
||||||
|
onClickAllowToSpend: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
|
|
@ -38,7 +42,7 @@ internal fun TransactionCheckResultsItem(item: WcSendReceiveTransactionCheckResu
|
||||||
if (item.estimatedWalletChanges != null) {
|
if (item.estimatedWalletChanges != null) {
|
||||||
WcEstimatedWalletChangesItem(item.estimatedWalletChanges)
|
WcEstimatedWalletChangesItem(item.estimatedWalletChanges)
|
||||||
} else if (item.spendAllowance != null) {
|
} else if (item.spendAllowance != null) {
|
||||||
WcSpendAllowanceItem(item.spendAllowance)
|
WcSpendAllowanceItem(item.spendAllowance, onClickAllowToSpend)
|
||||||
} else {
|
} else {
|
||||||
WcEstimatedWalletChangesNotLoadedItem()
|
WcEstimatedWalletChangesNotLoadedItem()
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +61,7 @@ private fun TransactionCheckResultsItemPreview(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(TangemTheme.colors.background.tertiary),
|
.background(TangemTheme.colors.background.tertiary),
|
||||||
) {
|
) {
|
||||||
TransactionCheckResultsItem(item = item)
|
TransactionCheckResultsItem(item = item, {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import com.domain.blockaid.models.transaction.SimulationResult
|
||||||
import com.domain.blockaid.models.transaction.ValidationResult
|
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.blockchain.common.Amount
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
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
|
||||||
|
|
@ -21,21 +22,20 @@ import javax.inject.Inject
|
||||||
|
|
||||||
internal const val DECIMALS_AMOUNT = 2
|
internal const val DECIMALS_AMOUNT = 2
|
||||||
|
|
||||||
|
@Suppress("CyclomaticComplexMethod")
|
||||||
internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor(
|
internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor(
|
||||||
private val estimatedWalletChangeUMConverter: WcEstimatedWalletChangeUMConverter,
|
private val estimatedWalletChangeUMConverter: WcEstimatedWalletChangeUMConverter,
|
||||||
private val spendAllowanceUMConverter: WcSpendAllowanceUMConverter,
|
private val spendAllowanceUMConverter: WcSpendAllowanceUMConverter,
|
||||||
) :
|
) : Converter<WcSendAndReceiveBlockAidUiConverter.Input, WcSendReceiveTransactionCheckResultsUM> {
|
||||||
Converter<CheckTransactionResult, WcSendReceiveTransactionCheckResultsUM> {
|
override fun convert(value: Input): WcSendReceiveTransactionCheckResultsUM {
|
||||||
override fun convert(value: CheckTransactionResult): WcSendReceiveTransactionCheckResultsUM {
|
val description = value.result.description
|
||||||
return WcSendReceiveTransactionCheckResultsUM(
|
return WcSendReceiveTransactionCheckResultsUM(
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
notificationText = when (value.validation) {
|
notificationText = when (value.result.validation) {
|
||||||
ValidationResult.SAFE, ValidationResult.FAILED_TO_VALIDATE -> null
|
ValidationResult.SAFE, ValidationResult.FAILED_TO_VALIDATE -> null
|
||||||
// TODO("Add text after approve with designer")
|
ValidationResult.UNSAFE -> if (!description.isNullOrEmpty()) TextReference.Str(description) else null
|
||||||
ValidationResult.UNSAFE ->
|
|
||||||
TextReference.Str("The transaction approves tokens to a known malicious address")
|
|
||||||
},
|
},
|
||||||
estimatedWalletChanges = (value.simulation as? SimulationResult.Success)?.data?.let { data ->
|
estimatedWalletChanges = (value.result.simulation as? SimulationResult.Success)?.data?.let { data ->
|
||||||
when (data) {
|
when (data) {
|
||||||
is SimulationData.Approve -> null
|
is SimulationData.Approve -> null
|
||||||
is SimulationData.SendAndReceive -> {
|
is SimulationData.SendAndReceive -> {
|
||||||
|
|
@ -82,15 +82,21 @@ internal class WcSendAndReceiveBlockAidUiConverter @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spendAllowance = (value.simulation as? SimulationResult.Success)?.data?.let { data ->
|
spendAllowance = (value.result.simulation as? SimulationResult.Success)?.data?.let { data ->
|
||||||
when (data) {
|
when (data) {
|
||||||
is SimulationData.SendAndReceive -> null
|
is SimulationData.SendAndReceive -> null
|
||||||
is SimulationData.Approve -> data.approvedAmounts.map { spendAllowanceUMConverter.convert(it) }
|
is SimulationData.Approve -> value.approvedAmount?.let {
|
||||||
.firstOrNull()
|
data.approvedAmounts.map { spendAllowanceUMConverter.convert(it) }.firstOrNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Input(
|
||||||
|
val result: CheckTransactionResult,
|
||||||
|
val approvedAmount: Amount?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun BigDecimal.amountText() = format { crypto("", DECIMALS_AMOUNT) }
|
internal fun BigDecimal.amountText() = format { crypto("", DECIMALS_AMOUNT) }
|
||||||
|
|
@ -2,6 +2,7 @@ package com.tangem.features.walletconnect.transaction.ui.blockaid
|
||||||
|
|
||||||
import com.domain.blockaid.models.transaction.simultation.ApprovedAmount
|
import com.domain.blockaid.models.transaction.simultation.ApprovedAmount
|
||||||
import com.tangem.core.ui.extensions.TextReference
|
import com.tangem.core.ui.extensions.TextReference
|
||||||
|
import com.tangem.core.ui.extensions.getActiveIconRes
|
||||||
import com.tangem.features.walletconnect.impl.R
|
import com.tangem.features.walletconnect.impl.R
|
||||||
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
|
import com.tangem.features.walletconnect.transaction.entity.approve.WcSpendAllowanceUM
|
||||||
import com.tangem.utils.converter.Converter
|
import com.tangem.utils.converter.Converter
|
||||||
|
|
@ -10,12 +11,15 @@ import javax.inject.Inject
|
||||||
internal class WcSpendAllowanceUMConverter @Inject constructor() : Converter<ApprovedAmount, WcSpendAllowanceUM> {
|
internal class WcSpendAllowanceUMConverter @Inject constructor() : Converter<ApprovedAmount, WcSpendAllowanceUM> {
|
||||||
|
|
||||||
override fun convert(value: ApprovedAmount) = WcSpendAllowanceUM(
|
override fun convert(value: ApprovedAmount) = WcSpendAllowanceUM(
|
||||||
|
amountValue = value.approvedAmount,
|
||||||
amountText = if (value.isUnlimited) {
|
amountText = if (value.isUnlimited) {
|
||||||
TextReference.Res(R.string.wc_common_unlimited)
|
TextReference.Res(R.string.wc_common_unlimited)
|
||||||
} else {
|
} else {
|
||||||
TextReference.Str(value.approvedAmount.amountText())
|
TextReference.Str(value.approvedAmount.amountText())
|
||||||
},
|
},
|
||||||
|
isUnlimited = value.isUnlimited,
|
||||||
tokenSymbol = value.tokenInfo.symbol,
|
tokenSymbol = value.tokenInfo.symbol,
|
||||||
tokenImageUrl = value.tokenInfo.logoUrl,
|
tokenImageUrl = value.tokenInfo.logoUrl,
|
||||||
|
networkIconRes = value.tokenInfo.chainId?.toString()?.let { getActiveIconRes(it) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -46,6 +46,7 @@ internal fun WcSendTransactionModalBottomSheet(
|
||||||
onClickTransactionRequest: () -> Unit,
|
onClickTransactionRequest: () -> Unit,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
|
onClickAllowToSpend: () -> Unit,
|
||||||
) {
|
) {
|
||||||
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
|
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
|
||||||
config = TangemBottomSheetConfig(
|
config = TangemBottomSheetConfig(
|
||||||
|
|
@ -92,7 +93,7 @@ internal fun WcSendTransactionModalBottomSheet(
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.padding(top = 16.dp)) {
|
Column(modifier = Modifier.padding(top = 16.dp)) {
|
||||||
if (state.estimatedWalletChanges != null) {
|
if (state.estimatedWalletChanges != null) {
|
||||||
TransactionCheckResultsItem(state.estimatedWalletChanges)
|
TransactionCheckResultsItem(state.estimatedWalletChanges, onClickAllowToSpend)
|
||||||
}
|
}
|
||||||
Spacer(Modifier.height(16.dp))
|
Spacer(Modifier.height(16.dp))
|
||||||
WcSendTransactionItems(
|
WcSendTransactionItems(
|
||||||
|
|
@ -140,7 +141,7 @@ private fun WcSendTransactionBottomSheetPreview(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
WcSendTransactionModalBottomSheet(state, {}, {}, {})
|
WcSendTransactionModalBottomSheet(state, {}, {}, {}, {})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue