Skip to content

Commit

Permalink
Merge pull request #1288 from WalletConnect/feat/notify/notification_…
Browse files Browse the repository at this point in the history
…history

feat: Notifications History with changed ids
  • Loading branch information
Elyniss authored Jan 29, 2024
2 parents daaadfa + 33abb62 commit ab3f487
Show file tree
Hide file tree
Showing 71 changed files with 1,055 additions and 468 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ object Core {
data class Notify(
val title: String,
val body: String,
val icon: String?,
val url: String?,
val type: String,
val topic: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ internal class JsonRpcResultAdapter(val moshi: Moshi) : JsonAdapter<JsonRpcRespo
moshi.adapter(CoreNotifyParams.UpdateParams::class.java, emptySet(), "result")
private val chatNotifyResponseAuthParamsAdapter: JsonAdapter<ChatNotifyResponseAuthParams.ResponseAuth> =
moshi.adapter(ChatNotifyResponseAuthParams.ResponseAuth::class.java, emptySet(), "result")
private val chatNotifyAuthParamsAdapter: JsonAdapter<ChatNotifyResponseAuthParams.Auth> =
moshi.adapter(ChatNotifyResponseAuthParams.Auth::class.java, emptySet(), "result")

@Volatile
private var constructorRef: Constructor<JsonRpcResponse.JsonRpcResult>? = null
Expand Down Expand Up @@ -71,6 +73,10 @@ internal class JsonRpcResultAdapter(val moshi: Moshi) : JsonAdapter<JsonRpcRespo
chatNotifyResponseAuthParamsAdapter.fromJson(reader)
}

runCatching { chatNotifyAuthParamsAdapter.fromJson(reader.peekJson()) }.isSuccess -> {
chatNotifyAuthParamsAdapter.fromJson(reader)
}

else -> anyAdapter.fromJson(reader)
}
}
Expand Down Expand Up @@ -146,6 +152,13 @@ internal class JsonRpcResultAdapter(val moshi: Moshi) : JsonAdapter<JsonRpcRespo
}
}

(value_.result as? ChatNotifyResponseAuthParams.Auth) != null -> {
val notifyResponseParamsString = chatNotifyAuthParamsAdapter.toJson(value_.result)
writer.valueSink().use {
it.writeUtf8(notifyResponseParamsString)
}
}

(value_.result as? CoreNotifyParams.UpdateParams) != null -> {
val notifySubscribeUpdateParamsString = notifySubscribeUpdateParamsAdapter.toJson(value_.result)
writer.valueSink().use {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ class ExplorerRepository(
name = name,
description = description,
imageUrl = imageUrl?.toImageUrl(),
homepage = homepage,
homepage = homepage ?: "",
dappUrl = dappUrl,
isVerified = isVerified,
)
}
}

private fun NotificationTypeDTO.toNotificationType(): NotificationType = NotificationType(name = name, id = id, description = description)
private fun NotificationTypeDTO.toNotificationType(): NotificationType = NotificationType(name = name, id = id, description = description, imageUrl = imageUrl?.toImageUrl())


private fun ProjectListingDTO.toProjectListing(): ProjectListing {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ data class NotificationType(
val name: String,
val id: String,
val description: String,
val imageUrl: ImageUrl?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ data class NotifyConfigDTO(
@JsonClass(generateAdapter = true)
data class NotifyConfigDataDTO(
@Json(name = "name") val name: String,
@Json(name = "homepage") val homepage: String,
@Json(name = "homepage") val homepage: String?,
@Json(name = "description") val description: String,
@Json(name = "dapp_url") val dappUrl: String,
@Json(name = "image_url") val imageUrl: ImageUrlDTO?,
Expand All @@ -31,4 +31,8 @@ data class NotificationTypeDTO(
val id: String,
@Json(name = "description")
val description: String,
)
@Json(name = "imageUrls")
val imageUrl: ImageUrlDTO?,


)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.walletconnect.android.internal.common.explorer.domain.usecase
import com.walletconnect.android.internal.common.explorer.ExplorerRepository
import com.walletconnect.android.internal.common.explorer.data.model.NotifyConfig

class GetNotifyConfigUseCase(
private val explorerRepository: ExplorerRepository,
) {
class GetNotifyConfigUseCase(private val explorerRepository: ExplorerRepository) {
suspend operator fun invoke(appDomain: String): Result<NotifyConfig> = runCatching { explorerRepository.getNotifyConfig(appDomain) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,8 @@ enum class Tags(val id: Int) {
NOTIFY_SUBSCRIPTIONS_CHANGED(4012),
NOTIFY_SUBSCRIPTIONS_CHANGED_RESPONSE(4013),

NOTIFY_GET_NOTIFICATIONS(4014),
NOTIFY_GET_NOTIFICATIONS_RESPONSE(4015),

//todo: Discuss: Should Tags be in specific SDKs?
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ interface ChatNotifyResponseAuthParams {
@Json(name = "responseAuth")
val responseAuth: String,
) : ClientParams

@JsonClass(generateAdapter = true)
data class Auth(
@Json(name = "auth")
val auth: String,
) : ClientParams
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ sealed interface CoreNotifyParams : ClientParams {
@Json(name = "subscriptionsChangedAuth")
val subscriptionsChangedAuth: String,
) : CoreNotifyParams

@JsonClass(generateAdapter = true)
data class GetNotificationsParams(
@Json(name = "auth")
val auth: String,
) : CoreNotifyParams
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.walletconnect.android.Core
import com.walletconnect.android.CoreInterface
import com.walletconnect.android.cacao.SignatureInterface
import com.walletconnect.foundation.common.model.PrivateKey
import kotlin.time.Duration

object Notify {

Expand All @@ -22,14 +23,13 @@ object Notify {
data class Decrypted(
override val title: String,
override val body: String,
val icon: String?,
val url: String?,
val type: String,
val topic: String,
) : Notification()
}

data class NotificationRecord(val id: String, val topic: String, val publishedAt: Long, val message: Notification, val metadata: Core.Model.AppMetaData) : Model()
data class NotificationRecord(val id: String, val topic: String, val sentAt: Long, val notification: Notification, val metadata: Core.Model.AppMetaData) : Model()

data class Subscription(
val topic: String,
Expand Down Expand Up @@ -58,20 +58,19 @@ object Notify {
) : Model()
}

data class NotificationType(val id: String, val name: String, val description: String) : Model()
data class NotificationType(val id: String, val name: String, val description: String, val iconUrl: String?) : Model()

data class Error(val throwable: Throwable) : Model()

data class CacaoPayloadWithIdentityPrivateKey(val payload: Cacao.Payload, val key: PrivateKey) : Model()
}

sealed class Event {
data class Notification (val notification: Model.NotificationRecord) : Event()
data class Notification(val notification: Model.NotificationRecord) : Event()

data class SubscriptionsChanged(val subscriptions: List<Model.Subscription>) : Event()
}

// todo: move to model
sealed interface Result {
sealed interface Subscribe {
data class Success(val subscription: Model.Subscription) : Subscribe
Expand All @@ -87,21 +86,28 @@ object Notify {
data class Success(val topic: String) : DeleteSubscription
data class Error(val error: Model.Error) : DeleteSubscription
}

sealed interface GetNotificationHistory {
data class Success(val notifications: List<Model.NotificationRecord>, val hasMore: Boolean) : GetNotificationHistory
data class Error(val error: Model.Error) : GetNotificationHistory
}
}

sealed class Params {

class Init(val core: CoreInterface) : Params()

data class Subscribe(val appDomain: Uri, val account: String) : Params()
data class Subscribe(val appDomain: Uri, val account: String, val timeout: Duration? = null) : Params()

data class UpdateSubscription(val topic: String, val scope: List<String>, val timeout: Duration? = null) : Params()

data class UpdateSubscription(val topic: String, val scope: List<String>) : Params()
data class GetNotificationTypes(val appDomain: String, val timeout: Duration? = null) : Params()

data class GetNotificationTypes(val appDomain: String) : Params()
data class GetNotificationHistory(val topic: String, val limit: Int? = null, val startingAfter: String? = null, val timeout: Duration? = null) : Params()

data class GetNotificationHistory(val topic: String) : Params()
data class DeleteSubscription(val topic: String, val timeout: Duration? = null) : Params()

data class DeleteSubscription(val topic: String) : Params()
data class GetActiveSubscriptions(val account: String, val timeout: Duration? = null) : Params()

data class DecryptNotification(val topic: String, val encryptedMessage: String) : Params()

Expand All @@ -111,6 +117,6 @@ object Notify {

data class IsRegistered(val account: String, val domain: String, val allApps: Boolean = true) : Params()

data class Unregister (val account: String) : Params()
data class Unregister(val account: String) : Params()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.walletconnect.notify.client

interface NotifyInterface {
interface Delegate {
//todo: migration guide and remove all deprecations
fun onNotifyNotification(notifyNotification: Notify.Event.Notification)

fun onError(error: Notify.Model.Error)
Expand Down Expand Up @@ -42,13 +41,13 @@ interface NotifyInterface {
* Caution: This function is blocking and runs on the current thread.
* It is advised that this function be called from background operation
*/
fun getActiveSubscriptions(): Map<String, Notify.Model.Subscription>
fun getActiveSubscriptions(params: Notify.Params.GetActiveSubscriptions): Map<String, Notify.Model.Subscription>

/**
* Caution: This function is blocking and runs on the current thread.
* It is advised that this function be called from background operation
*/
fun getNotificationHistory(params: Notify.Params.GetNotificationHistory): Map<Long, Notify.Model.NotificationRecord>
fun getNotificationHistory(params: Notify.Params.GetNotificationHistory): Notify.Result.GetNotificationHistory


fun decryptNotification(params: Notify.Params.DecryptNotification, onSuccess: (Notify.Model.Notification.Decrypted) -> Unit, onError: (Notify.Model.Error) -> Unit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.walletconnect.android.internal.common.di.DatabaseConfig
import com.walletconnect.android.internal.common.model.SDKError
import com.walletconnect.android.internal.common.scope
import com.walletconnect.android.internal.common.wcKoinApp
import com.walletconnect.notify.common.model.NotifyRecord
import com.walletconnect.notify.common.model.Notification
import com.walletconnect.notify.common.model.SubscriptionChanged
import com.walletconnect.notify.common.model.toClient
import com.walletconnect.notify.common.model.toCommon
Expand Down Expand Up @@ -46,7 +46,7 @@ class NotifyProtocol(private val koinApp: KoinApplication = wcKoinApp) : NotifyI

notifyEngine.engineEvent.onEach { event ->
when (event) {
is NotifyRecord -> delegate.onNotifyNotification(Notify.Event.Notification(event.toClient()))
is Notification -> delegate.onNotifyNotification(Notify.Event.Notification(event.toClient()))
is SubscriptionChanged -> delegate.onSubscriptionsChanged(event.toClient())
is SDKError -> delegate.onError(event.toClient())
}
Expand All @@ -58,7 +58,7 @@ class NotifyProtocol(private val koinApp: KoinApplication = wcKoinApp) : NotifyI

return runBlocking {
try {
notifyEngine.subscribeToDapp(params.appDomain, params.account).toClient()
notifyEngine.subscribeToDapp(params.appDomain, params.account, params.timeout).toClient()
} catch (e: Exception) {
Notify.Result.Subscribe.Error(Notify.Model.Error(e))
}
Expand All @@ -70,7 +70,7 @@ class NotifyProtocol(private val koinApp: KoinApplication = wcKoinApp) : NotifyI

return runBlocking {
try {
notifyEngine.update(params.topic, params.scope).toClient()
notifyEngine.update(params.topic, params.scope, params.timeout).toClient()
} catch (e: Exception) {
Notify.Result.UpdateSubscription.Error(Notify.Model.Error(e))
}
Expand All @@ -81,35 +81,37 @@ class NotifyProtocol(private val koinApp: KoinApplication = wcKoinApp) : NotifyI
checkEngineInitialization()

return runBlocking {
notifyEngine.getNotificationTypes(params.appDomain).mapValues { (_, notificationType) ->
notificationType.toClient()
}
notifyEngine.getNotificationTypes(params.appDomain, params.timeout).mapValues { (_, notificationType) -> notificationType.toClient() }
}
}


override fun getActiveSubscriptions(): Map<String, Notify.Model.Subscription> {
override fun getActiveSubscriptions(params: Notify.Params.GetActiveSubscriptions): Map<String, Notify.Model.Subscription> {
checkEngineInitialization()

return runBlocking {
notifyEngine.getListOfActiveSubscriptions().mapValues { (_, subscriptionWMetadata) ->
subscriptionWMetadata.toClient()
}
notifyEngine.getActiveSubscriptions(params.account, params.timeout).mapValues { (_, subscriptionWMetadata) -> subscriptionWMetadata.toClient() }
}
}

override fun getNotificationHistory(params: Notify.Params.GetNotificationHistory): Map<Long, Notify.Model.NotificationRecord> {
override fun getNotificationHistory(params: Notify.Params.GetNotificationHistory): Notify.Result.GetNotificationHistory {
checkEngineInitialization()

return runBlocking { notifyEngine.getListOfNotifications(params.topic).mapValues { (_, notifyRecord) -> notifyRecord.toClient() } }
return runBlocking {
try {
notifyEngine.getNotificationHistory(params.topic, params.limit, params.startingAfter, params.timeout).toClient()
} catch (e: Exception) {
Notify.Result.GetNotificationHistory.Error(Notify.Model.Error(e))
}
}
}

override fun deleteSubscription(params: Notify.Params.DeleteSubscription): Notify.Result.DeleteSubscription {
checkEngineInitialization()

return runBlocking {
try {
notifyEngine.deleteSubscription(params.topic).toClient()
notifyEngine.deleteSubscription(params.topic, params.timeout).toClient()
} catch (e: Exception) {
Notify.Result.DeleteSubscription.Error(Notify.Model.Error(e))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ internal object JsonRpcMethod {

@get:JvmSynthetic
const val WC_NOTIFY_SUBSCRIPTIONS_CHANGED: String = "wc_notifySubscriptionsChanged"

@get:JvmSynthetic
const val WC_NOTIFY_GET_NOTIFICATIONS: String = "wc_notifyGetNotifications"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package com.walletconnect.notify.common

import com.walletconnect.android.internal.common.model.Expiry
import com.walletconnect.android.internal.utils.monthInSeconds
import java.nio.charset.Charset
import java.util.concurrent.TimeUnit

@JvmSynthetic
Expand All @@ -13,4 +14,11 @@ internal fun calcExpiry(): Expiry {
val expiryTimeSeconds = currentTimeSeconds + monthInSeconds

return Expiry(expiryTimeSeconds)
}
}


@JvmSynthetic
internal fun convertToUTF8(input: String): String {
val bytes = input.toByteArray(Charset.forName("ISO-8859-1"))
return String(bytes, Charset.forName("UTF-8"))
}
Loading

0 comments on commit ab3f487

Please sign in to comment.