Creates a default relay list for indexers in new accounts
This commit is contained in:
@@ -52,6 +52,7 @@ import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
|||||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListEvent
|
import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListEvent
|
||||||
@@ -99,6 +100,7 @@ private object PrefKeys {
|
|||||||
const val LATEST_DM_RELAY_LIST = "latestDMRelayList"
|
const val LATEST_DM_RELAY_LIST = "latestDMRelayList"
|
||||||
const val LATEST_NIP65_RELAY_LIST = "latestNIP65RelayList"
|
const val LATEST_NIP65_RELAY_LIST = "latestNIP65RelayList"
|
||||||
const val LATEST_SEARCH_RELAY_LIST = "latestSearchRelayList"
|
const val LATEST_SEARCH_RELAY_LIST = "latestSearchRelayList"
|
||||||
|
const val LATEST_INDEX_RELAY_LIST = "latestIndexRelayList"
|
||||||
const val LATEST_BLOCKED_RELAY_LIST = "latestBlockedRelayList"
|
const val LATEST_BLOCKED_RELAY_LIST = "latestBlockedRelayList"
|
||||||
const val LATEST_TRUSTED_RELAY_LIST = "latestTrustedRelayList"
|
const val LATEST_TRUSTED_RELAY_LIST = "latestTrustedRelayList"
|
||||||
const val LATEST_MUTE_LIST = "latestMuteList"
|
const val LATEST_MUTE_LIST = "latestMuteList"
|
||||||
@@ -334,6 +336,7 @@ object LocalPreferences {
|
|||||||
putOrRemove(PrefKeys.LATEST_DM_RELAY_LIST, settings.backupDMRelayList)
|
putOrRemove(PrefKeys.LATEST_DM_RELAY_LIST, settings.backupDMRelayList)
|
||||||
putOrRemove(PrefKeys.LATEST_NIP65_RELAY_LIST, settings.backupNIP65RelayList)
|
putOrRemove(PrefKeys.LATEST_NIP65_RELAY_LIST, settings.backupNIP65RelayList)
|
||||||
putOrRemove(PrefKeys.LATEST_SEARCH_RELAY_LIST, settings.backupSearchRelayList)
|
putOrRemove(PrefKeys.LATEST_SEARCH_RELAY_LIST, settings.backupSearchRelayList)
|
||||||
|
putOrRemove(PrefKeys.LATEST_INDEX_RELAY_LIST, settings.backupIndexRelayList)
|
||||||
putOrRemove(PrefKeys.LATEST_BLOCKED_RELAY_LIST, settings.backupBlockedRelayList)
|
putOrRemove(PrefKeys.LATEST_BLOCKED_RELAY_LIST, settings.backupBlockedRelayList)
|
||||||
putOrRemove(PrefKeys.LATEST_TRUSTED_RELAY_LIST, settings.backupTrustedRelayList)
|
putOrRemove(PrefKeys.LATEST_TRUSTED_RELAY_LIST, settings.backupTrustedRelayList)
|
||||||
|
|
||||||
@@ -469,6 +472,7 @@ object LocalPreferences {
|
|||||||
val latestDmRelayList = parseEventOrNull<ChatMessageRelayListEvent>(PrefKeys.LATEST_DM_RELAY_LIST)
|
val latestDmRelayList = parseEventOrNull<ChatMessageRelayListEvent>(PrefKeys.LATEST_DM_RELAY_LIST)
|
||||||
val latestNip65RelayList = parseEventOrNull<AdvertisedRelayListEvent>(PrefKeys.LATEST_NIP65_RELAY_LIST)
|
val latestNip65RelayList = parseEventOrNull<AdvertisedRelayListEvent>(PrefKeys.LATEST_NIP65_RELAY_LIST)
|
||||||
val latestSearchRelayList = parseEventOrNull<SearchRelayListEvent>(PrefKeys.LATEST_SEARCH_RELAY_LIST)
|
val latestSearchRelayList = parseEventOrNull<SearchRelayListEvent>(PrefKeys.LATEST_SEARCH_RELAY_LIST)
|
||||||
|
val latestIndexRelayList = parseEventOrNull<IndexerRelayListEvent>(PrefKeys.LATEST_INDEX_RELAY_LIST)
|
||||||
val latestBlockedRelayList = parseEventOrNull<BlockedRelayListEvent>(PrefKeys.LATEST_BLOCKED_RELAY_LIST)
|
val latestBlockedRelayList = parseEventOrNull<BlockedRelayListEvent>(PrefKeys.LATEST_BLOCKED_RELAY_LIST)
|
||||||
val latestTrustedRelayList = parseEventOrNull<TrustedRelayListEvent>(PrefKeys.LATEST_TRUSTED_RELAY_LIST)
|
val latestTrustedRelayList = parseEventOrNull<TrustedRelayListEvent>(PrefKeys.LATEST_TRUSTED_RELAY_LIST)
|
||||||
val latestMuteList = parseEventOrNull<MuteListEvent>(PrefKeys.LATEST_MUTE_LIST)
|
val latestMuteList = parseEventOrNull<MuteListEvent>(PrefKeys.LATEST_MUTE_LIST)
|
||||||
@@ -511,6 +515,7 @@ object LocalPreferences {
|
|||||||
backupNIP65RelayList = latestNip65RelayList,
|
backupNIP65RelayList = latestNip65RelayList,
|
||||||
backupDMRelayList = latestDmRelayList,
|
backupDMRelayList = latestDmRelayList,
|
||||||
backupSearchRelayList = latestSearchRelayList,
|
backupSearchRelayList = latestSearchRelayList,
|
||||||
|
backupIndexRelayList = latestIndexRelayList,
|
||||||
backupBlockedRelayList = latestBlockedRelayList,
|
backupBlockedRelayList = latestBlockedRelayList,
|
||||||
backupTrustedRelayList = latestTrustedRelayList,
|
backupTrustedRelayList = latestTrustedRelayList,
|
||||||
backupPrivateHomeRelayList = latestPrivateHomeRelayList,
|
backupPrivateHomeRelayList = latestPrivateHomeRelayList,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import com.vitorpamplona.quartz.nip51Lists.geohashList.GeohashListEvent
|
|||||||
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
import com.vitorpamplona.quartz.nip51Lists.hashtagList.HashtagListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.BlockedRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.TrustedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.CommandType
|
import com.vitorpamplona.quartz.nip55AndroidSigner.api.CommandType
|
||||||
import com.vitorpamplona.quartz.nip55AndroidSigner.api.permission.Permission
|
import com.vitorpamplona.quartz.nip55AndroidSigner.api.permission.Permission
|
||||||
@@ -123,6 +124,7 @@ class AccountSettings(
|
|||||||
var backupDMRelayList: ChatMessageRelayListEvent? = null,
|
var backupDMRelayList: ChatMessageRelayListEvent? = null,
|
||||||
var backupNIP65RelayList: AdvertisedRelayListEvent? = null,
|
var backupNIP65RelayList: AdvertisedRelayListEvent? = null,
|
||||||
var backupSearchRelayList: SearchRelayListEvent? = null,
|
var backupSearchRelayList: SearchRelayListEvent? = null,
|
||||||
|
var backupIndexRelayList: IndexerRelayListEvent? = null,
|
||||||
var backupBlockedRelayList: BlockedRelayListEvent? = null,
|
var backupBlockedRelayList: BlockedRelayListEvent? = null,
|
||||||
var backupTrustedRelayList: TrustedRelayListEvent? = null,
|
var backupTrustedRelayList: TrustedRelayListEvent? = null,
|
||||||
var backupMuteList: MuteListEvent? = null,
|
var backupMuteList: MuteListEvent? = null,
|
||||||
@@ -342,6 +344,16 @@ class AccountSettings(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateIndexRelayList(newIndexRelayList: IndexerRelayListEvent?) {
|
||||||
|
if (newIndexRelayList == null || newIndexRelayList.tags.isEmpty()) return
|
||||||
|
|
||||||
|
// Events might be different objects, we have to compare their ids.
|
||||||
|
if (backupIndexRelayList?.id != newIndexRelayList.id) {
|
||||||
|
backupIndexRelayList = newIndexRelayList
|
||||||
|
saveAccountSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateBlockedRelayList(newBlockedRelayList: BlockedRelayListEvent?) {
|
fun updateBlockedRelayList(newBlockedRelayList: BlockedRelayListEvent?) {
|
||||||
if (newBlockedRelayList == null || newBlockedRelayList.tags.isEmpty()) return
|
if (newBlockedRelayList == null || newBlockedRelayList.tags.isEmpty()) return
|
||||||
|
|
||||||
|
|||||||
+41
-4
@@ -21,20 +21,27 @@
|
|||||||
package com.vitorpamplona.amethyst.model.nip51Lists.indexerRelays
|
package com.vitorpamplona.amethyst.model.nip51Lists.indexerRelays
|
||||||
|
|
||||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||||
|
import com.vitorpamplona.amethyst.model.DefaultIndexerRelayList
|
||||||
|
import com.vitorpamplona.amethyst.model.DefaultSearchRelayList
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.NoteState
|
import com.vitorpamplona.amethyst.model.NoteState
|
||||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||||
|
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.utils.Log
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class IndexerRelayListState(
|
class IndexerRelayListState(
|
||||||
val signer: NostrSigner,
|
val signer: NostrSigner,
|
||||||
@@ -52,10 +59,11 @@ class IndexerRelayListState(
|
|||||||
|
|
||||||
fun getIndexerRelayList(): IndexerRelayListEvent? = indexerListNote.event as? IndexerRelayListEvent
|
fun getIndexerRelayList(): IndexerRelayListEvent? = indexerListNote.event as? IndexerRelayListEvent
|
||||||
|
|
||||||
suspend fun normalizeIndexerRelayListWithBackup(note: Note): Set<NormalizedRelayUrl> {
|
fun indexListEvent(note: Note) = note.event as? IndexerRelayListEvent ?: settings.backupIndexRelayList
|
||||||
val event = note.event as? IndexerRelayListEvent
|
|
||||||
return event?.let { decryptionCache.relays(it) } ?: emptySet()
|
suspend fun normalizeIndexerRelayListWithBackup(note: Note): Set<NormalizedRelayUrl> = indexListEvent(note)?.let { decryptionCache.relays(it) }?.ifEmpty { null } ?: DefaultIndexerRelayList
|
||||||
}
|
|
||||||
|
suspend fun normalizeIndexerRelayListWithBackupNoDefaults(note: Note): Set<NormalizedRelayUrl> = indexListEvent(note)?.let { decryptionCache.relays(it) } ?: emptySet()
|
||||||
|
|
||||||
val flow =
|
val flow =
|
||||||
getIndexerRelayListFlow()
|
getIndexerRelayListFlow()
|
||||||
@@ -68,6 +76,17 @@ class IndexerRelayListState(
|
|||||||
emptySet(),
|
emptySet(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val flowNoDefaults =
|
||||||
|
getIndexerRelayListFlow()
|
||||||
|
.map { normalizeIndexerRelayListWithBackupNoDefaults(it.note) }
|
||||||
|
.onStart { emit(normalizeIndexerRelayListWithBackupNoDefaults(indexerListNote)) }
|
||||||
|
.flowOn(Dispatchers.Default)
|
||||||
|
.stateIn(
|
||||||
|
scope,
|
||||||
|
SharingStarted.Eagerly,
|
||||||
|
emptySet(),
|
||||||
|
)
|
||||||
|
|
||||||
suspend fun saveRelayList(indexerRelays: List<NormalizedRelayUrl>): IndexerRelayListEvent {
|
suspend fun saveRelayList(indexerRelays: List<NormalizedRelayUrl>): IndexerRelayListEvent {
|
||||||
val relayListForIndexer = getIndexerRelayList()
|
val relayListForIndexer = getIndexerRelayList()
|
||||||
|
|
||||||
@@ -84,4 +103,22 @@ class IndexerRelayListState(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
settings.backupIndexRelayList?.let {
|
||||||
|
Log.d("AccountRegisterObservers", "Loading saved index relay list ${it.toJson()}")
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
GlobalScope.launch(Dispatchers.IO) { LocalCache.justConsumeMyOwnEvent(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.launch(Dispatchers.Default) {
|
||||||
|
Log.d("AccountRegisterObservers", "Index Relay List Collector Start")
|
||||||
|
getIndexerRelayListFlow().collect {
|
||||||
|
Log.d("AccountRegisterObservers", "Updating Index Relay List for ${signer.pubKey}")
|
||||||
|
(it.note.event as? IndexerRelayListEvent)?.let {
|
||||||
|
settings.updateIndexRelayList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.vitorpamplona.amethyst.LocalPreferences
|
|||||||
import com.vitorpamplona.amethyst.model.AccountSettings
|
import com.vitorpamplona.amethyst.model.AccountSettings
|
||||||
import com.vitorpamplona.amethyst.model.DefaultChannels
|
import com.vitorpamplona.amethyst.model.DefaultChannels
|
||||||
import com.vitorpamplona.amethyst.model.DefaultDMRelayList
|
import com.vitorpamplona.amethyst.model.DefaultDMRelayList
|
||||||
|
import com.vitorpamplona.amethyst.model.DefaultIndexerRelayList
|
||||||
import com.vitorpamplona.amethyst.model.DefaultNIP65List
|
import com.vitorpamplona.amethyst.model.DefaultNIP65List
|
||||||
import com.vitorpamplona.amethyst.model.DefaultNIP65RelaySet
|
import com.vitorpamplona.amethyst.model.DefaultNIP65RelaySet
|
||||||
import com.vitorpamplona.amethyst.model.DefaultSearchRelayList
|
import com.vitorpamplona.amethyst.model.DefaultSearchRelayList
|
||||||
@@ -57,6 +58,7 @@ import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
|||||||
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
|
import com.vitorpamplona.quartz.nip28PublicChat.list.ChannelListEvent
|
||||||
import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49
|
import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49
|
||||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||||
|
import com.vitorpamplona.quartz.nip51Lists.relayLists.IndexerRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.utils.Hex
|
import com.vitorpamplona.quartz.utils.Hex
|
||||||
import com.vitorpamplona.quartz.utils.Log
|
import com.vitorpamplona.quartz.utils.Log
|
||||||
@@ -288,6 +290,7 @@ class AccountStateViewModel : ViewModel() {
|
|||||||
accountSettings.backupNIP65RelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
accountSettings.backupNIP65RelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
||||||
accountSettings.backupDMRelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
accountSettings.backupDMRelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
||||||
accountSettings.backupSearchRelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
accountSettings.backupSearchRelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
||||||
|
accountSettings.backupIndexRelayList?.let { Amethyst.instance.client.send(it, toPost) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,6 +312,7 @@ class AccountStateViewModel : ViewModel() {
|
|||||||
backupNIP65RelayList = AdvertisedRelayListEvent.create(DefaultNIP65List, tempSigner),
|
backupNIP65RelayList = AdvertisedRelayListEvent.create(DefaultNIP65List, tempSigner),
|
||||||
backupDMRelayList = ChatMessageRelayListEvent.create(DefaultDMRelayList, tempSigner),
|
backupDMRelayList = ChatMessageRelayListEvent.create(DefaultDMRelayList, tempSigner),
|
||||||
backupSearchRelayList = SearchRelayListEvent.create(DefaultSearchRelayList.toList(), tempSigner),
|
backupSearchRelayList = SearchRelayListEvent.create(DefaultSearchRelayList.toList(), tempSigner),
|
||||||
|
backupIndexRelayList = IndexerRelayListEvent.create(DefaultIndexerRelayList.toList(), tempSigner),
|
||||||
backupChannelList = ChannelListEvent.create(emptyList(), DefaultChannels, tempSigner),
|
backupChannelList = ChannelListEvent.create(emptyList(), DefaultChannels, tempSigner),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
|||||||
|
|
||||||
class IndexerRelayListViewModel : BasicRelaySetupInfoModel() {
|
class IndexerRelayListViewModel : BasicRelaySetupInfoModel() {
|
||||||
override fun getRelayList(): List<NormalizedRelayUrl>? =
|
override fun getRelayList(): List<NormalizedRelayUrl>? =
|
||||||
account.indexerRelayList.flow.value
|
account.indexerRelayList.flowNoDefaults.value
|
||||||
.toList()
|
.toList()
|
||||||
|
|
||||||
override suspend fun saveRelayList(urlList: List<NormalizedRelayUrl>) {
|
override suspend fun saveRelayList(urlList: List<NormalizedRelayUrl>) {
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ class IndexerRelayListEvent(
|
|||||||
return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray)
|
return signer.signNip51List(createdAt, KIND, TAGS, privateTagArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun create(
|
fun create(
|
||||||
relays: List<NormalizedRelayUrl>,
|
relays: List<NormalizedRelayUrl>,
|
||||||
signer: NostrSignerSync,
|
signer: NostrSignerSync,
|
||||||
createdAt: Long = TimeUtils.now(),
|
createdAt: Long = TimeUtils.now(),
|
||||||
|
|||||||
Reference in New Issue
Block a user