Updated on 2026-08-14
This commit is contained in:
commit
83ab0146ec
4 changed files with 39 additions and 5 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
package com.tangem.data.walletconnect.request
|
package com.tangem.data.walletconnect.request
|
||||||
|
|
||||||
import com.reown.walletkit.client.Wallet
|
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.WcRespondService
|
||||||
import com.tangem.data.walletconnect.utils.WC_TAG
|
import com.tangem.data.walletconnect.utils.WC_TAG
|
||||||
import com.tangem.data.walletconnect.utils.WcSdkObserver
|
import com.tangem.data.walletconnect.utils.WcSdkObserver
|
||||||
|
|
@ -9,8 +11,9 @@ import com.tangem.domain.walletconnect.WcRequestService
|
||||||
import com.tangem.domain.walletconnect.model.WcMethodName
|
import com.tangem.domain.walletconnect.model.WcMethodName
|
||||||
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
|
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import org.joda.time.DateTime
|
||||||
|
import org.joda.time.Duration
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
internal class DefaultWcRequestService(
|
internal class DefaultWcRequestService(
|
||||||
|
|
@ -18,8 +21,12 @@ internal class DefaultWcRequestService(
|
||||||
private val respondService: WcRespondService,
|
private val respondService: WcRespondService,
|
||||||
) : WcSdkObserver, WcRequestService {
|
) : 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)
|
private val _wcRequest: Channel<Pair<WcMethodName, WcSdkSessionRequest>> = Channel(Channel.BUFFERED)
|
||||||
override val wcRequest: Flow<Pair<WcMethodName, WcSdkSessionRequest>> = _wcRequest.receiveAsFlow()
|
override val wcRequest: Flow<Pair<WcMethodName, WcSdkSessionRequest>> = _wcRequest.receiveAsFlow()
|
||||||
|
.filter { filterDuplicateRequest(request = it.second) }
|
||||||
|
.onEach { saveRequest(request = it.second) }
|
||||||
|
|
||||||
override fun onSessionRequest(
|
override fun onSessionRequest(
|
||||||
sessionRequest: Wallet.Model.SessionRequest,
|
sessionRequest: Wallet.Model.SessionRequest,
|
||||||
|
|
@ -42,4 +49,25 @@ internal class DefaultWcRequestService(
|
||||||
}
|
}
|
||||||
_wcRequest.trySend(name to sr)
|
_wcRequest.trySend(name to sr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun filterDuplicateRequest(request: WcSdkSessionRequest): Boolean {
|
||||||
|
val hash = request.request.params.calculateSha256().toHexString()
|
||||||
|
val now = DateTime.now().millis
|
||||||
|
val expiredMillis = now - expireDuration.millis
|
||||||
|
val cachedRequest = cachedRequest.updateAndGet {
|
||||||
|
it.filterTo(mutableSetOf()) { (millis, _) -> millis > expiredMillis }
|
||||||
|
}
|
||||||
|
|
||||||
|
val noHaveCached = cachedRequest.none { (_, hashParams) -> hash == hashParams }
|
||||||
|
if (!noHaveCached) {
|
||||||
|
Timber.tag(WC_TAG).i("filter request $request")
|
||||||
|
}
|
||||||
|
return noHaveCached
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveRequest(request: WcSdkSessionRequest) {
|
||||||
|
val hash = request.request.params.calculateSha256().toHexString()
|
||||||
|
val now = DateTime.now().millis
|
||||||
|
cachedRequest.update { it + (now to hash) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +36,12 @@ internal class DefaultWcRespondService : WcRespondService {
|
||||||
}
|
}
|
||||||
is Wallet.Model.JsonRpcResponse.JsonRpcResult -> {
|
is Wallet.Model.JsonRpcResponse.JsonRpcResult -> {
|
||||||
Timber.tag(WC_TAG).i("Successful respond $response for request $request")
|
Timber.tag(WC_TAG).i("Successful respond $response for request $request")
|
||||||
response.result.right()
|
if (response.result == null) {
|
||||||
|
Timber.tag(WC_TAG).e(
|
||||||
|
"Response result is null, but it should be String. Casted to empty",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
(response.result ?: "").right()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continuation.resume(result)
|
continuation.resume(result)
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ internal class DefaultWcPairUseCaseTest {
|
||||||
proposerPublicKey = "",
|
proposerPublicKey = "",
|
||||||
relayProtocol = "",
|
relayProtocol = "",
|
||||||
relayData = "",
|
relayData = "",
|
||||||
|
scopedProperties = null,
|
||||||
)
|
)
|
||||||
private val sdkVerifyContext: Wallet.Model.VerifyContext
|
private val sdkVerifyContext: Wallet.Model.VerifyContext
|
||||||
get() = Wallet.Model.VerifyContext(
|
get() = Wallet.Model.VerifyContext(
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ zxingQrCode = "3.5.1"
|
||||||
kotlinSerialization = "1.8.0"
|
kotlinSerialization = "1.8.0"
|
||||||
kotlinDatetime = "0.6.2"
|
kotlinDatetime = "0.6.2"
|
||||||
arrow = "1.2.4" # 2.0.1 breaks the build
|
arrow = "1.2.4" # 2.0.1 breaks the build
|
||||||
reownCore = "1.1.2"
|
reownCore = "1.4.9"
|
||||||
reownWeb3 = "1.1.2"
|
reownWeb3 = "1.4.9"
|
||||||
prettyLogger = "2.2.0"
|
prettyLogger = "2.2.0"
|
||||||
okHttp-prettyLogging = "3.1.0"
|
okHttp-prettyLogging = "3.1.0"
|
||||||
chucker = "4.0.0"
|
chucker = "4.0.0"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue