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.verify
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.tags.aTag.ATag
import com.vitorpamplona.quartz.nip03Timestamp.EmptyOtsResolverBuilder
@@ -55,7 +54,7 @@ class ThreadDualAxisChartAssemblerTest {
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val client =
NostrClient(
DefaultNostrClient(
OkHttpWebSocket.Builder {
OkHttpClient
.Builder()
@@ -24,7 +24,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.vitorpamplona.amethyst.model.Constants
import com.vitorpamplona.amethyst.service.okhttp.DefaultContentTypeInterceptor
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.auth.RelayAuthenticator
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.normalizeRelayUrl
@@ -68,7 +67,7 @@ class EventSyncTest {
inboxTargets = { setOf(vitor) },
dmTargets = { setOf(vitor) },
clientBuilder = {
NostrClient(socketBuilder, appScope)
DefaultNostrClient(socketBuilder, appScope)
},
scope = appScope,
)
@@ -87,7 +86,7 @@ class EventSyncTest {
inboxTargets = { setOf(vitor) },
dmTargets = { setOf(vitor) },
clientBuilder = {
val newClient = NostrClient(socketBuilder, appScope)
val newClient = DefaultNostrClient(socketBuilder, appScope)
val logger = RelayLogger(newClient, debugSending = true, debugReceiving = false)
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.tor.TorManager
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.accessories.RelayLogger
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.RelayOfflineTracker
@@ -256,7 +255,7 @@ class AppModules(
val cache: LocalCache = LocalCache
// 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
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.PubKeyHintProvider
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.downloadFirstEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchFirst
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate
@@ -244,7 +244,7 @@ class Account(
val nwcFilterAssembler: () -> NWCPaymentFilterAssembler,
val otsResolverBuilder: () -> OtsResolver,
val cache: LocalCache,
val client: INostrClient,
val client: NostrClient,
val scope: CoroutineScope,
) : IAccount {
private var userProfileCache: User? = null
@@ -606,7 +606,7 @@ class Account(
onResponse: (Response?) -> Unit,
) {
val (event, relay) = nip47SignerState.sendNwcRequest(request, onResponse)
client.send(event, setOf(relay))
client.publish(event, setOf(relay))
}
suspend fun sendZapPaymentRequestFor(
@@ -615,7 +615,7 @@ class Account(
onResponse: (Response?) -> Unit,
) {
val (event, relay) = nip47SignerState.sendZapPaymentRequestFor(bolt11, zappedNote, onResponse)
client.send(event, setOf(relay))
client.publish(event, setOf(relay))
}
suspend fun createZapRequestFor(
@@ -701,7 +701,7 @@ class Account(
suspend fun boost(note: Note) {
RepostAction.repost(note, signer)?.let { event ->
client.send(event, computeMyReactionToNote(note, event))
client.publish(event, computeMyReactionToNote(note, event))
cache.justConsumeMyOwnEvent(event)
}
}
@@ -723,7 +723,7 @@ class Account(
event: Event,
relays: Set<NormalizedRelayUrl>,
) {
client.send(event, relays)
client.publish(event, relays)
cache.justConsumeMyOwnEvent(event)
}
@@ -939,7 +939,7 @@ class Account(
// download the event and send it.
noteEvent.host?.let { host ->
client
.downloadFirstEvent(
.fetchFirst(
filters =
note.relays.associateWith { relay ->
listOf(
@@ -1012,7 +1012,7 @@ class Account(
fun sendAutomatic(event: Event?) {
if (event == null) return
cache.justConsumeMyOwnEvent(event)
client.send(event, computeRelayListToBroadcast(event))
client.publish(event, computeRelayListToBroadcast(event))
}
suspend fun sendWebBookmark(
@@ -1043,7 +1043,7 @@ class Account(
fun sendMyPublicAndPrivateOutbox(event: Event?) {
if (event == null) return
cache.justConsumeMyOwnEvent(event)
client.send(event, outboxRelays.flow.value)
client.publish(event, outboxRelays.flow.value)
}
fun sendMyPublicAndPrivateOutbox(events: List<Event>) {
@@ -1054,7 +1054,7 @@ class Account(
}
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)
}
@@ -1287,7 +1287,7 @@ class Account(
) {
val event = signer.sign(template)
cache.justConsumeMyOwnEvent(event)
client.send(event, relayList)
client.publish(event, relayList)
}
suspend fun <T : Event> signAndSendPrivatelyOrBroadcast(
@@ -1298,9 +1298,9 @@ class Account(
cache.justConsumeMyOwnEvent(event)
val relays = relayList(event)
if (!relays.isNullOrEmpty()) {
client.send(event, relays.toSet())
client.publish(event, relays.toSet())
} else {
client.send(event, computeRelayListToBroadcast(event))
client.publish(event, computeRelayListToBroadcast(event))
}
return event
}
@@ -1320,7 +1320,7 @@ class Account(
val relayList = computeRelayListToBroadcast(note)
client.send(event, relayList)
client.publish(event, relayList)
broadcast.forEach { client.send(it, relayList) }
@@ -1344,7 +1344,7 @@ class Account(
val relayList = computeRelayListToBroadcast(note)
client.send(event, relayList)
client.publish(event, relayList)
broadcast.forEach { client.send(it, relayList) }
@@ -1463,9 +1463,9 @@ class Account(
val relayList = privateStorageRelayList.flow.value + localRelayList.flow.value
if (relayList.isNotEmpty()) {
client.send(event, relayList + noteRelays)
client.publish(event, relayList + noteRelays)
} else {
client.send(event, outboxRelays.flow.value + noteRelays)
client.publish(event, outboxRelays.flow.value + noteRelays)
}
cache.justConsumeMyOwnEvent(event)
}
@@ -1489,9 +1489,9 @@ class Account(
val relayList = privateStorageRelayList.flow.value + localRelayList.flow.value
if (relayList.isNotEmpty()) {
client.send(event, relayList + noteRelays)
client.publish(event, relayList + noteRelays)
} else {
client.send(event, outboxRelays.flow.value + noteRelays)
client.publish(event, outboxRelays.flow.value + noteRelays)
}
cache.justConsumeMyOwnEvent(event)
}
@@ -1652,7 +1652,7 @@ class Account(
val note = cache.getOrCreateNote(event.id)
val relayList = computeRelayListToBroadcast(note)
client.send(event, relayList = relayList)
client.publish(event, relayList = 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.quartz.nip01Core.core.HexKey
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.NostrSignerInternal
import com.vitorpamplona.quartz.nip03Timestamp.OtsResolver
@@ -50,7 +50,7 @@ class AccountCacheState(
val contentResolverFn: () -> ContentResolver,
val otsResolverBuilder: () -> OtsResolver,
val cache: LocalCache,
val client: INostrClient,
val client: NostrClient,
) {
val accounts = MutableStateFlow<Map<HexKey, Account>>(emptyMap())
@@ -23,8 +23,8 @@ package com.vitorpamplona.amethyst.model.nip62Vanish
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.LocalCache.notes
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.downloadFirstEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchFirst
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
@@ -61,7 +61,7 @@ enum class ComplianceStatus {
class VanishRequestsState(
val signer: NostrSigner,
val cache: LocalCache,
val client: INostrClient,
val client: NostrClient,
val scope: CoroutineScope,
) {
val noteFlow =
@@ -105,7 +105,7 @@ class VanishRequestsState(
try {
val foundEvent =
withContext(Dispatchers.IO) {
client.downloadFirstEvent(
client.fetchFirst(
relay = relay,
filter =
Filter(
@@ -21,8 +21,8 @@
package com.vitorpamplona.amethyst.service.broadcast
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
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.OkMessage
@@ -71,7 +71,7 @@ class BroadcastTracker {
suspend fun trackBroadcast(
event: Event,
relays: Set<NormalizedRelayUrl>,
client: INostrClient,
client: NostrClient,
) {
val trackingId = UUID.randomUUID().toString()
@@ -90,7 +90,7 @@ class BroadcastTracker {
val resultChannel = Channel<RelayResponse>(UNLIMITED)
val subscription =
object : IRelayClientListener {
object : RelayConnectionListener {
override fun onCannotConnect(
relay: IRelayClient,
errorMessage: String,
@@ -143,7 +143,7 @@ class BroadcastTracker {
}
try {
client.subscribe(subscription)
client.addConnectionListener(subscription)
val finalBroadcast =
coroutineScope {
@@ -178,7 +178,7 @@ class BroadcastTracker {
}
// Send after setting up listener
client.send(event, relays)
client.publish(event, relays)
resultCollector.await()
}
@@ -192,7 +192,7 @@ class BroadcastTracker {
Log.d(TAG, "Broadcast $trackingId complete: ${finalBroadcast.successCount}/${finalBroadcast.totalRelays} success")
} finally {
client.unsubscribe(subscription)
client.removeConnectionListener(subscription)
}
}
@@ -232,7 +232,7 @@ class BroadcastTracker {
@OptIn(DelicateCoroutinesApi::class)
suspend fun retry(
broadcast: BroadcastEvent,
client: INostrClient,
client: NostrClient,
specificRelay: NormalizedRelayUrl? = null,
): BroadcastEvent {
val event = broadcast.event
@@ -266,7 +266,7 @@ class BroadcastTracker {
val resultChannel = Channel<RelayResponse>(UNLIMITED)
val subscription =
object : IRelayClientListener {
object : RelayConnectionListener {
override fun onCannotConnect(
relay: IRelayClient,
errorMessage: String,
@@ -318,7 +318,7 @@ class BroadcastTracker {
}
}
client.subscribe(subscription)
client.addConnectionListener(subscription)
val finalBroadcast =
coroutineScope {
@@ -370,12 +370,12 @@ class BroadcastTracker {
currentBroadcast.copy(status = newStatus)
}
client.send(event, relaysToRetry)
client.publish(event, relaysToRetry)
resultCollector.await()
}
client.unsubscribe(subscription)
client.removeConnectionListener(subscription)
resultChannel.close()
// 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.Note
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.RelayInsertConfirmationCollector
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
class CacheClientConnector(
val client: INostrClient,
val client: NostrClient,
val cache: LocalCache,
) {
val receiver =
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.connectivity.ConnectivityStatus
import com.vitorpamplona.amethyst.service.okhttp.DualHttpClientManagerForRelays
import com.vitorpamplona.amethyst.ui.tor.TorManager
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 kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -48,7 +48,7 @@ class RelayProxyClientConnector(
val okHttpClients: DualHttpClientManagerForRelays,
val connManager: ConnectivityManager,
val torManager: TorManager,
val client: INostrClient,
val client: NostrClient,
val scope: CoroutineScope,
) {
data class RelayServiceInfra(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service.relayClient.authCommand.model
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.isDebug
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.signers.NostrSignerSync
import com.vitorpamplona.quartz.utils.Log
@@ -35,7 +35,7 @@ class ScreenAuthAccount(
@Stable
class AuthCoordinator(
client: INostrClient,
client: NostrClient,
scope: CoroutineScope,
) {
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.SincePerRelayMap
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.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.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -42,7 +42,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* shares all EOSEs among all users.
*/
abstract class PerUniqueIdEoseManager<T, U : Any>(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) {
@@ -68,8 +68,8 @@ abstract class PerUniqueIdEoseManager<T, U : Any>(
open fun newSub(key: T): Subscription =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -78,11 +78,11 @@ abstract class PerUniqueIdEoseManager<T, U : Any>(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
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.SincePerRelayMap
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.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.filters.Filter
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
*/
abstract class PerUserAndFollowListEoseManager<T, U : Any>(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) {
@@ -69,8 +69,8 @@ abstract class PerUserAndFollowListEoseManager<T, U : Any>(
open fun newSub(key: T): Subscription =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -79,11 +79,11 @@ abstract class PerUserAndFollowListEoseManager<T, U : Any>(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
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.SincePerRelayMap
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.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.filters.Filter
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.
*/
abstract class PerUserEoseManager<T>(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) {
@@ -67,8 +67,8 @@ abstract class PerUserEoseManager<T>(
open fun newSub(key: T): Subscription =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -77,11 +77,11 @@ abstract class PerUserEoseManager<T>(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
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.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.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.normalizer.NormalizedRelayUrl
@@ -35,14 +35,14 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
* filters
*/
abstract class SingleSubNoEoseCacheEoseManager<T>(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) {
val sub =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -53,11 +53,11 @@ abstract class SingleSubNoEoseCacheEoseManager<T>(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
if (invalidateAfterEose) {
invalidateFilters()
}
@@ -20,11 +20,11 @@
*/
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
class NotifyCoordinator(
client: INostrClient,
client: NostrClient,
) {
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.threadview.datasources.ThreadFilterAssembler
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.auth.IAuthStatus
import kotlinx.coroutines.CoroutineScope
class RelaySubscriptionsCoordinator(
cache: LocalCache,
client: INostrClient,
client: NostrClient,
authenticator: IAuthStatus,
failureTracker: RelayOfflineTracker,
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.ui.screen.loggedIn.AccountFeedContentStates
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.auth.IAuthStatus
import kotlinx.coroutines.CoroutineScope
@@ -50,7 +50,7 @@ class AccountQueryState(
*/
@Stable
class AccountFilterAssembler(
client: INostrClient,
client: NostrClient,
cache: LocalCache,
authenticator: IAuthStatus,
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.reqCommand.account.AccountQueryState
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
class AccountDraftsEoseManager(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
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.relays.EOSEAccountFast
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.auth.IAuthStatus
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.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.subscriptions.SubscriptionController
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
@@ -56,7 +56,7 @@ import kotlinx.coroutines.launch
* It needs to be super fast on startup.
*/
class AccountFollowsLoaderSubAssembler(
val client: INostrClient,
val client: NostrClient,
val cache: LocalCache,
val scope: CoroutineScope,
val authStatus: IAuthStatus,
@@ -107,8 +107,8 @@ class AccountFollowsLoaderSubAssembler(
val sub =
orchestrator.requestNewSubscription(
if (isDebug) logTag + newSubId() else newSubId(),
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -117,11 +117,11 @@ class AccountFollowsLoaderSubAssembler(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
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.reqCommand.account.AccountQueryState
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.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -35,7 +35,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
class AccountMetadataEoseManager(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
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.reqCommand.account.AccountQueryState
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.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -36,7 +36,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class AccountNotificationsEoseFromInboxRelaysManager(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
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.reqCommand.account.AccountQueryState
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.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class AccountNotificationsEoseFromRandomRelaysManager(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
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.reqCommand.account.AccountQueryState
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
class AccountGiftWrapsEoseManager(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<AccountQueryState>,
) : PerUserEoseManager<AccountQueryState>(client, allKeys) {
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.service.relayClient.reqCommand.channel.mixChatsLive.ChannelMetadataAndLiveActivityWatcherSubAssembler
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
@Stable
@@ -35,7 +35,7 @@ class ChannelFinderQueryState(
@Stable
class ChannelFinderFilterAssemblyGroup(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<ChannelFinderQueryState>() {
val group =
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.nip53LiveActivities.filterLiveStreamUpdatesByAddress
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.utils.mapOfSet
@@ -39,7 +39,7 @@ import com.vitorpamplona.quartz.utils.mapOfSet
* only one EOSE for everybody.
*/
class ChannelMetadataAndLiveActivityWatcherSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>,
) : SingleSubEoseManager<ChannelFinderQueryState>(client, allKeys) {
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.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
/**
@@ -35,7 +35,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
* This is one filter for everybody.
*/
class ChannelLoaderSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>,
) : SingleSubNoEoseCacheEoseManager<ChannelFinderQueryState>(client, allKeys, invalidateAfterEose = true) {
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.reqCommand.channel.ChannelFinderQueryState
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
class ChannelMetadataWatcherSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>,
) : PerUniqueIdEoseManager<ChannelFinderQueryState, Channel>(client, allKeys) {
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.reqCommand.channel.ChannelFinderQueryState
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
/**
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
* since they are replaceable.
*/
class LiveActivityWatcherSubAssembly(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChannelFinderQueryState>,
) : PerUniqueIdEoseManager<ChannelFinderQueryState, Channel>(client, allKeys) {
override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.loaders.NoteEventLoaderSubAssembler
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
@Stable
@@ -37,7 +37,7 @@ class EventFinderQueryState(
@Stable
class EventFinderFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<EventFinderQueryState>() {
val group =
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.reqCommand.event.EventFinderQueryState
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
class NoteEventLoaderSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<EventFinderQueryState>,
) : SingleSubNoEoseCacheEoseManager<EventFinderQueryState>(client, allKeys, invalidateAfterEose = true) {
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.MutableTime
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.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
class EventWatcherSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<EventFinderQueryState>,
) : SingleSubEoseManager<EventFinderQueryState>(client, allKeys) {
var lastNotesOnFilter = emptyList<Note>()
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -37,7 +37,7 @@ class NWCPaymentQueryState(
@Stable
class NWCPaymentFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<NWCPaymentQueryState>() {
val group =
listOf(
@@ -21,11 +21,11 @@
package com.vitorpamplona.amethyst.service.relayClient.reqCommand.nwc
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
class NWCPaymentWatcherSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<NWCPaymentQueryState>,
) : SingleSubNoEoseCacheEoseManager<NWCPaymentQueryState>(client, allKeys) {
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.UserReportsSubAssembler
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -41,7 +41,7 @@ class UserFinderQueryState(
@Stable
class UserFinderFilterAssembler(
client: INostrClient,
client: NostrClient,
cache: LocalCache,
failureTracker: RelayOfflineTracker,
) : 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.relays.EOSEAccountFast
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.pool.RelayBasedFilter
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.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
import com.vitorpamplona.quartz.utils.TimeUtils
class UserOutboxFinderSubAssembler(
client: INostrClient,
client: NostrClient,
val cache: LocalCache,
val failureTracker: RelayOfflineTracker,
allKeys: () -> Set<UserFinderQueryState>,
@@ -68,8 +68,8 @@ class UserOutboxFinderSubAssembler(
val sub =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
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.SincePerRelayMap
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.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.mapOfSet
class UserCardsSubAssembler(
client: INostrClient,
client: NostrClient,
val cache: LocalCache,
allKeys: () -> Set<UserFinderQueryState>,
) : 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.relays.MutableTime
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.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.mapOfSet
class UserReportsSubAssembler(
client: INostrClient,
client: NostrClient,
val cache: LocalCache,
allKeys: () -> Set<UserFinderQueryState>,
) : 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.relays.EOSEAccountFast
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.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.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.TimeUtils
class UserWatcherSubAssembler(
client: INostrClient,
client: NostrClient,
val cache: LocalCache,
allKeys: () -> Set<UserFinderQueryState>,
) : BaseEoseManager<UserFinderQueryState>(client, allKeys) {
@@ -61,8 +61,8 @@ class UserWatcherSubAssembler(
val sub =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -71,11 +71,11 @@ class UserWatcherSubAssembler(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
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.service.relayClient.searchCommand.subassemblies.SearchPostWatcherSubAssembler
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.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -42,7 +42,7 @@ class SearchQueryState(
@Stable
class SearchFilterAssembler(
client: INostrClient,
client: NostrClient,
scope: CoroutineScope,
val cache: LocalCache,
) : 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.relays.SincePerRelayMap
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.nip19Bech32.Nip19Parser
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
@@ -44,7 +44,7 @@ import com.vitorpamplona.quartz.utils.Hex
*/
class SearchPostWatcherSubAssembler(
val cache: LocalCache,
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<SearchQueryState>,
) : PerUniqueIdEoseManager<SearchQueryState, Int>(client, allKeys) {
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.relays.SincePerRelayMap
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.nip19Bech32.Nip19Parser
import com.vitorpamplona.quartz.nip19Bech32.entities.NAddress
@@ -45,7 +45,7 @@ import com.vitorpamplona.quartz.utils.Hex
*/
class SearchUserWatcherSubAssembler(
val cache: LocalCache,
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<SearchQueryState>,
) : PerUniqueIdEoseManager<SearchQueryState, Int>(client, allKeys) {
override fun updateFilter(
@@ -20,8 +20,8 @@
*/
package com.vitorpamplona.amethyst.service.relayClient.speedLogger
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
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.Message
@@ -32,7 +32,7 @@ import com.vitorpamplona.quartz.utils.bytesUsedInMemory
* Listens to NostrClient's onNotify messages from the relay
*/
class RelaySpeedLogger(
val client: INostrClient,
val client: NostrClient,
) {
companion object {
val TAG: String = RelaySpeedLogger::class.java.simpleName
@@ -41,7 +41,7 @@ class RelaySpeedLogger(
var current = FrameStat()
private val clientListener =
object : IRelayClientListener {
object : RelayConnectionListener {
override fun onIncomingMessage(
relay: IRelayClient,
msgStr: String,
@@ -55,7 +55,7 @@ class RelaySpeedLogger(
init {
Log.d(TAG, "Init, Subscribe")
client.subscribe(clientListener)
client.addConnectionListener(clientListener)
// OkHttpDebugLogging.enableHttp2()
// OkHttpDebugLogging.enableTaskRunner()
}
@@ -63,6 +63,6 @@ class RelaySpeedLogger(
fun destroy() {
// makes sure to run
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.crypto.KeyPair
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.nip02FollowList.ContactListEvent
import com.vitorpamplona.quartz.nip02FollowList.tags.ContactTag
@@ -94,7 +94,7 @@ sealed class AccountState {
class AccountSessionManager(
val accountsCache: AccountCacheState,
val nip05ClientBuilder: () -> Nip05Client,
val clientBuilder: () -> INostrClient,
val clientBuilder: () -> NostrClient,
val localPreferences: LocalPreferences,
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.hints.EventHintBundle
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.auth.EmptyIAuthStatus
import com.vitorpamplona.quartz.nip01Core.relay.client.auth.RelayAuthenticator
@@ -220,7 +219,7 @@ class AccountViewModel(
val customScope = CoroutineScope(viewModelScope.coroutineContext + SupervisorJob())
// Provides a relay pool
val newClient = NostrClient(Amethyst.instance.websocketBuilder, customScope)
val newClient = DefaultNostrClient(Amethyst.instance.websocketBuilder, customScope)
// Authenticates with relays.
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.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
// This allows multiple screen to be listening to tags, even the same tag
@@ -34,7 +34,7 @@ class ChatroomQueryState(
}
class ChatroomFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<ChatroomQueryState>() {
val group =
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.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
class ChatroomFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChatroomQueryState>,
) : PerUserAndFollowListEoseManager<ChatroomQueryState, String>(client, allKeys) {
override fun updateFilter(
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManager
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.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
class ChannelQueryState(
@@ -34,7 +34,7 @@ class ChannelQueryState(
)
class ChannelFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<ChannelQueryState>() {
val group =
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.relays.SincePerRelayMap
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
class ChannelFromUserFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChannelQueryState>,
) : PerUserAndFollowListEoseManager<ChannelQueryState, Channel>(client, allKeys) {
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.relays.SincePerRelayMap
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
class ChannelPublicFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChannelQueryState>,
) : PerUniqueIdEoseManager<ChannelQueryState, Channel>(client, allKeys) {
override fun updateFilter(
@@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.datasource
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
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
@Stable
@@ -33,7 +33,7 @@ class ChatroomListState(
@Stable
class ChatroomListFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<ChatroomListState>() {
val group =
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.service.relayClient.eoseManagers.PerUserEoseManager
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -33,7 +33,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
class DMsFromUserFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChatroomListState>,
) : PerUserEoseManager<ChatroomListState>(client, allKeys) {
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.service.relayClient.eoseManagers.PerUserEoseManager
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class FollowingEphemeralChatSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChatroomListState>,
) : PerUserEoseManager<ChatroomListState>(client, allKeys) {
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.service.relayClient.eoseManagers.PerUserEoseManager
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class FollowingPublicChatSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChatroomListState>,
) : PerUserEoseManager<ChatroomListState>(client, allKeys) {
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.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.normalizer.NormalizedRelayUrl
@@ -42,7 +42,7 @@ data class ChessQueryState(
* Sub-assembler that creates the actual relay filters
*/
class ChessFeedFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ChessQueryState>,
) : PerUniqueIdEoseManager<ChessQueryState, String>(client, allKeys) {
override fun updateFilter(
@@ -21,13 +21,13 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.chess.datasource
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
*/
class ChessFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<ChessQueryState>() {
val group =
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.model.LocalCache
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.nip72ModCommunities.definition.CommunityDefinitionEvent
import com.vitorpamplona.quartz.utils.mapOfSet
class CommunityFeedFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<CommunityQueryState>,
) : SingleSubEoseManager<CommunityQueryState>(client, allKeys) {
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.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
class CommunityQueryState(
@@ -30,7 +30,7 @@ class CommunityQueryState(
)
class CommunityFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<CommunityQueryState>() {
val group =
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.model.Account
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -34,7 +34,7 @@ class DiscoveryQueryState(
)
class DiscoveryFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<DiscoveryQueryState>() {
val group =
listOf(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUserAndFol
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.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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class DiscoveryFollowsSetsAndLiveStreamsSubAssembler2(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<DiscoveryQueryState>,
) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) {
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.nip90DVMs.makeContentDVMsFilter
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -39,7 +39,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class DiscoveryLongFormClassifiedsAndDVMSubAssembler1(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<DiscoveryQueryState>,
) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) {
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.ui.screen.loggedIn.discover.nip28Chats.makePublicChatsFilter
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -38,7 +38,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class DiscoveryPublicChatsAndCommunitiesSubAssembler3(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<DiscoveryQueryState>,
) : PerUserAndFollowListEoseManager<DiscoveryQueryState, TopFilter>(client, allKeys) {
override fun updateFilter(
@@ -24,7 +24,7 @@ import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManagers.ComposeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account
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
class FollowPackFeedQueryState(
@@ -34,7 +34,7 @@ class FollowPackFeedQueryState(
@Stable
class FollowPackFeedFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<FollowPackFeedQueryState>() {
val group =
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.service.relays.SincePerRelayMap
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.nip51Lists.followList.FollowListEvent
class FollowPackFeedFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<FollowPackFeedQueryState>,
) : SingleSubEoseManager<FollowPackFeedQueryState>(client, allKeys) {
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.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
class GeoHashFeedFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<GeohashQueryState>,
) : PerUniqueIdEoseManager<GeohashQueryState, String>(client, allKeys) {
override fun updateFilter(
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.geohash.datasource
import androidx.compose.runtime.Stable
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -38,7 +38,7 @@ class GeohashQueryState(
*/
@Stable
class GeoHashFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<GeohashQueryState>() {
val group =
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.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
class HashtagFeedFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<HashtagQueryState>,
) : PerUniqueIdEoseManager<HashtagQueryState, String>(client, allKeys) {
override fun updateFilter(
@@ -21,7 +21,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.hashtag.datasource
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -33,7 +33,7 @@ class HashtagQueryState(
}
class HashtagFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<HashtagQueryState>() {
val group =
listOf(
@@ -25,7 +25,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -39,7 +39,7 @@ class HomeQueryState(
@Stable
class HomeFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<HomeQueryState>() {
val group =
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.nip72Communities.filterHomePostsByAllCommunities
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.subscriptions.Subscription
import kotlinx.coroutines.Dispatchers
@@ -51,7 +51,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class HomeOutboxEventsEoseManager(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<HomeQueryState>,
) : PerUserAndFollowListEoseManager<HomeQueryState, TopFilter>(client, allKeys) {
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.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
class UserProfileQueryState(
@@ -30,7 +30,7 @@ class UserProfileQueryState(
)
class UserProfileFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<UserProfileQueryState>() {
val group =
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.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
class UserProfileFollowersFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
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.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
class UserProfileMediaFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
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.model.LocalCache
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.utils.mapOfSet
class UserProfileMetadataFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : SingleSubEoseManager<UserProfileQueryState>(client, allKeys) {
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.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
class UserProfilePostsFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
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.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
class UserProfileZapsFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<UserProfileQueryState>,
) : PerUserEoseManager<UserProfileQueryState>(client, allKeys) {
override fun updateFilter(
@@ -21,7 +21,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relay.datasource
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
// This allows multiple screens to be listening to the same or different relay feeds.
@@ -30,7 +30,7 @@ class RelayFeedQueryState(
)
class RelayFeedFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<RelayFeedQueryState>() {
val group =
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.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
class RelayFeedFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<RelayFeedQueryState>,
) : PerUniqueIdEoseManager<RelayFeedQueryState, String>(client, allKeys) {
override fun updateFilter(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.service.replace
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 kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
@@ -99,7 +99,7 @@ abstract class BasicRelaySetupInfoModel : ViewModel() {
filters.forEach { countFilter ->
viewModelScope.launch(Dispatchers.IO) {
val result = client.queryCountSuspend(item.relay, countFilter.filter)
val result = client.count(item.relay, countFilter.filter)
if (result != null) {
_countResults.update { currentMap ->
val current = currentMap[item.relay] ?: RelayCountResult()
@@ -21,7 +21,7 @@
package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.datasource
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
class RelayInfoNip66QueryState(
@@ -30,7 +30,7 @@ class RelayInfoNip66QueryState(
)
class RelayInfoNip66FilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<RelayInfoNip66QueryState>() {
val group =
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.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.filters.Filter
import com.vitorpamplona.quartz.nip66RelayMonitor.discovery.RelayDiscoveryEvent
class RelayInfoNip66FilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<RelayInfoNip66QueryState>,
) : PerUniqueIdEoseManager<RelayInfoNip66QueryState, String>(client, allKeys) {
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.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.reqBypassingRelayLimits
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchAllPages
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayConnectionListener
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.OkMessage
@@ -65,7 +65,7 @@ import kotlin.coroutines.cancellation.CancellationException
* 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.
*
* 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.
*
* 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 inboxTargets: () -> Set<NormalizedRelayUrl>,
private val dmTargets: () -> Set<NormalizedRelayUrl>,
private val clientBuilder: () -> INostrClient,
private val clientBuilder: () -> NostrClient,
private val scope: CoroutineScope,
) {
companion object {
@@ -406,7 +406,7 @@ class EventSync(
)
val okListener =
object : IRelayClientListener {
object : RelayConnectionListener {
override fun onCannotConnect(
relay: IRelayClient,
errorMessage: String,
@@ -500,7 +500,7 @@ class EventSync(
_syncState.emit(runningState)
clientBuilder().use { client ->
client.subscribe(okListener)
client.addConnectionListener(okListener)
try {
client.downloadFromPool(
relays = relaysToProcess,
@@ -523,21 +523,21 @@ class EventSync(
// Each routing rule is independent: an event can match more than one.
if (isMyEvent && outboxTargets.isNotEmpty()) {
if (outboxDedup.add(event.id)) {
client.send(event, outboxTargets)
client.publish(event, outboxTargets)
newEvent = true
}
matchesAtLeastOneFilter = true
}
if (mentionsMe && isDmKind && dmTargets.isNotEmpty()) {
if (dmDedup.add(event.id)) {
client.send(event, dmTargets)
client.publish(event, dmTargets)
newEvent = true
}
matchesAtLeastOneFilter = true
}
if (mentionsMe && !isDmKind && inboxTargets.isNotEmpty()) {
if (inboxDedup.add(event.id)) {
client.send(event, inboxTargets)
client.publish(event, inboxTargets)
newEvent = true
}
matchesAtLeastOneFilter = true
@@ -610,7 +610,7 @@ class EventSync(
if (e is CancellationException) throw e
_syncState.value = SyncState.Error(e.message ?: "Unknown error", filterSince, filterUntil)
} 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.
*/
private suspend fun INostrClient.downloadFromPool(
private suspend fun NostrClient.downloadFromPool(
relays: List<NormalizedRelayUrl>,
filters: Map<NormalizedRelayUrl, List<Filter>>,
onNewPage: (Long, NormalizedRelayUrl) -> Unit,
@@ -661,10 +661,10 @@ class EventSync(
*
* @return total number of events received across all pages.
*/
private suspend fun INostrClient.downloadFromRelay(
private suspend fun NostrClient.downloadFromRelay(
relay: NormalizedRelayUrl,
filters: List<Filter>,
onNewPage: (Long) -> 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.RelayCountResult
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.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip65RelayList.tags.AdvertisedRelayInfo
@@ -131,7 +131,7 @@ class Nip65RelayListViewModel : ViewModel() {
_homeRelays.value.forEach { item ->
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) {
val countResult =
RelayCountResult(
@@ -150,7 +150,7 @@ class Nip65RelayListViewModel : ViewModel() {
_notificationRelays.value.forEach { item ->
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) {
val countResult =
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.ThreadFilterSubAssembler
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
@Stable
@@ -37,7 +37,7 @@ class ThreadQueryState(
@Stable
class ThreadFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<ThreadQueryState>() {
val group =
listOf(
@@ -26,7 +26,7 @@ import com.vitorpamplona.amethyst.service.relayClient.eoseManagers.PerUniqueIdEo
import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
import com.vitorpamplona.amethyst.ui.screen.loggedIn.threadview.datasources.ThreadQueryState
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
/**
@@ -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
*/
class ThreadEventLoaderSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ThreadQueryState>,
) : PerUniqueIdEoseManager<ThreadQueryState, HexKey>(client, allKeys, invalidateAfterEose = true) {
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.ui.screen.loggedIn.threadview.datasources.ThreadQueryState
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
/**
@@ -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
*/
class ThreadFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ThreadQueryState>,
) : PerUniqueIdEoseManager<ThreadQueryState, HexKey>(client, allKeys) {
override fun updateFilter(
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.composeSubscriptionManager
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountFeedContentStates
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
// This allows multiple screen to be listening to tags, even the same tag
@@ -35,7 +35,7 @@ class VideoQueryState(
)
class VideoFilterAssembler(
client: INostrClient,
client: NostrClient,
) : ComposeSubscriptionManager<VideoQueryState>() {
val group =
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.nip72Communities.filterPictureAndVideoByAllCommunities
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.subscriptions.Subscription
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -52,7 +52,7 @@ import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch
class VideoOutboxEventsFilterSubAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<VideoQueryState>,
) : PerUserAndFollowListEoseManager<VideoQueryState, TopFilter>(client, allKeys) {
override fun updateFilter(
@@ -21,8 +21,8 @@
package com.vitorpamplona.amethyst.commons.chess
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -49,7 +49,7 @@ enum class RelayFetchStatus {
/**
* 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).
*
* 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.
*/
class ChessRelayFetchHelper(
private val client: INostrClient,
private val client: NostrClient,
) {
/**
* 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 onProgress Optional callback for progress updates per relay
* @return Deduplicated list of events received before timeout/EOSE
@@ -88,10 +88,10 @@ class ChessRelayFetchHelper(
}
val listener =
object : IRequestListener {
object : SubscriptionListener {
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -100,7 +100,7 @@ class ChessRelayFetchHelper(
onProgress?.invoke(RelayFetchProgress(relay, RelayFetchStatus.RECEIVING, count))
}
override fun onEose(
override fun onCaughtUp(
relay: NormalizedRelayUrl,
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() }
// Mark timed-out relays
@@ -127,7 +127,7 @@ class ChessRelayFetchHelper(
}
}
client.close(subId)
client.unsubscribe(subId)
return events.values.toList()
}
@@ -20,7 +20,7 @@
*/
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.nip46RemoteSigner.signer.NostrSignerRemote
import kotlinx.coroutines.flow.first
@@ -32,7 +32,7 @@ object BunkerLoginUseCase {
suspend fun execute(
bunkerUri: String,
ephemeralSigner: NostrSignerInternal,
client: INostrClient,
client: NostrClient,
): BunkerLoginResult {
val remoteSigner = NostrSignerRemote.fromBunkerUri(bunkerUri, ephemeralSigner, client)
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.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.StaticSubscription
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
@@ -83,7 +83,7 @@ object NostrConnectLoginUseCase {
suspend fun awaitAndLogin(
uriData: NostrConnectUri,
client: INostrClient,
client: NostrClient,
): BunkerLoginResult {
val connectData =
waitForConnectRequest(
@@ -117,19 +117,22 @@ object NostrConnectLoginUseCase {
ephemeralPubKey: HexKey,
relays: Set<NormalizedRelayUrl>,
expectedSecret: String,
client: INostrClient,
client: NostrClient,
): ConnectRequestData {
val deferred = CompletableDeferred<NostrConnectEvent>()
val subscription =
client.req(
relays = relays.toList(),
filter =
Filter(
kinds = listOf(NostrConnectEvent.KIND),
tags = mapOf("p" to listOf(ephemeralPubKey)),
since = TimeUtils.now() - 60,
),
StaticSubscription(
client,
relays.associateWith {
listOf(
Filter(
kinds = listOf(NostrConnectEvent.KIND),
tags = mapOf("p" to listOf(ephemeralPubKey)),
since = TimeUtils.now() - 60,
),
)
},
) { event ->
if (event is NostrConnectEvent && !deferred.isCompleted) {
deferred.complete(event)
@@ -198,7 +201,7 @@ object NostrConnectLoginUseCase {
ephemeralSigner: NostrSignerInternal,
connectData: ConnectRequestData,
relays: Set<NormalizedRelayUrl>,
client: INostrClient,
client: NostrClient,
) {
val ackResponse = BunkerResponseAck(id = connectData.requestId!!)
val ackEvent =
@@ -207,7 +210,7 @@ object NostrConnectLoginUseCase {
remoteKey = connectData.signerPubkey,
signer = ephemeralSigner,
)
client.send(ackEvent, relays)
client.publish(ackEvent, relays)
}
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.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -55,7 +55,7 @@ import kotlinx.coroutines.CoroutineScope
* ```
*/
class FeedMetadataCoordinator(
private val client: INostrClient,
private val client: NostrClient,
private val scope: CoroutineScope,
private val indexRelays: Set<NormalizedRelayUrl>,
private val preloader: MetadataPreloader? = null,
@@ -79,10 +79,10 @@ class FeedMetadataCoordinator(
// Create listener to pass events to the callback
val listener =
if (onEvent != null) {
object : IRequestListener {
object : SubscriptionListener {
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -93,7 +93,7 @@ class FeedMetadataCoordinator(
null
}
client.openReqSubscription(
client.subscribe(
subId = newSubId(),
filters = filterMap,
listener = listener,
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.commons.relayClient.eoseManagers.SingleSubEose
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
import com.vitorpamplona.quartz.nip01Core.core.HexKey
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.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -48,7 +48,7 @@ data class MetadataQueryState(
* - Caches EOSE to avoid re-fetching known metadata
*/
class MetadataFilterAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<MetadataQueryState>,
) : SingleSubEoseManager<MetadataQueryState>(client, allKeys, invalidateAfterEose = true) {
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.relays.SincePerRelayMap
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.filters.Filter
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
@@ -48,7 +48,7 @@ data class ReactionsQueryState(
* - Caches EOSE to avoid re-fetching known reactions
*/
class ReactionsFilterAssembler(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<ReactionsQueryState>,
) : SingleSubEoseManager<ReactionsQueryState>(client, allKeys, invalidateAfterEose = true) {
override fun distinct(key: ReactionsQueryState): Any = key.noteIds.hashCode()
@@ -21,14 +21,14 @@
package com.vitorpamplona.amethyst.commons.relayClient.eoseManagers
import com.vitorpamplona.amethyst.commons.service.BundledUpdate
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
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.subscriptions.SubscriptionController
import kotlinx.coroutines.Dispatchers
abstract class BaseEoseManager<T>(
val client: INostrClient,
val client: NostrClient,
val allKeys: () -> Set<T>,
val sampleTime: Long = 500,
) : IEoseManager {
@@ -38,7 +38,7 @@ abstract class BaseEoseManager<T>(
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)
@@ -23,10 +23,10 @@ package com.vitorpamplona.amethyst.commons.relayClient.eoseManagers
import com.vitorpamplona.amethyst.commons.relays.EOSECache
import com.vitorpamplona.amethyst.commons.relays.SincePerRelayMap
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.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.filters.Filter
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.
*/
abstract class PerKeyEoseManager<T, K : Any>(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false,
cacheSize: Int = 200,
@@ -82,8 +82,8 @@ abstract class PerKeyEoseManager<T, K : Any>(
*/
open fun newSub(queryState: T): Subscription =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -92,11 +92,11 @@ abstract class PerKeyEoseManager<T, K : Any>(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
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.SincePerRelayMap
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.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.normalizer.NormalizedRelayUrl
import com.vitorpamplona.quartz.utils.TimeUtils
@@ -44,7 +44,7 @@ import com.vitorpamplona.quartz.utils.TimeUtils
* shares all EOSEs among all users.
*/
abstract class SingleSubEoseManager<T>(
client: INostrClient,
client: NostrClient,
allKeys: () -> Set<T>,
val invalidateAfterEose: Boolean = false,
) : BaseEoseManager<T>(client, allKeys) {
@@ -66,8 +66,8 @@ abstract class SingleSubEoseManager<T>(
val sub =
requestNewSubscription(
object : IRequestListener {
override fun onEose(
object : SubscriptionListener {
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
@@ -76,11 +76,11 @@ abstract class SingleSubEoseManager<T>(
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) {
if (isLive) {
if (isRealTime) {
newEose(relay, TimeUtils.now(), forFilters)
}
}
@@ -21,9 +21,9 @@
package com.vitorpamplona.amethyst.commons.chess
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.sendAndWaitForResponse
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.publishAndConfirm
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.SubscriptionListener
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
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.
*
* 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.
*/
class ChessEventBroadcaster(
private val client: INostrClient,
private val client: NostrClient,
) {
/**
* Broadcast an event to the chess relays with confirmation.
@@ -84,15 +84,15 @@ class ChessEventBroadcaster(
)
val listener =
object : IRequestListener {
object : SubscriptionListener {
override fun onEvent(
event: Event,
isLive: Boolean,
isRealTime: Boolean,
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) { }
override fun onEose(
override fun onCaughtUp(
relay: NormalizedRelayUrl,
forFilters: List<Filter>?,
) { }
@@ -100,19 +100,19 @@ class ChessEventBroadcaster(
// Open subscription to all target relays (triggers connection)
val filterMap = targetRelays.associateWith { listOf(dummyFilter) }
client.openReqSubscription(subId, filterMap, listener)
client.subscribe(subId, filterMap, listener)
// Wait for relays to connect (poll with timeout)
waitForRelays(targetRelays, 5000L)
// Close the dummy subscription
client.close(subId)
client.unsubscribe(subId)
}
// 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
return BroadcastResult(
success = success,
@@ -193,7 +193,7 @@ fun main() {
}
Window(
onCloseRequest = ::exitApplication,
onSubscriptionCloseduest = ::exitApplication,
state = windowState,
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.toHexKey
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
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.commands.toClient.Message
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) ---
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 {
nip46Client ?: NostrClient(
nip46Client ?: DefaultNostrClient(
BasicOkHttpWebSocket.Builder(DesktopHttpClient::getHttpClient),
).also {
nip46Client = it
@@ -156,7 +155,7 @@ class AccountManager internal constructor(
* but we must wait for the websocket to be ready before sending requests.
*/
private suspend fun awaitNip46RelayConnection(
client: NostrClient,
client: DefaultNostrClient,
targetRelays: Set<NormalizedRelayUrl>,
) {
withTimeout(NIP46_RELAY_CONNECT_TIMEOUT_MS) {
@@ -180,8 +179,8 @@ class AccountManager internal constructor(
}
}
private fun createLoginRelayListener(): IRelayClientListener =
object : IRelayClientListener {
private fun createLoginRelayListener(): RelayConnectionListener =
object : RelayConnectionListener {
override fun onConnected(
relay: IRelayClient,
pingMillis: Int,
@@ -303,7 +302,7 @@ class AccountManager internal constructor(
suspend fun loginWithBunker(bunkerUri: String): Result<AccountState.LoggedIn> {
val listener = createLoginRelayListener()
var client: NostrClient? = null
var client: DefaultDefaultNostrClient? = null
try {
val ephemeralKeyPair = KeyPair()
val ephemeralSigner = NostrSignerInternal(ephemeralKeyPair)
@@ -316,7 +315,7 @@ class AccountManager internal constructor(
LoginProgress.ConnectingToRelays(
relaysFromUri.associateWith { RelayLoginStatus.CONNECTING },
)
nip46Client.subscribe(listener)
nip46Client.addConnectionListener(listener)
_loginProgress.value =
LoginProgress.WaitingForSigner(
@@ -356,7 +355,7 @@ class AccountManager internal constructor(
return Result.failure(Exception("Connection failed: ${e.message}"))
} finally {
_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> {
val listener = createLoginRelayListener()
var client: NostrClient? = null
var client: DefaultDefaultNostrClient? = null
try {
val ephemeralKeyPair = KeyPair()
val uriData = NostrConnectLoginUseCase.generateUri(ephemeralKeyPair, NIP46_RELAYS, "Amethyst%20Desktop")
@@ -376,7 +375,7 @@ class AccountManager internal constructor(
LoginProgress.ConnectingToRelays(
uriData.relays.associateWith { RelayLoginStatus.CONNECTING },
)
nip46Client.subscribe(listener)
nip46Client.addConnectionListener(listener)
onUriGenerated(uriData.uri)
@@ -415,7 +414,7 @@ class AccountManager internal constructor(
return Result.failure(Exception("Connection failed: ${e.message}"))
} finally {
_loginProgress.value = null
client?.unsubscribe(listener)
client?.removeConnectionListener(listener)
}
}
@@ -140,7 +140,7 @@ fun ChessScreen(
onEvent = { event, _, _, _ ->
viewModel.handleIncomingEvent(event)
},
onEose = { _, _ ->
onCaughtUp = { _, _ ->
// ChessLobbyLogic handles loading state internally
},
)

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