Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-16 14:09:53 +05:00
parent cd1ad461a4
commit 4ef10e6600
9 changed files with 95 additions and 42 deletions

View file

@ -66,7 +66,7 @@ internal class WcSelectNetworksComponent(
}
interface ModelCallback {
fun onNetworksSelected(selectedNetworks: Set<Network.RawID>)
fun onNetworksSelected(selectedNetworks: Set<Network>)
}
data class WcSelectNetworksParams(
@ -74,7 +74,7 @@ internal class WcSelectNetworksComponent(
val requiredNetworks: Set<Network>,
val availableNetworks: Set<Network>,
val notAddedNetworks: Set<Network>,
val enabledAvailableNetworks: Set<Network.RawID>,
val enabledAvailableNetworks: Set<Network>,
val onDismiss: () -> Unit,
val callback: ModelCallback,
)
@ -87,8 +87,6 @@ private fun WcSelectNetworksBS(
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
) {
if (state.required.isEmpty()) return // required can/must not be empty
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
config = TangemBottomSheetConfig(
isShown = true,
@ -117,7 +115,6 @@ private fun WcSelectNetworksBS(
.fillMaxWidth(),
text = "Done",
onClick = state.onDone,
enabled = state.missing.isEmpty(),
)
},
)

View file

@ -26,10 +26,7 @@ import com.tangem.features.walletconnect.connections.components.WcSelectNetworks
import com.tangem.features.walletconnect.connections.components.WcSelectWalletComponent
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
import com.tangem.features.walletconnect.connections.entity.WcPrimaryButtonConfig
import com.tangem.features.walletconnect.connections.model.transformers.WcAppInfoTransformer
import com.tangem.features.walletconnect.connections.model.transformers.WcAppInfoWalletChangedTransformer
import com.tangem.features.walletconnect.connections.model.transformers.WcConnectButtonProgressTransformer
import com.tangem.features.walletconnect.connections.model.transformers.WcDAppVerifiedStateConverter
import com.tangem.features.walletconnect.connections.model.transformers.*
import com.tangem.features.walletconnect.connections.routes.WcAppInfoRoutes
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
@ -67,7 +64,7 @@ internal class WcPairModel @Inject constructor(
MutableStateFlow(getWalletsUseCase.invokeSync().first { it.walletId == params.userWalletId })
private var proposalNetwork by Delegates.notNull<WcSessionProposal.ProposalNetwork>()
private var sessionProposal by Delegates.notNull<WcSessionProposal>()
private val additionallyEnabledNetworks = mutableSetOf<Network.RawID>()
private var additionallyEnabledNetworks = setOf<Network>()
private val dAppVerifiedStateConverter = WcDAppVerifiedStateConverter(onVerifiedClick = ::showVerifiedAlert)
val appInfoUiState: StateFlow<WcAppInfoUM>
@ -102,7 +99,7 @@ internal class WcPairModel @Inject constructor(
is WcPairState.Proposal -> {
sessionProposal = pairState.dAppSession
proposalNetwork = sessionProposal.proposalNetwork.getValue(selectedUserWalletFlow.value)
proposalNetwork.available.mapTo(additionallyEnabledNetworks) { it.id.rawId }
additionallyEnabledNetworks = proposalNetwork.available
appInfoUiState.transformerUpdate(
WcAppInfoTransformer(
dAppSession = sessionProposal,
@ -127,6 +124,7 @@ internal class WcPairModel @Inject constructor(
},
userWallet = selectedUserWalletFlow.value,
proposalNetwork = proposalNetwork,
additionallyEnabledNetworks = additionallyEnabledNetworks,
),
)
}
@ -154,7 +152,7 @@ internal class WcPairModel @Inject constructor(
private fun connect() {
val enabledAvailableNetworks =
proposalNetwork.available.filter { network -> network.id.rawId in additionallyEnabledNetworks }
proposalNetwork.available.filter { network -> network in additionallyEnabledNetworks }
wcPairUseCase.approve(
WcSessionApprove(
wallet = selectedUserWalletFlow.value,
@ -179,14 +177,25 @@ internal class WcPairModel @Inject constructor(
val selectedUserWallet = sessionProposal.proposalNetwork.keys.first { it.walletId == userWalletId }
proposalNetwork = sessionProposal.proposalNetwork.getValue(selectedUserWallet)
selectedUserWalletFlow.update { selectedUserWallet }
appInfoUiState.transformerUpdate(WcAppInfoWalletChangedTransformer(selectedUserWallet, proposalNetwork))
additionallyEnabledNetworks.clear()
proposalNetwork.available.mapTo(additionallyEnabledNetworks) { it.id.rawId }
additionallyEnabledNetworks = proposalNetwork.available
appInfoUiState.transformerUpdate(
WcAppInfoWalletChangedTransformer(
selectedUserWallet = selectedUserWallet,
proposalNetwork = proposalNetwork,
additionallyEnabledNetworks = additionallyEnabledNetworks,
),
)
}
override fun onNetworksSelected(selectedNetworks: Set<Network.RawID>) {
additionallyEnabledNetworks.clear()
additionallyEnabledNetworks.addAll(selectedNetworks)
override fun onNetworksSelected(selectedNetworks: Set<Network>) {
additionallyEnabledNetworks = selectedNetworks
appInfoUiState.transformerUpdate(
WcNetworksSelectedTransformer(
missingNetworks = proposalNetwork.missingRequired,
requiredNetworks = proposalNetwork.required,
additionallyEnabledNetworks = additionallyEnabledNetworks,
),
)
}
private fun createLoadingState(): WcAppInfoUM.Loading {

View file

@ -29,7 +29,7 @@ internal class WcSelectNetworksModel @Inject constructor(
) : Model() {
private val params = paramsContainer.require<WcSelectNetworksParams>()
private val additionallyEnabledNetworks = MutableStateFlow<Set<Network.RawID>>(
private val additionallyEnabledNetworks = MutableStateFlow<Set<Network>>(
filterAdditionallyEnabledNetworks(
availableNetworks = params.availableNetworks,
additionallyEnabledNetworks = params.enabledAvailableNetworks,
@ -39,11 +39,11 @@ internal class WcSelectNetworksModel @Inject constructor(
val state: StateFlow<WcSelectNetworksUM>
field = MutableStateFlow(getInitialState())
private fun onCheckedChange(isChecked: Boolean, networkId: String) {
private fun onCheckedChange(isChecked: Boolean, network: Network) {
additionallyEnabledNetworks.update {
if (isChecked) it.plus(Network.RawID(networkId)) else it.minus(Network.RawID(networkId))
if (isChecked) it.plus(network) else it.minus(network)
}
state.update(WcSelectNetworksCheckedTransformer(networkId, isChecked))
state.update(WcSelectNetworksCheckedTransformer(network = network, isChecked = isChecked))
}
private fun onDone() {
@ -53,12 +53,9 @@ internal class WcSelectNetworksModel @Inject constructor(
private fun filterAdditionallyEnabledNetworks(
availableNetworks: Set<Network>,
additionallyEnabledNetworks: Set<Network.RawID>,
): Set<Network.RawID> {
return availableNetworks
.asSequence()
.filter { it.id.rawId in additionallyEnabledNetworks }
.mapTo(hashSetOf()) { it.id.rawId }
additionallyEnabledNetworks: Set<Network>,
): Set<Network> {
return availableNetworks.filterTo(hashSetOf()) { it in additionallyEnabledNetworks }
}
private fun getInitialState(): WcSelectNetworksUM {
@ -85,8 +82,8 @@ internal class WcSelectNetworksModel @Inject constructor(
icon = network.iconResId,
name = network.name,
symbol = network.currencySymbol,
checked = network.id.rawId in additionallyEnabledNetworks.value,
onCheckedChange = { onCheckedChange(it, network.rawId) },
checked = network in additionallyEnabledNetworks.value,
onCheckedChange = { onCheckedChange(it, network) },
)
}.toImmutableList(),
notAdded = params.notAddedNetworks.map { network ->

View file

@ -1,6 +1,7 @@
package com.tangem.features.walletconnect.connections.model.transformers
import com.domain.blockaid.models.dapp.CheckDAppResult
import com.tangem.domain.models.network.Network
import com.tangem.domain.walletconnect.model.WcSessionProposal
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.walletconnect.connections.entity.WcAppInfoSecurityNotification
@ -18,6 +19,7 @@ internal class WcAppInfoTransformer(
private val onNetworksClick: () -> Unit,
private val userWallet: UserWallet,
private val proposalNetwork: WcSessionProposal.ProposalNetwork,
private val additionallyEnabledNetworks: Set<Network>,
) : Transformer<WcAppInfoUM> {
override fun transform(prevState: WcAppInfoUM): WcAppInfoUM {
@ -31,7 +33,13 @@ internal class WcAppInfoTransformer(
notification = createNotification(dAppSession.securityStatus),
walletName = userWallet.name,
onWalletClick = onWalletClick,
networksInfo = WcNetworksInfoConverter.convert(proposalNetwork),
networksInfo = WcNetworksInfoConverter.convert(
value = WcNetworksInfoConverter.Input(
missingNetworks = proposalNetwork.missingRequired,
requiredNetworks = proposalNetwork.required,
additionallyEnabledNetworks = additionallyEnabledNetworks,
),
),
onNetworksClick = onNetworksClick,
connectButtonConfig = WcPrimaryButtonConfig(
showProgress = false,

View file

@ -1,5 +1,6 @@
package com.tangem.features.walletconnect.connections.model.transformers
import com.tangem.domain.models.network.Network
import com.tangem.domain.walletconnect.model.WcSessionProposal
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
@ -8,12 +9,19 @@ import com.tangem.utils.transformer.Transformer
internal class WcAppInfoWalletChangedTransformer(
private val selectedUserWallet: UserWallet,
private val proposalNetwork: WcSessionProposal.ProposalNetwork,
private val additionallyEnabledNetworks: Set<Network>,
) : Transformer<WcAppInfoUM> {
override fun transform(prevState: WcAppInfoUM): WcAppInfoUM {
val contentState = prevState as? WcAppInfoUM.Content ?: return prevState
return contentState.copy(
walletName = selectedUserWallet.name,
networksInfo = WcNetworksInfoConverter.convert(proposalNetwork),
networksInfo = WcNetworksInfoConverter.convert(
WcNetworksInfoConverter.Input(
missingNetworks = proposalNetwork.missingRequired,
requiredNetworks = proposalNetwork.required,
additionallyEnabledNetworks = additionallyEnabledNetworks,
),
),
connectButtonConfig = prevState.connectButtonConfig.copy(
enabled = proposalNetwork.missingRequired.isEmpty(),
),

View file

@ -1,22 +1,21 @@
package com.tangem.features.walletconnect.connections.model.transformers
import com.tangem.core.ui.extensions.iconResId
import com.tangem.domain.walletconnect.model.WcSessionProposal
import com.tangem.domain.models.network.Network
import com.tangem.features.walletconnect.connections.entity.WcNetworkInfoItem
import com.tangem.features.walletconnect.connections.entity.WcNetworksInfo
import com.tangem.utils.converter.Converter
import kotlinx.collections.immutable.toImmutableList
internal object WcNetworksInfoConverter : Converter<WcSessionProposal.ProposalNetwork, WcNetworksInfo> {
override fun convert(value: WcSessionProposal.ProposalNetwork): WcNetworksInfo {
return if (value.missingRequired.isNotEmpty()) {
internal object WcNetworksInfoConverter : Converter<WcNetworksInfoConverter.Input, WcNetworksInfo> {
override fun convert(value: Input): WcNetworksInfo {
return if (value.missingNetworks.isNotEmpty()) {
WcNetworksInfo.MissingRequiredNetworkInfo(
networks = value.missingRequired
.joinToString { it.name },
networks = value.missingNetworks.joinToString { it.name },
)
} else {
WcNetworksInfo.ContainsAllRequiredNetworks(
items = (value.required + value.available)
items = (value.requiredNetworks + value.additionallyEnabledNetworks)
.map {
WcNetworkInfoItem.Required(
id = it.rawId,
@ -29,4 +28,10 @@ internal object WcNetworksInfoConverter : Converter<WcSessionProposal.ProposalNe
)
}
}
data class Input(
val missingNetworks: Set<Network>,
val requiredNetworks: Set<Network>,
val additionallyEnabledNetworks: Set<Network>,
)
}

View file

@ -0,0 +1,28 @@
package com.tangem.features.walletconnect.connections.model.transformers
import com.tangem.domain.models.network.Network
import com.tangem.features.walletconnect.connections.entity.WcAppInfoUM
import com.tangem.utils.transformer.Transformer
internal class WcNetworksSelectedTransformer(
private val missingNetworks: Set<Network>,
private val requiredNetworks: Set<Network>,
private val additionallyEnabledNetworks: Set<Network>,
) : Transformer<WcAppInfoUM> {
override fun transform(prevState: WcAppInfoUM): WcAppInfoUM {
val contentState = prevState as? WcAppInfoUM.Content ?: return prevState
return contentState.copy(
connectButtonConfig = contentState.connectButtonConfig.copy(
enabled = missingNetworks.isEmpty() &&
(requiredNetworks.isNotEmpty() || additionallyEnabledNetworks.isNotEmpty()),
),
networksInfo = WcNetworksInfoConverter.convert(
value = WcNetworksInfoConverter.Input(
missingNetworks = missingNetworks,
requiredNetworks = requiredNetworks,
additionallyEnabledNetworks = additionallyEnabledNetworks,
),
),
)
}
}

View file

@ -1,17 +1,18 @@
package com.tangem.features.walletconnect.connections.model.transformers
import com.tangem.domain.models.network.Network
import com.tangem.features.walletconnect.connections.entity.WcSelectNetworksUM
import com.tangem.utils.transformer.Transformer
import kotlinx.collections.immutable.toImmutableList
internal class WcSelectNetworksCheckedTransformer(
private val networkId: String,
private val network: Network,
private val isChecked: Boolean,
) : Transformer<WcSelectNetworksUM> {
override fun transform(prevState: WcSelectNetworksUM): WcSelectNetworksUM {
return prevState.copy(
available = prevState.available
.map { item -> if (item.id == networkId) item.copy(checked = isChecked) else item }
.map { item -> if (item.id == network.rawId) item.copy(checked = isChecked) else item }
.toImmutableList(),
)
}

View file

@ -21,7 +21,7 @@ internal sealed class WcAppInfoRoutes : TangemBottomSheetConfigContent, Route {
val missingRequiredNetworks: Set<Network>,
val requiredNetworks: Set<Network>,
val availableNetworks: Set<Network>,
val enabledAvailableNetworks: Set<Network.RawID>,
val enabledAvailableNetworks: Set<Network>,
val notAddedNetworks: Set<Network>,
) : WcAppInfoRoutes()