feat(quartz-relay): rename + promote to a real Nostr relay
Renames :quartz-test-relay to :quartz-relay and promotes it from a test-only fixture to a real, runnable Nostr relay that just happens to also be used in tests. Two transports now share the same `Relay` core: - `RelayHub` + `InProcessWebSocket` — no socket, fastest path; ideal for unit tests inside one JVM. - `LocalRelayServer` — Ktor `embeddedServer` (CIO engine) listening on a real `ws://` port. Use for `cli` interop tests, Android instrumented tests, or running the relay standalone. NIPs implemented (all driven through production `NostrClient` in the new `LocalRelayServerTest`): - NIP-01 wire protocol (REQ/EVENT/EOSE/CLOSE) over real WebSockets - NIP-09 deletion (via existing `DeletionRequestModule`) - NIP-11 relay info doc — `RelayInfo` wraps the existing `Nip11RelayInformation` model and is served on HTTP GET when `Accept: application/nostr+json` is requested. Loadable from a JSON config file via `RelayInfo.fromFile(...)`. - NIP-40 expiration (existing `ExpirationModule`) - NIP-42 AUTH (existing `FullAuthPolicy`, opted-in via the `--auth` flag in the standalone runner) - NIP-45 COUNT - NIP-50 search via the existing FTS index - NIP-62 right-to-vanish (existing module) Adds a standalone runner: `./gradlew :quartz-relay:run --args="--port 7447 --verify"` binds the relay to a real port. Flags: --host, --port, --path, --info <file>, --db <file>, --auth, --verify. Test-only event generators moved to a clearly-named `com.vitorpamplona.quartz.relay.fixtures` package so they're still shareable with consumer tests without polluting the production API. Adds `LocalRelayServerTest` covering NIP-01/11/42/45/50 over a real loopback WebSocket. Existing 11-test `Nip01ComplianceTest` (in-process transport) continues to pass.
This commit is contained in:
@@ -182,8 +182,10 @@ kotlin {
|
||||
implementation(libs.kotlinx.coroutines.test)
|
||||
|
||||
// In-process Nostr relay so JVM/Android host tests don't
|
||||
// need network access or a Rust toolchain.
|
||||
implementation(project(":quartz-test-relay"))
|
||||
// need network access or a Rust toolchain. The
|
||||
// `relay.fixtures` package carries the test-only event
|
||||
// generators and corpus loader.
|
||||
implementation(project(":quartz-relay"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -20,11 +20,11 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.relay
|
||||
|
||||
import com.vitorpamplona.quartz.testrelay.TestRelayHub
|
||||
import com.vitorpamplona.quartz.relay.RelayHub
|
||||
|
||||
/**
|
||||
* Base for tests that drive a real `NostrClient` against an in-process Nostr
|
||||
* relay. Each subclass instance gets its own [TestRelayHub] so tests can
|
||||
* relay. Each subclass instance gets its own [RelayHub] so tests can
|
||||
* preload events and assert deterministic counts without hitting the
|
||||
* network or relying on production relays.
|
||||
*
|
||||
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.testrelay.TestRelayHub
|
||||
* the specific test that needs it.
|
||||
*/
|
||||
open class BaseNostrClientTest {
|
||||
val relayHub: TestRelayHub = TestRelayHub()
|
||||
val relayHub: RelayHub = RelayHub()
|
||||
|
||||
/** Plug into `NostrClient(socketBuilder, scope)`. */
|
||||
val socketBuilder get() = relayHub
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ 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.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.count
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.normalizeRelayUrl
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.fetchAllPages
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.subscribeAsFlow
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ 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.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.fetchAsFlow
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.testrelay.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.relay.fixtures.SyntheticEvents
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
Reference in New Issue
Block a user