Starts NIP-65 implementation

pull/549/head
Vitor Pamplona 2023-08-14 23:05:16 -04:00
rodzic 3a8a50006d
commit 5d24950d7f
4 zmienionych plików z 104 dodań i 0 usunięć

Wyświetl plik

@ -220,6 +220,26 @@ object LocalCache {
}
}
private fun consume(event: AdvertisedRelayListEvent) {
val version = getOrCreateNote(event.id)
val note = getOrCreateAddressableNote(event.address())
val author = getOrCreateUser(event.pubKey)
if (version.event == null) {
version.loadEvent(event, author, emptyList())
version.moveAllReferencesTo(note)
}
// Already processed this event.
if (note.event?.id() == event.id()) return
if (event.createdAt > (note.createdAt() ?: 0)) {
note.loadEvent(event, author, emptyList())
refreshObservers(note)
}
}
fun formattedDateTime(timestamp: Long): String {
return Instant.ofEpochSecond(timestamp).atZone(ZoneId.systemDefault())
.format(DateTimeFormatter.ofPattern("uuuu MMM d hh:mm a"))
@ -1497,6 +1517,7 @@ object LocalCache {
try {
when (event) {
is AdvertisedRelayListEvent -> consume(event)
is AppDefinitionEvent -> consume(event)
is AppRecommendationEvent -> consume(event)
is AudioTrackEvent -> consume(event)

Wyświetl plik

@ -48,6 +48,17 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
)
}
fun createAccountRelayListFilter(): TypedFilter {
return TypedFilter(
types = COMMON_FEED_TYPES,
filter = JsonFilter(
kinds = listOf(AdvertisedRelayListEvent.kind),
authors = listOf(account.userProfile().pubkeyHex),
limit = 1
)
)
}
fun createAccountAcceptedAwardsFilter(): TypedFilter {
return TypedFilter(
types = COMMON_FEED_TYPES,
@ -155,6 +166,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
accountChannel.typedFilters = listOf(
createAccountMetadataFilter(),
createAccountContactListFilter(),
createAccountRelayListFilter(),
createNotificationFilter(),
createGiftWrapsToMeFilter(),
createAccountReportsFilter(),

Wyświetl plik

@ -0,0 +1,70 @@
package com.vitorpamplona.amethyst.service.model
import androidx.compose.runtime.Immutable
import com.vitorpamplona.amethyst.model.HexKey
import com.vitorpamplona.amethyst.model.TimeUtils
import com.vitorpamplona.amethyst.model.toHexKey
import com.vitorpamplona.amethyst.service.CryptoUtils
@Immutable
class AdvertisedRelayListEvent(
id: HexKey,
pubKey: HexKey,
createdAt: Long,
tags: List<List<String>>,
content: String,
sig: HexKey
) : Event(id, pubKey, createdAt, kind, tags, content, sig), AddressableEvent {
override fun dTag() = fixedDTag
override fun address() = ATag(kind, pubKey, dTag(), null)
fun relays(): List<AdvertisedRelayInfo> {
return tags.mapNotNull {
if (it.size > 1 && it[0] == "r") {
val type = when (it.getOrNull(2)) {
"read" -> AdvertisedRelayType.READ
"write" -> AdvertisedRelayType.WRITE
else -> AdvertisedRelayType.BOTH
}
AdvertisedRelayInfo(it[1], type)
} else {
null
}
}
}
companion object {
const val kind = 10002
const val fixedDTag = ""
fun create(
list: List<AdvertisedRelayInfo>,
privateKey: ByteArray,
createdAt: Long = TimeUtils.now()
): AdvertisedRelayListEvent {
val tags = list.map {
if (it.type == AdvertisedRelayType.BOTH) {
listOf(it.relayUrl)
} else {
listOf(it.relayUrl, it.type.code)
}
}
val msg = ""
val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey()
val id = generateId(pubKey, createdAt, kind, tags, msg)
val sig = CryptoUtils.sign(id, privateKey)
return AdvertisedRelayListEvent(id.toHexKey(), pubKey, createdAt, tags, msg, sig.toHexKey())
}
}
@Immutable
data class AdvertisedRelayInfo(val relayUrl: String, val type: AdvertisedRelayType)
@Immutable
enum class AdvertisedRelayType(val code: String) {
BOTH(""),
READ("read"),
WRITE("write")
}
}

Wyświetl plik

@ -14,6 +14,7 @@ class EventFactory {
sig: String,
lenient: Boolean
) = when (kind) {
AdvertisedRelayListEvent.kind -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig)
AppDefinitionEvent.kind -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
AppRecommendationEvent.kind -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig)
AudioTrackEvent.kind -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig)