2026-03-23 01:41:39 +02:00
|
|
|
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
|
|
|
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
|
|
|
|
|
|
|
|
plugins {
|
|
|
|
|
alias(libs.plugins.androidApplication)
|
2026-05-02 00:05:38 +02:00
|
|
|
// alias(libs.plugins.androidx.room)
|
|
|
|
|
alias(libs.plugins.androidx.room3)
|
2026-03-24 04:47:19 +02:00
|
|
|
alias(libs.plugins.kotlinMultiplatform)
|
2026-03-23 01:41:39 +02:00
|
|
|
alias(libs.plugins.composeMultiplatform)
|
|
|
|
|
alias(libs.plugins.composeCompiler)
|
|
|
|
|
alias(libs.plugins.composeHotReload)
|
2026-03-23 02:21:18 +02:00
|
|
|
alias(libs.plugins.kotlinPluginSerialization)
|
2026-03-24 04:47:19 +02:00
|
|
|
alias(libs.plugins.ksp)
|
2026-06-15 14:39:46 +02:00
|
|
|
alias(libs.plugins.sqldelight)
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kotlin {
|
2026-03-26 00:20:20 +02:00
|
|
|
compilerOptions {
|
|
|
|
|
freeCompilerArgs.add("-Xexpect-actual-classes")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 01:41:39 +02:00
|
|
|
androidTarget {
|
|
|
|
|
compilerOptions {
|
2026-06-23 13:59:17 +02:00
|
|
|
jvmTarget.set(JvmTarget.JVM_21)
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
build: bump lightning-kmp-app to bbba08b, building lightning-kmp from source
lightning-kmp-app moves 6745d88 -> bbba08b, four commits:
57353cf Minor updates
9f3cd72 Build lightning-kmp from the experimental submodule via a composite build
f22c30a Follow the submodule chain onto Gradle 9.7.1
bbba08b Declare the ios targets only on a mac, so the IDE can import the project
9f3cd72 is the substantive one. lightning-kmp no longer comes from maven central: the
submodule now carries its own experimental/lightning-kmp submodule on branch `threshold`
-- the branch with the FROST/prefractal signers -- and substitutes
fr.acinq.lightning:lightning-kmp-core for that build's project. That build includes
bitcoin-kmp, which includes secp256k1-kmp, which compiles the C library from a secp256k1-zkp
fork. So this repo's build tree is now four levels deep and compiles native code.
Cloning therefore needs `git submodule update --init --recursive`, and because each included
build resolves the android SDK from its own local.properties rather than inheriting the
root's, the three new nested builds each need a (gitignored) local.properties with sdk.dir.
57353cf changed two signatures that MantraApplication implements -- LightningApplication
gained getApplicationContext(), and BusinessManager.initialize now takes the application
rather than a Context. Neither needed a source change: MantraApplication extends
android.app.Application, which already supplies getApplicationContext(), and it was already
passing `this`, which satisfies the narrowed parameter type.
The rest of this commit is what the update forces on the outer build.
gradle-wrapper.properties, 9.3.1 -> 9.7.1: f22c30a moved every build in the chain onto
9.7.1. An included build does not use its own wrapper -- the root build's gradle version runs
the whole tree -- so this repo has to follow for the chain to build at all.
gradle.properties, configuration cache off: secp256k1-kmp's `:jni:generateHeaders` and
`:native:buildSecp256k1<target>` both hold gradle script object references and cannot be
serialized. The configuration cache covers a whole build tree and has no per-build opt-out,
so an included build's incompatibility is this build's problem. The comment records how to
undo this once those tasks are fixed upstream.
composeApp/build.gradle.kts, ios targets gated on the host: secp256k1-kmp declares a
libsecp256k1 cinterop, which makes gradle switch off klib cross compilation for apple
targets. On linux nothing in the tree then offers an ios variant of
fr.acinq.phoenix:lightning-kmp-app, and the ios compilations failed with "No matching variant
of project ':lightning-kmp-app:library'" -- not a warning, a build failure. The gate covers
the target declarations, the iosMain dependencies (the source set only exists when the
targets do) and the kspIos* configurations (likewise). This mirrors bbba08b, which applied
the same gate inside the submodule for the same reason.
secp256k1-frost-kmp d3b294d applies that gate there too. Substitution rules apply across a
whole build tree, so that project's own lightning-kmp-core coordinate started resolving to
the source project without it asking, and every apple source set stopped resolving. The
android build masked it -- ios compilations are not in its task graph -- but
kmpPartiallyResolvedDependenciesChecker reported it and compileAppleMainKotlinMetadata failed
outright, which would have broken IDE import.
Note that `:composeApp:compileCommonMainKotlinMetadata` no longer exists on a linux host.
With ios gated off, androidTarget is the only declared target (jvm() is still commented out),
and KMP does not generate a commonMain metadata compilation for a single-target project.
`:composeApp:compileDebugKotlinAndroid` is the check now; it passes clean, with none of the
resolution errors above.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:50:59 +02:00
|
|
|
// Declared only on a mac, mirroring the gate lightning-kmp-app's :library applies to its own ios
|
|
|
|
|
// targets. Down the composite chain secp256k1-kmp declares a libsecp256k1 cinterop, which makes
|
|
|
|
|
// gradle switch off klib cross compilation for apple targets, so on a linux/windows host nothing
|
|
|
|
|
// in the build tree offers an ios variant of fr.acinq.phoenix:lightning-kmp-app. Declaring these
|
|
|
|
|
// targets anyway leaves every ios compilation unable to resolve it and fails the build outright.
|
|
|
|
|
// Building an ios binary needs a mac regardless.
|
|
|
|
|
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
|
|
|
|
|
listOf(
|
|
|
|
|
iosArm64(),
|
|
|
|
|
iosSimulatorArm64()
|
|
|
|
|
).forEach { iosTarget ->
|
|
|
|
|
iosTarget.binaries.framework {
|
|
|
|
|
baseName = "ComposeApp"
|
|
|
|
|
isStatic = true
|
|
|
|
|
}
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-16 20:28:05 +03:00
|
|
|
// jvm()
|
2026-03-23 01:41:39 +02:00
|
|
|
|
|
|
|
|
sourceSets {
|
|
|
|
|
androidMain.dependencies {
|
build: package the android secp256k1 natives, with ChillDKG in them
The android app had no android secp256k1 natives at all, and had not had any for
as long as lightning-kmp-core has been a dependency. `dependencyInsight` on
debugRuntimeClasspath resolved every secp256k1 coordinate to
`:secp256k1-kmp:jni:jvm:{darwin,linux,mingw}` -- desktop .so/.dylib/.dll files,
loaded by extracting them from a jar, which cannot work on a device.
The cause is a chain of individually reasonable decisions. lightning-kmp-core
publishes no android variant, so an android consumer resolves it to the jvm one;
the jvm variant asks for `secp256k1-kmp-jni-jvm`; and nothing anywhere asks for
`secp256k1-kmp-jni-android`. lightning-kmp-app names it only in androidDeviceTest,
so consumers of the published library do not get it. It has to be named here.
Naming it alone would not have been enough. bitcoin-kmp's settings.gradle.kts
substituted five of secp256k1-kmp's coordinates to the fork's projects but not
-jni-android, so it would have resolved from Maven Central to stock 0.24.0 --
built from upstream libsecp256k1, with no ChillDKG module. Because the kotlin API
comes from the substituted root project, that combination type-checks and links
and then fails with UnsatisfiedLinkError at the first native call. The rule is
added in the submodule commits this carries.
Submodule commits carried here:
lightning-kmp-app ce1ed01 -> 6434282 build: carry the jni-android substitution
down from bitcoin-kmp
experimental/lightning-kmp 77be7b78 -> 5103b79e
experimental/bitcoin-kmp 196a479 -> 65c4aab build: substitute
secp256k1-kmp-jni-android to the
included build too
Verified through the artifact rather than the graph: composeApp-debug.apk now
carries lib/{arm64-v8a,armeabi-v7a,x86,x86_64}/libsecp256k1-jni.so, and `nm -D` on
the arm64 one exports all twelve Java_..._chilldkg_... JNI entry points --
hostpubkey_gen, params_hash, participant_step1/step2/finalize,
coordinator_step1/finalize, and the recover and investigate calls.
The three builds in the chain sit on `build/substitute-jni-android` branches
(lightning-kmp-app on `build/agp-9.4.0`, which now carries two commits) and none
are pushed, so a fresh clone cannot resolve these pointers yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:25:23 +02:00
|
|
|
// The android secp256k1 natives. Nothing pulls these in transitively: lightning-kmp-core
|
|
|
|
|
// publishes no android variant, so the android target resolves it to the jvm one, which
|
|
|
|
|
// asks for secp256k1-kmp-jni-jvm and gets desktop .so/.dylib/.dll files that cannot load
|
|
|
|
|
// on a device. The app has to name the android artifact itself.
|
|
|
|
|
//
|
|
|
|
|
// Resolved from source via the composite build, not from Maven Central -- bitcoin-kmp's
|
|
|
|
|
// settings.gradle.kts substitutes this coordinate for secp256k1-kmp's :jni:android. That
|
|
|
|
|
// matters: the stock artifact has no ChillDKG module, so ChillDKG would compile and then
|
|
|
|
|
// fail with UnsatisfiedLinkError. The version is never resolved; substitution matches on
|
|
|
|
|
// group:name.
|
|
|
|
|
implementation("fr.acinq.secp256k1:secp256k1-kmp-jni-android:0.24.0")
|
|
|
|
|
|
2026-03-23 01:41:39 +02:00
|
|
|
implementation(libs.androidx.activity.compose)
|
2026-05-02 00:05:38 +02:00
|
|
|
// implementation(libs.androidx.room.sqlite.wrapper)
|
2026-03-30 13:14:37 +02:00
|
|
|
implementation(libs.compose.uiToolingPreview)
|
2026-06-15 14:39:46 +02:00
|
|
|
|
|
|
|
|
implementation(libs.sqldelight.android.driver)
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
commonMain.dependencies {
|
2026-04-19 04:30:29 +02:00
|
|
|
implementation(libs.androidx.datastore)
|
2026-04-18 21:58:32 +02:00
|
|
|
implementation(libs.androidx.datastore.preferences)
|
|
|
|
|
|
2026-03-30 13:14:37 +02:00
|
|
|
implementation(libs.androidx.lifecycle.viewmodelCompose)
|
|
|
|
|
implementation(libs.androidx.lifecycle.runtimeCompose)
|
|
|
|
|
|
2026-05-02 00:05:38 +02:00
|
|
|
// implementation(libs.androidx.room.runtime)
|
|
|
|
|
implementation(libs.androidx.room3.runtime)
|
2026-03-30 13:14:37 +02:00
|
|
|
implementation(libs.androidx.sqlite.bundled)
|
|
|
|
|
|
2026-04-21 23:49:54 +02:00
|
|
|
implementation(libs.coil.compose)
|
|
|
|
|
implementation(libs.coil.network.ktor3)
|
2026-04-20 22:57:15 +02:00
|
|
|
|
2026-03-23 01:41:39 +02:00
|
|
|
implementation(libs.compose.runtime)
|
|
|
|
|
implementation(libs.compose.foundation)
|
|
|
|
|
implementation(libs.compose.material3)
|
|
|
|
|
implementation (libs.compose.material.icons.core)
|
|
|
|
|
implementation (libs.compose.material.icons.extended)
|
|
|
|
|
implementation(libs.compose.ui)
|
|
|
|
|
implementation(libs.compose.components.resources)
|
|
|
|
|
implementation(libs.compose.uiToolingPreview)
|
|
|
|
|
|
2026-04-18 21:58:32 +02:00
|
|
|
|
2026-03-23 01:41:39 +02:00
|
|
|
implementation(libs.kermit)
|
|
|
|
|
|
2026-03-30 13:09:49 +02:00
|
|
|
implementation(libs.kotlinx.datetime)
|
2026-03-30 13:14:37 +02:00
|
|
|
implementation(libs.kotlinx.serialization.json)
|
2026-06-15 14:39:46 +02:00
|
|
|
implementation(libs.kotlinx.serialization.cbor)
|
|
|
|
|
|
2026-03-30 13:09:49 +02:00
|
|
|
|
2026-03-27 13:35:29 +02:00
|
|
|
implementation(libs.ktor.client.core)
|
2026-03-30 13:25:19 +02:00
|
|
|
implementation(libs.ktor.client.cio)
|
2026-03-30 13:14:37 +02:00
|
|
|
implementation(libs.ktor.client.websockets)
|
|
|
|
|
implementation(libs.ktor.serialization.kotlinx.json)
|
|
|
|
|
|
2026-06-15 14:39:46 +02:00
|
|
|
|
|
|
|
|
|
2026-08-15 17:07:31 +02:00
|
|
|
// implementation(libs.lightning.kmp.core)
|
|
|
|
|
|
|
|
|
|
// resolved via the lightning-kmp-app composite build (see settings.gradle.kts)
|
|
|
|
|
implementation("fr.acinq.phoenix:lightning-kmp-app:1.0.0")
|
2026-06-15 14:39:46 +02:00
|
|
|
|
|
|
|
|
implementation(libs.navigation.compose)
|
|
|
|
|
|
2026-04-18 02:41:31 +02:00
|
|
|
implementation(libs.okio)
|
|
|
|
|
|
2026-07-01 15:11:31 +02:00
|
|
|
implementation(libs.qrose)
|
2026-06-15 14:39:46 +02:00
|
|
|
|
|
|
|
|
implementation(libs.sqldelight.runtime)
|
|
|
|
|
implementation(libs.sqldelight.coroutines.extensions)
|
|
|
|
|
|
2026-03-30 13:14:37 +02:00
|
|
|
implementation(libs.vitorpamplona.quartz)
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
commonTest.dependencies {
|
|
|
|
|
implementation(libs.kotlin.test)
|
test: cover the long-running sync, and open the seams needed to do it
The six commits that built the live chat sync added no tests. Everything they
touch fails silently by nature — a filter that drops messages, a subscription
that stops being replayed, a group whose id never reaches the `#h` tag — so the
symptom is always "some messages didn't arrive", days later, on someone else's
phone. 46 tests, in four files.
**What is covered**
RelayPoolSubscriptionTest (13) — the pool's half of surviving a dropped socket.
A query is retained and replayed on reconnect; a closed one is forgotten and
stops the socket reconnecting for it; closing one of two leaves the other alone;
a negentropy exchange is never replayed (its rounds are stateful, so resuming
one reconciles against a conversation the relay is no longer having); an update
to a live subscription replaces what gets replayed, including when the send
itself fails; dropping a relay or closing the pool forgets what they carried;
replay is scoped to the relay that reconnected. Plus the semantic the whole
change rests on, asserted in both directions: a live subscription keeps
delivering after EOSE, a one-shot query still ends at it.
LiveSubscriptionReconcileTest (12) — the requirement this all exists for: the
group filter follows group membership with nobody calling a subscribe function.
Joining widens the filter *in place* rather than reopening (a reopen would drop
the live tail of every other group in that chunk); leaving drops one; leaving
everything closes the subscription; churn inside the debounce window collapses
to one update; a NIP-17 room never becomes a group subscription. Then the
collect loop: events stored against the relay they came from, an event after
EOSE still stored, a CLOSED reopened once the back-off elapses and not before,
and a rate-limited CLOSED waiting far longer — but still coming back.
Backgrounding closes and foregrounding rebuilds, reconnects, and queues the
catch-up.
LiveSubscriptionPlanTest (11) — the filter and planning rules, led by the one
most likely to be "tidied up" later: the gift wrap filter carries no `since`,
because NIP-59 randomizes created_at into the past and a `since` near the
present silently drops new messages.
RelayBackPressureTest (4) and ReconnectBackoffTest (6) — the two pure decisions.
Which CLOSED reasons mean "ease off", and the backoff arithmetic including the
exponent clamp: 2.0.pow(4000) is Infinity and Duration * Double throws on it, so
without it a socket failing long enough turned its reconnect loop into a crash
loop, at the point the network was least likely to recover unaided.
**Seams opened to get there**, each a readability win on its own terms:
- NostrSocketClientFactory becomes an interface with DefaultNostrSocketClientFactory
behind it, so the pool can be driven by a fake socket.
- RelayPool takes its CoroutineScope, so the replay a reconnect triggers can be
observed rather than raced.
- LiveSubscriptionManager depends on a new LiveSubscriptionTransport (4
methods) rather than RelaysSocketManager, which observes the active wallet in
its init and cannot be stood up in a test at all.
- Its pure planning helpers move to the companion as `internal`, and its
launches inherit the caller's dispatcher instead of pinning Dispatchers.IO.
SynchronizationViewModel already launches observe() on IO, so nothing moves —
but a coroutine that picks its own dispatcher cannot be driven by a test
scheduler.
- reconnectDelay is extracted to ReconnectBackoff.kt with jitter as a
parameter, so the arithmetic can be pinned without randomness.
- endsLiveSubscription names the live-subscription termination rule next to
isTerminalFor, which is the one-shot rule. Having both named makes the
difference between them reviewable rather than implicit.
kotlinx-coroutines-test is added to commonTest: the pool's bookkeeping is all
suspend functions and there is no runBlocking in a common source set.
The tests were checked by mutation, not just by passing — reintroducing a
`since`, making EOSE terminal, dropping the leftGroupAt filter and removing
retention from query() each produce failures.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 23:31:11 +02:00
|
|
|
// runTest: the relay pool's bookkeeping is all suspend functions, and there is no
|
|
|
|
|
// runBlocking in a common source set.
|
|
|
|
|
implementation(libs.kotlinx.coroutinesTest)
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
jvmMain.dependencies {
|
|
|
|
|
implementation(compose.desktop.currentOs)
|
|
|
|
|
implementation(libs.kotlinx.coroutinesSwing)
|
|
|
|
|
}
|
build: bump lightning-kmp-app to bbba08b, building lightning-kmp from source
lightning-kmp-app moves 6745d88 -> bbba08b, four commits:
57353cf Minor updates
9f3cd72 Build lightning-kmp from the experimental submodule via a composite build
f22c30a Follow the submodule chain onto Gradle 9.7.1
bbba08b Declare the ios targets only on a mac, so the IDE can import the project
9f3cd72 is the substantive one. lightning-kmp no longer comes from maven central: the
submodule now carries its own experimental/lightning-kmp submodule on branch `threshold`
-- the branch with the FROST/prefractal signers -- and substitutes
fr.acinq.lightning:lightning-kmp-core for that build's project. That build includes
bitcoin-kmp, which includes secp256k1-kmp, which compiles the C library from a secp256k1-zkp
fork. So this repo's build tree is now four levels deep and compiles native code.
Cloning therefore needs `git submodule update --init --recursive`, and because each included
build resolves the android SDK from its own local.properties rather than inheriting the
root's, the three new nested builds each need a (gitignored) local.properties with sdk.dir.
57353cf changed two signatures that MantraApplication implements -- LightningApplication
gained getApplicationContext(), and BusinessManager.initialize now takes the application
rather than a Context. Neither needed a source change: MantraApplication extends
android.app.Application, which already supplies getApplicationContext(), and it was already
passing `this`, which satisfies the narrowed parameter type.
The rest of this commit is what the update forces on the outer build.
gradle-wrapper.properties, 9.3.1 -> 9.7.1: f22c30a moved every build in the chain onto
9.7.1. An included build does not use its own wrapper -- the root build's gradle version runs
the whole tree -- so this repo has to follow for the chain to build at all.
gradle.properties, configuration cache off: secp256k1-kmp's `:jni:generateHeaders` and
`:native:buildSecp256k1<target>` both hold gradle script object references and cannot be
serialized. The configuration cache covers a whole build tree and has no per-build opt-out,
so an included build's incompatibility is this build's problem. The comment records how to
undo this once those tasks are fixed upstream.
composeApp/build.gradle.kts, ios targets gated on the host: secp256k1-kmp declares a
libsecp256k1 cinterop, which makes gradle switch off klib cross compilation for apple
targets. On linux nothing in the tree then offers an ios variant of
fr.acinq.phoenix:lightning-kmp-app, and the ios compilations failed with "No matching variant
of project ':lightning-kmp-app:library'" -- not a warning, a build failure. The gate covers
the target declarations, the iosMain dependencies (the source set only exists when the
targets do) and the kspIos* configurations (likewise). This mirrors bbba08b, which applied
the same gate inside the submodule for the same reason.
secp256k1-frost-kmp d3b294d applies that gate there too. Substitution rules apply across a
whole build tree, so that project's own lightning-kmp-core coordinate started resolving to
the source project without it asking, and every apple source set stopped resolving. The
android build masked it -- ios compilations are not in its task graph -- but
kmpPartiallyResolvedDependenciesChecker reported it and compileAppleMainKotlinMetadata failed
outright, which would have broken IDE import.
Note that `:composeApp:compileCommonMainKotlinMetadata` no longer exists on a linux host.
With ios gated off, androidTarget is the only declared target (jvm() is still commented out),
and KMP does not generate a commonMain metadata compilation for a single-target project.
`:composeApp:compileDebugKotlinAndroid` is the check now; it passes clean, with none of the
resolution errors above.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:50:59 +02:00
|
|
|
// Only exists when the ios targets above were declared; the default hierarchy template
|
|
|
|
|
// creates this source set from them.
|
|
|
|
|
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
|
|
|
|
|
iosMain.dependencies {
|
|
|
|
|
implementation(libs.sqldelight.native.driver)
|
|
|
|
|
}
|
2026-03-27 13:35:29 +02:00
|
|
|
}
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
android {
|
2026-07-15 01:14:46 +02:00
|
|
|
namespace = "press.mantra.android"
|
2026-03-23 01:41:39 +02:00
|
|
|
compileSdk = libs.versions.android.compileSdk.get().toInt()
|
|
|
|
|
|
2026-06-15 14:39:46 +02:00
|
|
|
buildFeatures {
|
|
|
|
|
buildConfig = true
|
|
|
|
|
}
|
2026-03-23 01:41:39 +02:00
|
|
|
defaultConfig {
|
2026-07-15 01:14:46 +02:00
|
|
|
applicationId = "press.mantra.android"
|
2026-03-23 01:41:39 +02:00
|
|
|
minSdk = libs.versions.android.minSdk.get().toInt()
|
|
|
|
|
targetSdk = libs.versions.android.targetSdk.get().toInt()
|
|
|
|
|
versionCode = 1
|
2026-04-22 22:31:03 +02:00
|
|
|
versionName = "0.1.0"
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
packaging {
|
|
|
|
|
resources {
|
|
|
|
|
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
2026-03-23 02:21:18 +02:00
|
|
|
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
buildTypes {
|
|
|
|
|
getByName("release") {
|
|
|
|
|
isMinifyEnabled = false
|
|
|
|
|
}
|
2026-03-23 02:21:18 +02:00
|
|
|
getByName("debug") {
|
|
|
|
|
applicationIdSuffix = ".debug"
|
|
|
|
|
versionNameSuffix = "-DEBUG"
|
|
|
|
|
}
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
compileOptions {
|
2026-06-23 13:59:17 +02:00
|
|
|
sourceCompatibility = JavaVersion.VERSION_21
|
|
|
|
|
targetCompatibility = JavaVersion.VERSION_21
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dependencies {
|
|
|
|
|
debugImplementation(libs.compose.uiTooling)
|
2026-05-02 00:05:38 +02:00
|
|
|
// ksp(libs.androidx.room3.compiler)
|
|
|
|
|
add("kspAndroid", libs.androidx.room3.compiler)
|
build: bump lightning-kmp-app to bbba08b, building lightning-kmp from source
lightning-kmp-app moves 6745d88 -> bbba08b, four commits:
57353cf Minor updates
9f3cd72 Build lightning-kmp from the experimental submodule via a composite build
f22c30a Follow the submodule chain onto Gradle 9.7.1
bbba08b Declare the ios targets only on a mac, so the IDE can import the project
9f3cd72 is the substantive one. lightning-kmp no longer comes from maven central: the
submodule now carries its own experimental/lightning-kmp submodule on branch `threshold`
-- the branch with the FROST/prefractal signers -- and substitutes
fr.acinq.lightning:lightning-kmp-core for that build's project. That build includes
bitcoin-kmp, which includes secp256k1-kmp, which compiles the C library from a secp256k1-zkp
fork. So this repo's build tree is now four levels deep and compiles native code.
Cloning therefore needs `git submodule update --init --recursive`, and because each included
build resolves the android SDK from its own local.properties rather than inheriting the
root's, the three new nested builds each need a (gitignored) local.properties with sdk.dir.
57353cf changed two signatures that MantraApplication implements -- LightningApplication
gained getApplicationContext(), and BusinessManager.initialize now takes the application
rather than a Context. Neither needed a source change: MantraApplication extends
android.app.Application, which already supplies getApplicationContext(), and it was already
passing `this`, which satisfies the narrowed parameter type.
The rest of this commit is what the update forces on the outer build.
gradle-wrapper.properties, 9.3.1 -> 9.7.1: f22c30a moved every build in the chain onto
9.7.1. An included build does not use its own wrapper -- the root build's gradle version runs
the whole tree -- so this repo has to follow for the chain to build at all.
gradle.properties, configuration cache off: secp256k1-kmp's `:jni:generateHeaders` and
`:native:buildSecp256k1<target>` both hold gradle script object references and cannot be
serialized. The configuration cache covers a whole build tree and has no per-build opt-out,
so an included build's incompatibility is this build's problem. The comment records how to
undo this once those tasks are fixed upstream.
composeApp/build.gradle.kts, ios targets gated on the host: secp256k1-kmp declares a
libsecp256k1 cinterop, which makes gradle switch off klib cross compilation for apple
targets. On linux nothing in the tree then offers an ios variant of
fr.acinq.phoenix:lightning-kmp-app, and the ios compilations failed with "No matching variant
of project ':lightning-kmp-app:library'" -- not a warning, a build failure. The gate covers
the target declarations, the iosMain dependencies (the source set only exists when the
targets do) and the kspIos* configurations (likewise). This mirrors bbba08b, which applied
the same gate inside the submodule for the same reason.
secp256k1-frost-kmp d3b294d applies that gate there too. Substitution rules apply across a
whole build tree, so that project's own lightning-kmp-core coordinate started resolving to
the source project without it asking, and every apple source set stopped resolving. The
android build masked it -- ios compilations are not in its task graph -- but
kmpPartiallyResolvedDependenciesChecker reported it and compileAppleMainKotlinMetadata failed
outright, which would have broken IDE import.
Note that `:composeApp:compileCommonMainKotlinMetadata` no longer exists on a linux host.
With ios gated off, androidTarget is the only declared target (jvm() is still commented out),
and KMP does not generate a commonMain metadata compilation for a single-target project.
`:composeApp:compileDebugKotlinAndroid` is the check now; it passes clean, with none of the
resolution errors above.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:50:59 +02:00
|
|
|
// These configurations only exist when the ios targets are declared, which the kotlin block
|
|
|
|
|
// above does only on a mac.
|
|
|
|
|
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
|
|
|
|
|
add("kspIosSimulatorArm64", libs.androidx.room3.compiler)
|
|
|
|
|
// add("kspIosX64", libs.androidx.room.compiler)
|
|
|
|
|
add("kspIosArm64", libs.androidx.room3.compiler)
|
|
|
|
|
}
|
2026-06-16 20:28:05 +03:00
|
|
|
// add("kspJvm", libs.androidx.room3.compiler)
|
2026-03-24 04:47:19 +02:00
|
|
|
// Add any other platform target you use in your project, for example kspDesktop
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 00:05:38 +02:00
|
|
|
room3 {
|
2026-03-24 04:47:19 +02:00
|
|
|
schemaDirectory("$projectDir/schemas")
|
2026-03-23 01:41:39 +02:00
|
|
|
}
|
|
|
|
|
|
2026-06-15 14:39:46 +02:00
|
|
|
sqldelight {
|
|
|
|
|
databases {
|
|
|
|
|
create("ChannelsDatabase") {
|
|
|
|
|
packageName.set("fr.acinq.phoenix.db.sqldelight")
|
|
|
|
|
srcDirs.from("src/commonMain/sqldelight/channelsdb")
|
|
|
|
|
}
|
|
|
|
|
create("PaymentsDatabase") {
|
|
|
|
|
packageName.set("fr.acinq.phoenix.db.sqldelight")
|
|
|
|
|
srcDirs.from("src/commonMain/sqldelight/paymentsdb")
|
|
|
|
|
}
|
|
|
|
|
create("AppDatabase") {
|
|
|
|
|
packageName.set("fr.acinq.phoenix.db.sqldelight")
|
|
|
|
|
srcDirs.from("src/commonMain/sqldelight/appdb")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-23 01:41:39 +02:00
|
|
|
compose.desktop {
|
|
|
|
|
application {
|
2026-07-15 01:14:46 +02:00
|
|
|
mainClass = "press.mantra.desktop.MainKt"
|
2026-03-23 01:41:39 +02:00
|
|
|
|
|
|
|
|
nativeDistributions {
|
|
|
|
|
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
2026-07-15 01:14:46 +02:00
|
|
|
packageName = "press.mantra.desktop"
|
2026-03-23 01:41:39 +02:00
|
|
|
packageVersion = "1.0.0"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|