@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.
|
|
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
|
|
package/dist/EKYCModule.d.ts
CHANGED
|
@@ -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.
|
|
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;
|
package/dist/EKYCModule.js
CHANGED
|
@@ -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.
|
|
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.
|
|
12
|
-
'
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
' -
|
|
17
|
-
'
|
|
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.
|
|
4
|
-
"description": "React Native SDK for eKYC
|
|
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": [
|