Files
amethyst/nestsClient/build.gradle.kts
T
Claude 933b522273 feat(nestsClient): NIP-98 auth + nests room-info client
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
2026-04-22 02:58:24 +00:00

85 lines
2.1 KiB
Kotlin

import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidKotlinMultiplatformLibrary)
alias(libs.plugins.serialization)
}
kotlin {
jvm {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
android {
namespace = "com.vitorpamplona.nestsclient"
compileSdk =
libs.versions.android.compileSdk
.get()
.toInt()
minSdk =
libs.versions.android.minSdk
.get()
.toInt()
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
withHostTest {}
}
sourceSets {
commonMain {
dependencies {
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
api(project(":quartz"))
}
}
commonTest {
dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
}
}
val jvmAndroid =
create("jvmAndroid") {
dependsOn(commonMain.get())
dependencies {
implementation(libs.okhttp)
implementation(libs.okhttpCoroutines)
}
}
jvmMain {
dependsOn(jvmAndroid)
}
androidMain {
dependsOn(jvmAndroid)
}
jvmTest {
dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
implementation(libs.secp256k1.kmp.jni.jvm)
}
}
getByName("androidHostTest") {
dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
implementation(libs.secp256k1.kmp.jni.jvm)
}
}
}
}