mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
udpate specs (#1909)
This commit is contained in:
@@ -115,20 +115,20 @@ See [KMP Revival Spec](./workstreams/kmp-revival/SPEC.md) for details.
|
||||
|
||||
## Module Table
|
||||
|
||||
| Module | Location | Status | Current Role | Action Needed |
|
||||
| -------------------- | ----------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| WebView UI | `packages/webview-app/` | Active | Primary product surface, route orchestration, mock-first screen migration | Finish remaining UI migration specs/routes |
|
||||
| SDK Core | `packages/mobile-sdk-alpha/` | Active | Shared engine for WebView/browser delivery | Keep browser entry clean and request-driven |
|
||||
| WebView Bridge | `packages/webview-bridge/` | Active | Host callback surface for future lifecycle wiring | Stable for current UI pass |
|
||||
| Android Shell | `packages/native-shell-android/` | Deferred | Future thin Kotlin shell: keychain/crypto + WebView host | Not required for current UI migration |
|
||||
| iOS Shell | `packages/native-shell-ios/` | Deferred | Future thin Swift shell: keychain/crypto + WebView host | Not required for current UI migration |
|
||||
| Test App | `packages/sdk-test-app/` | Deferred | Future native E2E harness | Not required for current UI migration |
|
||||
| KMP Native Shell | `packages/kmp-sdk/` | Active | Native shell for KMP consumers — 3-domain scope (secureStorage, crypto, lifecycle) | KR-01 (Android), KR-02 (iOS), KR-03 (validate) |
|
||||
| Swift Providers | `packages/self-sdk-swift/` | Active | iOS keychain/crypto provider implementations for KMP SDK | Required by KR-02 (query param support) |
|
||||
| RN SDK | `packages/rn-sdk/` | Paused | Retained React Native shell work | Do not advance unless scope reopens |
|
||||
| Native Consolidation | `app/ios/`, `packages/mobile-sdk-alpha/ios/`, related native code | Paused | Historical native cleanup and parity track | Keep as reference only for now |
|
||||
| KMP Test App | `packages/kmp-sdk-test-app/` | Active | E2E test harness for KMP SDK | Scope to 3-domain in KR-03 |
|
||||
| MiniPay Sample | `packages/kmp-minipay-sample/` | Paused | Historical KMP integration example | May resume now that KMP path is active |
|
||||
| Module | Location | Status | Current Role | Action Needed |
|
||||
| -------------------- | ----------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------- | ---------------------------------------------- |
|
||||
| WebView UI | `packages/webview-app/` | Active | Primary product surface, route orchestration, mock-first screen migration | Finish remaining UI migration specs/routes |
|
||||
| SDK Core | `packages/mobile-sdk-alpha/` | Active | Shared engine for WebView/browser delivery | Keep browser entry clean and request-driven |
|
||||
| WebView Bridge | `packages/webview-bridge/` | Active | Host callback surface for future lifecycle wiring | Stable for current UI pass |
|
||||
| Android Shell | `packages/native-shell-android/` | Deferred | Future thin Kotlin shell: keychain/crypto + WebView host | Not required for current UI migration |
|
||||
| iOS Shell | `packages/native-shell-ios/` | Deferred | Future thin Swift shell: keychain/crypto + WebView host | Not required for current UI migration |
|
||||
| Test App | `packages/sdk-test-app/` | Deferred | Future native E2E harness | Not required for current UI migration |
|
||||
| KMP Native Shell | `packages/kmp-sdk/` | Active | Native shell for KMP consumers — 3-domain scope (secureStorage, crypto, lifecycle) | KR-01 (Android), KR-02 (iOS), KR-03 (validate) |
|
||||
| Swift Providers | `packages/self-sdk-swift/` | Active | iOS keychain/crypto provider implementations for KMP SDK | Required by KR-02 (query param support) |
|
||||
| RN SDK | `packages/rn-sdk/` | Paused | Retained React Native shell work | Do not advance unless scope reopens |
|
||||
| Native Consolidation | `app/ios/`, `packages/mobile-sdk-alpha/ios/`, related native code | Paused | Historical native cleanup and parity track | Keep as reference only for now |
|
||||
| KMP Test App | `packages/kmp-sdk-test-app/` | Active | E2E test harness for KMP SDK | Scope to 3-domain in KR-03 |
|
||||
| MiniPay Sample | `packages/kmp-minipay-sample/` | Paused | Historical KMP integration example | May resume now that KMP path is active |
|
||||
|
||||
## Scope Rules
|
||||
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
|
||||
## Why Offer a KMP Option
|
||||
|
||||
| Dimension | KMP SDK | Native Shells Lite |
|
||||
|-----------|---------|-------------------|
|
||||
| Target consumer | Apps using Kotlin Multiplatform | Pure Kotlin (Android) / pure Swift (iOS) apps |
|
||||
| Provider pattern | Built-in via `SdkProviderRegistry` (both platforms) | NSL-04 adds it (~500-700 LOC) |
|
||||
| Test coverage | ~10 test files | Zero tests (pending) |
|
||||
| Publishing setup | `maven-publish` configured | None yet |
|
||||
| Result types | Strongly-typed `VerificationResult` + `SelfSdkError` | Raw JSON string |
|
||||
| Config model | Separated `SelfSdkConfig` + `VerificationRequest` | Flat config with 15+ params |
|
||||
| Extra handlers | NFC, camera, biometrics available (not registered by default) | 3 domains only |
|
||||
| Dimension | KMP SDK | Native Shells Lite |
|
||||
| ---------------- | ------------------------------------------------------------- | --------------------------------------------- |
|
||||
| Target consumer | Apps using Kotlin Multiplatform | Pure Kotlin (Android) / pure Swift (iOS) apps |
|
||||
| Provider pattern | Built-in via `SdkProviderRegistry` (both platforms) | NSL-04 adds it (~500-700 LOC) |
|
||||
| Test coverage | ~10 test files | Zero tests (pending) |
|
||||
| Publishing setup | `maven-publish` configured | None yet |
|
||||
| Result types | Strongly-typed `VerificationResult` + `SelfSdkError` | Raw JSON string |
|
||||
| Config model | Separated `SelfSdkConfig` + `VerificationRequest` | Flat config with 15+ params |
|
||||
| Extra handlers | NFC, camera, biometrics available (not registered by default) | 3 domains only |
|
||||
|
||||
Both options are valid. KMP has more infrastructure already built; native-shells-lite is simpler for non-KMP consumers.
|
||||
|
||||
@@ -54,19 +54,19 @@ Both options are valid. KMP has more infrastructure already built; native-shells
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Depends On | Type | Status | Notes |
|
||||
|---|---|---|---|
|
||||
| `packages/webview-bridge/` | Upstream (bridge protocol) | Done | Defines message shapes and transport names |
|
||||
| `packages/webview-app/` | Upstream (WebView bundle) | Active | KMP loads this bundle |
|
||||
| Build pipeline (BP-01) | Downstream | Done | Copies webview-app dist into native assets |
|
||||
| Depends On | Type | Status | Notes |
|
||||
| -------------------------- | -------------------------- | ------ | ------------------------------------------ |
|
||||
| `packages/webview-bridge/` | Upstream (bridge protocol) | Done | Defines message shapes and transport names |
|
||||
| `packages/webview-app/` | Upstream (WebView bundle) | Active | KMP loads this bundle |
|
||||
| Build pipeline (BP-01) | Downstream | Done | Copies webview-app dist into native assets |
|
||||
|
||||
## Backlog
|
||||
|
||||
| ID | Title | Status | Priority | Depends On | Plan | Est. LOC |
|
||||
|---|---|---|---|---|---|---|
|
||||
| KR-01 | Scope KMP Android to 3-domain parity with provider delegation | Ready | High | - | [plans/KR-01-android-parity.md](./plans/KR-01-android-parity.md) | ~600-900 |
|
||||
| KR-02 | Scope KMP iOS to 3-domain native shell parity | Ready | High | - | [plans/KR-02-ios-parity.md](./plans/KR-02-ios-parity.md) | ~200-300 |
|
||||
| KR-03 | Validate build artifacts and test app | Ready | Medium | KR-01, KR-02 | [plans/KR-03-validate-and-publish.md](./plans/KR-03-validate-and-publish.md) | ~200 |
|
||||
| ID | Title | Status | Priority | Depends On | Plan | Est. LOC |
|
||||
| ----- | ------------------------------------------------------------- | ------ | -------- | ------------ | ---------------------------------------------------------------------------- | -------- |
|
||||
| KR-01 | Scope KMP Android to 3-domain parity with provider delegation | Ready | High | - | [plans/KR-01-android-parity.md](./plans/KR-01-android-parity.md) | ~600-900 |
|
||||
| KR-02 | Scope KMP iOS to 3-domain native shell parity | Ready | High | - | [plans/KR-02-ios-parity.md](./plans/KR-02-ios-parity.md) | ~200-300 |
|
||||
| KR-03 | Validate build artifacts and test app | Ready | Medium | KR-01, KR-02 | [plans/KR-03-validate-and-publish.md](./plans/KR-03-validate-and-publish.md) | ~200 |
|
||||
|
||||
Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
|
||||
@@ -84,16 +84,16 @@ Allowed statuses: `Ready`, `In Progress`, `Blocked`, `Deferred`, `Done`
|
||||
|
||||
## Reference Implementations
|
||||
|
||||
| What | Source | Notes |
|
||||
|---|---|---|
|
||||
| Bridge protocol (message shapes) | `packages/webview-bridge/src/types.ts` | Canonical — native must match |
|
||||
| Storage adapter expectations | `packages/webview-bridge/src/adapters/storage.ts:15-18` | `get()` returns `{ value: string \| null }` |
|
||||
| Crypto adapter expectations | `packages/webview-bridge/src/adapters/crypto.ts` | Defines request params and response shapes |
|
||||
| CryptoHandler (Android ref) | `packages/native-shell-android/.../handlers/CryptoHandler.kt` | Reference for default `AndroidKeystoreCryptoProvider` — uses AndroidKeyStore, secp256r1, SHA256withECDSA |
|
||||
| SecureStorageHandler (Android ref) | `packages/native-shell-android/.../handlers/SecureStorageHandler.kt` | Reference for provider-delegated handler — wraps `get()` in `{ value: ... }` |
|
||||
| WebChromeClient | `packages/native-shell-android/.../webview/AndroidWebViewHost.kt:109-173` | Port permission + file upload handling |
|
||||
| iOS provider registry | `packages/kmp-sdk/.../iosMain/.../providers/SdkProviderRegistry.kt` | Current iOS-only registry — move to commonMain |
|
||||
| iOS CryptoBridgeHandler | `packages/kmp-sdk/.../iosMain/.../handlers/CryptoBridgeHandler.kt` | Provider-delegated crypto — reuse pattern for both platforms |
|
||||
| What | Source | Notes |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| Bridge protocol (message shapes) | `packages/webview-bridge/src/types.ts` | Canonical — native must match |
|
||||
| Storage adapter expectations | `packages/webview-bridge/src/adapters/storage.ts:15-18` | `get()` returns `{ value: string \| null }` |
|
||||
| Crypto adapter expectations | `packages/webview-bridge/src/adapters/crypto.ts` | Defines request params and response shapes |
|
||||
| CryptoHandler (Android ref) | `packages/native-shell-android/.../handlers/CryptoHandler.kt` | Reference for default `AndroidKeystoreCryptoProvider` — uses AndroidKeyStore, secp256r1, SHA256withECDSA |
|
||||
| SecureStorageHandler (Android ref) | `packages/native-shell-android/.../handlers/SecureStorageHandler.kt` | Reference for provider-delegated handler — wraps `get()` in `{ value: ... }` |
|
||||
| WebChromeClient | `packages/native-shell-android/.../webview/AndroidWebViewHost.kt:109-173` | Port permission + file upload handling |
|
||||
| iOS provider registry | `packages/kmp-sdk/.../iosMain/.../providers/SdkProviderRegistry.kt` | Current iOS-only registry — move to commonMain |
|
||||
| iOS CryptoBridgeHandler | `packages/kmp-sdk/.../iosMain/.../handlers/CryptoBridgeHandler.kt` | Provider-delegated crypto — reuse pattern for both platforms |
|
||||
|
||||
## Bridge Domain Contract
|
||||
|
||||
@@ -101,35 +101,35 @@ Only 3 domains are registered by the scoped KMP:
|
||||
|
||||
### `secureStorage`
|
||||
|
||||
| Method | Params | Response |
|
||||
|---|---|---|
|
||||
| `get` | `{ key: string }` | `{ value: string \| null }` |
|
||||
| `set` | `{ key: string, value: string }` | `null` |
|
||||
| `remove` | `{ key: string }` | `null` |
|
||||
| Method | Params | Response |
|
||||
| -------- | -------------------------------- | --------------------------- |
|
||||
| `get` | `{ key: string }` | `{ value: string \| null }` |
|
||||
| `set` | `{ key: string, value: string }` | `null` |
|
||||
| `remove` | `{ key: string }` | `null` |
|
||||
|
||||
### `crypto`
|
||||
|
||||
| Method | Params | Response |
|
||||
|---|---|---|
|
||||
| `generateKey` | `{ keyRef: string }` | `{ keyRef: string, success: true }` |
|
||||
| `getPublicKey` | `{ keyRef: string }` | `{ publicKey: string }` (base64) |
|
||||
| `sign` | `{ data: string, keyRef: string }` (data is base64) | `{ signature: string }` (base64) |
|
||||
| Method | Params | Response |
|
||||
| -------------- | --------------------------------------------------- | ----------------------------------- |
|
||||
| `generateKey` | `{ keyRef: string }` | `{ keyRef: string, success: true }` |
|
||||
| `getPublicKey` | `{ keyRef: string }` | `{ publicKey: string }` (base64) |
|
||||
| `sign` | `{ data: string, keyRef: string }` (data is base64) | `{ signature: string }` (base64) |
|
||||
|
||||
### `lifecycle`
|
||||
|
||||
| Method | Params | Response |
|
||||
|---|---|---|
|
||||
| `ready` | `{}` | `null` (no-op) |
|
||||
| `dismiss` | `{ reason?: string }` | `null` (finishes Activity / dismisses VC) |
|
||||
| `setResult` | `{ success: bool, userId?, verificationId?, error? }` | `null` (forwards to host, then finishes) |
|
||||
| Method | Params | Response |
|
||||
| ----------- | ----------------------------------------------------- | ----------------------------------------- |
|
||||
| `ready` | `{}` | `null` (no-op) |
|
||||
| `dismiss` | `{ reason?: string }` | `null` (finishes Activity / dismisses VC) |
|
||||
| `setResult` | `{ success: bool, userId?, verificationId?, error? }` | `null` (forwards to host, then finishes) |
|
||||
|
||||
Any other domain request returns a `DOMAIN_NOT_FOUND` error response.
|
||||
|
||||
## Related Specs
|
||||
|
||||
| Spec | Relationship |
|
||||
|---|---|
|
||||
| [SDK Overview](../../OVERVIEW.md) | Parent architecture |
|
||||
| [Native Shells Lite](../native-shells-lite/SPEC.md) | Sibling — serves non-KMP consumers |
|
||||
| [Paused Native Shells (KMP)](../../paused/native-shells/SPEC.md) | Historical KMP work — validated foundation |
|
||||
| [Build Pipeline](../build-pipeline/SPEC.md) | Downstream — bundles webview-app into native assets |
|
||||
| Spec | Relationship |
|
||||
| ---------------------------------------------------------------- | --------------------------------------------------- |
|
||||
| [SDK Overview](../../OVERVIEW.md) | Parent architecture |
|
||||
| [Native Shells Lite](../native-shells-lite/SPEC.md) | Sibling — serves non-KMP consumers |
|
||||
| [Paused Native Shells (KMP)](../../paused/native-shells/SPEC.md) | Historical KMP work — validated foundation |
|
||||
| [Build Pipeline](../build-pipeline/SPEC.md) | Downstream — bundles webview-app into native assets |
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
The KMP SDK Android target registers 5 handlers (NFC, Camera, Biometric, SecureStorage, Lifecycle) but is missing the `crypto` handler that native-shells-lite provides. The Android SecureStorage handler hardcodes `EncryptedSharedPreferences` instead of delegating to a consumer-provided provider (the iOS target already delegates via `SdkProviderRegistry`). There are also gaps in WebView capabilities (no WebChromeClient, no query params), an incorrect SecureStorage response shape, and no bridge protocol version validation.
|
||||
|
||||
You are closing these gaps by:
|
||||
|
||||
1. Moving provider interfaces to `commonMain` so both platforms share the same contract
|
||||
2. Making Android handlers delegate to providers (matching iOS pattern)
|
||||
3. Shipping default Android provider implementations consumers can use or replace
|
||||
@@ -26,6 +27,7 @@ You are closing these gaps by:
|
||||
- Provider delegation: move interfaces to commonMain, add default Android implementations
|
||||
- WebView host upgrades (WebChromeClient, query params)
|
||||
- Bridge alignment (response shapes, protocol version)
|
||||
- Android SDK slimming needed to make the 3-domain scope real: stop registering unused handlers, remove out-of-scope Android permissions, and drop no-longer-needed Android dependencies from the published artifact
|
||||
|
||||
### Out of Scope
|
||||
|
||||
@@ -43,12 +45,14 @@ You are closing these gaps by:
|
||||
Currently `SecureStorageProvider` and `CryptoProvider` live in `iosMain/kotlin/xyz/self/sdk/providers/`. Move them to `commonMain` so both platforms share the same contract.
|
||||
|
||||
**Move:**
|
||||
|
||||
- `packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/providers/SecureStorageProvider.kt` → `packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/providers/SecureStorageProvider.kt`
|
||||
- `packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/providers/CryptoProvider.kt` → `packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/providers/CryptoProvider.kt`
|
||||
|
||||
The interfaces remain identical — same package (`xyz.self.sdk.providers`), same methods. The iOS handlers that reference them will compile without changes since `commonMain` is visible to `iosMain`.
|
||||
|
||||
**Current `SecureStorageProvider` interface (iosMain):**
|
||||
|
||||
```kotlin
|
||||
interface SecureStorageProvider {
|
||||
fun get(key: String): String?
|
||||
@@ -59,6 +63,7 @@ interface SecureStorageProvider {
|
||||
```
|
||||
|
||||
**Current `CryptoProvider` interface (iosMain):**
|
||||
|
||||
```kotlin
|
||||
interface CryptoProvider {
|
||||
fun generateKey(keyRef: String)
|
||||
@@ -79,6 +84,7 @@ No changes to the interfaces themselves — just the source set location.
|
||||
**Move to:** `packages/kmp-sdk/shared/src/commonMain/kotlin/xyz/self/sdk/providers/SdkProviderRegistry.kt`
|
||||
|
||||
**Rewrite for 3-domain scope:**
|
||||
|
||||
```kotlin
|
||||
package xyz.self.sdk.providers
|
||||
|
||||
@@ -116,6 +122,7 @@ object SdkProviderRegistry {
|
||||
```
|
||||
|
||||
**Key changes:**
|
||||
|
||||
- `isConfigured()` now checks only the 2 required providers (secureStorage, crypto) instead of all 8
|
||||
- Added `reset()` for clean teardown between sessions
|
||||
- Optional providers retained for future use but not required
|
||||
@@ -301,6 +308,7 @@ class SecureStorageBridgeHandler : BridgeHandler {
|
||||
```
|
||||
|
||||
**Key changes from current:**
|
||||
|
||||
- No longer takes `Context` parameter (no direct EncryptedSharedPreferences)
|
||||
- Delegates to `SdkProviderRegistry.secureStorage`
|
||||
- `get()` returns `buildJsonObject { put("value", ...) }` instead of bare `JsonPrimitive`/`JsonNull`
|
||||
@@ -396,6 +404,7 @@ class CryptoBridgeHandler : BridgeHandler {
|
||||
If moved to `commonMain`, **delete** the existing `iosMain/.../handlers/CryptoBridgeHandler.kt` to avoid duplicate class definitions.
|
||||
|
||||
Response shapes match `webview-bridge/src/adapters/crypto.ts`:
|
||||
|
||||
- `generateKey` → `{ keyRef: string, success: true }`
|
||||
- `getPublicKey` → `{ publicKey: string }` (base64)
|
||||
- `sign` → `{ signature: string }` (base64)
|
||||
@@ -405,6 +414,7 @@ Response shapes match `webview-bridge/src/adapters/crypto.ts`:
|
||||
**File:** `packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/webview/SelfVerificationActivity.kt`
|
||||
|
||||
**Current `registerHandlers()` (lines 88-103):**
|
||||
|
||||
```kotlin
|
||||
private fun registerHandlers() {
|
||||
router.register(NfcBridgeHandler(this, router))
|
||||
@@ -416,6 +426,7 @@ private fun registerHandlers() {
|
||||
```
|
||||
|
||||
**Change to:**
|
||||
|
||||
```kotlin
|
||||
private fun registerHandlers() {
|
||||
router.register(SecureStorageBridgeHandler()) // no Context — delegates to provider
|
||||
@@ -425,6 +436,7 @@ private fun registerHandlers() {
|
||||
```
|
||||
|
||||
**Also:**
|
||||
|
||||
- Remove `requiredPermissions` array, `permissionLauncher`, and the permission-check block in `onCreate()` (lines 29-56). The 3-domain scope does not need CAMERA or NFC permissions at startup. The WebChromeClient (step 8) handles camera permissions on-demand.
|
||||
- Simplify `onCreate()` to call `initVerificationFlow()` directly.
|
||||
- Add provider initialization before handler registration:
|
||||
@@ -448,6 +460,25 @@ This gives consumers the option to set their own providers before launching the
|
||||
- Remove unused imports: `BiometricBridgeHandler`, `CameraMrzBridgeHandler`, `NfcBridgeHandler`, `Manifest`, `PackageManager`, `ActivityResultContracts`, `ContextCompat`.
|
||||
- Add imports: `CryptoBridgeHandler`, `SdkProviderRegistry`, `EncryptedSharedPreferencesProvider`, `AndroidKeystoreCryptoProvider`.
|
||||
|
||||
#### 6a. Trim Android manifest and dependency surface
|
||||
|
||||
This ownership belongs to KR-01, not KR-03. KR-03 validates the trimmed artifact; KR-01 performs the actual slimming.
|
||||
|
||||
**Android manifest**
|
||||
|
||||
- Remove out-of-scope permissions and features from `shared/src/androidMain/AndroidManifest.xml` that are only needed for NFC, camera/MRZ, or haptics.
|
||||
- Keep only permissions and features required by the scoped 3-domain Android delivery.
|
||||
|
||||
**Gradle dependencies**
|
||||
|
||||
- Remove Android dependencies from `shared/build.gradle.kts` that only exist to support out-of-scope handlers once those handlers are no longer registered.
|
||||
- Expected removals include NFC/passport-reading, camera/MRZ, and biometric-specific dependencies if no remaining 3-domain code path needs them.
|
||||
- Keep Android WebView, activity/lifecycle, and encrypted storage dependencies required by the scoped SDK.
|
||||
|
||||
**Artifact expectation**
|
||||
|
||||
- `shared-release.aar` should become smaller after this step because out-of-scope Android code paths and dependencies are no longer pulled into the published artifact.
|
||||
|
||||
#### 7. Add query param support to WebView URL loading
|
||||
|
||||
**File:** `packages/kmp-sdk/shared/src/androidMain/kotlin/xyz/self/sdk/webview/AndroidWebViewHost.kt`
|
||||
@@ -457,6 +488,7 @@ This gives consumers the option to set their own providers before launching the
|
||||
**Change to:** `fun createWebView(queryParams: String = ""): WebView`
|
||||
|
||||
**Update loadUrl calls (lines 129-139):**
|
||||
|
||||
```kotlin
|
||||
// Before
|
||||
webView.loadUrl("https://appassets.androidplatform.net/index.html")
|
||||
@@ -472,6 +504,7 @@ Apply the same pattern to the debug URL (`http://127.0.0.1:5173`).
|
||||
**Update caller in SelfVerificationActivity:** Build query params from intent extras (or `VerificationRequest` if available) and pass to `createWebView(queryParams)`. Reference `packages/native-shell-android/.../SelfVerificationActivity.kt:64-84` for the query string builder pattern using `buildString { }` with `Uri.encode()`.
|
||||
|
||||
The native-shell-android extracts 14 intent extras and encodes them. KMP currently only extracts `EXTRA_DEBUG_MODE`, `EXTRA_VERIFICATION_REQUEST`, and `EXTRA_CONFIG`. You need to either:
|
||||
|
||||
- Parse `EXTRA_VERIFICATION_REQUEST` JSON and build query params from it, or
|
||||
- Add the same 14 intent extras as native-shell-android
|
||||
|
||||
@@ -551,12 +584,14 @@ webChromeClient = object : WebChromeClient() {
|
||||
```
|
||||
|
||||
Add class-level fields:
|
||||
|
||||
```kotlin
|
||||
var pendingPermissionRequest: PermissionRequest? = null
|
||||
var fileUploadCallback: ValueCallback<Array<Uri>>? = null
|
||||
```
|
||||
|
||||
Add companion object constants:
|
||||
|
||||
```kotlin
|
||||
companion object {
|
||||
const val FILE_CHOOSER_REQUEST_CODE = 1001
|
||||
@@ -565,6 +600,7 @@ companion object {
|
||||
```
|
||||
|
||||
**Also add permission result handling** to `SelfVerificationActivity`:
|
||||
|
||||
```kotlin
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
@@ -599,6 +635,7 @@ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
|
||||
**Current (lines 26-32):** After parsing the BridgeRequest, handler lookup proceeds immediately with no version check.
|
||||
|
||||
**Add after parsing (line 32, before handler lookup):**
|
||||
|
||||
```kotlin
|
||||
val request = json.decodeFromString<BridgeRequest>(rawJson)
|
||||
|
||||
@@ -616,6 +653,7 @@ if (request.version != BRIDGE_PROTOCOL_VERSION) {
|
||||
```
|
||||
|
||||
Add companion object constant (matching `webview-bridge/src/types.ts:152`):
|
||||
|
||||
```kotlin
|
||||
companion object {
|
||||
const val BRIDGE_PROTOCOL_VERSION = 1
|
||||
@@ -629,6 +667,7 @@ companion object {
|
||||
**File:** `packages/kmp-sdk/shared/build.gradle.kts`
|
||||
|
||||
**Remove or comment out these androidMain dependencies:**
|
||||
|
||||
```kotlin
|
||||
// NFC/Passport — not needed for 3-domain scope
|
||||
// implementation("org.jmrtd:jmrtd:0.8.1")
|
||||
@@ -647,6 +686,7 @@ companion object {
|
||||
```
|
||||
|
||||
**Keep:**
|
||||
|
||||
- `androidx.webkit:webkit` — WebView
|
||||
- `androidx.security:security-crypto` — Default EncryptedSharedPreferencesProvider
|
||||
- `androidx.appcompat:appcompat` — Activity
|
||||
@@ -657,33 +697,33 @@ companion object {
|
||||
|
||||
### Files Created
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `shared/src/commonMain/.../providers/SecureStorageProvider.kt` | Moved from iosMain — shared interface |
|
||||
| `shared/src/commonMain/.../providers/CryptoProvider.kt` | Moved from iosMain — shared interface |
|
||||
| `shared/src/commonMain/.../providers/SdkProviderRegistry.kt` | Moved from iosMain — unified registry, 3-domain `isConfigured()` |
|
||||
| `shared/src/commonMain/.../handlers/CryptoBridgeHandler.kt` | Provider-delegated crypto handler (replaces iOS-only version) |
|
||||
| `shared/src/androidMain/.../providers/EncryptedSharedPreferencesProvider.kt` | Default Android SecureStorageProvider |
|
||||
| `shared/src/androidMain/.../providers/AndroidKeystoreCryptoProvider.kt` | Default Android CryptoProvider |
|
||||
| File | Purpose |
|
||||
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| `shared/src/commonMain/.../providers/SecureStorageProvider.kt` | Moved from iosMain — shared interface |
|
||||
| `shared/src/commonMain/.../providers/CryptoProvider.kt` | Moved from iosMain — shared interface |
|
||||
| `shared/src/commonMain/.../providers/SdkProviderRegistry.kt` | Moved from iosMain — unified registry, 3-domain `isConfigured()` |
|
||||
| `shared/src/commonMain/.../handlers/CryptoBridgeHandler.kt` | Provider-delegated crypto handler (replaces iOS-only version) |
|
||||
| `shared/src/androidMain/.../providers/EncryptedSharedPreferencesProvider.kt` | Default Android SecureStorageProvider |
|
||||
| `shared/src/androidMain/.../providers/AndroidKeystoreCryptoProvider.kt` | Default Android CryptoProvider |
|
||||
|
||||
### Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `shared/src/androidMain/.../handlers/SecureStorageBridgeHandler.kt` | Rewrite: delegate to provider, fix `get()` response shape |
|
||||
| `shared/src/androidMain/.../webview/SelfVerificationActivity.kt` | Register 3 handlers, default provider init, remove permission requests, add query params, add permission/file callbacks |
|
||||
| `shared/src/androidMain/.../webview/AndroidWebViewHost.kt` | Add WebChromeClient, query params, permission/file fields |
|
||||
| `shared/src/commonMain/.../bridge/MessageRouter.kt` | Add protocol version validation |
|
||||
| `shared/build.gradle.kts` | Remove NFC/camera/biometric dependencies |
|
||||
| File | Change |
|
||||
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `shared/src/androidMain/.../handlers/SecureStorageBridgeHandler.kt` | Rewrite: delegate to provider, fix `get()` response shape |
|
||||
| `shared/src/androidMain/.../webview/SelfVerificationActivity.kt` | Register 3 handlers, default provider init, remove permission requests, add query params, add permission/file callbacks |
|
||||
| `shared/src/androidMain/.../webview/AndroidWebViewHost.kt` | Add WebChromeClient, query params, permission/file fields |
|
||||
| `shared/src/commonMain/.../bridge/MessageRouter.kt` | Add protocol version validation |
|
||||
| `shared/build.gradle.kts` | Remove NFC/camera/biometric dependencies |
|
||||
|
||||
### Files Deleted
|
||||
|
||||
| File | Reason |
|
||||
|------|--------|
|
||||
| `shared/src/iosMain/.../providers/SecureStorageProvider.kt` | Moved to commonMain |
|
||||
| `shared/src/iosMain/.../providers/CryptoProvider.kt` | Moved to commonMain |
|
||||
| `shared/src/iosMain/.../providers/SdkProviderRegistry.kt` | Moved to commonMain |
|
||||
| `shared/src/iosMain/.../handlers/CryptoBridgeHandler.kt` | Replaced by commonMain version |
|
||||
| File | Reason |
|
||||
| ----------------------------------------------------------- | ------------------------------ |
|
||||
| `shared/src/iosMain/.../providers/SecureStorageProvider.kt` | Moved to commonMain |
|
||||
| `shared/src/iosMain/.../providers/CryptoProvider.kt` | Moved to commonMain |
|
||||
| `shared/src/iosMain/.../providers/SdkProviderRegistry.kt` | Moved to commonMain |
|
||||
| `shared/src/iosMain/.../handlers/CryptoBridgeHandler.kt` | Replaced by commonMain version |
|
||||
|
||||
### Files NOT Modified
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ You are scoping KMP iOS to 3-domain parity with native-shell-ios.
|
||||
- `packages/webview-bridge/` — bridge protocol unchanged
|
||||
- `packages/webview-app/` — WebView code unchanged
|
||||
- NFC, Camera, Biometric provider code in self-sdk-swift — retain but do not require registration
|
||||
- Removing retained Swift-side NFC / biometrics code or dependencies from `packages/self-sdk-swift/` — the short-term strategy is "retain but do not register" to avoid broad Swift package churn during parity work
|
||||
|
||||
### Implementation Steps
|
||||
|
||||
@@ -41,6 +42,7 @@ You are scoping KMP iOS to 3-domain parity with native-shell-ios.
|
||||
**Required:** The TypeScript adapter at `webview-bridge/src/adapters/storage.ts:16` does `result?.value ?? null` — expects `{ value: string | null }`.
|
||||
|
||||
**Change:**
|
||||
|
||||
```kotlin
|
||||
// Before (line 44)
|
||||
return if (value != null) JsonPrimitive(value) else JsonNull
|
||||
@@ -64,12 +66,14 @@ Add import: `import kotlinx.serialization.json.buildJsonObject`
|
||||
**Current:** `createWebView(onMessageReceived:isDebugMode:)` loads `Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "self-sdk-web")` without appending query params.
|
||||
|
||||
**Required:** native-shell-ios passes verification config as query params via `URLComponents`:
|
||||
|
||||
```swift
|
||||
var components = URLComponents(url: fileURL, resolvingAgainstBaseURL: false)
|
||||
components?.query = queryParams
|
||||
```
|
||||
|
||||
**Change the method signature:**
|
||||
|
||||
```swift
|
||||
// Before
|
||||
@objc(createWebViewOnMessageReceived:isDebugMode:)
|
||||
@@ -84,6 +88,7 @@ public func createWebView(onMessageReceived: @escaping (String) -> Void,
|
||||
```
|
||||
|
||||
**Update the URL loading logic** to append query params when provided:
|
||||
|
||||
```swift
|
||||
if let htmlURL = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "self-sdk-web") {
|
||||
var targetURL = htmlURL
|
||||
@@ -105,6 +110,7 @@ Apply the same pattern to the debug URL (`http://localhost:5173`).
|
||||
**Current (lines 18-29):** `createWebView()` calls `provider.createWebView(onMessageReceived, isDebugMode)` with no query params.
|
||||
|
||||
**Update `WebViewProvider` interface** (in `iosMain/kotlin/xyz/self/sdk/providers/WebViewProvider.kt` or wherever it's defined) to add the query param:
|
||||
|
||||
```kotlin
|
||||
interface WebViewProvider {
|
||||
fun createWebView(
|
||||
@@ -116,6 +122,7 @@ interface WebViewProvider {
|
||||
```
|
||||
|
||||
**Update `IosWebViewHost`** to forward query params from the `VerificationRequest`:
|
||||
|
||||
```kotlin
|
||||
fun createWebView(queryParams: String? = null): UIView {
|
||||
val provider = SdkProviderRegistry.webView
|
||||
@@ -133,6 +140,7 @@ fun createWebView(queryParams: String? = null): UIView {
|
||||
**File:** `packages/kmp-sdk/shared/src/iosMain/kotlin/xyz/self/sdk/api/SelfSdk.ios.kt`
|
||||
|
||||
**Current (lines 145-158) registers 9 handlers:**
|
||||
|
||||
```kotlin
|
||||
router.register(BiometricBridgeHandler())
|
||||
router.register(SecureStorageBridgeHandler())
|
||||
@@ -146,6 +154,7 @@ router.register(NfcBridgeHandler(router))
|
||||
```
|
||||
|
||||
**Change to 3 handlers:**
|
||||
|
||||
```kotlin
|
||||
router.register(SecureStorageBridgeHandler())
|
||||
router.register(CryptoBridgeHandler()) // now from commonMain after KR-01
|
||||
@@ -169,15 +178,23 @@ The launch flow receives a `VerificationRequest`. Build query params from it and
|
||||
|
||||
Reference the native-shell-ios `SelfSdkConfig.toQueryParams()` pattern for the field list. The KMP already has structured types, so use those rather than raw string extras.
|
||||
|
||||
#### 7. Preserve retained Swift providers without requiring them
|
||||
|
||||
`packages/self-sdk-swift/` still contains provider implementations and dependencies for NFC, camera/MRZ, biometrics, haptics, and documents. KR-02 does not remove that code. The parity requirement is narrower:
|
||||
|
||||
- Only `secureStorage`, `crypto`, and `webView` must be registered for the scoped KMP flow.
|
||||
- Retained Swift providers may continue to compile and ship, but they must not be required by KMP startup or `SdkProviderRegistry.isConfigured()`.
|
||||
- Document this explicitly in implementation notes so the temporary iOS package footprint is not mistaken for a spec bug.
|
||||
|
||||
### Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `shared/src/iosMain/.../handlers/SecureStorageBridgeHandler.kt` | Fix `get()` response shape to `{ value: ... }` |
|
||||
| `packages/self-sdk-swift/.../WebViewProviderImpl.swift` | Add `queryParams` parameter, append to URL |
|
||||
| `shared/src/iosMain/.../webview/IosWebViewHost.kt` | Forward query params to provider |
|
||||
| `shared/src/iosMain/.../providers/WebViewProvider.kt` | Add `queryParams` to interface |
|
||||
| `shared/src/iosMain/.../api/SelfSdk.ios.kt` | Register only 3 handlers, build and pass query params |
|
||||
| File | Change |
|
||||
| --------------------------------------------------------------- | ----------------------------------------------------- |
|
||||
| `shared/src/iosMain/.../handlers/SecureStorageBridgeHandler.kt` | Fix `get()` response shape to `{ value: ... }` |
|
||||
| `packages/self-sdk-swift/.../WebViewProviderImpl.swift` | Add `queryParams` parameter, append to URL |
|
||||
| `shared/src/iosMain/.../webview/IosWebViewHost.kt` | Forward query params to provider |
|
||||
| `shared/src/iosMain/.../providers/WebViewProvider.kt` | Add `queryParams` to interface |
|
||||
| `shared/src/iosMain/.../api/SelfSdk.ios.kt` | Register only 3 handlers, build and pass query params |
|
||||
|
||||
### Files NOT Modified
|
||||
|
||||
@@ -186,6 +203,7 @@ Reference the native-shell-ios `SelfSdkConfig.toQueryParams()` pattern for the f
|
||||
- `packages/webview-app/` — WebView code unchanged
|
||||
- Self-sdk-swift crypto/secureStorage providers — already match native-shell-ios functionality
|
||||
- `commonMain` files — already updated in KR-01
|
||||
- Removal of retained NFC / camera / biometric Swift provider code and dependencies — deferred follow-up, not part of KR-02
|
||||
|
||||
### Preconditions
|
||||
|
||||
@@ -219,6 +237,7 @@ cd packages/kmp-sdk && ./gradlew :shared:jvmTest
|
||||
- [ ] `WebViewProvider` interface includes `queryParams` parameter
|
||||
- [ ] Only 3 handlers registered on iOS (SecureStorage, Crypto, Lifecycle)
|
||||
- [ ] SDK does not crash if optional providers (NFC, Camera, etc.) are not registered
|
||||
- [ ] `self-sdk-swift` may retain optional provider code/dependencies, but KMP startup only requires `secureStorage`, `crypto`, and `webView`
|
||||
- [ ] Query params built from VerificationRequest and passed to WebView
|
||||
- [ ] XCFramework builds cleanly
|
||||
- [ ] self-sdk-swift builds cleanly
|
||||
|
||||
@@ -16,14 +16,16 @@ After KR-01 (Android parity) and KR-02 (iOS parity), you need to validate that t
|
||||
### Scope
|
||||
|
||||
- `packages/kmp-sdk/` — build artifact validation
|
||||
- `packages/kmp-sdk-test-app/` — test app adaptation for 3-domain scope
|
||||
- `packages/self-sdk-swift/` — ensure it integrates cleanly with scoped KMP
|
||||
- `packages/kmp-sdk-test-app/` — simplify the test harness to validate only the 3-domain contract end-to-end
|
||||
- `packages/self-sdk-swift/` — ensure it integrates cleanly with scoped KMP without requiring registration of optional providers
|
||||
|
||||
### Out of Scope
|
||||
|
||||
- Actual publishing to external Maven/SPM registries (that's a follow-up, equivalent to paused NS-08)
|
||||
- `packages/native-shell-android/` and `packages/native-shell-ios/` — do not modify
|
||||
- CI/CD pipeline changes
|
||||
- Android dependency trimming or Android manifest slimming inside `packages/kmp-sdk/` — that ownership belongs to KR-01; KR-03 validates the result
|
||||
- Removing retained NFC / biometric Swift provider code or dependencies from `packages/self-sdk-swift/` — validate current integration shape, do not redesign it here
|
||||
|
||||
### Implementation Steps
|
||||
|
||||
@@ -59,33 +61,55 @@ cd packages/kmp-sdk
|
||||
./gradlew createXCFramework
|
||||
|
||||
# Verify output
|
||||
ls -la shared/build/XCFrameworks/
|
||||
ls -la shared/build/xcframework/
|
||||
```
|
||||
|
||||
#### 3. Adapt kmp-sdk-test-app for 3-domain scope
|
||||
|
||||
**Location:** `packages/kmp-sdk-test-app/`
|
||||
|
||||
The test app currently exercises all KMP handlers including NFC and camera. Update it to only use the 3-domain scope.
|
||||
The current test app still contains a full MRZ/NFC-oriented verification flow. KR-03 should simplify the harness so its primary job is validating the 3-domain KMP contract, not preserving the older full-verification demo.
|
||||
|
||||
**Android (`packages/kmp-sdk-test-app/androidApp/`):**
|
||||
- Remove NFC and Camera permission requests from AndroidManifest.xml (if present)
|
||||
**Decision:** gut the MRZ/NFC-first flow from the default harness rather than gating it behind a flag. Keep the test app focused on `secureStorage`, `crypto`, and `lifecycle`.
|
||||
|
||||
**Expected harness behavior**
|
||||
|
||||
- The default app flow should expose a simple, repeatable smoke-test path for the 3 bridge domains.
|
||||
- Avoid UI paths that require camera, NFC, biometrics, or documents to demonstrate success.
|
||||
- Existing MRZ/NFC-specific state, screens, and tests may be removed or aggressively simplified if they do not serve the 3-domain validation goal.
|
||||
|
||||
**Android (`packages/kmp-sdk-test-app/composeApp/` and platform wrappers):**
|
||||
|
||||
- Remove test-app-level NFC and camera permission requests from Android manifests if they are only used by the deleted MRZ/NFC flows
|
||||
- The app should rely on default providers (Activity auto-initializes `EncryptedSharedPreferencesProvider` and `AndroidKeystoreCryptoProvider` if not set). Alternatively, demonstrate explicit provider registration before launch:
|
||||
```kotlin
|
||||
SdkProviderRegistry.secureStorage = EncryptedSharedPreferencesProvider(context)
|
||||
SdkProviderRegistry.crypto = AndroidKeystoreCryptoProvider()
|
||||
```
|
||||
- Verify the app launches the SDK, loads the WebView, and handles lifecycle callbacks
|
||||
- Verify crypto operations work (generateKey, getPublicKey, sign)
|
||||
- Verify secure storage operations work (get, set, remove)
|
||||
- Provide a visible pass/fail mechanism for each scoped domain check
|
||||
|
||||
**iOS (`packages/kmp-sdk-test-app/iosApp/`):**
|
||||
|
||||
- Register only required providers: `secureStorage`, `crypto`, `webView`
|
||||
- Remove registration of NFC, Camera, Biometric, Haptic, Documents providers
|
||||
- Verify the app launches the SDK, loads the WebView, and handles lifecycle callbacks
|
||||
- Ensure `self-sdk-web/` assets are in Copy Bundle Resources
|
||||
- Do not require registration of retained optional providers from `self-sdk-swift`
|
||||
|
||||
#### 4. Run full test suite
|
||||
#### 4. Add scripted domain smoke checks to the test app
|
||||
|
||||
Manual "launch and eyeball it" validation is not enough. Add one explicit smoke check per scoped domain, surfaced through the test app UI or logs so a human can run the same sequence on both platforms.
|
||||
|
||||
**Required checks**
|
||||
|
||||
- `secureStorage`: write a value, read it back, remove it, then confirm a subsequent read returns `null`
|
||||
- `crypto`: generate a key, fetch the public key, sign a message, and log the returned artifacts
|
||||
- `lifecycle`: trigger `ready`, then `setResult`, and confirm the Activity / view controller returns control to the host with the expected result payload
|
||||
|
||||
These do not need to be Espresso/XCUITest. A deterministic in-app smoke-test button or scripted harness flow is sufficient if it produces clear pass/fail output.
|
||||
|
||||
#### 5. Run full test suite
|
||||
|
||||
```bash
|
||||
# Common tests (bridge, routing, serialization, lifecycle)
|
||||
@@ -95,7 +119,7 @@ cd packages/kmp-sdk && ./gradlew :shared:jvmTest
|
||||
# Tests for NFC, Camera, MRZ should still pass (they test code, not registration)
|
||||
```
|
||||
|
||||
#### 5. Update OVERVIEW.md module table
|
||||
#### 6. Update OVERVIEW.md module table
|
||||
|
||||
**File:** `specs/projects/sdk/OVERVIEW.md`
|
||||
|
||||
@@ -103,23 +127,24 @@ Update the module table (around line 110) to reflect KMP revival:
|
||||
|
||||
**Already done** — OVERVIEW.md module table was updated as part of the spec review on 2026-04-01. Verify it still reflects:
|
||||
|
||||
| Module | Status | Notes |
|
||||
|--------|--------|-------|
|
||||
| KMP Native Shell (`packages/kmp-sdk/`) | Active (3-domain scope) | Serves KMP consumers, provider delegation on both platforms |
|
||||
| Swift Providers (`packages/self-sdk-swift/`) | Active | iOS providers for KMP |
|
||||
| KMP Test App (`packages/kmp-sdk-test-app/`) | Active | E2E harness |
|
||||
| Module | Status | Notes |
|
||||
| -------------------------------------------- | ----------------------- | ----------------------------------------------------------- |
|
||||
| KMP Native Shell (`packages/kmp-sdk/`) | Active (3-domain scope) | Serves KMP consumers, provider delegation on both platforms |
|
||||
| Swift Providers (`packages/self-sdk-swift/`) | Active | iOS providers for KMP |
|
||||
| KMP Test App (`packages/kmp-sdk-test-app/`) | Active | E2E harness |
|
||||
|
||||
### Files Modified
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `packages/kmp-sdk-test-app/` (multiple files) | Scope to 3-domain handlers/providers |
|
||||
| `specs/projects/sdk/OVERVIEW.md` | Update module table with KMP status |
|
||||
| File | Change |
|
||||
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `packages/kmp-sdk-test-app/` (multiple files) | Remove MRZ/NFC-first default flow, scope harness to 3-domain handlers/providers, add scripted domain checks |
|
||||
| `specs/projects/sdk/OVERVIEW.md` | Update module table with KMP status |
|
||||
|
||||
### Files NOT Modified
|
||||
|
||||
- `packages/kmp-sdk/` — no code changes (KR-01 and KR-02 handle this)
|
||||
- `packages/kmp-sdk/` — no new feature work; KR-03 only validates the artifact shape produced by KR-01 and KR-02
|
||||
- `packages/native-shell-*` — sibling implementations, unchanged
|
||||
- `packages/self-sdk-swift/` retained optional provider code/dependencies — validate integration shape, do not slim package contents here
|
||||
|
||||
### Preconditions
|
||||
|
||||
@@ -137,7 +162,7 @@ cd packages/kmp-sdk && ./gradlew createXCFramework
|
||||
cd packages/self-sdk-swift && swift build
|
||||
|
||||
# Test app Android build
|
||||
cd packages/kmp-sdk-test-app/androidApp && ../gradlew :androidApp:assembleDebug
|
||||
cd packages/kmp-sdk-test-app && ./gradlew :composeApp:assembleDebug
|
||||
|
||||
# Test app iOS build (Xcode required)
|
||||
# Open packages/kmp-sdk-test-app/iosApp/ in Xcode and build for simulator
|
||||
@@ -151,13 +176,15 @@ cd packages/kmp-sdk-test-app/androidApp && ../gradlew :androidApp:assembleDebug
|
||||
- [ ] All jvmTest tests pass
|
||||
- [ ] Test app Android builds and runs
|
||||
- [ ] Test app iOS builds and runs
|
||||
- [ ] Crypto operations work in test app (generateKey, sign, getPublicKey)
|
||||
- [ ] SecureStorage operations work in test app (get, set, remove)
|
||||
- [ ] Lifecycle operations work in test app (ready, dismiss, setResult)
|
||||
- [ ] Default test-app flow no longer depends on MRZ/NFC/camera features
|
||||
- [ ] Test app exposes deterministic smoke checks for each scoped domain
|
||||
- [ ] Crypto smoke check passes in test app (generateKey, sign, getPublicKey)
|
||||
- [ ] SecureStorage smoke check passes in test app (get, set, remove)
|
||||
- [ ] Lifecycle smoke check passes in test app (`ready`, `setResult`, host returns to caller)
|
||||
- [ ] OVERVIEW.md module table updated
|
||||
- [ ] AAR size is smaller than pre-scoping (NFC/camera deps removed)
|
||||
- [ ] AAR size is smaller than pre-scoping (validated result of KR-01 Android slimming)
|
||||
- [ ] Provider delegation works end-to-end on Android (default providers)
|
||||
- [ ] Provider delegation works end-to-end on iOS (self-sdk-swift providers)
|
||||
- [ ] Provider delegation works end-to-end on iOS (`self-sdk-swift` registers only the required providers for scoped flow)
|
||||
|
||||
### Estimated PR Size
|
||||
|
||||
@@ -167,3 +194,4 @@ cd packages/kmp-sdk-test-app/androidApp && ../gradlew :androidApp:assembleDebug
|
||||
|
||||
- 2026-03-31: Plan created.
|
||||
- 2026-04-01: Updated for provider delegation (KR-01 change). Added provider E2E validation. OVERVIEW.md already updated.
|
||||
- 2026-04-01: Clarified XCFramework output path, moved Android slimming ownership fully into KR-01, and made KR-03 require a simplified 3-domain test harness with explicit smoke checks.
|
||||
|
||||
Reference in New Issue
Block a user