Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Link Mode Success Rate #1467

Merged
merged 21 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.walletconnect.android

import android.app.Application
import android.content.SharedPreferences
import com.walletconnect.android.di.coreStorageModule
import com.walletconnect.android.internal.common.di.AndroidCommonDITags
import com.walletconnect.android.internal.common.di.KEY_CLIENT_ID
import com.walletconnect.android.internal.common.di.coreAndroidNetworkModule
import com.walletconnect.android.internal.common.di.coreCommonModule
import com.walletconnect.android.internal.common.di.coreCryptoModule
Expand Down Expand Up @@ -155,6 +157,7 @@ class CoreProtocol(private val koinApp: KoinApplication = wcKoinApp) : CoreInter

modules(
coreStorageModule(bundleId = bundleId),
module { single(named(AndroidCommonDITags.CLIENT_ID)) { requireNotNull(get<SharedPreferences>().getString(KEY_CLIENT_ID, null)) } },
pushModule(),
module { single { relay ?: Relay } },
module {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit

private const val INIT_BACKOFF_MILLIS = 1L
private const val MAX_BACKOFF_SEC = 20L
internal const val KEY_CLIENT_ID = "clientId"

@Suppress("LocalVariableName")
@JvmSynthetic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.squareup.moshi.Moshi
import com.walletconnect.android.internal.common.model.TelemetryEnabled
import com.walletconnect.android.pulse.data.PulseService
import com.walletconnect.android.pulse.domain.InsertEventUseCase
import com.walletconnect.android.pulse.domain.InsertTelemetryEventUseCase
import com.walletconnect.android.pulse.domain.SendBatchEventUseCase
import com.walletconnect.android.pulse.domain.SendEventInterface
import com.walletconnect.android.pulse.domain.SendEventUseCase
Expand Down Expand Up @@ -45,6 +46,13 @@ fun pulseModule(bundleId: String) = module {
)
}

single {
InsertTelemetryEventUseCase(
logger = get(named(AndroidCommonDITags.LOGGER)),
eventsRepository = get(),
)
}

single {
InsertEventUseCase(
logger = get(named(AndroidCommonDITags.LOGGER)),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.walletconnect.android.internal.common.di

import android.content.SharedPreferences
import com.walletconnect.android.push.PushInterface
import com.walletconnect.android.push.network.PushService
import com.walletconnect.android.push.notifications.DecryptMessageUseCaseInterface
import org.koin.core.qualifier.named
Expand All @@ -26,9 +24,5 @@ internal fun pushModule() = module {
get<Retrofit>(named(AndroidCommonDITags.PUSH_RETROFIT)).create(PushService::class.java)
}

single(named(AndroidCommonDITags.CLIENT_ID)) {
requireNotNull(get<SharedPreferences>().getString(PushInterface.KEY_CLIENT_ID, null))
}

single<MutableMap<String, DecryptMessageUseCaseInterface>>(named(AndroidCommonDITags.DECRYPT_USE_CASES)) { mutableMapOf() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package com.walletconnect.android.internal.common.jwt.clientid

import android.content.SharedPreferences
import androidx.core.content.edit
import com.walletconnect.android.push.PushInterface
import com.walletconnect.android.internal.common.di.KEY_CLIENT_ID
import com.walletconnect.android.utils.strippedUrl
import com.walletconnect.foundation.crypto.data.repository.ClientIdJwtRepository

Expand All @@ -13,7 +13,7 @@ internal class GenerateJwtStoreClientIdUseCase(private val clientIdJwtRepository
operator fun invoke(relayUrl: String): String =
clientIdJwtRepository.generateJWT(relayUrl.strippedUrl()) { clientId ->
sharedPreferences.edit {
putString(PushInterface.KEY_CLIENT_ID, clientId)
putString(KEY_CLIENT_ID, clientId)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ enum class Tags(val id: Int) {
SESSION_AUTHENTICATE_RESPONSE_REJECT(1118),
SESSION_AUTHENTICATE_RESPONSE_AUTO_REJECT(1119),

SESSION_AUTHENTICATE_LINK_MODE(1122),
SESSION_AUTHENTICATE_LINK_MODE_RESPONSE_APPROVE(1123),
SESSION_AUTHENTICATE_LINK_MODE_RESPONSE_REJECT(1124),

SESSION_REQUEST_LINK_MODE(1125),
SESSION_REQUEST_LINK_MODE_RESPONSE(1126),

CHAT_INVITE(2000),
CHAT_INVITE_RESPONSE(2001),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.walletconnect.android.internal.common.model.TelemetryEnabled
import com.walletconnect.android.pulse.model.Event
import com.walletconnect.android.pulse.model.properties.Properties
import com.walletconnect.android.pulse.model.properties.Props
import com.walletconnect.android.sdk.storage.data.dao.EventDao
import com.walletconnect.android.sdk.storage.data.dao.EventQueries
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
Expand All @@ -18,47 +19,49 @@ class EventsRepository(
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) {
@Throws(SQLiteException::class)
suspend fun insertOrAbort(props: Props) = withContext(dispatcher) {
suspend fun insertOrAbortTelemetry(props: Props) = withContext(dispatcher) {
if (telemetryEnabled.value) {
with(Event(bundleId = bundleId, props = props)) {
eventQueries.insertOrAbort(
eventId,
bundleId,
timestamp,
this.props.event,
this.props.type,
this.props.properties?.topic,
this.props.properties?.trace
)
}
insertOrAbort(props)
}
}

@Throws(SQLiteException::class)
suspend fun insertOrAbort(props: Props) = withContext(dispatcher) {
with(Event(bundleId = bundleId, props = props)) {
eventQueries.insertOrAbort(
eventId,
bundleId,
timestamp,
this.props.event,
this.props.type,
this.props.properties?.topic,
this.props.properties?.trace,
this.props.properties?.correlationId,
this.props.properties?.clientId,
this.props.properties?.direction
)
}
}

@Throws(SQLiteException::class)
suspend fun getAllWithLimitAndOffset(limit: Int, offset: Int): List<Event> {
return eventQueries.getAllWithLimitAndOffset(limit.toLong(), offset.toLong())
suspend fun getAllEventsWithLimitAndOffset(limit: Int, offset: Int): List<Event> {
return eventQueries.getAllEventsWithLimitAndOffset(limit.toLong(), offset.toLong())
.awaitAsList()
.map {
Event(
eventId = it.event_id,
bundleId = it.bundle_id,
timestamp = it.timestamp,
props = Props(
event = it.event_name,
type = it.type,
properties = Properties(
topic = it.topic,
trace = it.trace
)
)
)
}
.map { dao -> dao.toEvent() }
}

@Throws(SQLiteException::class)
suspend fun deleteAll() {
suspend fun getAllNonTelemetryEventsWithLimitAndOffset(limit: Int, offset: Int): List<Event> {
return eventQueries.getAllEventsWithLimitAndOffset(limit.toLong(), offset.toLong())
.awaitAsList()
.filter { dao -> dao.correlation_id != null }
.map { dao -> dao.toEvent() }
}

@Throws(SQLiteException::class)
suspend fun deleteAllTelemetry() {
return withContext(dispatcher) {
eventQueries.deleteAll()
eventQueries.deleteAllTelemetry()
}
}

Expand All @@ -68,4 +71,22 @@ class EventsRepository(
eventQueries.deleteByIds(eventIds)
}
}

private fun EventDao.toEvent(): Event =
Event(
eventId = event_id,
bundleId = bundle_id,
timestamp = timestamp,
props = Props(
event = event_name,
type = type,
properties = Properties(
topic = topic,
trace = trace,
clientId = client_id,
correlationId = correlation_id,
direction = direction
)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.walletconnect.android.internal.common.wcKoinApp
import com.walletconnect.android.pairing.engine.domain.PairingEngine
import com.walletconnect.android.pairing.engine.model.EngineDO
import com.walletconnect.android.pairing.model.mapper.toCore
import com.walletconnect.android.pulse.domain.InsertEventUseCase
import com.walletconnect.android.pulse.domain.InsertTelemetryEventUseCase
import com.walletconnect.android.pulse.model.EventType
import com.walletconnect.android.pulse.model.properties.Props
import com.walletconnect.android.relay.RelayConnectionInterface
Expand All @@ -26,7 +26,7 @@ internal class PairingProtocol(private val koinApp: KoinApplication = wcKoinApp)
private lateinit var pairingEngine: PairingEngine
private val logger: Logger by lazy { koinApp.koin.get() }
private val relayClient: RelayConnectionInterface by lazy { koinApp.koin.get() }
private val insertEventUseCase: InsertEventUseCase by lazy { koinApp.koin.get() }
private val insertEventUseCase: InsertTelemetryEventUseCase by lazy { koinApp.koin.get() }

override fun initialize() {
pairingEngine = koinApp.koin.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import com.walletconnect.android.pairing.model.PairingParams
import com.walletconnect.android.pairing.model.PairingRpc
import com.walletconnect.android.pairing.model.mapper.toCore
import com.walletconnect.android.pairing.model.pairingExpiry
import com.walletconnect.android.pulse.domain.InsertEventUseCase
import com.walletconnect.android.pulse.domain.InsertTelemetryEventUseCase
import com.walletconnect.android.pulse.domain.SendBatchEventUseCase
import com.walletconnect.android.pulse.model.EventType
import com.walletconnect.android.pulse.model.Trace
Expand Down Expand Up @@ -84,7 +84,7 @@ internal class PairingEngine(
private val crypto: KeyManagementRepository,
private val jsonRpcInteractor: RelayJsonRpcInteractorInterface,
private val pairingRepository: PairingStorageRepositoryInterface,
private val insertEventUseCase: InsertEventUseCase,
private val insertEventUseCase: InsertTelemetryEventUseCase,
private val sendBatchEventUseCase: SendBatchEventUseCase
) {
private var jsonRpcRequestsJob: Job? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,30 @@ import com.walletconnect.foundation.util.Logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

interface InsertEventUseCaseInterface {
suspend operator fun invoke(props: Props)
}

class InsertTelemetryEventUseCase(
private val eventsRepository: EventsRepository,
private val logger: Logger
) : InsertEventUseCaseInterface {
override suspend operator fun invoke(props: Props) {
withContext(Dispatchers.IO) {
try {
eventsRepository.insertOrAbortTelemetry(props)
} catch (e: Exception) {
logger.error("Inserting event ${props.type} error: $e")
}
}
}
}

class InsertEventUseCase(
private val eventsRepository: EventsRepository,
private val logger: Logger
) {
suspend operator fun invoke(props: Props) {
) : InsertEventUseCaseInterface {
override suspend operator fun invoke(props: Props) {
withContext(Dispatchers.IO) {
try {
eventsRepository.insertOrAbort(props)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.walletconnect.android.pulse.domain
import com.walletconnect.android.internal.common.model.TelemetryEnabled
import com.walletconnect.android.internal.common.storage.events.EventsRepository
import com.walletconnect.android.pulse.data.PulseService
import com.walletconnect.android.pulse.model.Event
import com.walletconnect.android.pulse.model.SDKType
import com.walletconnect.foundation.util.Logger
import kotlinx.coroutines.Dispatchers
Expand All @@ -16,33 +17,39 @@ class SendBatchEventUseCase(
) {
suspend operator fun invoke() = withContext(Dispatchers.IO) {
if (telemetryEnabled.value) {
var continueProcessing = true
while (continueProcessing) {
val events = eventsRepository.getAllWithLimitAndOffset(LIMIT, 0)
if (events.isNotEmpty()) {
try {
logger.log("Sending batch events: ${events.size}")
val response = pulseService.sendEventBatch(body = events, sdkType = SDKType.EVENTS.type)
if (response.isSuccessful) {
eventsRepository.deleteByIds(events.map { it.eventId })
} else {
logger.log("Failed to send events: ${events.size}")
continueProcessing = false
}
} catch (e: Exception) {
logger.error("Error sending batch events: ${e.message}")
continueProcessing = false
}
} else {
continueProcessing = false
}
}
sendEventsInBatches { eventsRepository.getAllEventsWithLimitAndOffset(LIMIT, 0) }
} else {
try {
eventsRepository.deleteAll()
eventsRepository.deleteAllTelemetry()
} catch (e: Exception) {
logger.error("Failed to delete events, error: $e")
}

sendEventsInBatches { eventsRepository.getAllNonTelemetryEventsWithLimitAndOffset(LIMIT, 0) }
}
}

private suspend fun sendEventsInBatches(getEvents: suspend () -> List<Event>) {
var continueProcessing = true
while (continueProcessing) {
val events = getEvents()
if (events.isNotEmpty()) {
try {
logger.log("Sending batch events: ${events.size}")
val response = pulseService.sendEventBatch(body = events, sdkType = SDKType.EVENTS.type)
if (response.isSuccessful) {
eventsRepository.deleteByIds(events.map { it.eventId })
} else {
logger.log("Failed to send events: ${events.size}")
continueProcessing = false
}
} catch (e: Exception) {
logger.error("Error sending batch events: ${e.message}")
continueProcessing = false
}
} else {
continueProcessing = false
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.walletconnect.android.pulse.model

enum class Direction(val state: String) {
SENT("sent"),
RECEIVED("received")
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.walletconnect.android.pulse.model
object EventType {
@get:JvmSynthetic
const val ERROR: String = "ERROR"
@get:JvmSynthetic
const val SUCCESS: String = "SUCCESS"

@get:JvmSynthetic
const val TRACK: String = "TRACE"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ data class Properties(
val trace: List<String>? = null,
@Json(name = "topic")
val topic: String? = null,
)
@Json(name = "correlation_id")
val correlationId: Long? = null,
@Json(name = "client_id")
val clientId: String? = null,
@Json(name = "direction")
val direction: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,4 @@ interface PushInterface {
fun register(firebaseAccessToken: String, enableEncrypted: Boolean = false, onSuccess: () -> Unit, onError: (Throwable) -> Unit)

fun unregister(onSuccess: () -> Unit, onError: (Throwable) -> Unit)

companion object {

@JvmSynthetic
internal const val KEY_CLIENT_ID = "clientId"
}
}
Loading
Loading