Updated on 2026-08-14
This commit is contained in:
parent
c8a163fd0a
commit
65ace6c5f2
21 changed files with 349 additions and 39 deletions
|
|
@ -38,5 +38,23 @@ internal class AlertsComponent(
|
|||
|
||||
@Serializable
|
||||
data class WcDisconnected(override val onDismiss: () -> Unit) : AlertType()
|
||||
|
||||
@Serializable
|
||||
data class TangemUnsupportedNetwork(
|
||||
val network: String,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : AlertType()
|
||||
|
||||
@Serializable
|
||||
data class RequiredAddNetwork(
|
||||
val network: String,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : AlertType()
|
||||
|
||||
@Serializable
|
||||
data class RequiredReconnectWithNetwork(
|
||||
val network: String,
|
||||
override val onDismiss: () -> Unit,
|
||||
) : AlertType()
|
||||
}
|
||||
}
|
||||
|
|
@ -18,8 +18,10 @@ import com.tangem.features.send.v2.api.FeeSelectorBlockComponent
|
|||
import com.tangem.features.send.v2.api.FeeSelectorComponent
|
||||
import com.tangem.features.walletconnect.components.WcRoutingComponent
|
||||
import com.tangem.features.walletconnect.connections.components.AlertsComponent
|
||||
import com.tangem.features.walletconnect.connections.components.AlertsComponent.AlertType.*
|
||||
import com.tangem.features.walletconnect.connections.components.WcPairComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.chain.WcAddNetworkContainerComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.chain.WcSwitchNetworkComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
|
||||
import com.tangem.features.walletconnect.transaction.components.send.WcSendTransactionContainerComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.sign.WcSignTransactionContainerComponent
|
||||
|
|
@ -71,6 +73,10 @@ internal class DefaultWcRoutingComponent @AssistedInject constructor(
|
|||
appComponentContext = childContext,
|
||||
params = WcTransactionModelParams(config.rawRequest),
|
||||
)
|
||||
is WcInnerRoute.SwitchNetwork -> WcSwitchNetworkComponent(
|
||||
appComponentContext = childContext,
|
||||
params = WcTransactionModelParams(config.rawRequest),
|
||||
)
|
||||
is WcInnerRoute.Send -> WcSendTransactionContainerComponent(
|
||||
appComponentContext = childContext,
|
||||
params = WcTransactionModelParams(config.rawRequest),
|
||||
|
|
@ -88,13 +94,31 @@ internal class DefaultWcRoutingComponent @AssistedInject constructor(
|
|||
is WcInnerRoute.UnsupportedMethodAlert -> AlertsComponent(
|
||||
childContext,
|
||||
AlertsComponent.Params(
|
||||
alertType = AlertsComponent.AlertType.UnsupportedMethod { model.innerRouter.pop() },
|
||||
alertType = UnsupportedMethod { model.innerRouter.pop() },
|
||||
),
|
||||
)
|
||||
is WcInnerRoute.WcDappDisconnected -> AlertsComponent(
|
||||
childContext,
|
||||
AlertsComponent.Params(
|
||||
alertType = AlertsComponent.AlertType.WcDisconnected { model.innerRouter.pop() },
|
||||
alertType = WcDisconnected { model.innerRouter.pop() },
|
||||
),
|
||||
)
|
||||
is WcInnerRoute.TangemUnsupportedNetwork -> AlertsComponent(
|
||||
childContext,
|
||||
AlertsComponent.Params(
|
||||
alertType = TangemUnsupportedNetwork(config.networkName) { model.innerRouter.pop() },
|
||||
),
|
||||
)
|
||||
is WcInnerRoute.RequiredAddNetwork -> AlertsComponent(
|
||||
childContext,
|
||||
AlertsComponent.Params(
|
||||
alertType = RequiredAddNetwork(config.networkName) { model.innerRouter.pop() },
|
||||
),
|
||||
)
|
||||
is WcInnerRoute.RequiredReconnectWithNetwork -> AlertsComponent(
|
||||
childContext,
|
||||
AlertsComponent.Params(
|
||||
alertType = RequiredReconnectWithNetwork(config.networkName) { model.innerRouter.pop() },
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ internal sealed interface WcInnerRoute : Route {
|
|||
@Serializable
|
||||
data class AddNetwork(override val rawRequest: WcSdkSessionRequest) : Method
|
||||
|
||||
@Serializable
|
||||
data class SwitchNetwork(override val rawRequest: WcSdkSessionRequest) : Method
|
||||
|
||||
@Serializable
|
||||
data class Pair(val request: WcPairRequest) : WcInnerRoute
|
||||
|
||||
|
|
@ -30,4 +33,13 @@ internal sealed interface WcInnerRoute : Route {
|
|||
|
||||
@Serializable
|
||||
data object WcDappDisconnected : WcInnerRoute
|
||||
|
||||
@Serializable
|
||||
data class TangemUnsupportedNetwork(val networkName: String) : WcInnerRoute
|
||||
|
||||
@Serializable
|
||||
data class RequiredAddNetwork(val networkName: String) : WcInnerRoute
|
||||
|
||||
@Serializable
|
||||
data class RequiredReconnectWithNetwork(val networkName: String) : WcInnerRoute
|
||||
}
|
||||
|
|
@ -51,6 +51,8 @@ internal class WcRoutingModel @Inject constructor(
|
|||
-> WcInnerRoute.SignMessage(rawRequest)
|
||||
WcEthMethodName.AddEthereumChain,
|
||||
-> WcInnerRoute.AddNetwork(rawRequest)
|
||||
WcEthMethodName.SwitchEthereumChain,
|
||||
-> WcInnerRoute.SwitchNetwork(rawRequest)
|
||||
WcEthMethodName.SignTransaction,
|
||||
WcEthMethodName.SendTransaction,
|
||||
WcSolanaMethodName.SignTransaction,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,11 @@ private fun ButtonsContainer(alert: AlertsComponent.AlertType, modifier: Modifie
|
|||
) {
|
||||
val buttonsModifier = Modifier.fillMaxWidth()
|
||||
when (alert) {
|
||||
is AlertsComponent.AlertType.UnsupportedMethod -> SecondaryButton(
|
||||
is AlertsComponent.AlertType.UnsupportedMethod,
|
||||
is AlertsComponent.AlertType.RequiredAddNetwork,
|
||||
is AlertsComponent.AlertType.RequiredReconnectWithNetwork,
|
||||
is AlertsComponent.AlertType.TangemUnsupportedNetwork,
|
||||
-> SecondaryButton(
|
||||
modifier = buttonsModifier,
|
||||
onClick = alert.onDismiss,
|
||||
text = stringResourceSafe(R.string.balance_hidden_got_it_button),
|
||||
|
|
@ -105,16 +109,28 @@ private fun ButtonsContainer(alert: AlertsComponent.AlertType, modifier: Modifie
|
|||
private fun AlertIcon(alert: AlertsComponent.AlertType, modifier: Modifier = Modifier) {
|
||||
val color = when (alert) {
|
||||
is AlertsComponent.AlertType.WcDisconnected -> TangemTheme.colors.icon.informative
|
||||
is AlertsComponent.AlertType.UnsupportedMethod -> TangemTheme.colors.icon.attention
|
||||
is AlertsComponent.AlertType.UnsupportedMethod,
|
||||
is AlertsComponent.AlertType.RequiredAddNetwork,
|
||||
is AlertsComponent.AlertType.RequiredReconnectWithNetwork,
|
||||
is AlertsComponent.AlertType.TangemUnsupportedNetwork,
|
||||
-> TangemTheme.colors.icon.attention
|
||||
}
|
||||
|
||||
@DrawableRes val drawableId = when (alert) {
|
||||
is AlertsComponent.AlertType.WcDisconnected -> R.drawable.ic_wallet_connect_24
|
||||
is AlertsComponent.AlertType.UnsupportedMethod -> R.drawable.img_attention_20
|
||||
is AlertsComponent.AlertType.UnsupportedMethod,
|
||||
is AlertsComponent.AlertType.RequiredAddNetwork,
|
||||
is AlertsComponent.AlertType.RequiredReconnectWithNetwork,
|
||||
is AlertsComponent.AlertType.TangemUnsupportedNetwork,
|
||||
-> R.drawable.img_attention_20
|
||||
}
|
||||
val iconTint = when (alert) {
|
||||
is AlertsComponent.AlertType.WcDisconnected -> color
|
||||
is AlertsComponent.AlertType.UnsupportedMethod -> Color.Unspecified
|
||||
is AlertsComponent.AlertType.UnsupportedMethod,
|
||||
is AlertsComponent.AlertType.RequiredAddNetwork,
|
||||
is AlertsComponent.AlertType.RequiredReconnectWithNetwork,
|
||||
is AlertsComponent.AlertType.TangemUnsupportedNetwork,
|
||||
-> Color.Unspecified
|
||||
}
|
||||
Box(
|
||||
modifier = modifier
|
||||
|
|
@ -138,6 +154,9 @@ private fun AlertContentTitle(alert: AlertsComponent.AlertType, modifier: Modifi
|
|||
@StringRes val titleRes: Int = when (alert) {
|
||||
is AlertsComponent.AlertType.WcDisconnected -> R.string.wc_alert_session_disconnected_title
|
||||
is AlertsComponent.AlertType.UnsupportedMethod -> R.string.wc_alert_unsupported_method_title
|
||||
is AlertsComponent.AlertType.RequiredAddNetwork -> R.string.wc_alert_add_network_to_portfolio_title
|
||||
is AlertsComponent.AlertType.RequiredReconnectWithNetwork -> R.string.wc_alert_network_not_connected_title
|
||||
is AlertsComponent.AlertType.TangemUnsupportedNetwork -> R.string.wc_alert_unsupported_network_title
|
||||
}
|
||||
Text(
|
||||
modifier = modifier,
|
||||
|
|
@ -157,6 +176,18 @@ private fun AlertContentDescription(alert: AlertsComponent.AlertType, modifier:
|
|||
is AlertsComponent.AlertType.UnsupportedMethod -> stringResourceSafe(
|
||||
R.string.wc_alert_unsupported_method_description,
|
||||
)
|
||||
is AlertsComponent.AlertType.RequiredAddNetwork -> stringResourceSafe(
|
||||
R.string.wc_alert_unsupported_method_description,
|
||||
alert.network,
|
||||
)
|
||||
is AlertsComponent.AlertType.RequiredReconnectWithNetwork -> stringResourceSafe(
|
||||
R.string.wc_alert_network_not_connected_description,
|
||||
alert.network,
|
||||
)
|
||||
is AlertsComponent.AlertType.TangemUnsupportedNetwork -> stringResourceSafe(
|
||||
R.string.wc_alert_unsupported_network_description,
|
||||
alert.network,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = modifier,
|
||||
|
|
@ -188,5 +219,8 @@ private class AlertTypesProvider : CollectionPreviewParameterProvider<AlertsComp
|
|||
collection = listOf(
|
||||
AlertsComponent.AlertType.WcDisconnected(onDismiss = {}),
|
||||
AlertsComponent.AlertType.UnsupportedMethod(onDismiss = {}),
|
||||
AlertsComponent.AlertType.TangemUnsupportedNetwork(network = "Solana", onDismiss = {}),
|
||||
AlertsComponent.AlertType.RequiredAddNetwork(network = "Solana", onDismiss = {}),
|
||||
AlertsComponent.AlertType.RequiredReconnectWithNetwork(network = "Solana", onDismiss = {}),
|
||||
),
|
||||
)
|
||||
|
|
@ -7,6 +7,7 @@ import com.tangem.features.walletconnect.connections.routing.WcRoutingModel
|
|||
import com.tangem.features.walletconnect.transaction.model.WcAddNetworkModel
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSendTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSwitchNetworkModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -57,6 +58,11 @@ internal interface WalletConnectModelModule {
|
|||
@ClassKey(WcAddNetworkModel::class)
|
||||
fun bindWcAddNetworkModel(model: WcAddNetworkModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WcSwitchNetworkModel::class)
|
||||
fun bindWcSwitchNetworkModel(model: WcSwitchNetworkModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WcSendTransactionModel::class)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.features.walletconnect.transaction.components.chain
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSwitchNetworkModel
|
||||
|
||||
internal class WcSwitchNetworkComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: WcTransactionModelParams,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: WcSwitchNetworkModel = getOrCreateModel(params = params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
}
|
||||
}
|
||||
|
|
@ -12,5 +12,9 @@ internal object WcHandleMethodErrorConverter :
|
|||
is HandleMethodError.UnknownError,
|
||||
-> WcInnerRoute.UnsupportedMethodAlert
|
||||
HandleMethodError.UnknownSession -> WcInnerRoute.WcDappDisconnected
|
||||
|
||||
is HandleMethodError.NotAddedNetwork -> WcInnerRoute.RequiredAddNetwork(value.networkName)
|
||||
is HandleMethodError.RequiredNetwork -> WcInnerRoute.RequiredReconnectWithNetwork(value.networkName)
|
||||
is HandleMethodError.TangemUnsupportedNetwork -> WcInnerRoute.TangemUnsupportedNetwork(value.unsupportedNetwork)
|
||||
}
|
||||
}
|
||||
|
|
@ -57,22 +57,27 @@ internal class WcAddNetworkModel @Inject constructor(
|
|||
.onLeft { router.push(WcHandleMethodErrorConverter.convert(it)) }
|
||||
.getOrNull() ?: return@launch
|
||||
sendSignatureReceivedAnalytics(useCase)
|
||||
_uiState.emit(
|
||||
wcAddEthereumChainUMConverter.convert(
|
||||
WcAddEthereumChainUMConverter.Input(
|
||||
useCase = useCase,
|
||||
actions = WcTransactionActionsUM(
|
||||
onShowVerifiedAlert = ::showVerifiedAlert,
|
||||
onDismiss = { cancel(useCase) },
|
||||
onSign = { sign(useCase) },
|
||||
onCopy = { copyData(useCase.rawSdkRequest.request.params) },
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
val either = useCase.invoke()
|
||||
either
|
||||
.onLeft { router.push(WcHandleMethodErrorConverter.convert(it)) }
|
||||
.map { showUI() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun showUI() {
|
||||
_uiState.value = wcAddEthereumChainUMConverter.convert(
|
||||
WcAddEthereumChainUMConverter.Input(
|
||||
useCase = useCase,
|
||||
actions = WcTransactionActionsUM(
|
||||
onShowVerifiedAlert = ::showVerifiedAlert,
|
||||
onDismiss = { cancel(useCase) },
|
||||
onSign = { sign(useCase) },
|
||||
onCopy = { copyData(useCase.rawSdkRequest.request.params) },
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
_uiState.value?.transaction?.onDismiss?.invoke() ?: router.pop()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.tangem.features.walletconnect.transaction.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
|
||||
import com.tangem.domain.walletconnect.model.HandleMethodError
|
||||
import com.tangem.domain.walletconnect.usecase.method.WcSwitchNetworkUseCase
|
||||
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionModelParams
|
||||
import com.tangem.features.walletconnect.transaction.converter.WcHandleMethodErrorConverter
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class WcSwitchNetworkModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val useCaseFactory: WcRequestUseCaseFactory,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<WcTransactionModelParams>()
|
||||
|
||||
init {
|
||||
modelScope.launch {
|
||||
val useCase = useCaseFactory.createUseCase<WcSwitchNetworkUseCase>(params.rawRequest)
|
||||
.onLeft { showErrorDialog(it) }
|
||||
.getOrNull() ?: return@launch
|
||||
val either = useCase.invoke()
|
||||
useCase.reject()
|
||||
either
|
||||
.onLeft { showErrorDialog(it) }
|
||||
.map { showErrorDialog(HandleMethodError.RequiredNetwork(it.network.name)) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun showErrorDialog(error: HandleMethodError) {
|
||||
router.push(WcHandleMethodErrorConverter.convert(error))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue