
Modular client SDK: unified networking, encrypted settings, security policies and MFA, multi-method identity and session management, WebSocket lifecycles, pluggable error parsers, composable UI and navigation.
A modular Kotlin Multiplatform (KMP) client SDK for Android and Web (Wasm). It provides a unified foundation for building multiplatform applications with shared logic for networking, encrypted storage, security policies, and identity management. By bundling Compose Multiplatform UI and Decompose navigation, it allows host apps to integrate complex auth flows and system settings with minimal boilerplate.
| Module | Purpose |
|---|---|
| core/common |
Foundation: Ktor bootstrap, WebSocket lifecycle, EncryptedSettings abstraction, platform metadata, and error parsing. |
| core/settings | Global Settings: Logic for application configuration, Ktor network client, encrypted caching, and reactive state management. |
| core/security | Security Domain: Password policy validation, MFA state management, Ktor network client, and localized security errors. |
| feature/user | Base Identity: Foundational models, use cases, and storage for user identity and authentication. |
| feature/clientuser | Client Identity: Identity solution for standard user applications, including UI and social login. |
| feature/managementuser | Management Identity: Administrative identity solution for internal staff, resource oversight, and audit logs. |
| bom | Bill of Materials: Gradle platform to ensure version alignment across all SDK modules. |
Add the BOM and the required modules to your commonMain dependencies:
kotlin {
sourceSets {
commonMain.dependencies {
implementation(platform("io.github.mudrichenkoevgeny:kmp-platform-sdk-bom:0.0.1"))
implementation("io.github.mudrichenkoevgeny:kmp-platform-sdk-core-common")
implementation("io.github.mudrichenkoevgeny:kmp-platform-sdk-feature-clientuser")
// Add other core or feature modules as needed
}
}
}Initialize the EncryptedSettingsComponent and the root CommonComponent using platform-specific context.
val encryptedSettingsComponent = EncryptedSettingsComponent(platformContext)
val commonComponent = CommonComponent(
encryptedSettings = encryptedSettingsComponent.encryptedSettings,
deviceInfo = deviceInfo,
baseUrl = "https://api.example.com",
accessTokenProvider = authStorage,
appScope = appScope,
platformContext = platformContext
)Construct domain components by sharing the core HttpClient and WebSocketService.
val securityComponent = SecurityComponent(
webSocketService = commonComponent.webSocketService,
httpClient = commonComponent.httpClient,
encryptedSettings = commonComponent.encryptedSettings,
parentScope = appScope
)
val settingsComponent = SettingsComponent(
webSocketService = commonComponent.webSocketService,
httpClient = commonComponent.httpClient,
encryptedSettings = commonComponent.encryptedSettings,
parentScope = appScope
)Wire the ClientUserComponent with its core collaborators and platform-specific authentication services.
val clientUserComponent = ClientUserComponent(
commonComponent = commonComponent,
settingsComponent = settingsComponent,
securityComponent = securityComponent,
authStorage = encryptedAuthStorage,
authServices = platformAuthServices,
parentScope = appScope
)Register auth interceptors, domain error parsers, and WebSocket message handlers during the application startup sequence.
fun init() {
commonComponent.httpClientConfigPlugins.add(clientUserComponent.authHttpClientConfigPlugin)
commonComponent.init(
appErrorParserSpecificParsers = listOf(
SecurityErrorParser,
UserErrorParser
)
)
commonComponent.webSocketService.updateWebSocketMessageHandlers(
listOf(
commonComponent.commonWebSocketMessageHandler,
settingsComponent.settingsWebSocketMessageHandler,
securityComponent.securityWebSocketMessageHandler,
clientUserComponent.userWebSocketMessageHandler
)
)
}Inject the SDK graph into your Compose Multiplatform tree using CompositionLocalProvider.
@Composable
fun App(clientAppComponent: ClientAppComponent) {
val isInitialized by clientAppComponent.isInitialized.collectAsState()
if (isInitialized) {
CompositionLocalProvider(
LocalCommonComponent provides clientAppComponent.commonComponent,
LocalErrorParser provides clientAppComponent.commonComponent.appErrorParser,
LocalClientAppComponent provides clientAppComponent
) {
// Embed feature UI or launch LoginRootComponent navigation
}
} else {
SplashScreen()
}
}For a complete wiring example, refer to the sampleclient or samplemanagement applications.
A modular Kotlin Multiplatform (KMP) client SDK for Android and Web (Wasm). It provides a unified foundation for building multiplatform applications with shared logic for networking, encrypted storage, security policies, and identity management. By bundling Compose Multiplatform UI and Decompose navigation, it allows host apps to integrate complex auth flows and system settings with minimal boilerplate.
| Module | Purpose |
|---|---|
| core/common |
Foundation: Ktor bootstrap, WebSocket lifecycle, EncryptedSettings abstraction, platform metadata, and error parsing. |
| core/settings | Global Settings: Logic for application configuration, Ktor network client, encrypted caching, and reactive state management. |
| core/security | Security Domain: Password policy validation, MFA state management, Ktor network client, and localized security errors. |
| feature/user | Base Identity: Foundational models, use cases, and storage for user identity and authentication. |
| feature/clientuser | Client Identity: Identity solution for standard user applications, including UI and social login. |
| feature/managementuser | Management Identity: Administrative identity solution for internal staff, resource oversight, and audit logs. |
| bom | Bill of Materials: Gradle platform to ensure version alignment across all SDK modules. |
Add the BOM and the required modules to your commonMain dependencies:
kotlin {
sourceSets {
commonMain.dependencies {
implementation(platform("io.github.mudrichenkoevgeny:kmp-platform-sdk-bom:0.0.1"))
implementation("io.github.mudrichenkoevgeny:kmp-platform-sdk-core-common")
implementation("io.github.mudrichenkoevgeny:kmp-platform-sdk-feature-clientuser")
// Add other core or feature modules as needed
}
}
}Initialize the EncryptedSettingsComponent and the root CommonComponent using platform-specific context.
val encryptedSettingsComponent = EncryptedSettingsComponent(platformContext)
val commonComponent = CommonComponent(
encryptedSettings = encryptedSettingsComponent.encryptedSettings,
deviceInfo = deviceInfo,
baseUrl = "https://api.example.com",
accessTokenProvider = authStorage,
appScope = appScope,
platformContext = platformContext
)Construct domain components by sharing the core HttpClient and WebSocketService.
val securityComponent = SecurityComponent(
webSocketService = commonComponent.webSocketService,
httpClient = commonComponent.httpClient,
encryptedSettings = commonComponent.encryptedSettings,
parentScope = appScope
)
val settingsComponent = SettingsComponent(
webSocketService = commonComponent.webSocketService,
httpClient = commonComponent.httpClient,
encryptedSettings = commonComponent.encryptedSettings,
parentScope = appScope
)Wire the ClientUserComponent with its core collaborators and platform-specific authentication services.
val clientUserComponent = ClientUserComponent(
commonComponent = commonComponent,
settingsComponent = settingsComponent,
securityComponent = securityComponent,
authStorage = encryptedAuthStorage,
authServices = platformAuthServices,
parentScope = appScope
)Register auth interceptors, domain error parsers, and WebSocket message handlers during the application startup sequence.
fun init() {
commonComponent.httpClientConfigPlugins.add(clientUserComponent.authHttpClientConfigPlugin)
commonComponent.init(
appErrorParserSpecificParsers = listOf(
SecurityErrorParser,
UserErrorParser
)
)
commonComponent.webSocketService.updateWebSocketMessageHandlers(
listOf(
commonComponent.commonWebSocketMessageHandler,
settingsComponent.settingsWebSocketMessageHandler,
securityComponent.securityWebSocketMessageHandler,
clientUserComponent.userWebSocketMessageHandler
)
)
}Inject the SDK graph into your Compose Multiplatform tree using CompositionLocalProvider.
@Composable
fun App(clientAppComponent: ClientAppComponent) {
val isInitialized by clientAppComponent.isInitialized.collectAsState()
if (isInitialized) {
CompositionLocalProvider(
LocalCommonComponent provides clientAppComponent.commonComponent,
LocalErrorParser provides clientAppComponent.commonComponent.appErrorParser,
LocalClientAppComponent provides clientAppComponent
) {
// Embed feature UI or launch LoginRootComponent navigation
}
} else {
SplashScreen()
}
}For a complete wiring example, refer to the sampleclient or samplemanagement applications.