From 3ae7fc2821861b2a6129af79a684041c2a730ade Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Thu, 4 Jun 2026 01:16:49 +0200 Subject: [PATCH 1/2] chore: bump bitkit core to 0.1.67 --- changelog.d/next/989.fixed.md | 1 + gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/next/989.fixed.md diff --git a/changelog.d/next/989.fixed.md b/changelog.d/next/989.fixed.md new file mode 100644 index 0000000000..3b8d3a0077 --- /dev/null +++ b/changelog.d/next/989.fixed.md @@ -0,0 +1 @@ +Bitkit now handles unexpected native on-chain lookup failures without crashing. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 18c654b70a..e8659a9550 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ activity-compose = { module = "androidx.activity:activity-compose", version = "1 appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.1" } barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version = "17.3.0" } biometric = { module = "androidx.biometric:biometric", version = "1.4.0-alpha05" } -bitkit-core = { module = "com.synonym:bitkit-core-android", version = "0.1.64" } +bitkit-core = { module = "com.synonym:bitkit-core-android", version = "0.1.67" } paykit = { module = "com.synonym:paykit-android", version = "0.1.0-rc8" } bouncycastle-provider-jdk = { module = "org.bouncycastle:bcprov-jdk18on", version = "1.83" } camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camera" } From d75f0fa1b13f1ad9073ef5503ebf5c71a5066b99 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Thu, 4 Jun 2026 15:10:46 +0200 Subject: [PATCH 2/2] fix: gate foreground service type --- .../androidServices/LightningNodeService.kt | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/to/bitkit/androidServices/LightningNodeService.kt b/app/src/main/java/to/bitkit/androidServices/LightningNodeService.kt index b6271fcc75..8a7514f439 100644 --- a/app/src/main/java/to/bitkit/androidServices/LightningNodeService.kt +++ b/app/src/main/java/to/bitkit/androidServices/LightningNodeService.kt @@ -5,7 +5,8 @@ import android.app.PendingIntent import android.app.Service import android.content.Intent import android.content.pm.ServiceInfo -import android.os.Build +import android.os.Build.VERSION +import android.os.Build.VERSION_CODES import android.os.IBinder import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat @@ -37,6 +38,8 @@ import to.bitkit.utils.Logger import to.bitkit.utils.jsonLogOf import javax.inject.Inject +typealias Hook = (() -> Unit)? + @AndroidEntryPoint class LightningNodeService : Service() { @@ -63,10 +66,6 @@ class LightningNodeService : Service() { private var hasStartedNode = false - override fun onCreate() { - super.onCreate() - } - private fun setupService() { if (hasStartedNode) return hasStartedNode = true @@ -157,19 +156,14 @@ class LightningNodeService : Service() { val action = intent?.action Logger.debug("Received start command action '$action'", context = TAG) when (action) { - ACTION_START_SERVICE -> { - if (promoteToForeground(startId)) setupService() - } ACTION_STOP_SERVICE_AND_APP -> { - Logger.debug("Received stop service action", context = TAG) - stopForegroundService(startId) + stopForegroundService(startId) { Logger.debug("Received stop service action", context = TAG) } activityManager.appTasks.forEach { it.finishAndRemoveTask() } serviceScope.launch { lightningRepo.stop() } } - else -> { - Logger.warn("Stopped service for unsupported action '$action'", context = TAG) - stopSelf(startId) - } + + ACTION_START_SERVICE -> if (promoteToForeground(startId)) setupService() + else -> stop(startId) { Logger.warn("Stopped service for unsupported action '$action'", context = TAG) } } return START_NOT_STICKY } @@ -180,22 +174,29 @@ class LightningNodeService : Service() { this, ID_NOTIFICATION_NODE, createNotification(), - ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC, + foregroundServiceTypeDataSync(), ) }.fold( onSuccess = { true }, onFailure = { if (it !is RuntimeException) throw it - - Logger.error("Failed to promote foreground service", it, context = TAG) - stopSelf(startId) + stop(startId) { Logger.error("Failed to promote foreground service", it, context = TAG) } false } ) } - private fun stopForegroundService(startId: Int) { + private fun foregroundServiceTypeDataSync(): Int { + return if (VERSION.SDK_INT >= VERSION_CODES.Q) ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC else 0 + } + + private fun stopForegroundService(startId: Int, hook: Hook = null) { ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE) + stop(startId, hook) + } + + private fun stop(startId: Int, hook: Hook = null) { + hook?.invoke() stopSelf(startId) } @@ -206,7 +207,7 @@ class LightningNodeService : Service() { super.onDestroy() } - @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @RequiresApi(VERSION_CODES.VANILLA_ICE_CREAM) override fun onTimeout(startId: Int, fgsType: Int) { Logger.warn("Reached foreground service timeout for type '$fgsType'", context = TAG) stopForegroundService(startId)