From db1d205bae0383490baebbaa49c511e48ea7328d Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 19 May 2025 22:49:30 +0700 Subject: [PATCH] Updated on 2026-08-14 --- .../di/WalletConnectDataModule.kt | 2 + .../ethereum/WcEthAddNetworkUseCase.kt | 42 +++++++++++++++++++ .../network/ethereum/WcEthNetwork.kt | 19 ++++++++- .../walletconnect/model/WcEthAddChain.kt | 10 +++++ .../domain/walletconnect/model/WcEthMethod.kt | 7 ++++ .../walletconnect/model/WcMethodName.kt | 1 + .../usecase/method/WcAddNetworkUseCase.kt | 11 +++++ .../connections/routing/WcRoutingModel.kt | 1 + 8 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthAddNetworkUseCase.kt create mode 100644 domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthAddChain.kt create mode 100644 domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/usecase/method/WcAddNetworkUseCase.kt diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt index f1fe67b26a..2eb8bb69d2 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/di/WalletConnectDataModule.kt @@ -128,11 +128,13 @@ internal object WalletConnectDataModule { sessionsManager: WcSessionsManager, factories: WcEthNetwork.Factories, namespaceConverter: WcEthNetwork.NamespaceConverter, + walletManagersFacade: WalletManagersFacade, ): WcEthNetwork = WcEthNetwork( moshi = moshi, namespaceConverter = namespaceConverter, sessionsManager = sessionsManager, factories = factories, + walletManagersFacade = walletManagersFacade, ) @Provides diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthAddNetworkUseCase.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthAddNetworkUseCase.kt new file mode 100644 index 0000000000..d94d4eba8f --- /dev/null +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthAddNetworkUseCase.kt @@ -0,0 +1,42 @@ +package com.tangem.data.walletconnect.network.ethereum + +import arrow.core.Either +import com.tangem.data.walletconnect.respond.WcRespondService +import com.tangem.data.walletconnect.sign.WcMethodUseCaseContext +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.walletconnect.model.WcEthMethod +import com.tangem.domain.walletconnect.model.WcSession +import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest +import com.tangem.domain.walletconnect.usecase.method.WcAddNetworkUseCase +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +internal class WcEthAddNetworkUseCase @AssistedInject constructor( + private val respondService: WcRespondService, + @Assisted val context: WcMethodUseCaseContext, + @Assisted override val method: WcEthMethod.AddEthereumChain, +) : WcAddNetworkUseCase { + + override val session: WcSession + get() = context.session + override val rawSdkRequest: WcSdkSessionRequest + get() = context.rawSdkRequest + override val network: Network + get() = context.network + override val walletAddress: String + get() = context.accountAddress + + override suspend fun approve(): Either { + return respondService.respond(rawSdkRequest, "") + } + + override fun reject() { + respondService.rejectRequestNonBlock(rawSdkRequest) + } + + @AssistedFactory + interface Factory { + fun create(context: WcMethodUseCaseContext, method: WcEthMethod.AddEthereumChain): WcEthAddNetworkUseCase + } +} \ No newline at end of file diff --git a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthNetwork.kt b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthNetwork.kt index 5dda26b898..2ae96265ea 100644 --- a/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthNetwork.kt +++ b/data/wallet-connect/src/main/kotlin/com/tangem/data/walletconnect/network/ethereum/WcEthNetwork.kt @@ -10,6 +10,7 @@ import com.tangem.data.walletconnect.request.WcRequestToUseCaseConverter.Compani import com.tangem.data.walletconnect.sign.WcMethodUseCaseContext import com.tangem.data.walletconnect.utils.WcNamespaceConverter import com.tangem.domain.tokens.model.Network +import com.tangem.domain.walletconnect.model.WcEthAddChain import com.tangem.domain.walletconnect.model.WcEthMethod import com.tangem.domain.walletconnect.model.WcEthMethodName import com.tangem.domain.walletconnect.model.WcEthSignTypedDataParams @@ -17,6 +18,7 @@ import com.tangem.domain.walletconnect.model.WcEthTransactionParams import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest import com.tangem.domain.walletconnect.repository.WcSessionsManager import com.tangem.domain.walletconnect.usecase.method.WcMethodUseCase +import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.models.UserWallet import jakarta.inject.Inject @@ -25,6 +27,7 @@ internal class WcEthNetwork( private val sessionsManager: WcSessionsManager, private val factories: Factories, private val namespaceConverter: NamespaceConverter, + private val walletManagersFacade: WalletManagersFacade, ) : WcRequestToUseCaseConverter { override fun toWcMethodName(request: WcSdkSessionRequest): WcEthMethodName? { @@ -33,16 +36,19 @@ internal class WcEthNetwork( return name } + @Suppress("CyclomaticComplexMethod") override suspend fun toUseCase(request: WcSdkSessionRequest): WcMethodUseCase? { val name = toWcMethodName(request) ?: return null - val method: WcEthMethod = name.toMethod(request) ?: return null val session = sessionsManager.findSessionByTopic(request.topic) ?: return null + val method: WcEthMethod = name.toMethod(request, session.wallet) ?: return null val network = namespaceConverter.toNetwork(request.chainId.orEmpty(), session.wallet) ?: return null + val walletManagerAddress = walletManagersFacade.getDefaultAddress(session.wallet.walletId, network).orEmpty() val accountAddress = when (method) { is WcEthMethod.MessageSign -> method.account is WcEthMethod.SendTransaction -> method.transaction.from is WcEthMethod.SignTransaction -> method.transaction.from is WcEthMethod.SignTypedData -> method.account + is WcEthMethod.AddEthereumChain -> walletManagerAddress } val context = WcMethodUseCaseContext( session = session, @@ -55,10 +61,11 @@ internal class WcEthNetwork( is WcEthMethod.SendTransaction -> factories.sendTransaction.create(context, method) is WcEthMethod.SignTransaction -> factories.signTransaction.create(context, method) is WcEthMethod.SignTypedData -> factories.signTypedData.create(context, method) + is WcEthMethod.AddEthereumChain -> factories.addNetwork.create(context, method) } } - private fun WcEthMethodName.toMethod(request: WcSdkSessionRequest): WcEthMethod? { + private fun WcEthMethodName.toMethod(request: WcSdkSessionRequest, wallet: UserWallet): WcEthMethod? { val rawParams = request.request.params return when (this) { WcEthMethodName.EthSign, @@ -78,6 +85,13 @@ internal class WcEthNetwork( WcEthMethod.SendTransaction(transaction = it) } } + WcEthMethodName.AddEthereumChain -> moshi.fromJson>(rawParams) + ?.firstOrNull() + ?.let { + val newNetwork = namespaceConverter + .toNetwork(it.chainId, wallet) ?: return null + WcEthMethod.AddEthereumChain(rawChain = it, network = newNetwork) + } } } @@ -130,5 +144,6 @@ internal class WcEthNetwork( val signTypedData: WcEthSignTypedDataUseCase.Factory, val sendTransaction: WcEthSendTransactionUseCase.Factory, val signTransaction: WcEthSignTransactionUseCase.Factory, + val addNetwork: WcEthAddNetworkUseCase.Factory, ) } \ No newline at end of file diff --git a/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthAddChain.kt b/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthAddChain.kt new file mode 100644 index 0000000000..9daf8154a1 --- /dev/null +++ b/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthAddChain.kt @@ -0,0 +1,10 @@ +package com.tangem.domain.walletconnect.model + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class WcEthAddChain( + @Json(name = "chainId") + val chainId: String, +) \ No newline at end of file diff --git a/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthMethod.kt b/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthMethod.kt index 8f85b4063f..e72a35c68c 100644 --- a/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthMethod.kt +++ b/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcEthMethod.kt @@ -1,5 +1,7 @@ package com.tangem.domain.walletconnect.model +import com.tangem.domain.tokens.model.Network + sealed interface WcEthMethod : WcMethod { data class MessageSign( @@ -23,4 +25,9 @@ sealed interface WcEthMethod : WcMethod { data class SignTransaction( val transaction: WcEthTransactionParams, ) : WcEthMethod + + data class AddEthereumChain( + val rawChain: WcEthAddChain, + val network: Network, + ) : WcEthMethod } \ No newline at end of file diff --git a/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcMethodName.kt b/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcMethodName.kt index 7b557f0223..6ae4b431ac 100644 --- a/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcMethodName.kt +++ b/domain/wallet-connect/models/src/main/java/com/tangem/domain/walletconnect/model/WcMethodName.kt @@ -13,6 +13,7 @@ enum class WcEthMethodName(override val raw: String) : WcMethodName { SignTypeDataV4("eth_signTypedData_v4"), SignTransaction("eth_signTransaction"), SendTransaction("eth_sendTransaction"), + AddEthereumChain("wallet_addEthereumChain"), } enum class WcSolanaMethodName(override val raw: String) : WcMethodName { diff --git a/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/usecase/method/WcAddNetworkUseCase.kt b/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/usecase/method/WcAddNetworkUseCase.kt new file mode 100644 index 0000000000..b7794de457 --- /dev/null +++ b/domain/wallet-connect/src/main/kotlin/com/tangem/domain/walletconnect/usecase/method/WcAddNetworkUseCase.kt @@ -0,0 +1,11 @@ +package com.tangem.domain.walletconnect.usecase.method + +import arrow.core.Either + +interface WcAddNetworkUseCase : + WcMethodUseCase, + WcMethodContext { + + suspend fun approve(): Either + fun reject() +} \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/WcRoutingModel.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/WcRoutingModel.kt index ed054eb3dc..99eaa067eb 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/WcRoutingModel.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/WcRoutingModel.kt @@ -53,6 +53,7 @@ internal class WcRoutingModel @Inject constructor( WcEthMethodName.SendTransaction -> TODO() WcSolanaMethodName.SignTransaction -> TODO() WcSolanaMethodName.SendAllTransaction -> TODO() + WcEthMethodName.AddEthereumChain -> TODO() is WcMethodName.Unsupported -> TODO() } }