Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-05 16:58:27 +07:00
parent 3de1deb8ae
commit 69b90910a7
9 changed files with 46 additions and 27 deletions

View file

@ -9,6 +9,8 @@ import com.reown.walletkit.client.Wallet
import com.reown.walletkit.client.WalletKit
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.data.walletconnect.pair.unsupportedDApps
import com.tangem.domain.walletconnect.WcPairService
import com.tangem.domain.walletconnect.model.WcPairRequest
import com.tangem.domain.walletconnect.model.legacy.Account
import com.tangem.domain.walletconnect.usecase.initialize.WcInitializeUseCase
import com.tangem.features.walletconnect.components.WalletConnectFeatureToggles
@ -31,6 +33,7 @@ internal class DefaultLegacyWalletConnectRepositoryFacade constructor(
private val legacy: DefaultLegacyWalletConnectRepository,
private val walletConnectFeatureToggles: WalletConnectFeatureToggles,
private val wcInitializeUseCase: WcInitializeUseCase,
private val wcPairService: WcPairService,
) : LegacyWalletConnectRepository {
private val isNewWc by lazy {
walletConnectFeatureToggles.isRedesignedWalletConnectEnabled
@ -62,7 +65,13 @@ internal class DefaultLegacyWalletConnectRepositoryFacade constructor(
}
override fun pair(uri: String, source: SourceType) {
if (isNewWc) stub.pair(uri, source) else legacy.pair(uri, source)
val src = when (source) {
SourceType.QR -> WcPairRequest.Source.QR
SourceType.DEEPLINK -> WcPairRequest.Source.DEEPLINK
SourceType.CLIPBOARD -> WcPairRequest.Source.CLIPBOARD
SourceType.ETC -> WcPairRequest.Source.ETC
}
if (isNewWc) wcPairService.pair(WcPairRequest(uri, src)) else legacy.pair(uri, source)
}
override fun disconnect(topic: String) {

View file

@ -7,6 +7,7 @@ import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import com.tangem.datasource.di.SdkMoshi
import com.tangem.datasource.files.FileReader
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.walletconnect.WcPairService
import com.tangem.domain.walletconnect.model.legacy.WalletConnectSessionsRepository
import com.tangem.domain.walletconnect.usecase.initialize.WcInitializeUseCase
import com.tangem.domain.walletmanager.WalletManagersFacade
@ -76,6 +77,7 @@ internal object WalletConnectModule {
analyticsHandler: AnalyticsEventHandler,
walletConnectFeatureToggles: WalletConnectFeatureToggles,
wcInitializeUseCase: WcInitializeUseCase,
wcPairService: WcPairService,
): LegacyWalletConnectRepository {
val legacy = DefaultLegacyWalletConnectRepository(
application = application,
@ -88,6 +90,7 @@ internal object WalletConnectModule {
legacy,
walletConnectFeatureToggles,
wcInitializeUseCase,
wcPairService,
)
}

View file

@ -13,7 +13,6 @@ import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.walletconnect.model.WcPairRequest
import com.tangem.features.walletconnect.connections.model.WcConnectionsModel
import com.tangem.features.walletconnect.connections.routes.WcConnectionsBottomSheetConfig
import com.tangem.features.walletconnect.connections.ui.WcConnectionsContent
@ -44,14 +43,6 @@ internal class ConnectionsComponent(
componentContext: ComponentContext,
): ComposableBottomSheetComponent {
return when (config) {
is WcConnectionsBottomSheetConfig.AppInfo -> WcAppInfoContainerComponent(
appComponentContext = childByContext(componentContext),
params = WcAppInfoContainerComponent.Params(
wcUrl = config.wcUrl,
source = WcPairRequest.Source.QR,
onDismiss = model.bottomSheetNavigation::dismiss,
),
)
is WcConnectionsBottomSheetConfig.ConnectedApp -> WcConnectedAppInfoComponent(
appComponentContext = childByContext(componentContext),
params = WcConnectedAppInfoComponent.Params(

View file

@ -16,7 +16,6 @@ import com.tangem.core.decompose.model.getOrCreateModel
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.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
@ -28,7 +27,7 @@ import com.tangem.features.walletconnect.impl.R
internal class WcAppInfoContainerComponent(
private val appComponentContext: AppComponentContext,
params: Params,
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val model: WcAppInfoModel = getOrCreateModel(params = params)
private val contentNavigation = StackNavigation<WcAppInfoRoutes>()
@ -39,12 +38,12 @@ internal class WcAppInfoContainerComponent(
childFactory = ::screenChild,
)
override fun dismiss() {
private fun dismiss() {
model.dismiss()
}
@Composable
override fun BottomSheet() {
override fun Content(modifier: Modifier) {
val content by contentStack.subscribeAsState()
TangemModalBottomSheet<WcAppInfoRoutes>(
config = TangemBottomSheetConfig(
@ -103,5 +102,5 @@ internal class WcAppInfoContainerComponent(
WcAppInfoRoutes.SelectWallet -> TODO()
}
data class Params(val wcUrl: String, val source: WcPairRequest.Source, val onDismiss: () -> Unit)
data class Params(val wcUrl: String, val source: WcPairRequest.Source)
}

View file

@ -4,6 +4,7 @@ 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.model.WcPairRequest
import com.tangem.domain.walletconnect.model.WcSessionApprove
import com.tangem.domain.walletconnect.model.WcSessionProposal
@ -26,6 +27,7 @@ import com.tangem.utils.transformer.update as transformerUpdate
internal class WcAppInfoModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
wcPairUseCaseFactory: WcPairUseCase.Factory,
private val router: Router,
paramsContainer: ParamsContainer,
) : Model() {
@ -53,7 +55,7 @@ internal class WcAppInfoModel @Inject constructor(
appInfoUiState.transformerUpdate(
WcConnectButtonProgressTransformer(showProgress = false),
)
params.onDismiss()
router.pop()
}
is WcPairState.Error -> {
// TODO: wc show toast/snackbar/alert?
@ -79,11 +81,17 @@ internal class WcAppInfoModel @Inject constructor(
fun dismiss() {
wcPairUseCase.reject()
params.onDismiss()
router.pop()
}
private fun onConnect() {
wcPairUseCase.approve(WcSessionApprove(wallet = userWallet, network = proposalNetwork.required.toList()))
wcPairUseCase.approve(
WcSessionApprove(
wallet = userWallet,
network =
proposalNetwork.required.plus(proposalNetwork.available).toList(),
),
)
}
private fun createLoadingState(): WcAppInfoUM.Loading {

View file

@ -17,6 +17,8 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.qrscanning.models.SourceType
import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase
import com.tangem.domain.walletconnect.model.WcSession
import com.tangem.domain.walletconnect.WcPairService
import com.tangem.domain.walletconnect.model.WcPairRequest
import com.tangem.domain.walletconnect.usecase.WcSessionsUseCase
import com.tangem.domain.walletconnect.usecase.disconnect.WcDisconnectUseCase
import com.tangem.features.walletconnect.connections.entity.WcConnectionsState
@ -32,6 +34,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ModelScoped
internal class WcConnectionsModel @Inject constructor(
private val router: Router,
@ -39,6 +42,7 @@ internal class WcConnectionsModel @Inject constructor(
private val listenToQrScanningUseCase: ListenToQrScanningUseCase,
private val wcSessionsUseCase: WcSessionsUseCase,
private val wcDisconnectUseCase: WcDisconnectUseCase,
private val wcPairService: WcPairService,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
@ -54,7 +58,7 @@ internal class WcConnectionsModel @Inject constructor(
private fun listenQrUpdates() {
listenToQrScanningUseCase(SourceType.WALLET_CONNECT)
.getOrElse { emptyFlow() }
.onEach { wcUrl -> bottomSheetNavigation.activate(WcConnectionsBottomSheetConfig.AppInfo(wcUrl)) }
.onEach { wcUrl -> wcPairService.pair(WcPairRequest(wcUrl, WcPairRequest.Source.QR)) }
.launchIn(modelScope)
}

View file

@ -4,9 +4,6 @@ import kotlinx.serialization.Serializable
@Serializable
internal sealed class WcConnectionsBottomSheetConfig {
@Serializable
data class AppInfo(val wcUrl: String) : WcConnectionsBottomSheetConfig()
@Serializable
data class ConnectedApp(val topic: String) : WcConnectionsBottomSheetConfig()
}

View file

@ -15,6 +15,8 @@ import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.walletconnect.components.WcRoutingComponent
import com.tangem.features.walletconnect.connections.components.WcAppInfoContainerComponent
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionComponent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@ -53,8 +55,14 @@ internal class DefaultWcRoutingComponent @AssistedInject constructor(
router = model.innerRouter,
)
return when (config) {
is WcInnerRoute.SignMessage -> TODO()
is WcInnerRoute.Pair -> TODO()
is WcInnerRoute.SignMessage -> WcSignTransactionComponent(
childContext,
params = WcSignTransactionComponent.Params(config.rawRequest),
)
is WcInnerRoute.Pair -> WcAppInfoContainerComponent(
childContext,
WcAppInfoContainerComponent.Params(config.request.uri, config.request.source),
)
}
}

View file

@ -45,12 +45,12 @@ internal class WcRoutingModel @Inject constructor(
when (methodName) {
WcEthMethodName.EthSign,
WcEthMethodName.PersonalSign,
WcEthMethodName.SignTypeData,
WcEthMethodName.SignTypeDataV4,
WcSolanaMethodName.SignMessage,
-> WcInnerRoute.SignMessage(rawRequest)
WcEthMethodName.SignTypeData -> TODO()
WcEthMethodName.SignTypeDataV4 -> TODO()
WcEthMethodName.SignTransaction -> TODO()
WcEthMethodName.SendTransaction -> TODO()
WcSolanaMethodName.SignMessage -> TODO()
WcSolanaMethodName.SignTransaction -> TODO()
WcSolanaMethodName.SendAllTransaction -> TODO()
is WcMethodName.Unsupported -> TODO()