@finos_sdk/sdk-ekyc 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,5 @@
1
- // ... existing code ...
2
1
  package finos.sdk.ekyc
3
2
 
4
- // Reuse the same implementation as app module to expose RN bridge
5
- // If needed, consider refactoring common code to a shared sourceSet
6
-
7
3
  import android.R
8
4
  import android.util.Base64
9
5
  import android.util.Log
@@ -39,74 +35,6 @@ import java.io.File
39
35
  import java.io.FileOutputStream
40
36
  import java.util.Date
41
37
 
42
- @ReactModule(name = EKYCModule.NAME)
43
- class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
44
-
45
- companion object {
46
- const val NAME = "EKYCModule"
47
- private const val TAG = "EKYCModule"
48
- }
49
-
50
- override fun getName(): String = NAME
51
-
52
- private fun sendEvent(eventName: String, params: WritableMap?) {
53
- reactApplicationContext
54
- .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
55
- .emit(eventName, params)
56
- }
57
-
58
- @ReactMethod
59
- fun initSdkEkyc(promise: Promise) {
60
- try {
61
- SdkEkyc.initSDKEkyc(reactApplicationContext) {
62
- val params = Arguments.createMap().apply {
63
- putString("status", "success")
64
- putString("message", "SDK EKYC initialized successfully")
65
- }
66
- sendEvent("EKYCInitEvent", params)
67
- promise.resolve(true)
68
- }
69
- } catch (e: Exception) {
70
- promise.reject("INIT_ERROR", "Failed to initialize SDK EKYC: ${e.message}")
71
- }
72
- }
73
-
74
- // The rest of methods mirror the app module implementation
75
- // startNfcScan, checkC06, startOcr, startLiveness, startFaceCompare, onResume, onPause, handleNewIntent, startEkycUI
76
- // For brevity in this edit, reuse the same content as in app module `EKYCModule.kt`.
77
- }
78
-
79
- package finos.sdk.ekyc
80
-
81
- import android.util.Base64
82
- import android.util.Log
83
- import com.facebook.react.bridge.Arguments
84
- import com.facebook.react.bridge.Promise
85
- import com.facebook.react.bridge.ReactApplicationContext
86
- import com.facebook.react.bridge.ReactContextBaseJavaModule
87
- import com.facebook.react.bridge.ReactMethod
88
- import com.facebook.react.bridge.WritableMap
89
- import com.facebook.react.module.annotations.ReactModule
90
- import com.facebook.react.modules.core.DeviceEventManagerModule
91
- import finos.sdk.c06.SdkEkycC06
92
- import finos.sdk.core.define.EKYCEvent
93
- import finos.sdk.core.define.SDKType
94
- import finos.sdk.core.model.response.SDKEkycResult
95
- import finos.sdk.core.model.sdk.config.C06Config
96
- import finos.sdk.core.model.sdk.config.EKYCConfigSDK
97
- import finos.sdk.core.model.sdk.config.FaceServiceConfig
98
- import finos.sdk.core.model.sdk.config.LivenessConfig
99
- import finos.sdk.core.model.sdk.config.NfcConfig
100
- import finos.sdk.core.model.sdk.config.OcrConfig
101
- import finos.sdk.ekyc.SdkEkyc
102
- import finos.sdk.faceservice.SdkEkycFaceService
103
- import finos.sdk.liveness.SdkEkycLiveness
104
- import finos.sdk.nfc.SdkEkycNfc
105
- import finos.sdk.ocr.SdkEkycOcr
106
- import java.io.File
107
- import java.io.FileOutputStream
108
- import java.util.Date
109
-
110
38
  @ReactModule(name = EKYCModule.NAME)
111
39
  class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
112
40
 
@@ -133,6 +61,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
133
61
  putString("message", "SDK EKYC initialized successfully")
134
62
  }
135
63
  sendEvent("EKYCInitEvent", params)
64
+ //promise.resolve("SDK EKYC initialized successfully")
136
65
  promise.resolve(true)
137
66
  }
138
67
  } catch (e: Exception) {
@@ -167,7 +96,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
167
96
  )
168
97
 
169
98
  val ekycConfig =
170
- EKYCConfigSDK(appKey = appKey, sdkType = SDKType.NFC, nfcConfig = nfcConfig)
99
+ EKYCConfigSDK(appKey = AppKeyConfig(appKey), sdkType = SDKType.NFC, nfcConfig = nfcConfig)
171
100
 
172
101
  SdkEkycNfc.startEkyc(
173
102
  activity = currentActivity,
@@ -179,7 +108,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
179
108
  EKYCEvent.SCAN_NFC_START -> {
180
109
  val eventMap =
181
110
  Arguments.createMap().apply {
182
- putString("event", event.name)
111
+ putString("event", event.name.toString())
183
112
  putString("data", data.toString())
184
113
  }
185
114
  sendEvent("onNfcScanStart", eventMap)
@@ -188,13 +117,13 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
188
117
  EKYCEvent.SCAN_NFC_SUCCESS -> {
189
118
  val eventMap =
190
119
  Arguments.createMap().apply {
191
- putString("event", event.name)
120
+ putString("event", event.name.toString())
192
121
  putString("data", (data as SDKEkycResult).nfcResponse)
193
122
  }
194
123
  sendEvent("onNfcScanSuccess", eventMap)
195
124
  val promiseMap =
196
125
  Arguments.createMap().apply {
197
- putString("event", event.name)
126
+ putString("event", event.name.toString())
198
127
  putString("data", (data as SDKEkycResult).nfcResponse)
199
128
  }
200
129
  promise.resolve(promiseMap)
@@ -203,7 +132,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
203
132
  else -> {
204
133
  val eventMap =
205
134
  Arguments.createMap().apply {
206
- putString("event", event.name)
135
+ putString("event", event.name.toString())
207
136
  putString("data", data.toString())
208
137
  }
209
138
  sendEvent("onNfcEvent", eventMap)
@@ -215,12 +144,12 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
215
144
 
216
145
  val errorMap =
217
146
  Arguments.createMap().apply {
218
- putString("event", event.name)
219
- putString("message", message ?: "Unknown error")
147
+ putString("event", event.name.toString())
148
+ putString("message", message?.toString() ?: "Unknown error")
220
149
  }
221
150
 
222
151
  sendEvent("onNfcError", errorMap)
223
- promise.reject(event.name, message ?: "Unknown NFC error")
152
+ promise.reject(event.name.toString(), message?.toString() ?: "Unknown NFC error")
224
153
  }
225
154
  )
226
155
  Log.d(TAG, "startNfcScan:::222222")
@@ -248,22 +177,23 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
248
177
  recentLocation = recentLocation
249
178
  )
250
179
 
251
- val ekycConfig = EKYCConfigSDK(appKey = appKey, c06Config = c06Config)
180
+ val ekycConfig = EKYCConfigSDK(appKey = AppKeyConfig(appKey), c06Config = c06Config)
252
181
 
253
182
  SdkEkycC06.startEkyc(
254
183
  ekycConfigSDK = ekycConfig,
255
184
  callbackSuccess = { event, data ->
256
185
  Log.d(TAG, "C06 Success - Event: $event, Data: $data")
257
186
 
187
+ // Create separate maps for event and promise
258
188
  val eventMap =
259
189
  Arguments.createMap().apply {
260
- putString("event", event.name)
190
+ putString("event", event.name.toString())
261
191
  putString("data", data.toString())
262
192
  }
263
193
 
264
194
  val promiseMap =
265
195
  Arguments.createMap().apply {
266
- putString("event", event.name)
196
+ putString("event", event.name.toString())
267
197
  putString("data", data.toString())
268
198
  }
269
199
  sendEvent("onC06Success", eventMap)
@@ -274,12 +204,12 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
274
204
 
275
205
  val errorMap =
276
206
  Arguments.createMap().apply {
277
- putString("event", event.name)
278
- putString("message", message ?: "Unknown error")
207
+ putString("event", event.name.toString())
208
+ putString("message", message?.toString() ?: "Unknown error")
279
209
  }
280
210
 
281
211
  sendEvent("onC06Error", errorMap)
282
- promise.reject(event.name, message ?: "Unknown C06 error")
212
+ promise.reject(event.name.toString(), message?.toString() ?: "Unknown C06 error")
283
213
  }
284
214
  )
285
215
  } catch (e: Exception) {
@@ -315,14 +245,14 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
315
245
  transactionId = transactionId
316
246
  )
317
247
  val ekycConfig =
318
- EKYCConfigSDK(appKey = appKey, sdkType = SDKType.OCR, ocrConfig = ocrConfig)
248
+ EKYCConfigSDK(appKey = AppKeyConfig(appKey), sdkType = SDKType.OCR, ocrConfig = ocrConfig)
319
249
  SdkEkycOcr.startEkyc(
320
250
  ekycConfigSDK = ekycConfig,
321
251
  callbackSuccess = { event, data ->
322
252
  Log.d(TAG, "OCR Success - Event: $event, Data: $data")
323
253
  val resultMap =
324
254
  Arguments.createMap().apply {
325
- putString("event", event.name)
255
+ putString("event", event.name.toString())
326
256
  putString(
327
257
  "data",
328
258
  (data as SDKEkycResult).ocrResponse.toString()
@@ -331,7 +261,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
331
261
  sendEvent("onOcrSuccess", resultMap)
332
262
  val promiseMap =
333
263
  Arguments.createMap().apply {
334
- putString("event", event.name)
264
+ putString("event", event.name.toString())
335
265
  putString(
336
266
  "data",
337
267
  (data as SDKEkycResult).ocrResponse.toString()
@@ -343,11 +273,11 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
343
273
  Log.e(TAG, "OCR Error - Event: $event, Message: $message")
344
274
  val errorMap =
345
275
  Arguments.createMap().apply {
346
- putString("event", event.name)
347
- putString("message", message ?: "Unknown error")
276
+ putString("event", event.name.toString())
277
+ putString("message", message?.toString() ?: "Unknown error")
348
278
  }
349
279
  sendEvent("onOcrError", errorMap)
350
- promise.reject(event.name, message ?: "Unknown OCR error")
280
+ promise.reject(event.name.toString(), message?.toString() ?: "Unknown OCR error")
351
281
  }
352
282
  )
353
283
  } catch (e: Exception) {
@@ -386,8 +316,8 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
386
316
  )
387
317
  val ekycConfig =
388
318
  EKYCConfigSDK(
389
- appKey = appKey,
390
- sdkType = SDKType.LIVE_NESS,
319
+ appKey = AppKeyConfig(appKey),
320
+ sdkType = SDKType.LIVENESS,
391
321
  livenessConfig = livenessConfig
392
322
  )
393
323
  SdkEkycLiveness.startEkyc(
@@ -396,7 +326,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
396
326
  Log.d(TAG, "Liveness Success - Event: $event, Data: $data")
397
327
  val resultMap =
398
328
  Arguments.createMap().apply {
399
- putString("event", event.name)
329
+ putString("event", event.name.toString())
400
330
  putString(
401
331
  "data",
402
332
  (data as SDKEkycResult).checkLivenessResponse.toString()
@@ -405,7 +335,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
405
335
  sendEvent("onLivenessSuccess", resultMap)
406
336
  val promiseMap =
407
337
  Arguments.createMap().apply {
408
- putString("event", event.name)
338
+ putString("event", event.name.toString())
409
339
  putString(
410
340
  "data",
411
341
  (data as SDKEkycResult).checkLivenessResponse.toString()
@@ -417,11 +347,11 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
417
347
  Log.e(TAG, "Liveness Error - Event: $event, Message: $message")
418
348
  val errorMap =
419
349
  Arguments.createMap().apply {
420
- putString("event", event.name)
421
- putString("message", message ?: "Unknown error")
350
+ putString("event", event.name.toString())
351
+ putString("message", message?.toString() ?: "Unknown error")
422
352
  }
423
353
  sendEvent("onLivenessError", errorMap)
424
- promise.reject(event.name, message ?: "Unknown Liveness error")
354
+ promise.reject(event.name.toString(), message?.toString() ?: "Unknown Liveness error")
425
355
  }
426
356
  )
427
357
  } catch (e: Exception) {
@@ -453,7 +383,6 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
453
383
 
454
384
  val faceServiceConfig =
455
385
  FaceServiceConfig(
456
- appKey = appKey,
457
386
  transactionId = transactionId,
458
387
  selfieImage = imageFile,
459
388
  idImage = idImageFile
@@ -465,13 +394,13 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
465
394
  Log.d(TAG, "Face Compare Success - Event: $event, Data: $data")
466
395
  val resultMap =
467
396
  Arguments.createMap().apply {
468
- putString("event", event.name)
397
+ putString("event", event.name.toString())
469
398
  putString("data", data.toString())
470
399
  }
471
400
  sendEvent("onFaceCompareSuccess", resultMap)
472
401
  val promiseMap =
473
402
  Arguments.createMap().apply {
474
- putString("event", event.name)
403
+ putString("event", event.name.toString())
475
404
  putString("data", data.toString())
476
405
  }
477
406
  promise.resolve(promiseMap)
@@ -480,11 +409,11 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
480
409
  Log.e(TAG, "FaceService Error - Event: $event, Message: $message")
481
410
  val errorMap =
482
411
  Arguments.createMap().apply {
483
- putString("event", event.name)
484
- putString("message", message ?: "Unknown error")
412
+ putString("event", event.name.toString())
413
+ putString("message", message?.toString() ?: "Unknown error")
485
414
  }
486
415
  sendEvent("onFaceCompareError", errorMap)
487
- promise.reject(event.name, message ?: "Unknown FaceService error")
416
+ promise.reject(event.name.toString(), message?.toString() ?: "Unknown FaceService error")
488
417
  }
489
418
  )
490
419
  } catch (e: Exception) {
@@ -516,26 +445,332 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
516
445
 
517
446
  private fun base64ToImageFile(base64Image: String): File {
518
447
  try {
448
+ // Remove data URI prefix if present (like "data:image/png;base64,")
519
449
  var processedBase64 = base64Image
520
450
  if (base64Image.contains(",")) {
521
451
  processedBase64 = base64Image.split(",")[1]
522
452
  }
523
453
 
454
+ // Decode base64 string to bytes
524
455
  val bytes = Base64.decode(processedBase64, Base64.DEFAULT)
456
+
457
+ // Create a unique filename with timestamp
525
458
  val timestamp = Date().time.toString()
526
459
  val fileName = "image_$timestamp.jpg"
460
+
461
+ // Get temporary directory and create file path
527
462
  val directory = reactApplicationContext.cacheDir
528
463
  val filePath = "${directory.path}/$fileName"
464
+
465
+ // Write bytes to file
529
466
  val imageFile = File(filePath)
530
467
  FileOutputStream(imageFile).use { it.write(bytes) }
468
+
531
469
  return imageFile
532
470
  } catch (e: Exception) {
533
471
  Log.e("LivenessFragment", "Error converting base64 to image file: ${e.message}", e)
472
+ // In case of error, create an empty file to avoid null returns
534
473
  val errorFile = File(reactApplicationContext.cacheDir, "error_image_${Date().time}.jpg")
535
474
  errorFile.createNewFile()
536
475
  return errorFile
537
476
  }
538
477
  }
539
- }
540
478
 
479
+ @ReactMethod
480
+ fun startEkycUI(
481
+ appKey: String,
482
+ flowSDK: String, // JSON string array like "[\"OCR\", \"NFC\", \"LIVENESS\"]"
483
+ language: String,
484
+ transactionId: String,
485
+ optionConfigJson: String, // JSON string for option config
486
+ appKeyConfigJson: String, // JSON string for app key config
487
+ styleConfigJson: String, // JSON string for style config
488
+ promise: Promise
489
+ ) {
490
+ try {
491
+ val currentActivity = currentActivity
492
+ if (currentActivity == null) {
493
+ promise.reject("NO_ACTIVITY", "Activity not available")
494
+ return
495
+ }
496
+
497
+ Log.d(TAG, "startEkycUI: appKey=$appKey, flowSDK=$flowSDK, language=$language, optionConfig=$optionConfigJson, appKeyConfig=$appKeyConfigJson, styleConfig=$styleConfigJson")
498
+
499
+ // Parse flowSDK JSON string to List<SDKType>
500
+ val flowList = parseFlowSDK(flowSDK)
501
+
502
+ // Use default flow if empty like MainActivity.kt startWithFlow
503
+ val finalFlow = if (flowList.isEmpty()) {
504
+ listOf(SDKType.OCR, SDKType.NFC, SDKType.LIVENESS)
505
+ } else {
506
+ flowList
507
+ }
508
+
509
+ // Parse OptionConfig JSON
510
+ val optionConfig = parseOptionConfig(optionConfigJson)
511
+
512
+ // Parse AppKeyConfig JSON from React Native
513
+ val appKeyConfig = parseAppKeyConfig(appKeyConfigJson)
514
+
515
+ // Parse StyleConfig JSON from React Native
516
+ val styleConfig = parseStyleConfig(styleConfigJson)
517
+
518
+ // Create EKYCConfigSDK like MainActivity.kt
519
+ val ekycConfigSDK = EKYCConfigSDK(
520
+ appKey = appKeyConfig,
521
+ optionConfig = optionConfig.copy(language = if (language == "en") "en" else "vi"),
522
+ styleConfig = styleConfig,
523
+ appIDType = AppIDType.VIKKI,
524
+ flowSDK = finalFlow
525
+ )
526
+
527
+ // Use actual SdkEkycUI.startEkyc like MainActivity.kt
528
+ Log.d(TAG, "Starting SdkEkycUI.startEkyc with config: $ekycConfigSDK")
529
+
530
+ SdkEkycUI.startEkyc(
531
+ activity = currentActivity,
532
+ ekycConfigSDK = ekycConfigSDK,
533
+ callbackSuccess = { event, data ->
534
+ Log.d(TAG, "eKYC UI Success - Event: $event, Data: $data")
535
+ val resultMap = Arguments.createMap().apply {
536
+ putString("status", "success")
537
+ putString("event", event.name.toString())
538
+ putString("data", data.toString())
539
+ }
540
+ val eventMap = Arguments.createMap().apply {
541
+ putString("status", "success")
542
+ putString("event", event.name.toString())
543
+ putString("data", data.toString())
544
+ }
545
+ sendEvent("onEkycUISuccess", eventMap)
546
+ promise.resolve(resultMap)
547
+ },
548
+ callbackError = { event, errorResult ->
549
+ Log.e(TAG, "eKYC UI Error - Event: $event, ErrorResult: $errorResult")
550
+ val errorMap = Arguments.createMap().apply {
551
+ putString("status", "error")
552
+ putString("event", event.name.toString())
553
+ putString("message", errorResult.message)
554
+ putString("errorCode", errorResult.toString())
555
+ }
556
+ val promiseErrorMap = Arguments.createMap().apply {
557
+ putString("status", "error")
558
+ putString("event", event.name.toString())
559
+ putString("message", errorResult.message)
560
+ putString("errorCode", errorResult.toString())
561
+ }
562
+ sendEvent("onEkycUIError", errorMap)
563
+ promise.reject(event.name.toString(), errorResult.message, Throwable(errorResult.message), promiseErrorMap)
564
+ }
565
+ )
566
+
567
+ } catch (e: Exception) {
568
+ Log.e(TAG, "Exception in startEkycUI: ${e.message}", e)
569
+ promise.reject("EKYC_UI_EXCEPTION", e.message, e)
570
+ }
571
+ }
572
+
573
+ private fun parseFlowSDK(flowSDKJson: String): List<SDKType> {
574
+ return try {
575
+ // Simple parsing for JSON array like ["OCR", "NFC", "LIVENESS"]
576
+ val cleanJson = flowSDKJson.replace("[", "").replace("]", "").replace("\"", "")
577
+ val flowArray = cleanJson.split(",").map { it.trim() }
578
+
579
+ flowArray.mapNotNull { sdkType ->
580
+ when (sdkType) {
581
+ "OCR" -> SDKType.OCR
582
+ "NFC" -> SDKType.NFC
583
+ "LIVENESS" -> SDKType.LIVENESS
584
+ else -> null
585
+ }
586
+ }
587
+ } catch (e: Exception) {
588
+ Log.e(TAG, "Error parsing flowSDK: ${e.message}", e)
589
+ // Default flow
590
+ listOf(SDKType.OCR, SDKType.NFC, SDKType.LIVENESS)
591
+ }
592
+ }
593
+
594
+ private fun parseOptionConfig(optionConfigJson: String): OptionConfig {
595
+ return try {
596
+ if (optionConfigJson.isBlank() || optionConfigJson == "{}") {
597
+ // Return default values based on demo OptionConfig.kt
598
+ OptionConfig(
599
+ baseUrl = null,
600
+ countMaxRetry = 3,
601
+ language = null
602
+ )
603
+ } else {
604
+ // Simple JSON parsing (in real implementation, use proper JSON library)
605
+ val baseUrl = extractStringValue(optionConfigJson, "baseUrl")
606
+ val countMaxRetry = extractIntValue(optionConfigJson, "countMaxRetry") ?: 3
607
+ val language = extractStringValue(optionConfigJson, "language")
608
+
609
+ OptionConfig(
610
+ baseUrl = baseUrl,
611
+ countMaxRetry = countMaxRetry,
612
+ language = language
613
+ )
614
+ }
615
+ } catch (e: Exception) {
616
+ Log.e(TAG, "Error parsing optionConfig: ${e.message}", e)
617
+ // Return default values
618
+ OptionConfig(
619
+ baseUrl = null,
620
+ countMaxRetry = 3,
621
+ language = null
622
+ )
623
+ }
624
+ }
625
+
626
+ private fun extractIntValue(json: String, key: String): Int? {
627
+ return try {
628
+ val pattern = "\"$key\"\\s*:\\s*(\\d+)".toRegex()
629
+ val match = pattern.find(json)
630
+ match?.groupValues?.get(1)?.toInt()
631
+ } catch (e: Exception) {
632
+ null
633
+ }
634
+ }
635
+
636
+ private fun extractBooleanValue(json: String, key: String): Boolean? {
637
+ return try {
638
+ val pattern = "\"$key\"\\s*:\\s*(true|false)".toRegex()
639
+ val match = pattern.find(json)
640
+ match?.groupValues?.get(1)?.toBoolean()
641
+ } catch (e: Exception) {
642
+ null
643
+ }
644
+ }
645
+
646
+ private fun parseAppKeyConfig(appKeyConfigJson: String): AppKeyConfig {
647
+ return try {
648
+ if (appKeyConfigJson.isBlank() || appKeyConfigJson == "{}") {
649
+ throw IllegalArgumentException("appKeyConfig is required and cannot be empty")
650
+ }
651
+
652
+ // Simple JSON parsing (in real implementation, use proper JSON library)
653
+ val appKey = extractStringValue(appKeyConfigJson, "appKey")
654
+ ?: throw IllegalArgumentException("appKey is required in appKeyConfig")
655
+ val appKeyNfc = extractStringValue(appKeyConfigJson, "appKeyNfc")
656
+ ?: throw IllegalArgumentException("appKeyNfc is required in appKeyConfig")
657
+ val appKeyOcr = extractStringValue(appKeyConfigJson, "appKeyOcr")
658
+ ?: throw IllegalArgumentException("appKeyOcr is required in appKeyConfig")
659
+ val appKeyLiveness = extractStringValue(appKeyConfigJson, "appKeyLiveness")
660
+ ?: throw IllegalArgumentException("appKeyLiveness is required in appKeyConfig")
661
+ val appKeyC06 = extractStringValue(appKeyConfigJson, "appKeyC06")
662
+ ?: throw IllegalArgumentException("appKeyC06 is required in appKeyConfig")
663
+ val appKeyFaceService = extractStringValue(appKeyConfigJson, "appKeyFaceService")
664
+ ?: throw IllegalArgumentException("appKeyFaceService is required in appKeyConfig")
665
+
666
+ AppKeyConfig(
667
+ appKey = appKey,
668
+ appKeyNfc = appKeyNfc,
669
+ appKeyOcr = appKeyOcr,
670
+ appKeyLiveness = appKeyLiveness,
671
+ appKeyC06 = appKeyC06,
672
+ appKeyFaceService = appKeyFaceService
673
+ )
674
+ } catch (e: Exception) {
675
+ Log.e(TAG, "Error parsing appKeyConfig: ${e.message}", e)
676
+ throw IllegalArgumentException("Invalid appKeyConfig: ${e.message}")
677
+ }
678
+ }
679
+
680
+ private fun parseStyleConfig(styleConfigJson: String): StyleConfig {
681
+ return try {
682
+ if (styleConfigJson.isBlank() || styleConfigJson == "{}") {
683
+ // Return default StyleConfig based on demo StyleConfig.kt
684
+ StyleConfig(
685
+ textSize = 14,
686
+ textFont = "",
687
+ textColor = R.color.black,
688
+ statusBarBackground = null,
689
+ backIcon = null,
690
+ titleStyle = null,
691
+ toolbarStyle = null,
692
+ instructionStyle = null,
693
+ errorStyle = null,
694
+ successStyle = null,
695
+ warningStyle = null
696
+ )
697
+ } else {
698
+ // Parse StyleConfig JSON based on demo StyleConfig.kt structure
699
+ val textSize = extractIntValue(styleConfigJson, "textSize") ?: 14
700
+ val textFont = extractStringValue(styleConfigJson, "textFont") ?: ""
701
+ val textColor = extractIntValue(styleConfigJson, "textColor") ?: R.color.black
702
+
703
+ // Parse TextStyle objects
704
+ val titleStyle = parseTextStyle(styleConfigJson, "titleStyle")
705
+ val toolbarStyle = parseTextStyle(styleConfigJson, "toolbarStyle")
706
+ val instructionStyle = parseTextStyle(styleConfigJson, "instructionStyle")
707
+ val errorStyle = parseTextStyle(styleConfigJson, "errorStyle")
708
+ val successStyle = parseTextStyle(styleConfigJson, "successStyle")
709
+ val warningStyle = parseTextStyle(styleConfigJson, "warningStyle")
710
+
711
+ StyleConfig(
712
+ textSize = textSize,
713
+ textFont = textFont,
714
+ textColor = textColor,
715
+ statusBarBackground = null, // sdkui resources not available
716
+ backIcon = null, // sdkui resources not available
717
+ titleStyle = titleStyle,
718
+ toolbarStyle = toolbarStyle,
719
+ instructionStyle = instructionStyle,
720
+ errorStyle = errorStyle,
721
+ successStyle = successStyle,
722
+ warningStyle = warningStyle
723
+ )
724
+ }
725
+ } catch (e: Exception) {
726
+ Log.e(TAG, "Error parsing styleConfig: ${e.message}", e)
727
+ // Return default values
728
+ StyleConfig(
729
+ textSize = 14,
730
+ textFont = "",
731
+ textColor = R.color.black,
732
+ statusBarBackground = null,
733
+ backIcon = null,
734
+ titleStyle = null,
735
+ toolbarStyle = null,
736
+ instructionStyle = null,
737
+ errorStyle = null,
738
+ successStyle = null,
739
+ warningStyle = null
740
+ )
741
+ }
742
+ }
541
743
 
744
+ private fun parseTextStyle(styleConfigJson: String, styleKey: String): StyleConfig.TextStyle? {
745
+ return try {
746
+ // Simple extraction for nested TextStyle objects
747
+ val textSize = extractIntValue(styleConfigJson, "${styleKey}.textSize")
748
+ val textFont = extractStringValue(styleConfigJson, "${styleKey}.textFont")
749
+ val textColor = extractIntValue(styleConfigJson, "${styleKey}.textColor")
750
+
751
+ if (textSize != null || textFont != null || textColor != null) {
752
+ StyleConfig.TextStyle(
753
+ textSize = textSize,
754
+ textFont = textFont,
755
+ textColor = textColor
756
+ )
757
+ } else {
758
+ null
759
+ }
760
+ } catch (e: Exception) {
761
+ Log.e(TAG, "Error parsing TextStyle for $styleKey: ${e.message}", e)
762
+ null
763
+ }
764
+ }
765
+
766
+ private fun extractStringValue(json: String, key: String): String? {
767
+ return try {
768
+ val pattern = "\"$key\"\\s*:\\s*\"([^\"]+)\"".toRegex()
769
+ val match = pattern.find(json)
770
+ match?.groupValues?.get(1)
771
+ } catch (e: Exception) {
772
+ null
773
+ }
774
+ }
775
+
776
+ }
@@ -15,24 +15,4 @@ class EKYCPackage : ReactPackage {
15
15
  }
16
16
  }
17
17
 
18
- package finos.sdk.ekyc
19
-
20
- import com.facebook.react.ReactPackage
21
- import com.facebook.react.bridge.NativeModule
22
- import com.facebook.react.bridge.ReactApplicationContext
23
- import com.facebook.react.uimanager.ViewManager
24
-
25
- class EKYCPackage : ReactPackage {
26
-
27
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
28
- return listOf(EKYCModule(reactContext))
29
- }
30
-
31
- override fun createViewManagers(
32
- reactContext: ReactApplicationContext
33
- ): List<ViewManager<*, *>> {
34
- return emptyList()
35
- }
36
- }
37
-
38
18
 
@@ -5,7 +5,7 @@ import { C06Config } from './src/types/ekycC06Type';
5
5
  import { OcrConfig } from './src/types/ekycOCRType';
6
6
  import { LivenessConfig } from './src/types/ekycLivenessType';
7
7
  import { FaceServiceConfig } from './src/types/ekycFaceType';
8
- export declare const SDK_VERSION = "0.0.39";
8
+ export declare const SDK_VERSION = "0.0.40";
9
9
  export declare const SDK_NAME = "@finos_sdk/sdk-ekyc";
10
10
  declare class SDKeKYC {
11
11
  private eventEmitter;
@@ -3,18 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDKeKYC = exports.SDK_NAME = exports.SDK_VERSION = void 0;
4
4
  const react_native_1 = require("react-native");
5
5
  // Version information
6
- exports.SDK_VERSION = '0.0.39';
6
+ exports.SDK_VERSION = '0.0.40';
7
7
  exports.SDK_NAME = '@finos_sdk/sdk-ekyc';
8
8
  const EKYCNativeModule = react_native_1.NativeModules.EKYCModule;
9
9
  // Validate that the module is available
10
10
  if (!EKYCNativeModule) {
11
- throw new Error('EKYCModule is not available. Make sure you have:\n' +
12
- '1. Called SdkEkyc.initSDKEkyc() in native code\n' +
13
- '2. Properly registered EKYCModule in MainApplication.kt\n' +
14
- '3. Rebuilt your app completely\n' +
15
- '4. If the error persists, try cleaning build folders:\n' +
16
- ' - rm -rf android/app/build\n' +
17
- ' - cd android && ./gradlew clean');
11
+ throw new Error('EKYCModule is not available. This is likely an autolinking issue.\n' +
12
+ 'Please try:\n' +
13
+ '1. Clean and rebuild your app:\n' +
14
+ ' - rm -rf android/app/build android/build\n' +
15
+ ' - cd android && ./gradlew clean && cd ..\n' +
16
+ ' - npx react-native run-android\n' +
17
+ '2. If using manual linking, remove it and rely on autolinking\n' +
18
+ '3. Ensure you have the latest version: npm install @finos_sdk/sdk-ekyc@latest');
18
19
  }
19
20
  // Initialize the module with Koin error handling
20
21
  try {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@finos_sdk/sdk-ekyc",
3
- "version": "0.0.40",
4
- "description": "React Native SDK for eKYC (electronic Know Your Customer) - Vietnamese CCCD NFC reading, OCR, Liveness detection, Face matching, and C06 residence verification",
3
+ "version": "0.0.42",
4
+ "description": "React Native SDK for eKYC - Vietnamese CCCD NFC reading, OCR, Liveness detection, Face matching, and C06 residence verification",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [