kopia lustrzana https://github.com/vitorpamplona/amethyst
Starts NIP-65 implementation
rodzic
3a8a50006d
commit
5d24950d7f
|
@ -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 {
|
fun formattedDateTime(timestamp: Long): String {
|
||||||
return Instant.ofEpochSecond(timestamp).atZone(ZoneId.systemDefault())
|
return Instant.ofEpochSecond(timestamp).atZone(ZoneId.systemDefault())
|
||||||
.format(DateTimeFormatter.ofPattern("uuuu MMM d hh:mm a"))
|
.format(DateTimeFormatter.ofPattern("uuuu MMM d hh:mm a"))
|
||||||
|
@ -1497,6 +1517,7 @@ object LocalCache {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
when (event) {
|
when (event) {
|
||||||
|
is AdvertisedRelayListEvent -> consume(event)
|
||||||
is AppDefinitionEvent -> consume(event)
|
is AppDefinitionEvent -> consume(event)
|
||||||
is AppRecommendationEvent -> consume(event)
|
is AppRecommendationEvent -> consume(event)
|
||||||
is AudioTrackEvent -> consume(event)
|
is AudioTrackEvent -> consume(event)
|
||||||
|
|
|
@ -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 {
|
fun createAccountAcceptedAwardsFilter(): TypedFilter {
|
||||||
return TypedFilter(
|
return TypedFilter(
|
||||||
types = COMMON_FEED_TYPES,
|
types = COMMON_FEED_TYPES,
|
||||||
|
@ -155,6 +166,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||||
accountChannel.typedFilters = listOf(
|
accountChannel.typedFilters = listOf(
|
||||||
createAccountMetadataFilter(),
|
createAccountMetadataFilter(),
|
||||||
createAccountContactListFilter(),
|
createAccountContactListFilter(),
|
||||||
|
createAccountRelayListFilter(),
|
||||||
createNotificationFilter(),
|
createNotificationFilter(),
|
||||||
createGiftWrapsToMeFilter(),
|
createGiftWrapsToMeFilter(),
|
||||||
createAccountReportsFilter(),
|
createAccountReportsFilter(),
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ class EventFactory {
|
||||||
sig: String,
|
sig: String,
|
||||||
lenient: Boolean
|
lenient: Boolean
|
||||||
) = when (kind) {
|
) = when (kind) {
|
||||||
|
AdvertisedRelayListEvent.kind -> AdvertisedRelayListEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
AppDefinitionEvent.kind -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
|
AppDefinitionEvent.kind -> AppDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
AppRecommendationEvent.kind -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig)
|
AppRecommendationEvent.kind -> AppRecommendationEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
AudioTrackEvent.kind -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig)
|
AudioTrackEvent.kind -> AudioTrackEvent(id, pubKey, createdAt, tags, content, sig)
|
||||||
|
|
Ładowanie…
Reference in New Issue