diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index b7c7b3f206e..e18a38b34d4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -49,7 +49,7 @@ repositories {
google()
}
-val nonFreeFlavors = setOf("prod", "internal", "staging", "beta", "dev")
+val nonFreeFlavors = setOf("prod", "internal", "staging", "beta", "dev", "enterprise")
val fossFlavors = setOf("fdroid")
val internalFlavors = setOf("internal", "staging", "beta", "dev")
val allFlavors = nonFreeFlavors + fossFlavors
@@ -199,6 +199,8 @@ dependencies {
implementationWithCoverage(projects.features.meetings)
implementationWithCoverage(projects.features.sync)
+ enterpriseImplementation(projects.core.nomad)
+
// Anonymous Analytics
val flavors = getFlavorsSettings()
val isCustomBuild = isCustomizationEnabled()
diff --git a/app/src/enterprise/AndroidManifest.xml b/app/src/enterprise/AndroidManifest.xml
new file mode 100644
index 00000000000..9994a4c9b58
--- /dev/null
+++ b/app/src/enterprise/AndroidManifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/enterprise/res/drawable/ic_launcher_background.xml b/app/src/enterprise/res/drawable/ic_launcher_background.xml
new file mode 100644
index 00000000000..58a11edd910
--- /dev/null
+++ b/app/src/enterprise/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/enterprise/res/drawable/ic_launcher_foreground.xml b/app/src/enterprise/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 00000000000..e63fed2e550
--- /dev/null
+++ b/app/src/enterprise/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000000..b0444ebeab6
--- /dev/null
+++ b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000000..b0444ebeab6
--- /dev/null
+++ b/app/src/enterprise/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt b/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt
index a6dc13fdd58..61c507a7a91 100644
--- a/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt
+++ b/buildSrc/src/main/kotlin/flavor/ProductFlavors.kt
@@ -35,6 +35,7 @@ sealed class ProductFlavors(
object Beta : ProductFlavors("beta", "Wire Beta")
object Internal : ProductFlavors("internal", "Wire Internal")
+ object Enterprise : ProductFlavors("enterprise", "Wire Enterprise")
object Production : ProductFlavors("prod", "Wire", shareduserId = "com.waz.userid")
object Fdroid : ProductFlavors(
buildName = "fdroid",
@@ -49,6 +50,7 @@ sealed class ProductFlavors(
Staging,
Beta,
Internal,
+ Enterprise,
Production,
Fdroid,
)
diff --git a/core/nomad/build.gradle.kts b/core/nomad/build.gradle.kts
new file mode 100644
index 00000000000..8760da1e77a
--- /dev/null
+++ b/core/nomad/build.gradle.kts
@@ -0,0 +1,16 @@
+plugins {
+ id(libs.plugins.wire.android.library.get().pluginId)
+ id(libs.plugins.wire.kover.get().pluginId)
+ id(libs.plugins.wire.hilt.get().pluginId)
+ alias(libs.plugins.compose.compiler)
+}
+
+dependencies {
+ implementation(projects.core.di)
+ implementation("com.wire.kalium:kalium-logic")
+ implementation("com.wire.kalium:kalium-nomaddevice")
+ implementation("com.wire.kalium:kalium-userstorage")
+ implementation("com.wire.kalium:kalium-hooks")
+ implementation(libs.androidx.startup)
+ implementation(libs.androidx.compose.runtime)
+}
diff --git a/core/nomad/src/main/kotlin/com/wire/android/nomad/NomadHookRegistrar.kt b/core/nomad/src/main/kotlin/com/wire/android/nomad/NomadHookRegistrar.kt
new file mode 100644
index 00000000000..b1330cd0209
--- /dev/null
+++ b/core/nomad/src/main/kotlin/com/wire/android/nomad/NomadHookRegistrar.kt
@@ -0,0 +1,37 @@
+/*
+ * Wire
+ * Copyright (C) 2026 Wire Swiss GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+package com.wire.android.nomad
+
+import com.wire.kalium.logic.CoreLogic
+import com.wire.kalium.nomaddevice.NomadRemoteBackupChangeLogHookNotifier
+import com.wire.kalium.userstorage.di.PlatformUserStorageProvider
+import dagger.Lazy
+
+public object NomadHookRegistrar {
+ /**
+ * Registers Nomad's persisted-message hook into CoreLogic during app startup.
+ */
+ public fun register(coreLogic: Lazy) {
+ coreLogic.get().registerPersistenceEventHook(
+ NomadRemoteBackupChangeLogHookNotifier(
+ userStorageProvider = PlatformUserStorageProvider()
+ )
+ )
+ }
+}
diff --git a/core/nomad/src/main/kotlin/com/wire/android/nomad/di/NomadInitializerEntryPoint.kt b/core/nomad/src/main/kotlin/com/wire/android/nomad/di/NomadInitializerEntryPoint.kt
new file mode 100644
index 00000000000..330bb736734
--- /dev/null
+++ b/core/nomad/src/main/kotlin/com/wire/android/nomad/di/NomadInitializerEntryPoint.kt
@@ -0,0 +1,43 @@
+/*
+ * Wire
+ * Copyright (C) 2026 Wire Swiss GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+package com.wire.android.nomad.di
+
+import android.content.Context
+import com.wire.android.di.KaliumCoreLogic
+import com.wire.kalium.logic.CoreLogic
+import dagger.Lazy
+import dagger.hilt.EntryPoint
+import dagger.hilt.InstallIn
+import dagger.hilt.android.EntryPointAccessors
+import dagger.hilt.components.SingletonComponent
+
+@EntryPoint
+@InstallIn(SingletonComponent::class)
+interface NomadInitializerEntryPoint {
+
+ @KaliumCoreLogic
+ fun coreLogic(): Lazy
+
+ companion object {
+ fun resolve(context: Context): NomadInitializerEntryPoint {
+ val appContext = context.applicationContext ?: throw IllegalStateException()
+ return EntryPointAccessors.fromApplication(appContext, NomadInitializerEntryPoint::class.java)
+ }
+ }
+}
diff --git a/core/nomad/src/main/kotlin/com/wire/android/nomad/initializer/NomadInitializer.kt b/core/nomad/src/main/kotlin/com/wire/android/nomad/initializer/NomadInitializer.kt
new file mode 100644
index 00000000000..621c973cf00
--- /dev/null
+++ b/core/nomad/src/main/kotlin/com/wire/android/nomad/initializer/NomadInitializer.kt
@@ -0,0 +1,34 @@
+/*
+ * Wire
+ * Copyright (C) 2026 Wire Swiss GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+package com.wire.android.nomad.initializer
+
+import android.content.Context
+import androidx.startup.Initializer
+import com.wire.android.nomad.NomadHookRegistrar
+import com.wire.android.nomad.di.NomadInitializerEntryPoint
+
+class NomadInitializer : Initializer {
+
+ override fun create(context: Context) {
+ val entryPoint = NomadInitializerEntryPoint.resolve(context)
+ NomadHookRegistrar.register(coreLogic = entryPoint.coreLogic())
+ }
+
+ override fun dependencies(): List>> = emptyList()
+}
diff --git a/default.json b/default.json
index a4ea456c220..688c510a162 100644
--- a/default.json
+++ b/default.json
@@ -71,7 +71,7 @@
"analytics_app_key": "8ffae535f1836ed5f58fd5c8a11c00eca07c5438",
"analytics_server_url": "https://wire.count.ly/",
"enable_new_registration": true,
- "use_async_flush_logging": true,
+ "use_async_flush_logging": true
},
"internal": {
"application_id": "com.wire.internal",
@@ -86,7 +86,18 @@
"use_strict_mls_filter": false,
"use_async_flush_logging": true,
"conversation_feeder_enabled": true,
- "db_invalidation_control_enabled": false,
+ "db_invalidation_control_enabled": false
+ },
+ "enterprise": {
+ "application_id": "com.wire.team",
+ "developer_features_enabled": false,
+ "logging_enabled": false,
+ "application_is_private_build": false,
+ "development_api_enabled": false,
+ "analytics_enabled": true,
+ "analytics_app_key": "4483f7a58ae3e70b3780319c4ccb5c88a037be49",
+ "analytics_server_url": "https://wire.count.ly/",
+ "enable_new_registration": true
},
"fdroid": {
"application_id": "com.wire",
diff --git a/include_builds.gradle.kts b/include_builds.gradle.kts
index 56f021dd41a..99c3bd549cb 100644
--- a/include_builds.gradle.kts
+++ b/include_builds.gradle.kts
@@ -23,6 +23,9 @@ includeBuild("kalium") {
substitute(module("com.wire.kalium:kalium-data")).using(project(":core:data"))
substitute(module("com.wire.kalium:kalium-common")).using(project(":core:common"))
substitute(module("com.wire.kalium:kalium-cells")).using(project(":domain:cells"))
+ substitute(module("com.wire.kalium:kalium-nomaddevice")).using(project(":domain:nomaddevice"))
+ substitute(module("com.wire.kalium:kalium-userstorage")).using(project(":domain:userstorage"))
+ substitute(module("com.wire.kalium:kalium-hooks")).using(project(":domain:messaging:hooks"))
// test modules
substitute(module("com.wire.kalium:kalium-mocks")).using(project(":test:mocks"))
substitute(module("com.wire.kalium:kalium-network")).using(project(":data:network"))
diff --git a/kalium b/kalium
index 83e3c7cbf31..9a9620e35e1 160000
--- a/kalium
+++ b/kalium
@@ -1 +1 @@
-Subproject commit 83e3c7cbf31e7996c03f91d9740b50e480acee35
+Subproject commit 9a9620e35e190a957ccf2d3e1229019a9b3471a1