refactor: simplify NostrClient API for beginner-friendliness

Comprehensive rename of the NostrClient relay infrastructure to use
intuitive, self-documenting names instead of protocol-level jargon.

Interface/class renames:
- INostrClient → NostrClient (interface)
- NostrClient → DefaultNostrClient (implementation)
- IRequestListener → SubscriptionListener
- IRelayClientListener → RelayConnectionListener
- IOpenNostrRequest → SubscriptionHandle
- NostrClientStaticReq → StaticSubscription
- NostrClientDynamicReq → DynamicSubscription

Method renames:
- openReqSubscription() → subscribe()
- close(subId) → unsubscribe(subId)
- send() → publish()
- queryCount() → count()
- subscribe/unsubscribe(listener) → addConnectionListener/removeConnectionListener
- renewFilters() → syncFilters()

Callback renames:
- onEose → onCaughtUp
- isLive → isRealTime
- onStartReq → onSubscriptionStarted
- onCloseReq → onSubscriptionClosed

Extension function renames:
- query() → fetchAll()
- downloadFirstEvent() → fetchFirst()
- req() → subscribe()
- reqAsFlow() → subscribeAsFlow()
- reqUntilEoseAsFlow() → fetchAsFlow()
- sendAndWaitForResponse() → publishAndConfirm()
- queryCountSuspend() → count()
- queryCountMergedHll() → countMerged()
- reqBypassingRelayLimits() → fetchAllPages()
- updateFilter() → refresh() on SubscriptionHandle

https://claude.ai/code/session_01JPcYCcRx5eZN4GvgGxGwbf
This commit is contained in:
Claude
2026-03-28 03:23:20 +00:00
parent 0054c01921
commit 4e2717c5c5
169 changed files with 888 additions and 892 deletions
@@ -33,7 +33,6 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.crypto.verify import com.vitorpamplona.quartz.nip01Core.crypto.verify
import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
import com.vitorpamplona.quartz.nip03Timestamp.EmptyOtsResolverBuilder import com.vitorpamplona.quartz.nip03Timestamp.EmptyOtsResolverBuilder
@@ -55,7 +54,7 @@ class ThreadDualAxisChartAssemblerTest {
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val client = val client =
NostrClient( DefaultNostrClient(
OkHttpWebSocket.Builder { OkHttpWebSocket.Builder {
OkHttpClient OkHttpClient
.Builder() .Builder()
@@ -24,7 +24,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.amethyst.model.Constants import com.vitorpamplona.amethyst.model.Constants
import com.vitorpamplona.amethyst.service.okhttp.DefaultContentTypeInterceptor import com.vitorpamplona.amethyst.service.okhttp.DefaultContentTypeInterceptor
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayLogger import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayLogger
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.normalizeRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.normalizeRelayUrl
@@ -68,7 +67,7 @@ class EventSyncTest {
inboxTargets = { setOf(vitor) }, inboxTargets = { setOf(vitor) },
dmTargets = { setOf(vitor) }, dmTargets = { setOf(vitor) },
clientBuilder = { clientBuilder = {
NostrClient(socketBuilder, appScope) DefaultNostrClient(socketBuilder, appScope)
}, },
scope = appScope, scope = appScope,
) )
@@ -87,7 +86,7 @@ class EventSyncTest {
inboxTargets = { setOf(vitor) }, inboxTargets = { setOf(vitor) },
dmTargets = { setOf(vitor) }, dmTargets = { setOf(vitor) },
clientBuilder = { clientBuilder = {
val newClient = NostrClient(socketBuilder, appScope) val newClient = DefaultNostrClient(socketBuilder, appScope)
val logger = RelayLogger(newClient, debugSending = true, debugReceiving = false) val logger = RelayLogger(newClient, debugSending = true, debugReceiving = false)
val signer = NostrSignerInternal(KeyPair()) val signer = NostrSignerInternal(KeyPair())
@@ -68,7 +68,6 @@ import com.vitorpamplona.amethyst.ui.screen.AccountSessionManager
import com.vitorpamplona.amethyst.ui.screen.UiSettingsState import com.vitorpamplona.amethyst.ui.screen.UiSettingsState
import com.vitorpamplona.amethyst.ui.tor.TorManager import com.vitorpamplona.amethyst.ui.tor.TorManager
import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.Address
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayLogger import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayLogger
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
@@ -256,7 +255,7 @@ class AppModules(
val cache: LocalCache = LocalCache val cache: LocalCache = LocalCache
// Provides a relay pool // Provides a relay pool
val client: INostrClient = NostrClient(websocketBuilder, applicationIOScope) val client: NostrClient = DefaultNostrClient(websocketBuilder, applicationIOScope)
// Watches for changes on Tor and Relay List Settings // Watches for changes on Tor and Relay List Settings
val relayProxyClientConnector = val relayProxyClientConnector =
@@ -135,8 +135,8 @@ import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider import com.vitorpamplona.quartz.nip01Core.hints.EventHintProvider
import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.downloadFirstEvent import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchFirst
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
@@ -244,7 +244,7 @@ class Account(
val nwcFilterAssembler: () -> NWCPaymentFilterAssembler, val nwcFilterAssembler: () -> NWCPaymentFilterAssembler,
val otsResolverBuilder: () -> OtsResolver, val otsResolverBuilder: () -> OtsResolver,
val cache: LocalCache, val cache: LocalCache,
val client: INostrClient, val client: NostrClient,
val scope: CoroutineScope, val scope: CoroutineScope,
) : IAccount { ) : IAccount {
private var userProfileCache: User? = null private var userProfileCache: User? = null
@@ -606,7 +606,7 @@ class Account(
onResponse: (Response?) -> Unit, onResponse: (Response?) -> Unit,
) { ) {
val (event, relay) = nip47SignerState.sendNwcRequest(request, onResponse) val (event, relay) = nip47SignerState.sendNwcRequest(request, onResponse)
client.send(event, setOf(relay)) client.publish(event, setOf(relay))
} }
suspend fun sendZapPaymentRequestFor( suspend fun sendZapPaymentRequestFor(
@@ -615,7 +615,7 @@ class Account(
onResponse: (Response?) -> Unit, onResponse: (Response?) -> Unit,
) { ) {
val (event, relay) = nip47SignerState.sendZapPaymentRequestFor(bolt11, zappedNote, onResponse) val (event, relay) = nip47SignerState.sendZapPaymentRequestFor(bolt11, zappedNote, onResponse)
client.send(event, setOf(relay)) client.publish(event, setOf(relay))
} }
suspend fun createZapRequestFor( suspend fun createZapRequestFor(
@@ -701,7 +701,7 @@ class Account(
suspend fun boost(note: Note) { suspend fun boost(note: Note) {
RepostAction.repost(note, signer)?.let { event -> RepostAction.repost(note, signer)?.let { event ->
client.send(event, computeMyReactionToNote(note, event)) client.publish(event, computeMyReactionToNote(note, event))
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
} }
} }
@@ -723,7 +723,7 @@ class Account(
event: Event, event: Event,
relays: Set<NormalizedRelayUrl>, relays: Set<NormalizedRelayUrl>,
) { ) {
client.send(event, relays) client.publish(event, relays)
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
} }
@@ -939,7 +939,7 @@ class Account(
// download the event and send it. // download the event and send it.
noteEvent.host?.let { host -> noteEvent.host?.let { host ->
client client
.downloadFirstEvent( .fetchFirst(
filters = filters =
note.relays.associateWith { relay -> note.relays.associateWith { relay ->
listOf( listOf(
@@ -1012,7 +1012,7 @@ class Account(
fun sendAutomatic(event: Event?) { fun sendAutomatic(event: Event?) {
if (event == null) return if (event == null) return
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
client.send(event, computeRelayListToBroadcast(event)) client.publish(event, computeRelayListToBroadcast(event))
} }
suspend fun sendWebBookmark( suspend fun sendWebBookmark(
@@ -1043,7 +1043,7 @@ class Account(
fun sendMyPublicAndPrivateOutbox(event: Event?) { fun sendMyPublicAndPrivateOutbox(event: Event?) {
if (event == null) return if (event == null) return
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
client.send(event, outboxRelays.flow.value) client.publish(event, outboxRelays.flow.value)
} }
fun sendMyPublicAndPrivateOutbox(events: List<Event>) { fun sendMyPublicAndPrivateOutbox(events: List<Event>) {
@@ -1054,7 +1054,7 @@ class Account(
} }
fun sendLiterallyEverywhere(event: Event) { fun sendLiterallyEverywhere(event: Event) {
client.send(event, followPlusAllMineWithIndex.flow.value + client.availableRelaysFlow().value) client.publish(event, followPlusAllMineWithIndex.flow.value + client.availableRelaysFlow().value)
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
} }
@@ -1287,7 +1287,7 @@ class Account(
) { ) {
val event = signer.sign(template) val event = signer.sign(template)
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
client.send(event, relayList) client.publish(event, relayList)
} }
suspend fun <T : Event> signAndSendPrivatelyOrBroadcast( suspend fun <T : Event> signAndSendPrivatelyOrBroadcast(
@@ -1298,9 +1298,9 @@ class Account(
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
val relays = relayList(event) val relays = relayList(event)
if (!relays.isNullOrEmpty()) { if (!relays.isNullOrEmpty()) {
client.send(event, relays.toSet()) client.publish(event, relays.toSet())
} else { } else {
client.send(event, computeRelayListToBroadcast(event)) client.publish(event, computeRelayListToBroadcast(event))
} }
return event return event
} }
@@ -1320,7 +1320,7 @@ class Account(
val relayList = computeRelayListToBroadcast(note) val relayList = computeRelayListToBroadcast(note)
client.send(event, relayList) client.publish(event, relayList)
broadcast.forEach { client.send(it, relayList) } broadcast.forEach { client.send(it, relayList) }
@@ -1344,7 +1344,7 @@ class Account(
val relayList = computeRelayListToBroadcast(note) val relayList = computeRelayListToBroadcast(note)
client.send(event, relayList) client.publish(event, relayList)
broadcast.forEach { client.send(it, relayList) } broadcast.forEach { client.send(it, relayList) }
@@ -1463,9 +1463,9 @@ class Account(
val relayList = privateStorageRelayList.flow.value + localRelayList.flow.value val relayList = privateStorageRelayList.flow.value + localRelayList.flow.value
if (relayList.isNotEmpty()) { if (relayList.isNotEmpty()) {
client.send(event, relayList + noteRelays) client.publish(event, relayList + noteRelays)
} else { } else {
client.send(event, outboxRelays.flow.value + noteRelays) client.publish(event, outboxRelays.flow.value + noteRelays)
} }
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
} }
@@ -1489,9 +1489,9 @@ class Account(
val relayList = privateStorageRelayList.flow.value + localRelayList.flow.value val relayList = privateStorageRelayList.flow.value + localRelayList.flow.value
if (relayList.isNotEmpty()) { if (relayList.isNotEmpty()) {
client.send(event, relayList + noteRelays) client.publish(event, relayList + noteRelays)
} else { } else {
client.send(event, outboxRelays.flow.value + noteRelays) client.publish(event, outboxRelays.flow.value + noteRelays)
} }
cache.justConsumeMyOwnEvent(event) cache.justConsumeMyOwnEvent(event)
} }
@@ -1652,7 +1652,7 @@ class Account(
val note = cache.getOrCreateNote(event.id) val note = cache.getOrCreateNote(event.id)
val relayList = computeRelayListToBroadcast(note) val relayList = computeRelayListToBroadcast(note)
client.send(event, relayList = relayList) client.publish(event, relayList = relayList)
broadcast.forEach { client.send(it, relayList) } broadcast.forEach { client.send(it, relayList) }
} }
@@ -28,7 +28,7 @@ import com.vitorpamplona.amethyst.service.location.LocationState
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc.NWCPaymentFilterAssembler
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
import com.vitorpamplona.quartz.nip03Timestamp.OtsResolver import com.vitorpamplona.quartz.nip03Timestamp.OtsResolver
@@ -50,7 +50,7 @@ class AccountCacheState(
val contentResolverFn: () -> ContentResolver, val contentResolverFn: () -> ContentResolver,
val otsResolverBuilder: () -> OtsResolver, val otsResolverBuilder: () -> OtsResolver,
val cache: LocalCache, val cache: LocalCache,
val client: INostrClient, val client: NostrClient,
) { ) {
val accounts = MutableStateFlow<Map<HexKey, Account>>(emptyMap()) val accounts = MutableStateFlow<Map<HexKey, Account>>(emptyMap())
@@ -23,8 +23,8 @@ package com.vitorpamplona.amethyst.model.nip62Vanish
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.LocalCache.notes import com.vitorpamplona.amethyst.model.LocalCache.notes
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.downloadFirstEvent import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchFirst
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
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
@@ -61,7 +61,7 @@ enum class ComplianceStatus {
class VanishRequestsState( class VanishRequestsState(
val signer: NostrSigner, val signer: NostrSigner,
val cache: LocalCache, val cache: LocalCache,
val client: INostrClient, val client: NostrClient,
val scope: CoroutineScope, val scope: CoroutineScope,
) { ) {
val noteFlow = val noteFlow =
@@ -105,7 +105,7 @@ class VanishRequestsState(
try { try {
val foundEvent = val foundEvent =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
client.downloadFirstEvent( client.fetchFirst(
relay = relay, relay = relay,
filter = filter =
Filter( Filter(
@@ -21,8 +21,8 @@
package com.vitorpamplona.amethyst.service.broadcast package com.vitorpamplona.amethyst.service.broadcast
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.OkMessage import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.OkMessage
@@ -71,7 +71,7 @@ class BroadcastTracker {
suspend fun trackBroadcast( suspend fun trackBroadcast(
event: Event, event: Event,
relays: Set<NormalizedRelayUrl>, relays: Set<NormalizedRelayUrl>,
client: INostrClient, client: NostrClient,
) { ) {
val trackingId = UUID.randomUUID().toString() val trackingId = UUID.randomUUID().toString()
@@ -90,7 +90,7 @@ class BroadcastTracker {
val resultChannel = Channel<RelayResponse>(UNLIMITED) val resultChannel = Channel<RelayResponse>(UNLIMITED)
val subscription = val subscription =
object : IRelayClientListener { object : RelayConnectionListener {
override fun onCannotConnect( override fun onCannotConnect(
relay: IRelayClient, relay: IRelayClient,
errorMessage: String, errorMessage: String,
@@ -143,7 +143,7 @@ class BroadcastTracker {
} }
try { try {
client.subscribe(subscription) client.addConnectionListener(subscription)
val finalBroadcast = val finalBroadcast =
coroutineScope { coroutineScope {
@@ -178,7 +178,7 @@ class BroadcastTracker {
} }
// Send after setting up listener // Send after setting up listener
client.send(event, relays) client.publish(event, relays)
resultCollector.await() resultCollector.await()
} }
@@ -192,7 +192,7 @@ class BroadcastTracker {
Log.d(TAG, "Broadcast $trackingId complete: ${finalBroadcast.successCount}/${finalBroadcast.totalRelays} success") Log.d(TAG, "Broadcast $trackingId complete: ${finalBroadcast.successCount}/${finalBroadcast.totalRelays} success")
} finally { } finally {
client.unsubscribe(subscription) client.removeConnectionListener(subscription)
} }
} }
@@ -232,7 +232,7 @@ class BroadcastTracker {
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
suspend fun retry( suspend fun retry(
broadcast: BroadcastEvent, broadcast: BroadcastEvent,
client: INostrClient, client: NostrClient,
specificRelay: NormalizedRelayUrl? = null, specificRelay: NormalizedRelayUrl? = null,
): BroadcastEvent { ): BroadcastEvent {
val event = broadcast.event val event = broadcast.event
@@ -266,7 +266,7 @@ class BroadcastTracker {
val resultChannel = Channel<RelayResponse>(UNLIMITED) val resultChannel = Channel<RelayResponse>(UNLIMITED)
val subscription = val subscription =
object : IRelayClientListener { object : RelayConnectionListener {
override fun onCannotConnect( override fun onCannotConnect(
relay: IRelayClient, relay: IRelayClient,
errorMessage: String, errorMessage: String,
@@ -318,7 +318,7 @@ class BroadcastTracker {
} }
} }
client.subscribe(subscription) client.addConnectionListener(subscription)
val finalBroadcast = val finalBroadcast =
coroutineScope { coroutineScope {
@@ -370,12 +370,12 @@ class BroadcastTracker {
currentBroadcast.copy(status = newStatus) currentBroadcast.copy(status = newStatus)
} }
client.send(event, relaysToRetry) client.publish(event, relaysToRetry)
resultCollector.await() resultCollector.await()
} }
client.unsubscribe(subscription) client.removeConnectionListener(subscription)
resultChannel.close() resultChannel.close()
// Update in active broadcasts // Update in active broadcasts
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service.relayClient
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.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.EventCollector import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.EventCollector
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayInsertConfirmationCollector import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayInsertConfirmationCollector
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -31,7 +31,7 @@ import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
class CacheClientConnector( class CacheClientConnector(
val client: INostrClient, val client: NostrClient,
val cache: LocalCache, val cache: LocalCache,
) { ) {
val receiver = val receiver =
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.connectivity.ConnectivityStatus
import com.vitorpamplona.amethyst.service.okhttp.DualHttpClientManagerForRelays import com.vitorpamplona.amethyst.service.okhttp.DualHttpClientManagerForRelays
import com.vitorpamplona.amethyst.ui.tor.TorManager import com.vitorpamplona.amethyst.ui.tor.TorManager
import com.vitorpamplona.amethyst.ui.tor.TorServiceStatus import com.vitorpamplona.amethyst.ui.tor.TorServiceStatus
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.Log
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -48,7 +48,7 @@ class RelayProxyClientConnector(
val okHttpClients: DualHttpClientManagerForRelays, val okHttpClients: DualHttpClientManagerForRelays,
val connManager: ConnectivityManager, val connManager: ConnectivityManager,
val torManager: TorManager, val torManager: TorManager,
val client: INostrClient, val client: NostrClient,
val scope: CoroutineScope, val scope: CoroutineScope,
) { ) {
data class RelayServiceInfra( data class RelayServiceInfra(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service.relayClient.authCommand.model
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.isDebug import com.vitorpamplona.amethyst.isDebug
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.utils.Log import com.vitorpamplona.quartz.utils.Log
@@ -35,7 +35,7 @@ class ScreenAuthAccount(
@Stable @Stable
class AuthCoordinator( class AuthCoordinator(
client: INostrClient, client: NostrClient,
scope: CoroutineScope, scope: CoroutineScope,
) { ) {
private val authWithAccounts = ListWithUniqueSetCache<ScreenAuthAccount, Account> { it.account } private val authWithAccounts = ListWithUniqueSetCache<ScreenAuthAccount, Account> { it.account }
@@ -24,10 +24,10 @@ import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.BaseEoseManag
import com.vitorpamplona.amethyst.service.relays.EOSEByKey import com.vitorpamplona.amethyst.service.relays.EOSEByKey
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -42,7 +42,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* shares all EOSEs among all users. * shares all EOSEs among all users.
*/ */
abstract class PerUniqueIdEoseManager<T, U : Any>( abstract class PerUniqueIdEoseManager<T, U : Any>(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<T>, allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false, val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) { ) : BaseEoseManager<T>(client, allKeys) {
@@ -68,8 +68,8 @@ abstract class PerUniqueIdEoseManager<T, U : Any>(
open fun newSub(key: T): Subscription = open fun newSub(key: T): Subscription =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -78,11 +78,11 @@ abstract class PerUniqueIdEoseManager<T, U : Any>(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(key, relay, TimeUtils.now(), forFilters) newEose(key, relay, TimeUtils.now(), forFilters)
} }
} }
@@ -25,10 +25,10 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relays.EOSEAccountKey import com.vitorpamplona.amethyst.service.relays.EOSEAccountKey
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -46,7 +46,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* app reuse the EOSE because it assumes the filter is going to be different * app reuse the EOSE because it assumes the filter is going to be different
*/ */
abstract class PerUserAndFollowListEoseManager<T, U : Any>( abstract class PerUserAndFollowListEoseManager<T, U : Any>(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<T>, allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false, val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) { ) : BaseEoseManager<T>(client, allKeys) {
@@ -69,8 +69,8 @@ abstract class PerUserAndFollowListEoseManager<T, U : Any>(
open fun newSub(key: T): Subscription = open fun newSub(key: T): Subscription =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -79,11 +79,11 @@ abstract class PerUserAndFollowListEoseManager<T, U : Any>(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(key, relay, TimeUtils.now(), forFilters) newEose(key, relay, TimeUtils.now(), forFilters)
} }
} }
@@ -25,10 +25,10 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -44,7 +44,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* the subscription disappears and comes back later. * the subscription disappears and comes back later.
*/ */
abstract class PerUserEoseManager<T>( abstract class PerUserEoseManager<T>(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<T>, allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false, val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) { ) : BaseEoseManager<T>(client, allKeys) {
@@ -67,8 +67,8 @@ abstract class PerUserEoseManager<T>(
open fun newSub(key: T): Subscription = open fun newSub(key: T): Subscription =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -77,11 +77,11 @@ abstract class PerUserEoseManager<T>(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(key, relay, TimeUtils.now(), forFilters) newEose(key, relay, TimeUtils.now(), forFilters)
} }
} }
@@ -22,10 +22,10 @@ package com.vitorpamplona.amethyst.service.relayClient.eoseManagers
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.BaseEoseManager import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.BaseEoseManager
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -35,14 +35,14 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
* filters * filters
*/ */
abstract class SingleSubNoEoseCacheEoseManager<T>( abstract class SingleSubNoEoseCacheEoseManager<T>(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<T>, allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false, val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) { ) : BaseEoseManager<T>(client, allKeys) {
val sub = val sub =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -53,11 +53,11 @@ abstract class SingleSubNoEoseCacheEoseManager<T>(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
if (invalidateAfterEose) { if (invalidateAfterEose) {
invalidateFilters() invalidateFilters()
} }
@@ -20,11 +20,11 @@
*/ */
package com.vitorpamplona.amethyst.service.relayClient.notifyCommand.model package com.vitorpamplona.amethyst.service.relayClient.notifyCommand.model
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayNotifier import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayNotifier
class NotifyCoordinator( class NotifyCoordinator(
client: INostrClient, client: NostrClient,
) { ) {
val requests = NotifyRequestsCache() val requests = NotifyRequestsCache()
@@ -43,14 +43,14 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource.RelayFeedF
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource.RelayInfoNip66FilterAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource.RelayInfoNip66FilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadFilterAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadFilterAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.VideoFilterAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.VideoFilterAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
class RelaySubscriptionsCoordinator( class RelaySubscriptionsCoordinator(
cache: LocalCache, cache: LocalCache,
client: INostrClient, client: NostrClient,
authenticator: IAuthStatus, authenticator: IAuthStatus,
failureTracker: RelayOfflineTracker, failureTracker: RelayOfflineTracker,
scope: CoroutineScope, scope: CoroutineScope,
@@ -32,7 +32,7 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.nip01No
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.nip59GiftWraps.AccountGiftWrapsEoseManager import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.nip59GiftWraps.AccountGiftWrapsEoseManager
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@@ -50,7 +50,7 @@ class AccountQueryState(
*/ */
@Stable @Stable
class AccountFilterAssembler( class AccountFilterAssembler(
client: INostrClient, client: NostrClient,
cache: LocalCache, cache: LocalCache,
authenticator: IAuthStatus, authenticator: IAuthStatus,
failureTracker: RelayOfflineTracker, failureTracker: RelayOfflineTracker,
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AccountDraftsEoseManager( class AccountDraftsEoseManager(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<AccountQueryState>, allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) { ) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
override fun user(key: AccountQueryState) = key.account.userProfile() override fun user(key: AccountQueryState) = key.account.userProfile()
@@ -30,12 +30,12 @@ import com.vitorpamplona.amethyst.service.BundledUpdate
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus import com.vitorpamplona.quartz.nip01Core.relay.client.auth.IAuthStatus
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.SubscriptionController import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.SubscriptionController
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
@@ -56,7 +56,7 @@ import kotlinx.coroutines.launch
* It needs to be super fast on startup. * It needs to be super fast on startup.
*/ */
class AccountFollowsLoaderSubAssembler( class AccountFollowsLoaderSubAssembler(
val client: INostrClient, val client: NostrClient,
val cache: LocalCache, val cache: LocalCache,
val scope: CoroutineScope, val scope: CoroutineScope,
val authStatus: IAuthStatus, val authStatus: IAuthStatus,
@@ -107,8 +107,8 @@ class AccountFollowsLoaderSubAssembler(
val sub = val sub =
orchestrator.requestNewSubscription( orchestrator.requestNewSubscription(
if (isDebug) logTag + newSubId() else newSubId(), if (isDebug) logTag + newSubId() else newSubId(),
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -117,11 +117,11 @@ class AccountFollowsLoaderSubAssembler(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(TimeUtils.now(), relay, forFilters) newEose(TimeUtils.now(), relay, forFilters)
} }
} }
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
@@ -35,7 +35,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AccountMetadataEoseManager( class AccountMetadataEoseManager(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<AccountQueryState>, allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) { ) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
override fun user(key: AccountQueryState) = key.account.userProfile() override fun user(key: AccountQueryState) = key.account.userProfile()
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
@@ -36,7 +36,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AccountNotificationsEoseFromInboxRelaysManager( class AccountNotificationsEoseFromInboxRelaysManager(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<AccountQueryState>, allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) { ) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
override fun user(key: AccountQueryState) = key.account.userProfile() override fun user(key: AccountQueryState) = key.account.userProfile()
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AccountNotificationsEoseFromRandomRelaysManager( class AccountNotificationsEoseFromRandomRelaysManager(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<AccountQueryState>, allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) { ) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
override fun user(key: AccountQueryState) = key.account.userProfile() override fun user(key: AccountQueryState) = key.account.userProfile()
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.AccountQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AccountGiftWrapsEoseManager( class AccountGiftWrapsEoseManager(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<AccountQueryState>, allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) { ) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
override fun user(key: AccountQueryState) = key.account.userProfile() override fun user(key: AccountQueryState) = key.account.userProfile()
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.model.Channel
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.mixChatsLive.ChannelMetadataAndLiveActivityWatcherSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.mixChatsLive.ChannelMetadataAndLiveActivityWatcherSubAssembler
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip28PublicChats.ChannelLoaderSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip28PublicChats.ChannelLoaderSubAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@Stable @Stable
@@ -35,7 +35,7 @@ class ChannelFinderQueryState(
@Stable @Stable
class ChannelFinderFilterAssemblyGroup( class ChannelFinderFilterAssemblyGroup(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<ChannelFinderQueryState>() { ) : ComposeSubscriptionManager<ChannelFinderQueryState>() {
val group = val group =
listOf( listOf(
@@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.Channel
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip28PublicChats.filterChannelMetadataUpdatesById import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip28PublicChats.filterChannelMetadataUpdatesById
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip53LiveActivities.filterLiveStreamUpdatesByAddress import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip53LiveActivities.filterLiveStreamUpdatesByAddress
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.utils.mapOfSet import com.vitorpamplona.quartz.utils.mapOfSet
@@ -39,7 +39,7 @@ import com.vitorpamplona.quartz.utils.mapOfSet
* only one EOSE for everybody. * only one EOSE for everybody.
*/ */
class ChannelMetadataAndLiveActivityWatcherSubAssembler( class ChannelMetadataAndLiveActivityWatcherSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>, allKeys: () -> Set<ChannelFinderQueryState>,
) : SingleSubEoseManager<ChannelFinderQueryState>(client, allKeys) { ) : SingleSubEoseManager<ChannelFinderQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.nip28P
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.SingleSubNoEoseCacheEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.SingleSubNoEoseCacheEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderQueryState
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
/** /**
@@ -35,7 +35,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
* This is one filter for everybody. * This is one filter for everybody.
*/ */
class ChannelLoaderSubAssembler( class ChannelLoaderSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>, allKeys: () -> Set<ChannelFinderQueryState>,
) : SingleSubNoEoseCacheEoseManager<ChannelFinderQueryState>(client, allKeys, invalidateAfterEose = true) { ) : SingleSubNoEoseCacheEoseManager<ChannelFinderQueryState>(client, allKeys, invalidateAfterEose = true) {
override fun updateFilter(keys: List<ChannelFinderQueryState>): List<RelayBasedFilter> = filterMissingChannelsById(keys) override fun updateFilter(keys: List<ChannelFinderQueryState>): List<RelayBasedFilter> = filterMissingChannelsById(keys)
@@ -25,11 +25,11 @@ import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChann
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class ChannelMetadataWatcherSubAssembler( class ChannelMetadataWatcherSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>, allKeys: () -> Set<ChannelFinderQueryState>,
) : PerUniqueIdEoseManager<ChannelFinderQueryState, Channel>(client, allKeys) { ) : PerUniqueIdEoseManager<ChannelFinderQueryState, Channel>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActiviti
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.channel.ChannelFinderQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
/** /**
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
* since they are replaceable. * since they are replaceable.
*/ */
class LiveActivityWatcherSubAssembly( class LiveActivityWatcherSubAssembly(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>, allKeys: () -> Set<ChannelFinderQueryState>,
) : PerUniqueIdEoseManager<ChannelFinderQueryState, Channel>(client, allKeys) { ) : PerUniqueIdEoseManager<ChannelFinderQueryState, Channel>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.loaders.NoteEventLoaderSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.loaders.NoteEventLoaderSubAssembler
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.watchers.EventWatcherSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.watchers.EventWatcherSubAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@Stable @Stable
@@ -37,7 +37,7 @@ class EventFinderQueryState(
@Stable @Stable
class EventFinderFilterAssembler( class EventFinderFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<EventFinderQueryState>() { ) : ComposeSubscriptionManager<EventFinderQueryState>() {
val group = val group =
listOf( listOf(
@@ -22,10 +22,10 @@ package com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.loaders
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.SingleSubNoEoseCacheEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.SingleSubNoEoseCacheEoseManager
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFinderQueryState
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
class NoteEventLoaderSubAssembler( class NoteEventLoaderSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<EventFinderQueryState>, allKeys: () -> Set<EventFinderQueryState>,
) : SingleSubNoEoseCacheEoseManager<EventFinderQueryState>(client, allKeys, invalidateAfterEose = true) { ) : SingleSubNoEoseCacheEoseManager<EventFinderQueryState>(client, allKeys, invalidateAfterEose = true) {
override fun updateFilter(keys: List<EventFinderQueryState>) = override fun updateFilter(keys: List<EventFinderQueryState>) =
@@ -27,13 +27,13 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.EventFind
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
import com.vitorpamplona.amethyst.service.relays.MutableTime import com.vitorpamplona.amethyst.service.relays.MutableTime
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
class EventWatcherSubAssembler( class EventWatcherSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<EventFinderQueryState>, allKeys: () -> Set<EventFinderQueryState>,
) : SingleSubEoseManager<EventFinderQueryState>(client, allKeys) { ) : SingleSubEoseManager<EventFinderQueryState>(client, allKeys) {
var lastNotesOnFilter = emptyList<Note>() var lastNotesOnFilter = emptyList<Note>()
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -37,7 +37,7 @@ class NWCPaymentQueryState(
@Stable @Stable
class NWCPaymentFilterAssembler( class NWCPaymentFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<NWCPaymentQueryState>() { ) : ComposeSubscriptionManager<NWCPaymentQueryState>() {
val group = val group =
listOf( listOf(
@@ -21,11 +21,11 @@
package com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc package com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.SingleSubNoEoseCacheEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.SingleSubNoEoseCacheEoseManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class NWCPaymentWatcherSubAssembler( class NWCPaymentWatcherSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<NWCPaymentQueryState>, allKeys: () -> Set<NWCPaymentQueryState>,
) : SingleSubNoEoseCacheEoseManager<NWCPaymentQueryState>(client, allKeys) { ) : SingleSubNoEoseCacheEoseManager<NWCPaymentQueryState>(client, allKeys) {
override fun updateFilter(keys: List<NWCPaymentQueryState>): List<RelayBasedFilter>? { override fun updateFilter(keys: List<NWCPaymentQueryState>): List<RelayBasedFilter>? {
@@ -29,7 +29,7 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.loaders.Us
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.watchers.UserCardsSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.watchers.UserCardsSubAssembler
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.watchers.UserReportsSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.watchers.UserReportsSubAssembler
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.watchers.UserWatcherSubAssembler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.watchers.UserWatcherSubAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -41,7 +41,7 @@ class UserFinderQueryState(
@Stable @Stable
class UserFinderFilterAssembler( class UserFinderFilterAssembler(
client: INostrClient, client: NostrClient,
cache: LocalCache, cache: LocalCache,
failureTracker: RelayOfflineTracker, failureTracker: RelayOfflineTracker,
) : ComposeSubscriptionManager<UserFinderQueryState>() { ) : ComposeSubscriptionManager<UserFinderQueryState>() {
@@ -27,18 +27,18 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.follows
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
class UserOutboxFinderSubAssembler( class UserOutboxFinderSubAssembler(
client: INostrClient, client: NostrClient,
val cache: LocalCache, val cache: LocalCache,
val failureTracker: RelayOfflineTracker, val failureTracker: RelayOfflineTracker,
allKeys: () -> Set<UserFinderQueryState>, allKeys: () -> Set<UserFinderQueryState>,
@@ -68,8 +68,8 @@ class UserOutboxFinderSubAssembler(
val sub = val sub =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -28,14 +28,14 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinder
import com.vitorpamplona.amethyst.service.relays.MutableTime import com.vitorpamplona.amethyst.service.relays.MutableTime
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.mapOfSet import com.vitorpamplona.quartz.utils.mapOfSet
class UserCardsSubAssembler( class UserCardsSubAssembler(
client: INostrClient, client: NostrClient,
val cache: LocalCache, val cache: LocalCache,
allKeys: () -> Set<UserFinderQueryState>, allKeys: () -> Set<UserFinderQueryState>,
) : SingleSubEoseManager<UserFinderQueryState>(client, allKeys) { ) : SingleSubEoseManager<UserFinderQueryState>(client, allKeys) {
@@ -27,14 +27,14 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState
import com.vitorpamplona.amethyst.service.relays.MutableTime import com.vitorpamplona.amethyst.service.relays.MutableTime
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.mapOfSet import com.vitorpamplona.quartz.utils.mapOfSet
class UserReportsSubAssembler( class UserReportsSubAssembler(
client: INostrClient, client: NostrClient,
val cache: LocalCache, val cache: LocalCache,
allKeys: () -> Set<UserFinderQueryState>, allKeys: () -> Set<UserFinderQueryState>,
) : SingleSubEoseManager<UserFinderQueryState>(client, allKeys) { ) : SingleSubEoseManager<UserFinderQueryState>(client, allKeys) {
@@ -27,15 +27,15 @@ import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderQueryState
import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast import com.vitorpamplona.amethyst.service.relays.EOSEAccountFast
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
class UserWatcherSubAssembler( class UserWatcherSubAssembler(
client: INostrClient, client: NostrClient,
val cache: LocalCache, val cache: LocalCache,
allKeys: () -> Set<UserFinderQueryState>, allKeys: () -> Set<UserFinderQueryState>,
) : BaseEoseManager<UserFinderQueryState>(client, allKeys) { ) : BaseEoseManager<UserFinderQueryState>(client, allKeys) {
@@ -61,8 +61,8 @@ class UserWatcherSubAssembler(
val sub = val sub =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -71,11 +71,11 @@ class UserWatcherSubAssembler(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(relay, TimeUtils.now(), forFilters) newEose(relay, TimeUtils.now(), forFilters)
} }
} }
@@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.subassemblies.SearchPostWatcherSubAssembler import com.vitorpamplona.amethyst.service.relayClient.searchCommand.subassemblies.SearchPostWatcherSubAssembler
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.subassemblies.SearchUserWatcherSubAssembler import com.vitorpamplona.amethyst.service.relayClient.searchCommand.subassemblies.SearchUserWatcherSubAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -42,7 +42,7 @@ class SearchQueryState(
@Stable @Stable
class SearchFilterAssembler( class SearchFilterAssembler(
client: INostrClient, client: NostrClient,
scope: CoroutineScope, scope: CoroutineScope,
val cache: LocalCache, val cache: LocalCache,
) : MutableComposeSubscriptionManager<SearchQueryState>(scope) { ) : MutableComposeSubscriptionManager<SearchQueryState>(scope) {
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEo
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.SearchQueryState import com.vitorpamplona.amethyst.service.relayClient.searchCommand.SearchQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
@@ -44,7 +44,7 @@ import com.vitorpamplona.quartz.utils.Hex
*/ */
class SearchPostWatcherSubAssembler( class SearchPostWatcherSubAssembler(
val cache: LocalCache, val cache: LocalCache,
client: INostrClient, client: NostrClient,
allKeys: () -> Set<SearchQueryState>, allKeys: () -> Set<SearchQueryState>,
) : PerUniqueIdEoseManager<SearchQueryState, Int>(client, allKeys) { ) : PerUniqueIdEoseManager<SearchQueryState, Int>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEo
import com.vitorpamplona.amethyst.service.relayClient.searchCommand.SearchQueryState import com.vitorpamplona.amethyst.service.relayClient.searchCommand.SearchQueryState
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
@@ -45,7 +45,7 @@ import com.vitorpamplona.quartz.utils.Hex
*/ */
class SearchUserWatcherSubAssembler( class SearchUserWatcherSubAssembler(
val cache: LocalCache, val cache: LocalCache,
client: INostrClient, client: NostrClient,
allKeys: () -> Set<SearchQueryState>, allKeys: () -> Set<SearchQueryState>,
) : PerUniqueIdEoseManager<SearchQueryState, Int>(client, allKeys) { ) : PerUniqueIdEoseManager<SearchQueryState, Int>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -20,8 +20,8 @@
*/ */
package com.vitorpamplona.amethyst.service.relayClient.speedLogger package com.vitorpamplona.amethyst.service.relayClient.speedLogger
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.EventMessage import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.EventMessage
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
@@ -32,7 +32,7 @@ import com.vitorpamplona.quartz.utils.bytesUsedInMemory
* Listens to NostrClient's onNotify messages from the relay * Listens to NostrClient's onNotify messages from the relay
*/ */
class RelaySpeedLogger( class RelaySpeedLogger(
val client: INostrClient, val client: NostrClient,
) { ) {
companion object { companion object {
val TAG: String = RelaySpeedLogger::class.java.simpleName val TAG: String = RelaySpeedLogger::class.java.simpleName
@@ -41,7 +41,7 @@ class RelaySpeedLogger(
var current = FrameStat() var current = FrameStat()
private val clientListener = private val clientListener =
object : IRelayClientListener { object : RelayConnectionListener {
override fun onIncomingMessage( override fun onIncomingMessage(
relay: IRelayClient, relay: IRelayClient,
msgStr: String, msgStr: String,
@@ -55,7 +55,7 @@ class RelaySpeedLogger(
init { init {
Log.d(TAG, "Init, Subscribe") Log.d(TAG, "Init, Subscribe")
client.subscribe(clientListener) client.addConnectionListener(clientListener)
// OkHttpDebugLogging.enableHttp2() // OkHttpDebugLogging.enableHttp2()
// OkHttpDebugLogging.enableTaskRunner() // OkHttpDebugLogging.enableTaskRunner()
} }
@@ -63,6 +63,6 @@ class RelaySpeedLogger(
fun destroy() { fun destroy() {
// makes sure to run // makes sure to run
Log.d(TAG, "Destroy, Unsubscribe") Log.d(TAG, "Destroy, Unsubscribe")
client.unsubscribe(clientListener) client.removeConnectionListener(clientListener)
} }
} }
@@ -38,7 +38,7 @@ import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag
@@ -94,7 +94,7 @@ sealed class AccountState {
class AccountSessionManager( class AccountSessionManager(
val accountsCache: AccountCacheState, val accountsCache: AccountCacheState,
val nip05ClientBuilder: () -> Nip05Client, val nip05ClientBuilder: () -> Nip05Client,
val clientBuilder: () -> INostrClient, val clientBuilder: () -> NostrClient,
val localPreferences: LocalPreferences, val localPreferences: LocalPreferences,
val scope: CoroutineScope, val scope: CoroutineScope,
) { ) {
@@ -98,7 +98,6 @@ import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
import com.vitorpamplona.quartz.nip01Core.relay.client.EmptyNostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.EmptyNostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.EmptyIAuthStatus import com.vitorpamplona.quartz.nip01Core.relay.client.auth.EmptyIAuthStatus
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator
@@ -220,7 +219,7 @@ class AccountViewModel(
val customScope = CoroutineScope(viewModelScope.coroutineContext + SupervisorJob()) val customScope = CoroutineScope(viewModelScope.coroutineContext + SupervisorJob())
// Provides a relay pool // Provides a relay pool
val newClient = NostrClient(Amethyst.instance.websocketBuilder, customScope) val newClient = DefaultNostrClient(Amethyst.instance.websocketBuilder, customScope)
// Authenticates with relays. // Authenticates with relays.
val auth = val auth =
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -34,7 +34,7 @@ class ChatroomQueryState(
} }
class ChatroomFilterAssembler( class ChatroomFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<ChatroomQueryState>() { ) : ComposeSubscriptionManager<ChatroomQueryState>() {
val group = val group =
listOf( listOf(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFollowListEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFollowListEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class ChatroomFilterSubAssembler( class ChatroomFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChatroomQueryState>, allKeys: () -> Set<ChatroomQueryState>,
) : PerUserAndFollowListEoseManager<ChatroomQueryState, String>(client, allKeys) { ) : PerUserAndFollowListEoseManager<ChatroomQueryState, String>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.subassemblies.ChannelFromUserFilterSubAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.subassemblies.ChannelFromUserFilterSubAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.subassemblies.ChannelPublicFilterSubAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.subassemblies.ChannelPublicFilterSubAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
class ChannelQueryState( class ChannelQueryState(
@@ -34,7 +34,7 @@ class ChannelQueryState(
) )
class ChannelFilterAssembler( class ChannelFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<ChannelQueryState>() { ) : ComposeSubscriptionManager<ChannelQueryState>() {
val group = val group =
listOf( listOf(
@@ -27,11 +27,11 @@ import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActiviti
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFollowListEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFollowListEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.ChannelQueryState import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.ChannelQueryState
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class ChannelFromUserFilterSubAssembler( class ChannelFromUserFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChannelQueryState>, allKeys: () -> Set<ChannelQueryState>,
) : PerUserAndFollowListEoseManager<ChannelQueryState, Channel>(client, allKeys) { ) : PerUserAndFollowListEoseManager<ChannelQueryState, Channel>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -27,11 +27,11 @@ import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActiviti
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.ChannelQueryState import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.publicChannels.datasource.ChannelQueryState
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class ChannelPublicFilterSubAssembler( class ChannelPublicFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChannelQueryState>, allKeys: () -> Set<ChannelQueryState>,
) : PerUniqueIdEoseManager<ChannelQueryState, Channel>(client, allKeys) { ) : PerUniqueIdEoseManager<ChannelQueryState, Channel>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@Stable @Stable
@@ -33,7 +33,7 @@ class ChatroomListState(
@Stable @Stable
class ChatroomListFilterAssembler( class ChatroomListFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<ChatroomListState>() { ) : ComposeSubscriptionManager<ChatroomListState>() {
val group = val group =
listOf( listOf(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -33,7 +33,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class DMsFromUserFilterSubAssembler( class DMsFromUserFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChatroomListState>, allKeys: () -> Set<ChatroomListState>,
) : PerUserEoseManager<ChatroomListState>(client, allKeys) { ) : PerUserEoseManager<ChatroomListState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class FollowingEphemeralChatSubAssembler( class FollowingEphemeralChatSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChatroomListState>, allKeys: () -> Set<ChatroomListState>,
) : PerUserEoseManager<ChatroomListState>(client, allKeys) { ) : PerUserEoseManager<ChatroomListState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class FollowingPublicChatSubAssembler( class FollowingPublicChatSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChatroomListState>, allKeys: () -> Set<ChatroomListState>,
) : PerUserEoseManager<ChatroomListState>(client, allKeys) { ) : PerUserEoseManager<ChatroomListState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -42,7 +42,7 @@ data class ChessQueryState(
* Sub-assembler that creates the actual relay filters * Sub-assembler that creates the actual relay filters
*/ */
class ChessFeedFilterSubAssembler( class ChessFeedFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ChessQueryState>, allKeys: () -> Set<ChessQueryState>,
) : PerUniqueIdEoseManager<ChessQueryState, String>(client, allKeys) { ) : PerUniqueIdEoseManager<ChessQueryState, String>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -21,13 +21,13 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
/** /**
* Filter assembler for chess events * Filter assembler for chess events
*/ */
class ChessFilterAssembler( class ChessFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<ChessQueryState>() { ) : ComposeSubscriptionManager<ChessQueryState>() {
val group = val group =
listOf( listOf(
@@ -23,13 +23,13 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.datasource
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent
import com.vitorpamplona.quartz.utils.mapOfSet import com.vitorpamplona.quartz.utils.mapOfSet
class CommunityFeedFilterSubAssembler( class CommunityFeedFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<CommunityQueryState>, allKeys: () -> Set<CommunityQueryState>,
) : SingleSubEoseManager<CommunityQueryState>(client, allKeys) { ) : SingleSubEoseManager<CommunityQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.communities.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
class CommunityQueryState( class CommunityQueryState(
@@ -30,7 +30,7 @@ class CommunityQueryState(
) )
class CommunityFilterAssembler( class CommunityFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<CommunityQueryState>() { ) : ComposeSubscriptionManager<CommunityQueryState>() {
val group = val group =
listOf( listOf(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -34,7 +34,7 @@ class DiscoveryQueryState(
) )
class DiscoveryFilterAssembler( class DiscoveryFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<DiscoveryQueryState>() { ) : ComposeSubscriptionManager<DiscoveryQueryState>() {
val group = val group =
listOf( listOf(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFol
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip51FollowSets.makeFollowSetsFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip51FollowSets.makeFollowSetsFilter
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip53LiveActivities.makeLiveActivitiesFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip53LiveActivities.makeLiveActivitiesFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class DiscoveryFollowsSetsAndLiveStreamsSubAssembler2( class DiscoveryFollowsSetsAndLiveStreamsSubAssembler2(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<DiscoveryQueryState>, allKeys: () -> Set<DiscoveryQueryState>,
) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) { ) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -27,7 +27,7 @@ import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip23LongForm.makeLongFormFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip23LongForm.makeLongFormFilter
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip90DVMs.makeContentDVMsFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip90DVMs.makeContentDVMsFilter
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip99Classifieds.makeClassifiedsFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip99Classifieds.makeClassifiedsFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -39,7 +39,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class DiscoveryLongFormClassifiedsAndDVMSubAssembler1( class DiscoveryLongFormClassifiedsAndDVMSubAssembler1(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<DiscoveryQueryState>, allKeys: () -> Set<DiscoveryQueryState>,
) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) { ) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFol
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip28Chats.makePublicChatsFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip28Chats.makePublicChatsFilter
import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip72Communities.makeCommunitiesFilter import com.vitorpamplona.amethyst.ui.screen.loggedIn.discover.nip72Communities.makeCommunitiesFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class DiscoveryPublicChatsAndCommunitiesSubAssembler3( class DiscoveryPublicChatsAndCommunitiesSubAssembler3(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<DiscoveryQueryState>, allKeys: () -> Set<DiscoveryQueryState>,
) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) { ) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -24,7 +24,7 @@ import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
class FollowPackFeedQueryState( class FollowPackFeedQueryState(
@@ -34,7 +34,7 @@ class FollowPackFeedQueryState(
@Stable @Stable
class FollowPackFeedFilterAssembler( class FollowPackFeedFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<FollowPackFeedQueryState>() { ) : ComposeSubscriptionManager<FollowPackFeedQueryState>() {
val group = val group =
listOf( listOf(
@@ -25,12 +25,12 @@ import com.vitorpamplona.amethyst.model.topNavFeeds.allUserFollows.AllUserFollow
import com.vitorpamplona.amethyst.model.topNavFeeds.allUserFollows.AllUserFollowsByProxyTopNavFilter import com.vitorpamplona.amethyst.model.topNavFeeds.allUserFollows.AllUserFollowsByProxyTopNavFilter
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip65Follows.filterHomePostsByAuthors import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip65Follows.filterHomePostsByAuthors
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent
class FollowPackFeedFilterSubAssembler( class FollowPackFeedFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<FollowPackFeedQueryState>, allKeys: () -> Set<FollowPackFeedQueryState>,
) : SingleSubEoseManager<FollowPackFeedQueryState>(client, allKeys) { ) : SingleSubEoseManager<FollowPackFeedQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.geohash.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class GeoHashFeedFilterSubAssembler( class GeoHashFeedFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<GeohashQueryState>, allKeys: () -> Set<GeohashQueryState>,
) : PerUniqueIdEoseManager<GeohashQueryState, String>(client, allKeys) { ) : PerUniqueIdEoseManager<GeohashQueryState, String>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.geohash.datasource
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -38,7 +38,7 @@ class GeohashQueryState(
*/ */
@Stable @Stable
class GeoHashFilterAssembler( class GeoHashFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<GeohashQueryState>() { ) : ComposeSubscriptionManager<GeohashQueryState>() {
val group = val group =
listOf( listOf(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class HashtagFeedFilterSubAssembler( class HashtagFeedFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<HashtagQueryState>, allKeys: () -> Set<HashtagQueryState>,
) : PerUniqueIdEoseManager<HashtagQueryState, String>(client, allKeys) { ) : PerUniqueIdEoseManager<HashtagQueryState, String>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -21,7 +21,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.datasource package com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -33,7 +33,7 @@ class HashtagQueryState(
} }
class HashtagFilterAssembler( class HashtagFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<HashtagQueryState>() { ) : ComposeSubscriptionManager<HashtagQueryState>() {
val group = val group =
listOf( listOf(
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip65Follows.HomeOutboxEventsEoseManager import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip65Follows.HomeOutboxEventsEoseManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -39,7 +39,7 @@ class HomeQueryState(
@Stable @Stable
class HomeFilterAssembler( class HomeFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<HomeQueryState>() { ) : ComposeSubscriptionManager<HomeQueryState>() {
val group = val group =
listOf( listOf(
@@ -40,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip01Core.f
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip64Chess.filterHomePostsByChess import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip64Chess.filterHomePostsByChess
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip72Communities.filterHomePostsByAllCommunities import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip72Communities.filterHomePostsByAllCommunities
import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip72Communities.filterHomePostsByCommunity import com.vitorpamplona.amethyst.ui.screen.loggedIn.home.datasource.nip72Communities.filterHomePostsByCommunity
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -51,7 +51,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class HomeOutboxEventsEoseManager( class HomeOutboxEventsEoseManager(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<HomeQueryState>, allKeys: () -> Set<HomeQueryState>,
) : PerUserAndFollowListEoseManager<HomeQueryState, TopFilter>(client, allKeys) { ) : PerUserAndFollowListEoseManager<HomeQueryState, TopFilter>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
class UserProfileQueryState( class UserProfileQueryState(
@@ -30,7 +30,7 @@ class UserProfileQueryState(
) )
class UserProfileFilterAssembler( class UserProfileFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<UserProfileQueryState>() { ) : ComposeSubscriptionManager<UserProfileQueryState>() {
val group = val group =
listOf( listOf(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfileFollowersFilterSubAssembler( class UserProfileFollowersFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>, allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) { ) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfileMediaFilterSubAssembler( class UserProfileMediaFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>, allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) { ) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -23,12 +23,12 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.utils.mapOfSet import com.vitorpamplona.quartz.utils.mapOfSet
class UserProfileMetadataFilterSubAssembler( class UserProfileMetadataFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>, allKeys: () -> Set<UserProfileQueryState>,
) : SingleSubEoseManager<UserProfileQueryState>(client, allKeys) { ) : SingleSubEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfilePostsFilterSubAssembler( class UserProfilePostsFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>, allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) { ) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class UserProfileZapsFilterSubAssembler( class UserProfileZapsFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>, allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) { ) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -21,7 +21,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource package com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
// This allows multiple screens to be listening to the same or different relay feeds. // This allows multiple screens to be listening to the same or different relay feeds.
@@ -30,7 +30,7 @@ class RelayFeedQueryState(
) )
class RelayFeedFilterAssembler( class RelayFeedFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<RelayFeedQueryState>() { ) : ComposeSubscriptionManager<RelayFeedQueryState>() {
val group = val group =
listOf( listOf(
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
class RelayFeedFilterSubAssembler( class RelayFeedFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<RelayFeedQueryState>, allKeys: () -> Set<RelayFeedQueryState>,
) : PerUniqueIdEoseManager<RelayFeedQueryState, String>(client, allKeys) { ) : PerUniqueIdEoseManager<RelayFeedQueryState, String>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.service.replace import com.vitorpamplona.amethyst.service.replace
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.queryCountSuspend import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.count
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -99,7 +99,7 @@ abstract class BasicRelaySetupInfoModel : ViewModel() {
filters.forEach { countFilter -> filters.forEach { countFilter ->
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val result = client.queryCountSuspend(item.relay, countFilter.filter) val result = client.count(item.relay, countFilter.filter)
if (result != null) { if (result != null) {
_countResults.update { currentMap -> _countResults.update { currentMap ->
val current = currentMap[item.relay] ?: RelayCountResult() val current = currentMap[item.relay] ?: RelayCountResult()
@@ -21,7 +21,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
class RelayInfoNip66QueryState( class RelayInfoNip66QueryState(
@@ -30,7 +30,7 @@ class RelayInfoNip66QueryState(
) )
class RelayInfoNip66FilterAssembler( class RelayInfoNip66FilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<RelayInfoNip66QueryState>() { ) : ComposeSubscriptionManager<RelayInfoNip66QueryState>() {
val group = val group =
listOf( listOf(
@@ -22,13 +22,13 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource
import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEoseManager
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip66RelayMonitor.discovery.RelayDiscoveryEvent import com.vitorpamplona.quartz.nip66RelayMonitor.discovery.RelayDiscoveryEvent
class RelayInfoNip66FilterSubAssembler( class RelayInfoNip66FilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<RelayInfoNip66QueryState>, allKeys: () -> Set<RelayInfoNip66QueryState>,
) : PerUniqueIdEoseManager<RelayInfoNip66QueryState, String>(client, allKeys) { ) : PerUniqueIdEoseManager<RelayInfoNip66QueryState, String>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -27,9 +27,9 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.eventsync.EventSync.
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.eventsync.EventSync.LiveSyncActivity.SourceRelayInfo import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.eventsync.EventSync.LiveSyncActivity.SourceRelayInfo
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.reqBypassingRelayLimits import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchAllPages
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.OkMessage import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.OkMessage
@@ -65,7 +65,7 @@ import kotlin.coroutines.cancellation.CancellationException
* Each relay is paginated individually: after EOSE the oldest [Event.createdAt] seen on that * Each relay is paginated individually: after EOSE the oldest [Event.createdAt] seen on that
* relay becomes the next `until` cursor, repeating until the relay returns no new events. * relay becomes the next `until` cursor, repeating until the relay returns no new events.
* *
* OK (true) responses from destination relays are tracked via [IRelayClientListener] and * OK (true) responses from destination relays are tracked via [RelayConnectionListener] and
* attributed back to the source relay that contributed each event. * attributed back to the source relay that contributed each event.
* *
* Live activity is emitted via [liveActivity] so the UI can show a per-relay log of events * Live activity is emitted via [liveActivity] so the UI can show a per-relay log of events
@@ -80,7 +80,7 @@ class EventSync(
private val outboxTargets: () -> Set<NormalizedRelayUrl>, private val outboxTargets: () -> Set<NormalizedRelayUrl>,
private val inboxTargets: () -> Set<NormalizedRelayUrl>, private val inboxTargets: () -> Set<NormalizedRelayUrl>,
private val dmTargets: () -> Set<NormalizedRelayUrl>, private val dmTargets: () -> Set<NormalizedRelayUrl>,
private val clientBuilder: () -> INostrClient, private val clientBuilder: () -> NostrClient,
private val scope: CoroutineScope, private val scope: CoroutineScope,
) { ) {
companion object { companion object {
@@ -406,7 +406,7 @@ class EventSync(
) )
val okListener = val okListener =
object : IRelayClientListener { object : RelayConnectionListener {
override fun onCannotConnect( override fun onCannotConnect(
relay: IRelayClient, relay: IRelayClient,
errorMessage: String, errorMessage: String,
@@ -500,7 +500,7 @@ class EventSync(
_syncState.emit(runningState) _syncState.emit(runningState)
clientBuilder().use { client -> clientBuilder().use { client ->
client.subscribe(okListener) client.addConnectionListener(okListener)
try { try {
client.downloadFromPool( client.downloadFromPool(
relays = relaysToProcess, relays = relaysToProcess,
@@ -523,21 +523,21 @@ class EventSync(
// Each routing rule is independent: an event can match more than one. // Each routing rule is independent: an event can match more than one.
if (isMyEvent && outboxTargets.isNotEmpty()) { if (isMyEvent && outboxTargets.isNotEmpty()) {
if (outboxDedup.add(event.id)) { if (outboxDedup.add(event.id)) {
client.send(event, outboxTargets) client.publish(event, outboxTargets)
newEvent = true newEvent = true
} }
matchesAtLeastOneFilter = true matchesAtLeastOneFilter = true
} }
if (mentionsMe && isDmKind && dmTargets.isNotEmpty()) { if (mentionsMe && isDmKind && dmTargets.isNotEmpty()) {
if (dmDedup.add(event.id)) { if (dmDedup.add(event.id)) {
client.send(event, dmTargets) client.publish(event, dmTargets)
newEvent = true newEvent = true
} }
matchesAtLeastOneFilter = true matchesAtLeastOneFilter = true
} }
if (mentionsMe && !isDmKind && inboxTargets.isNotEmpty()) { if (mentionsMe && !isDmKind && inboxTargets.isNotEmpty()) {
if (inboxDedup.add(event.id)) { if (inboxDedup.add(event.id)) {
client.send(event, inboxTargets) client.publish(event, inboxTargets)
newEvent = true newEvent = true
} }
matchesAtLeastOneFilter = true matchesAtLeastOneFilter = true
@@ -610,7 +610,7 @@ class EventSync(
if (e is CancellationException) throw e if (e is CancellationException) throw e
_syncState.value = SyncState.Error(e.message ?: "Unknown error", filterSince, filterUntil) _syncState.value = SyncState.Error(e.message ?: "Unknown error", filterSince, filterUntil)
} finally { } finally {
client.unsubscribe(okListener) client.removeConnectionListener(okListener)
} }
} }
} }
@@ -622,7 +622,7 @@ class EventSync(
* *
* [onEvent] receives the event and the URL of the relay it came from. * [onEvent] receives the event and the URL of the relay it came from.
*/ */
private suspend fun INostrClient.downloadFromPool( private suspend fun NostrClient.downloadFromPool(
relays: List<NormalizedRelayUrl>, relays: List<NormalizedRelayUrl>,
filters: Map<NormalizedRelayUrl, List<Filter>>, filters: Map<NormalizedRelayUrl, List<Filter>>,
onNewPage: (Long, NormalizedRelayUrl) -> Unit, onNewPage: (Long, NormalizedRelayUrl) -> Unit,
@@ -661,10 +661,10 @@ class EventSync(
* *
* @return total number of events received across all pages. * @return total number of events received across all pages.
*/ */
private suspend fun INostrClient.downloadFromRelay( private suspend fun NostrClient.downloadFromRelay(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
filters: List<Filter>, filters: List<Filter>,
onNewPage: (Long) -> Unit, onNewPage: (Long) -> Unit,
onEvent: (Event) -> Unit, onEvent: (Event) -> Unit,
): Int = reqBypassingRelayLimits(relay, filters, RELAY_TIMEOUT_MS, onNewPage, onEvent) ): Int = fetchAllPages(relay, filters, RELAY_TIMEOUT_MS, onNewPage, onEvent)
} }
@@ -31,7 +31,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfo
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.RelayCountResult
import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.queryCountSuspend import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.count
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip65RelayList.tags.AdvertisedRelayInfo import com.vitorpamplona.quartz.nip65RelayList.tags.AdvertisedRelayInfo
@@ -131,7 +131,7 @@ class Nip65RelayListViewModel : ViewModel() {
_homeRelays.value.forEach { item -> _homeRelays.value.forEach { item ->
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val result = client.queryCountSuspend(item.relay, Filter(authors = listOf(account.pubKey))) val result = client.count(item.relay, Filter(authors = listOf(account.pubKey)))
if (result != null) { if (result != null) {
val countResult = val countResult =
RelayCountResult( RelayCountResult(
@@ -150,7 +150,7 @@ class Nip65RelayListViewModel : ViewModel() {
_notificationRelays.value.forEach { item -> _notificationRelays.value.forEach { item ->
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val result = client.queryCountSuspend(item.relay, Filter(tags = mapOf("p" to listOf(account.pubKey)))) val result = client.count(item.relay, Filter(tags = mapOf("p" to listOf(account.pubKey))))
if (result != null) { if (result != null) {
val countResult = val countResult =
RelayCountResult( RelayCountResult(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.subassembies.ThreadEventLoaderSubAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.subassembies.ThreadEventLoaderSubAssembler
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.subassembies.ThreadFilterSubAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.subassembies.ThreadFilterSubAssembler
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@Stable @Stable
@@ -37,7 +37,7 @@ class ThreadQueryState(
@Stable @Stable
class ThreadFilterAssembler( class ThreadFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<ThreadQueryState>() { ) : ComposeSubscriptionManager<ThreadQueryState>() {
val group = val group =
listOf( listOf(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEo
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
/** /**
@@ -39,7 +39,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
* saves the of the thread EOSEs in the long run to avoid re-downloading * saves the of the thread EOSEs in the long run to avoid re-downloading
*/ */
class ThreadEventLoaderSubAssembler( class ThreadEventLoaderSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ThreadQueryState>, allKeys: () -> Set<ThreadQueryState>,
) : PerUniqueIdEoseManager<ThreadQueryState, HexKey>(client, allKeys, invalidateAfterEose = true) { ) : PerUniqueIdEoseManager<ThreadQueryState, HexKey>(client, allKeys, invalidateAfterEose = true) {
override fun updateFilter( override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEo
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
/** /**
@@ -36,7 +36,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
* saves the of the thread EOSEs in the long run to avoid re-downloading * saves the of the thread EOSEs in the long run to avoid re-downloading
*/ */
class ThreadFilterSubAssembler( class ThreadFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ThreadQueryState>, allKeys: () -> Set<ThreadQueryState>,
) : PerUniqueIdEoseManager<ThreadQueryState, HexKey>(client, allKeys) { ) : PerUniqueIdEoseManager<ThreadQueryState, HexKey>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.VideoOutboxEventsFilterSubAssembler import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.VideoOutboxEventsFilterSubAssembler
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
// This allows multiple screen to be listening to tags, even the same tag // This allows multiple screen to be listening to tags, even the same tag
@@ -35,7 +35,7 @@ class VideoQueryState(
) )
class VideoFilterAssembler( class VideoFilterAssembler(
client: INostrClient, client: NostrClient,
) : ComposeSubscriptionManager<VideoQueryState>() { ) : ComposeSubscriptionManager<VideoQueryState>() {
val group = val group =
listOf( listOf(
@@ -40,7 +40,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassembl
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.nip65Follows.filterPictureAndVideoByFollows import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.nip65Follows.filterPictureAndVideoByFollows
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.nip72Communities.filterPictureAndVideoByAllCommunities import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.nip72Communities.filterPictureAndVideoByAllCommunities
import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.nip72Communities.filterPictureAndVideoByCommunity import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.datasource.subassemblies.nip72Communities.filterPictureAndVideoByCommunity
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
@@ -52,7 +52,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class VideoOutboxEventsFilterSubAssembler( class VideoOutboxEventsFilterSubAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<VideoQueryState>, allKeys: () -> Set<VideoQueryState>,
) : PerUserAndFollowListEoseManager<VideoQueryState, TopFilter>(client, allKeys) { ) : PerUserAndFollowListEoseManager<VideoQueryState, TopFilter>(client, allKeys) {
override fun updateFilter( override fun updateFilter(
@@ -21,8 +21,8 @@
package com.vitorpamplona.amethyst.commons.chess package com.vitorpamplona.amethyst.commons.chess
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -49,7 +49,7 @@ enum class RelayFetchStatus {
/** /**
* One-shot relay fetch helper for chess events. * One-shot relay fetch helper for chess events.
* *
* Follows the existing INostrClient + IRequestListener + Channel pattern * Follows the existing NostrClient + SubscriptionListener + Channel pattern
* from quartz (see NostrClientSingleDownloadExt.kt). * from quartz (see NostrClientSingleDownloadExt.kt).
* *
* Each fetch opens a subscription, collects events until EOSE from all relays, * Each fetch opens a subscription, collects events until EOSE from all relays,
@@ -57,12 +57,12 @@ enum class RelayFetchStatus {
* no state is cached between fetches. * no state is cached between fetches.
*/ */
class ChessRelayFetchHelper( class ChessRelayFetchHelper(
private val client: INostrClient, private val client: NostrClient,
) { ) {
/** /**
* Fetch events matching filters from relays, waiting for EOSE. * Fetch events matching filters from relays, waiting for EOSE.
* *
* @param filters Map of relay filter list (same format as INostrClient.openReqSubscription) * @param filters Map of relay filter list (same format as NostrClient.subscribe)
* @param timeoutMs Max time to wait for relays to respond (default from ChessConfig) * @param timeoutMs Max time to wait for relays to respond (default from ChessConfig)
* @param onProgress Optional callback for progress updates per relay * @param onProgress Optional callback for progress updates per relay
* @return Deduplicated list of events received before timeout/EOSE * @return Deduplicated list of events received before timeout/EOSE
@@ -88,10 +88,10 @@ class ChessRelayFetchHelper(
} }
val listener = val listener =
object : IRequestListener { object : SubscriptionListener {
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -100,7 +100,7 @@ class ChessRelayFetchHelper(
onProgress?.invoke(RelayFetchProgress(relay, RelayFetchStatus.RECEIVING, count)) onProgress?.invoke(RelayFetchProgress(relay, RelayFetchStatus.RECEIVING, count))
} }
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -114,7 +114,7 @@ class ChessRelayFetchHelper(
} }
} }
client.openReqSubscription(subId, filters, listener) client.subscribe(subId, filters, listener)
val eoseResult = withTimeoutOrNull(timeoutMs) { allEose.await() } val eoseResult = withTimeoutOrNull(timeoutMs) { allEose.await() }
// Mark timed-out relays // Mark timed-out relays
@@ -127,7 +127,7 @@ class ChessRelayFetchHelper(
} }
} }
client.close(subId) client.unsubscribe(subId)
return events.values.toList() return events.values.toList()
} }
@@ -20,7 +20,7 @@
*/ */
package com.vitorpamplona.amethyst.commons.domain.nip46 package com.vitorpamplona.amethyst.commons.domain.nip46
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
import com.vitorpamplona.quartz.nip46RemoteSigner.signer.NostrSignerRemote import com.vitorpamplona.quartz.nip46RemoteSigner.signer.NostrSignerRemote
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
@@ -32,7 +32,7 @@ object BunkerLoginUseCase {
suspend fun execute( suspend fun execute(
bunkerUri: String, bunkerUri: String,
ephemeralSigner: NostrSignerInternal, ephemeralSigner: NostrSignerInternal,
client: INostrClient, client: NostrClient,
): BunkerLoginResult { ): BunkerLoginResult {
val remoteSigner = NostrSignerRemote.fromBunkerUri(bunkerUri, ephemeralSigner, client) val remoteSigner = NostrSignerRemote.fromBunkerUri(bunkerUri, ephemeralSigner, client)
remoteSigner.openSubscription() remoteSigner.openSubscription()
@@ -24,8 +24,8 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.StaticSubscription
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
@@ -83,7 +83,7 @@ object NostrConnectLoginUseCase {
suspend fun awaitAndLogin( suspend fun awaitAndLogin(
uriData: NostrConnectUri, uriData: NostrConnectUri,
client: INostrClient, client: NostrClient,
): BunkerLoginResult { ): BunkerLoginResult {
val connectData = val connectData =
waitForConnectRequest( waitForConnectRequest(
@@ -117,19 +117,22 @@ object NostrConnectLoginUseCase {
ephemeralPubKey: HexKey, ephemeralPubKey: HexKey,
relays: Set<NormalizedRelayUrl>, relays: Set<NormalizedRelayUrl>,
expectedSecret: String, expectedSecret: String,
client: INostrClient, client: NostrClient,
): ConnectRequestData { ): ConnectRequestData {
val deferred = CompletableDeferred<NostrConnectEvent>() val deferred = CompletableDeferred<NostrConnectEvent>()
val subscription = val subscription =
client.req( StaticSubscription(
relays = relays.toList(), client,
filter = relays.associateWith {
Filter( listOf(
kinds = listOf(NostrConnectEvent.KIND), Filter(
tags = mapOf("p" to listOf(ephemeralPubKey)), kinds = listOf(NostrConnectEvent.KIND),
since = TimeUtils.now() - 60, tags = mapOf("p" to listOf(ephemeralPubKey)),
), since = TimeUtils.now() - 60,
),
)
},
) { event -> ) { event ->
if (event is NostrConnectEvent && !deferred.isCompleted) { if (event is NostrConnectEvent && !deferred.isCompleted) {
deferred.complete(event) deferred.complete(event)
@@ -198,7 +201,7 @@ object NostrConnectLoginUseCase {
ephemeralSigner: NostrSignerInternal, ephemeralSigner: NostrSignerInternal,
connectData: ConnectRequestData, connectData: ConnectRequestData,
relays: Set<NormalizedRelayUrl>, relays: Set<NormalizedRelayUrl>,
client: INostrClient, client: NostrClient,
) { ) {
val ackResponse = BunkerResponseAck(id = connectData.requestId!!) val ackResponse = BunkerResponseAck(id = connectData.requestId!!)
val ackEvent = val ackEvent =
@@ -207,7 +210,7 @@ object NostrConnectLoginUseCase {
remoteKey = connectData.signerPubkey, remoteKey = connectData.signerPubkey,
signer = ephemeralSigner, signer = ephemeralSigner,
) )
client.send(ackEvent, relays) client.publish(ackEvent, relays)
} }
private fun generateSecret(): String { private fun generateSecret(): String {
@@ -27,8 +27,8 @@ import com.vitorpamplona.amethyst.commons.relayClient.subscriptions.Subscription
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -55,7 +55,7 @@ import kotlinx.coroutines.CoroutineScope
* ``` * ```
*/ */
class FeedMetadataCoordinator( class FeedMetadataCoordinator(
private val client: INostrClient, private val client: NostrClient,
private val scope: CoroutineScope, private val scope: CoroutineScope,
private val indexRelays: Set<NormalizedRelayUrl>, private val indexRelays: Set<NormalizedRelayUrl>,
private val preloader: MetadataPreloader? = null, private val preloader: MetadataPreloader? = null,
@@ -79,10 +79,10 @@ class FeedMetadataCoordinator(
// Create listener to pass events to the callback // Create listener to pass events to the callback
val listener = val listener =
if (onEvent != null) { if (onEvent != null) {
object : IRequestListener { object : SubscriptionListener {
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -93,7 +93,7 @@ class FeedMetadataCoordinator(
null null
} }
client.openReqSubscription( client.subscribe(
subId = newSubId(), subId = newSubId(),
filters = filterMap, filters = filterMap,
listener = listener, listener = listener,
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -48,7 +48,7 @@ data class MetadataQueryState(
* - Caches EOSE to avoid re-fetching known metadata * - Caches EOSE to avoid re-fetching known metadata
*/ */
class MetadataFilterAssembler( class MetadataFilterAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<MetadataQueryState>, allKeys: () -> Set<MetadataQueryState>,
) : SingleSubEoseManager<MetadataQueryState>(client, allKeys, invalidateAfterEose = true) { ) : SingleSubEoseManager<MetadataQueryState>(client, allKeys, invalidateAfterEose = true) {
override fun distinct(key: MetadataQueryState): Any = key.pubkeys.hashCode() override fun distinct(key: MetadataQueryState): Any = key.pubkeys.hashCode()
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.commons.relayClient.assemblers
import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEoseManager
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -48,7 +48,7 @@ data class ReactionsQueryState(
* - Caches EOSE to avoid re-fetching known reactions * - Caches EOSE to avoid re-fetching known reactions
*/ */
class ReactionsFilterAssembler( class ReactionsFilterAssembler(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<ReactionsQueryState>, allKeys: () -> Set<ReactionsQueryState>,
) : SingleSubEoseManager<ReactionsQueryState>(client, allKeys, invalidateAfterEose = true) { ) : SingleSubEoseManager<ReactionsQueryState>(client, allKeys, invalidateAfterEose = true) {
override fun distinct(key: ReactionsQueryState): Any = key.noteIds.hashCode() override fun distinct(key: ReactionsQueryState): Any = key.noteIds.hashCode()
@@ -21,14 +21,14 @@
package com.vitorpamplona.amethyst.commons.relayClient.eoseManagers package com.vitorpamplona.amethyst.commons.relayClient.eoseManagers
import com.vitorpamplona.amethyst.commons.service.BundledUpdate import com.vitorpamplona.amethyst.commons.service.BundledUpdate
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.SubscriptionController import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.SubscriptionController
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
abstract class BaseEoseManager<T>( abstract class BaseEoseManager<T>(
val client: INostrClient, val client: NostrClient,
val allKeys: () -> Set<T>, val allKeys: () -> Set<T>,
val sampleTime: Long = 500, val sampleTime: Long = 500,
) : IEoseManager { ) : IEoseManager {
@@ -38,7 +38,7 @@ abstract class BaseEoseManager<T>(
fun getSubscription(subId: String) = orchestrator.getSub(subId) fun getSubscription(subId: String) = orchestrator.getSub(subId)
fun requestNewSubscription(listener: IRequestListener) = orchestrator.requestNewSubscription(newSubId(), listener) fun requestNewSubscription(listener: SubscriptionListener) = orchestrator.requestNewSubscription(newSubId(), listener)
fun dismissSubscription(subId: String) = orchestrator.dismissSubscription(subId) fun dismissSubscription(subId: String) = orchestrator.dismissSubscription(subId)
@@ -23,10 +23,10 @@ package com.vitorpamplona.amethyst.commons.relayClient.eoseManagers
import com.vitorpamplona.amethyst.commons.relays.EOSECache import com.vitorpamplona.amethyst.commons.relays.EOSECache
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription import com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions.Subscription
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -46,7 +46,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* shared among multiple query states that map to the same key. * shared among multiple query states that map to the same key.
*/ */
abstract class PerKeyEoseManager<T, K : Any>( abstract class PerKeyEoseManager<T, K : Any>(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<T>, allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false, val invalidateAfterEose: Boolean = false,
cacheSize: Int = 200, cacheSize: Int = 200,
@@ -82,8 +82,8 @@ abstract class PerKeyEoseManager<T, K : Any>(
*/ */
open fun newSub(queryState: T): Subscription = open fun newSub(queryState: T): Subscription =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -92,11 +92,11 @@ abstract class PerKeyEoseManager<T, K : Any>(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(queryState, relay, TimeUtils.now(), forFilters) newEose(queryState, relay, TimeUtils.now(), forFilters)
} }
} }
@@ -23,10 +23,10 @@ package com.vitorpamplona.amethyst.commons.relayClient.eoseManagers
import com.vitorpamplona.amethyst.commons.relays.EOSERelayList import com.vitorpamplona.amethyst.commons.relays.EOSERelayList
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay import com.vitorpamplona.quartz.nip01Core.relay.client.pool.groupByRelay
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.utils.TimeUtils
@@ -44,7 +44,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* shares all EOSEs among all users. * shares all EOSEs among all users.
*/ */
abstract class SingleSubEoseManager<T>( abstract class SingleSubEoseManager<T>(
client: INostrClient, client: NostrClient,
allKeys: () -> Set<T>, allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false, val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) { ) : BaseEoseManager<T>(client, allKeys) {
@@ -66,8 +66,8 @@ abstract class SingleSubEoseManager<T>(
val sub = val sub =
requestNewSubscription( requestNewSubscription(
object : IRequestListener { object : SubscriptionListener {
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
@@ -76,11 +76,11 @@ abstract class SingleSubEoseManager<T>(
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { ) {
if (isLive) { if (isRealTime) {
newEose(relay, TimeUtils.now(), forFilters) newEose(relay, TimeUtils.now(), forFilters)
} }
} }
@@ -21,9 +21,9 @@
package com.vitorpamplona.amethyst.commons.chess package com.vitorpamplona.amethyst.commons.chess
import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.sendAndWaitForResponse import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.publishAndConfirm
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -42,11 +42,11 @@ data class BroadcastResult(
/** /**
* Helper for broadcasting chess events to relays with reliable delivery. * Helper for broadcasting chess events to relays with reliable delivery.
* *
* Uses sendAndWaitForResponse to get actual OK confirmations from relays, * Uses publishAndConfirm to get actual OK confirmations from relays,
* ensuring the event was actually received and accepted. * ensuring the event was actually received and accepted.
*/ */
class ChessEventBroadcaster( class ChessEventBroadcaster(
private val client: INostrClient, private val client: NostrClient,
) { ) {
/** /**
* Broadcast an event to the chess relays with confirmation. * Broadcast an event to the chess relays with confirmation.
@@ -84,15 +84,15 @@ class ChessEventBroadcaster(
) )
val listener = val listener =
object : IRequestListener { object : SubscriptionListener {
override fun onEvent( override fun onEvent(
event: Event, event: Event,
isLive: Boolean, isRealTime: Boolean,
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { } ) { }
override fun onEose( override fun onCaughtUp(
relay: NormalizedRelayUrl, relay: NormalizedRelayUrl,
forFilters: List<Filter>?, forFilters: List<Filter>?,
) { } ) { }
@@ -100,19 +100,19 @@ class ChessEventBroadcaster(
// Open subscription to all target relays (triggers connection) // Open subscription to all target relays (triggers connection)
val filterMap = targetRelays.associateWith { listOf(dummyFilter) } val filterMap = targetRelays.associateWith { listOf(dummyFilter) }
client.openReqSubscription(subId, filterMap, listener) client.subscribe(subId, filterMap, listener)
// Wait for relays to connect (poll with timeout) // Wait for relays to connect (poll with timeout)
waitForRelays(targetRelays, 5000L) waitForRelays(targetRelays, 5000L)
// Close the dummy subscription // Close the dummy subscription
client.close(subId) client.unsubscribe(subId)
} }
// Step 3: Send the event and wait for OK responses // Step 3: Send the event and wait for OK responses
val success = client.sendAndWaitForResponse(event, targetRelays, timeoutSeconds) val success = client.publishAndConfirm(event, targetRelays, timeoutSeconds)
// Note: sendAndWaitForResponse only returns aggregate success (any relay accepted) // Note: publishAndConfirm only returns aggregate success (any relay accepted)
// We don't have per-relay results, so relayResults is empty // We don't have per-relay results, so relayResults is empty
return BroadcastResult( return BroadcastResult(
success = success, success = success,
@@ -193,7 +193,7 @@ fun main() {
} }
Window( Window(
onCloseRequest = ::exitApplication, onSubscriptionCloseduest = ::exitApplication,
state = windowState, state = windowState,
title = "Amethyst", title = "Amethyst",
) { ) {
@@ -30,8 +30,7 @@ import com.vitorpamplona.amethyst.desktop.network.DesktopHttpClient
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.core.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
import com.vitorpamplona.quartz.nip01Core.relay.commands.toRelay.Command import com.vitorpamplona.quartz.nip01Core.relay.commands.toRelay.Command
@@ -132,11 +131,11 @@ class AccountManager internal constructor(
// --- Dedicated NIP-46 client (isolated from general relay pool) --- // --- Dedicated NIP-46 client (isolated from general relay pool) ---
private val nip46ClientMutex = Mutex() private val nip46ClientMutex = Mutex()
private var nip46Client: NostrClient? = null private var nip46Client: DefaultDefaultNostrClient? = null
private suspend fun getOrCreateNip46Client(): NostrClient = private suspend fun getOrCreateNip46Client(): DefaultNostrClient =
nip46ClientMutex.withLock { nip46ClientMutex.withLock {
nip46Client ?: NostrClient( nip46Client ?: DefaultNostrClient(
BasicOkHttpWebSocket.Builder(DesktopHttpClient::getHttpClient), BasicOkHttpWebSocket.Builder(DesktopHttpClient::getHttpClient),
).also { ).also {
nip46Client = it nip46Client = it
@@ -156,7 +155,7 @@ class AccountManager internal constructor(
* but we must wait for the websocket to be ready before sending requests. * but we must wait for the websocket to be ready before sending requests.
*/ */
private suspend fun awaitNip46RelayConnection( private suspend fun awaitNip46RelayConnection(
client: NostrClient, client: DefaultNostrClient,
targetRelays: Set<NormalizedRelayUrl>, targetRelays: Set<NormalizedRelayUrl>,
) { ) {
withTimeout(NIP46_RELAY_CONNECT_TIMEOUT_MS) { withTimeout(NIP46_RELAY_CONNECT_TIMEOUT_MS) {
@@ -180,8 +179,8 @@ class AccountManager internal constructor(
} }
} }
private fun createLoginRelayListener(): IRelayClientListener = private fun createLoginRelayListener(): RelayConnectionListener =
object : IRelayClientListener { object : RelayConnectionListener {
override fun onConnected( override fun onConnected(
relay: IRelayClient, relay: IRelayClient,
pingMillis: Int, pingMillis: Int,
@@ -303,7 +302,7 @@ class AccountManager internal constructor(
suspend fun loginWithBunker(bunkerUri: String): Result<AccountState.LoggedIn> { suspend fun loginWithBunker(bunkerUri: String): Result<AccountState.LoggedIn> {
val listener = createLoginRelayListener() val listener = createLoginRelayListener()
var client: NostrClient? = null var client: DefaultDefaultNostrClient? = null
try { try {
val ephemeralKeyPair = KeyPair() val ephemeralKeyPair = KeyPair()
val ephemeralSigner = NostrSignerInternal(ephemeralKeyPair) val ephemeralSigner = NostrSignerInternal(ephemeralKeyPair)
@@ -316,7 +315,7 @@ class AccountManager internal constructor(
LoginProgress.ConnectingToRelays( LoginProgress.ConnectingToRelays(
relaysFromUri.associateWith { RelayLoginStatus.CONNECTING }, relaysFromUri.associateWith { RelayLoginStatus.CONNECTING },
) )
nip46Client.subscribe(listener) nip46Client.addConnectionListener(listener)
_loginProgress.value = _loginProgress.value =
LoginProgress.WaitingForSigner( LoginProgress.WaitingForSigner(
@@ -356,7 +355,7 @@ class AccountManager internal constructor(
return Result.failure(Exception("Connection failed: ${e.message}")) return Result.failure(Exception("Connection failed: ${e.message}"))
} finally { } finally {
_loginProgress.value = null _loginProgress.value = null
client?.unsubscribe(listener) client?.removeConnectionListener(listener)
} }
} }
@@ -364,7 +363,7 @@ class AccountManager internal constructor(
suspend fun loginWithNostrConnect(onUriGenerated: (String) -> Unit): Result<AccountState.LoggedIn> { suspend fun loginWithNostrConnect(onUriGenerated: (String) -> Unit): Result<AccountState.LoggedIn> {
val listener = createLoginRelayListener() val listener = createLoginRelayListener()
var client: NostrClient? = null var client: DefaultDefaultNostrClient? = null
try { try {
val ephemeralKeyPair = KeyPair() val ephemeralKeyPair = KeyPair()
val uriData = NostrConnectLoginUseCase.generateUri(ephemeralKeyPair, NIP46_RELAYS, "Amethyst%20Desktop") val uriData = NostrConnectLoginUseCase.generateUri(ephemeralKeyPair, NIP46_RELAYS, "Amethyst%20Desktop")
@@ -376,7 +375,7 @@ class AccountManager internal constructor(
LoginProgress.ConnectingToRelays( LoginProgress.ConnectingToRelays(
uriData.relays.associateWith { RelayLoginStatus.CONNECTING }, uriData.relays.associateWith { RelayLoginStatus.CONNECTING },
) )
nip46Client.subscribe(listener) nip46Client.addConnectionListener(listener)
onUriGenerated(uriData.uri) onUriGenerated(uriData.uri)
@@ -415,7 +414,7 @@ class AccountManager internal constructor(
return Result.failure(Exception("Connection failed: ${e.message}")) return Result.failure(Exception("Connection failed: ${e.message}"))
} finally { } finally {
_loginProgress.value = null _loginProgress.value = null
client?.unsubscribe(listener) client?.removeConnectionListener(listener)
} }
} }
@@ -140,7 +140,7 @@ fun ChessScreen(
onEvent = { event, _, _, _ -> onEvent = { event, _, _, _ ->
viewModel.handleIncomingEvent(event) viewModel.handleIncomingEvent(event)
}, },
onEose = { _, _ -> onCaughtUp = { _, _ ->
// ChessLobbyLogic handles loading state internally // ChessLobbyLogic handles loading state internally
}, },
) )

Some files were not shown because too many files have changed in this diff Show More