Phase 3b-1 of the Clubhouse/nests integration. Lands the
[WebTransportSession] abstraction the MoQ layer (Phase 3c) will code
against, so MoQ framing + tests can develop in parallel with the real
Kwik-based transport integration (deferred to Phase 3b-2).
commonMain:
- `WebTransportSession` — bidi/uni stream access, datagrams, close.
- `WebTransportBidiStream` / `WebTransportReadStream` /
`WebTransportWriteStream` — minimal read/write surface.
- `WebTransportFactory.connect(authority, path, bearerToken)` for
opening sessions.
- `WebTransportException(kind, ...)` with four canonical failure modes
(HandshakeFailed, ConnectRejected, PeerClosed, NotImplemented) so UI
code doesn't need to know about library-specific exceptions.
- `FakeWebTransport.pair()` — in-memory, fully-wired client/server
pair for unit-testing MoQ framing without touching a real QUIC stack.
jvmAndroid:
- `KwikWebTransportFactory` stub that throws
`WebTransportException(NotImplemented)` at `connect()`. Doc spells
out the handshake sequence (QUIC dial → H3 SETTINGS →
`:method=CONNECT :protocol=webtransport` Extended CONNECT → 2xx) so
Phase 3b-2 can drop the real implementation in without touching
callers.
Tests:
- `FakeWebTransportTest` — datagram round-trip both directions,
bidi-stream write visible on peer side, close() flips isOpen.
- `WebTransportExceptionTest` — kind + message + cause preserved.
- `KwikWebTransportFactoryTest` — `connect()` currently fails with the
NotImplemented sentinel, so Phase 3b-2 can replace this test when
the real handshake lands.
https://claude.ai/code/session_013nVLALALKaHVgHm9u5Cg8D
Phase 3a of the Clubhouse/nests integration. Adds a new KMP module
`nestsClient` (Android + JVM targets) that owns the HTTP control plane
for talking to a nests audio-room backend. No transport/audio yet —
that arrives in 3b with WebTransport + MoQ.
Surface:
- `NestsAuth.header(signer, url, method)` signs a kind 27235 event via
Quartz's existing HTTPAuthorizationEvent and returns a ready-to-use
`Authorization: Nostr <base64>` header value.
- `NestsRoomInfo` data class + tolerant JSON parser (ignores unknown
fields so newer nests server revisions don't break older clients).
- `NestsClient.resolveRoom(serviceBase, roomId, signer)` calls
`<serviceBase>/<roomId>` with the signed NIP-98 header and returns
the MoQ endpoint + token the audio layer will need.
- `OkHttpNestsClient` (jvmAndroid) is the default implementation
shared between Android and desktop JVM.
Tests:
- `NestsRoomInfoTest` (commonTest) covers full/minimal payloads,
unknown-field tolerance, missing-endpoint rejection, and URL
construction edge cases.
- `NestsAuthTest` (jvmTest) signs a real 27235 event, decodes the
base64 back through Quartz's JacksonMapper, and asserts the
signature verifies and the url+method tags bind correctly.
https://claude.ai/code/session_013nVLALALKaHVgHm9u5Cg8D