Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-04 16:42:58 +07:00
parent 638a9a4930
commit f8a1ee8ad2
7 changed files with 54 additions and 28 deletions

View file

@ -124,7 +124,10 @@ internal object WalletConnectDataModule {
@Provides
@Singleton
fun defaultWcRequestService(diHelperBox: DiHelperBox, respondService: WcRespondService): DefaultWcRequestService {
fun defaultWcRequestService(
diHelperBox: DiHelperBox,
respondService: DefaultWcRespondService,
): DefaultWcRequestService {
return DefaultWcRequestService(
requestConverters = diHelperBox.handlers,
respondService = respondService,
@ -133,7 +136,11 @@ internal object WalletConnectDataModule {
@Provides
@Singleton
fun wcRespondService(): WcRespondService = DefaultWcRespondService()
fun wcDefaultWcRespondService(): DefaultWcRespondService = DefaultWcRespondService()
@Provides
@Singleton
fun wcRespondService(default: DefaultWcRespondService): WcRespondService = default
@Provides
@Singleton

View file

@ -1,9 +1,7 @@
package com.tangem.data.walletconnect.request
import com.reown.walletkit.client.Wallet
import com.tangem.common.extensions.calculateSha256
import com.tangem.common.extensions.toHexString
import com.tangem.data.walletconnect.respond.WcRespondService
import com.tangem.data.walletconnect.respond.DefaultWcRespondService
import com.tangem.data.walletconnect.utils.WC_TAG
import com.tangem.data.walletconnect.utils.WcSdkObserver
import com.tangem.data.walletconnect.utils.WcSdkSessionRequestConverter
@ -14,16 +12,13 @@ import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import org.joda.time.DateTime
import org.joda.time.Duration
import timber.log.Timber
internal class DefaultWcRequestService(
private val requestConverters: Set<WcRequestToUseCaseConverter>,
private val respondService: WcRespondService,
private val respondService: DefaultWcRespondService,
) : WcSdkObserver, WcRequestService {
private val expireDuration = Duration.standardSeconds(120)
private val cachedRequest = MutableStateFlow<Set<Pair<Long, String>>>(setOf())
private val _wcRequest: Channel<Pair<WcMethodName, WcSdkSessionRequest>> = Channel(Channel.BUFFERED)
override val wcRequest: Flow<Pair<WcMethodName, WcSdkSessionRequest>> = _wcRequest.receiveAsFlow()
.filter { filterDuplicateRequest(request = it.second) }
@ -52,10 +47,10 @@ internal class DefaultWcRequestService(
}
private fun filterDuplicateRequest(request: WcSdkSessionRequest): Boolean {
val hash = request.request.params.calculateSha256().toHexString()
val hash = respondService.sessionRequestHash(request)
val now = DateTime.now().millis
val expiredMillis = now - expireDuration.millis
val cachedRequest = cachedRequest.updateAndGet {
val expiredMillis = now - respondService.expireDuration.millis
val cachedRequest = respondService.cachedRequest.updateAndGet {
it.filterTo(mutableSetOf()) { (millis, _) -> millis > expiredMillis }
}
@ -67,8 +62,8 @@ internal class DefaultWcRequestService(
}
private fun saveRequest(request: WcSdkSessionRequest) {
val hash = request.request.params.calculateSha256().toHexString()
val hash = respondService.sessionRequestHash(request)
val now = DateTime.now().millis
cachedRequest.update { it + (now to hash) }
respondService.cachedRequest.update { it + (now to hash) }
}
}

View file

@ -5,15 +5,27 @@ import arrow.core.left
import arrow.core.right
import com.reown.walletkit.client.Wallet
import com.reown.walletkit.client.WalletKit
import com.tangem.common.extensions.calculateSha256
import com.tangem.common.extensions.toHexString
import com.tangem.data.walletconnect.utils.WC_TAG
import com.tangem.domain.walletconnect.model.WcRequestError
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.suspendCancellableCoroutine
import org.joda.time.Duration
import timber.log.Timber
import kotlin.coroutines.resume
internal class DefaultWcRespondService : WcRespondService {
internal val expireDuration = Duration.standardSeconds(120)
internal val cachedRequest = MutableStateFlow<Set<Pair<Long, String>>>(emptySet())
internal fun sessionRequestHash(request: WcSdkSessionRequest): String {
return request.request.params.calculateSha256().toHexString()
}
override suspend fun respond(request: WcSdkSessionRequest, response: String): Either<WcRequestError, String> =
suspendCancellableCoroutine { continuation ->
WalletKit.respondSessionRequest(
@ -56,6 +68,7 @@ internal class DefaultWcRespondService : WcRespondService {
override fun rejectRequestNonBlock(request: WcSdkSessionRequest, message: String) {
Timber.tag(WC_TAG).i("reject request $request")
removeCachedRequest(request)
WalletKit.respondSessionRequest(
params = Wallet.Params.SessionRequestResponse(
sessionTopic = request.topic,
@ -69,4 +82,10 @@ internal class DefaultWcRespondService : WcRespondService {
onError = {},
)
}
private fun removeCachedRequest(request: WcSdkSessionRequest) {
cachedRequest.update { set ->
set.filterTo(mutableSetOf()) { (_, hash) -> hash != sessionRequestHash(request) }
}
}
}