fix(nests): use moq-auth.nostrnests.com for JWT mint
The previous defaults pointed both `service` and `endpoint` URLs at
`moq.nostrnests.com:4443`. That host only listens on UDP/QUIC for the
WebTransport relay — TCP :4443 is unreachable. OkHttp can't speak HTTP/3,
so the JWT-mint POST hangs and fails with `ConnectException`, leaving
the room screen stuck on "Reconnecting".
The real nostrnests deployment co-locates auth and relay on different
hosts (verified against the production NestsUI bundle):
relay (WebTransport, QUIC only): https://moq.nostrnests.com:4443
auth (JWT mint, regular HTTPS): https://moq-auth.nostrnests.com
Split the defaults accordingly and add a `resolveServerPair` helper that
maps a single saved kind-10112 URL onto the (service, endpoint) pair the
kind-30312 event needs. The helper recognises both the auth-host and
the legacy relay-host the prior defaults wrote, so users upgrading from
the broken version migrate transparently the next time they open the
create-room sheet. Community deployments that genuinely co-locate keep
working via the fallback.
Update the recommended-servers list and the kind-10112 documentation to
match: the stored `server` URL is the moq-auth base (the URL that ends
up in the kind-30312 `service` tag).
This commit is contained in:
+6
-1
@@ -247,8 +247,13 @@ private fun NestsServerEntry(
|
|||||||
* Built-in suggestion list shown under "Recommended servers". Today
|
* Built-in suggestion list shown under "Recommended servers". Today
|
||||||
* just the public `nostrnests.com` deployment; add new entries here
|
* just the public `nostrnests.com` deployment; add new entries here
|
||||||
* as community-run moq-rs / moq-auth instances come online.
|
* as community-run moq-rs / moq-auth instances come online.
|
||||||
|
*
|
||||||
|
* The stored URL is the moq-auth (service / JWT mint) base — that's
|
||||||
|
* the URL that ends up in the kind-30312 `service` tag. The matching
|
||||||
|
* WebTransport relay endpoint is resolved by
|
||||||
|
* [com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.create.CreateNestViewModel.resolveServerPair].
|
||||||
*/
|
*/
|
||||||
val DEFAULT_NESTS_SERVERS: List<NestsServer> =
|
val DEFAULT_NESTS_SERVERS: List<NestsServer> =
|
||||||
listOf(
|
listOf(
|
||||||
NestsServer(name = "nostrnests.com", baseUrl = "https://moq.nostrnests.com:4443"),
|
NestsServer(name = "nostrnests.com", baseUrl = "https://moq-auth.nostrnests.com"),
|
||||||
)
|
)
|
||||||
|
|||||||
+9
-2
@@ -115,7 +115,11 @@ class NestsServersViewModel : ViewModel() {
|
|||||||
|
|
||||||
private fun displayHostName(url: String): String =
|
private fun displayHostName(url: String): String =
|
||||||
try {
|
try {
|
||||||
Rfc3986.host(url).removePrefix("moq.").removePrefix("nests.")
|
Rfc3986
|
||||||
|
.host(url)
|
||||||
|
.removePrefix("moq-auth.")
|
||||||
|
.removePrefix("moq.")
|
||||||
|
.removePrefix("nests.")
|
||||||
} catch (_: Throwable) {
|
} catch (_: Throwable) {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
@@ -124,7 +128,10 @@ class NestsServersViewModel : ViewModel() {
|
|||||||
/**
|
/**
|
||||||
* Display-friendly entry for [NestsServersViewModel].
|
* Display-friendly entry for [NestsServersViewModel].
|
||||||
* - [name] — short host label (e.g. `nostrnests.com`)
|
* - [name] — short host label (e.g. `nostrnests.com`)
|
||||||
* - [baseUrl] — exact bytes that go on the wire (`https://moq.nostrnests.com`)
|
* - [baseUrl] — exact bytes that go on the wire as the kind-30312
|
||||||
|
* `service` tag (`https://moq-auth.nostrnests.com`). The matching
|
||||||
|
* WebTransport endpoint is resolved at room-create time, not
|
||||||
|
* stored here.
|
||||||
*/
|
*/
|
||||||
data class NestsServer(
|
data class NestsServer(
|
||||||
val name: String,
|
val name: String,
|
||||||
|
|||||||
+33
-2
@@ -79,7 +79,8 @@ class CreateNestViewModel : ViewModel() {
|
|||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.takeIf { it.startsWith("http") }
|
?.takeIf { it.startsWith("http") }
|
||||||
if (savedFirst != null) {
|
if (savedFirst != null) {
|
||||||
_state.update { it.copy(serviceUrl = savedFirst, endpointUrl = savedFirst) }
|
val (service, endpoint) = resolveServerPair(savedFirst)
|
||||||
|
_state.update { it.copy(serviceUrl = service, endpointUrl = endpoint) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,8 +356,38 @@ class CreateNestViewModel : ViewModel() {
|
|||||||
* Public nostrnests deployment — a blank form produces a working
|
* Public nostrnests deployment — a blank form produces a working
|
||||||
* room here. Users can edit either field to point at their own
|
* room here. Users can edit either field to point at their own
|
||||||
* moq-auth / moq-relay pair.
|
* moq-auth / moq-relay pair.
|
||||||
|
*
|
||||||
|
* The auth sidecar (moq-auth) and the WebTransport relay
|
||||||
|
* (moq-rs) are on different hosts: moq-auth speaks regular
|
||||||
|
* HTTPS on :443 to mint JWTs; moq.nostrnests.com:4443 is the
|
||||||
|
* QUIC/WebTransport endpoint and does NOT accept TCP. Don't
|
||||||
|
* collapse them back into a single URL — OkHttp can't speak
|
||||||
|
* HTTP/3, so a TCP POST to :4443 will hang and fail.
|
||||||
*/
|
*/
|
||||||
const val DEFAULT_SERVICE_URL: String = "https://moq.nostrnests.com:4443"
|
const val DEFAULT_SERVICE_URL: String = "https://moq-auth.nostrnests.com"
|
||||||
const val DEFAULT_ENDPOINT_URL: String = "https://moq.nostrnests.com:4443"
|
const val DEFAULT_ENDPOINT_URL: String = "https://moq.nostrnests.com:4443"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a single saved kind-10112 URL onto the (service, endpoint)
|
||||||
|
* pair the kind-30312 event needs. Recognises the public
|
||||||
|
* nostrnests deployment (whether the user has the auth host or
|
||||||
|
* the relay host saved — earlier app versions stored the relay
|
||||||
|
* URL by mistake), and falls back to using the URL for both
|
||||||
|
* tags so community-run deployments that genuinely co-locate
|
||||||
|
* keep working.
|
||||||
|
*/
|
||||||
|
internal fun resolveServerPair(savedUrl: String): Pair<String, String> =
|
||||||
|
when (savedUrl.trimEnd('/')) {
|
||||||
|
"https://moq-auth.nostrnests.com",
|
||||||
|
"https://moq.nostrnests.com:4443",
|
||||||
|
"https://moq.nostrnests.com",
|
||||||
|
-> {
|
||||||
|
DEFAULT_SERVICE_URL to DEFAULT_ENDPOINT_URL
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
savedUrl to savedUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -42,19 +42,23 @@ import com.vitorpamplona.quartz.utils.TimeUtils
|
|||||||
* "kind": 10112,
|
* "kind": 10112,
|
||||||
* "tags": [
|
* "tags": [
|
||||||
* ["alt", "Audio-room (nests) MoQ servers used by the author"],
|
* ["alt", "Audio-room (nests) MoQ servers used by the author"],
|
||||||
* ["server", "https://moq.nostrnests.com"],
|
* ["server", "https://moq-auth.nostrnests.com"],
|
||||||
* ["server", "https://moq.example.org"],
|
* ["server", "https://moq.example.org"],
|
||||||
* ...
|
* ...
|
||||||
* ],
|
* ],
|
||||||
* "content": ""
|
* "content": ""
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* The `server` URL points at the moq-rs / moq-auth deployment's base
|
* The `server` URL is the moq-auth (JWT mint) base — that's also the
|
||||||
* URL — Amethyst's `CreateNestSheet` uses it for both the
|
* URL that goes into the kind-30312 `service` tag. The matching
|
||||||
* `service` (auth sidecar) and `endpoint` (WebTransport relay) tags
|
* WebTransport relay endpoint is NOT part of this list; reference
|
||||||
* on the kind-30312 event, since nostrnests's reference deployment
|
* deployments like nostrnests run the auth sidecar on regular HTTPS
|
||||||
* co-locates them. A future revision can split the two into separate
|
* (e.g. `https://moq-auth.nostrnests.com`) and the QUIC relay on a
|
||||||
* tag fields if the community pulls them apart.
|
* separate host/port (e.g. `https://moq.nostrnests.com:4443`), so
|
||||||
|
* Amethyst's `CreateNestSheet` resolves the pair via a known-deployment
|
||||||
|
* mapping (with a fallback that reuses the saved URL for both tags
|
||||||
|
* when a community deployment genuinely co-locates them). A future
|
||||||
|
* revision can split the two into separate tag fields if needed.
|
||||||
*
|
*
|
||||||
* This event is shaped 1:1 after `BlossomServersEvent` (kind 10063,
|
* This event is shaped 1:1 after `BlossomServersEvent` (kind 10063,
|
||||||
* NIP-B7) so existing list-state / settings UI patterns translate
|
* NIP-B7) so existing list-state / settings UI patterns translate
|
||||||
|
|||||||
Reference in New Issue
Block a user