dojah-kyc-sdk-react_native 0.1.1 → 0.1.2

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.
package/README.md CHANGED
@@ -35,14 +35,6 @@ dependencyResolutionManagement {
35
35
  }
36
36
  ```
37
37
 
38
- ### Enable Jetifier
39
- Enable Jetifier in android/gradle.properties
40
-
41
- ```
42
- android.enableJetifier=true
43
- ```
44
-
45
-
46
38
  ### Permissions
47
39
  For Android you don't need to declare permissions, its already included in the Package.
48
40
 
@@ -133,8 +125,8 @@ To start KYC, import Dojah in your React Native code, and launch Dojah Screen
133
125
  import {launchDojahKyc } from 'dojah-kyc-sdk-react_native';
134
126
 
135
127
 
136
- /**
137
- * The following parameters are available
128
+ /**
129
+ * The following parameters are available
138
130
  * for launching the flow.
139
131
  */
140
132
 
@@ -213,11 +205,11 @@ const metadata = {
213
205
  key2: 'value2'
214
206
  };
215
207
 
216
- /**
217
- * to launch the flow only [widgetId] is mandatory
208
+ /**
209
+ * to launch the flow only [widgetId] is mandatory
218
210
  * @returns - the Promise of the result, promise
219
- * will return a status that you can use to track
220
- * the immidiate progress.
211
+ * will return a status that you can use to track
212
+ * the immidiate progress.
221
213
  * @throws - an error if the Dojah KYC flow fails
222
214
  */
223
215
  launchDojahKyc(
@@ -258,7 +250,6 @@ launchDojahKyc(
258
250
  - `WidgetID` - a `REQUIRED` parameter. You get this ID when you sign up on the Dojah platform, follow the next step to generate your WidgetId.
259
251
  - `Reference ID` - an `OPTIONAL` parameter that allows you to initialize the SDK for an ongoing verification.
260
252
  - `Email Address` - an `OPTIONAL` parameter that allows you to initialize the SDK for an ongoing verification.
261
- - `ExtraUserData` - an `OPTIONAL` parameter that allows you to pass custom data to the SDK.
262
253
 
263
254
  ## How to Get a Widget ID
264
255
  To use the SDK, you need a WidgetID, which is a required parameter for initializing the SDK. You can obtain this by creating a flow on the Dojah platform. Follow these steps to configure and get your Widget ID:
@@ -289,113 +280,3 @@ To use the SDK, you need a WidgetID, which is a required parameter for initializ
289
280
 
290
281
  7. Copy Your Widget ID: After publishing, the platform will generate a Widget ID. Copy this Widget ID as you will need it to initialize the SDK as stated above.
291
282
  ```
292
-
293
-
294
- ## TroubleShooting
295
-
296
- ### Android ProGuard/R8 Configuration for Release Builds
297
- When building your Android application in release mode with code shrinking (R8/ProGuard) enabled, you might encounter issues where the SDK or its dependencies fail to function correctly. This happens because R8, the default code shrinker, might remove classes or methods that are used by the SDK but aren't explicitly referenced in a way R8 can detect.
298
-
299
- If you experience crashes or unexpected behavior related to missing classes (often indicated by errors like ClassNotFoundException or Missing classes detected while running R8), you'll need to add specific "keep" rules to your project's ProGuard configuration.
300
-
301
- ### How to Apply ProGuard Rules
302
-
303
- Locate your ProGuard file: In your Flutter project, navigate to android/app/proguard-rules.pro. If this file doesn't exist, create it.
304
-
305
- Add the necessary rules: Open the proguard-rules.pro file and add the following lines. These rules instruct R8 to preserve the essential components of the Dojah SDK and its underlying libraries during the build process.
306
-
307
- ```
308
- # These are essential for React Native's internal mechanisms and module linking.
309
- -keepclassmembers class com.facebook.react.bridge.JavaModule$$Props { *; }
310
- -keepclassmembers class com.facebook.react.bridge.ModuleSpec { *; }
311
- -keepclassmembers class * implements com.facebook.react.bridge.JavaScriptModule { *; }
312
- -keepclassmembers class * implements com.facebook.react.bridge.NativeModule { *; }
313
-
314
- # Prevents the stripping of unused methods in classes that are accessed dynamically.
315
- -keep public class * extends com.facebook.react.bridge.ViewManager { *; }
316
- -keep public class * extends com.facebook.react.uimanager.ViewManager { *; } # Older versions might use this
317
-
318
- # Keep React Native module classes and their constructors.
319
- # This is crucial for autolinking and manual linking.
320
- -keep class * implements com.facebook.react.bridge.NativeModule {
321
- <init>(...);
322
- }
323
- -keep class * extends com.facebook.react.bridge.BaseJavaModule {
324
- <init>(...);
325
- }
326
- -keep class * extends com.facebook.react.uimanager.ViewManager {
327
- <init>(...);
328
- }
329
-
330
- # Standard dontwarn rules for common React Native dependencies
331
- -dontwarn com.facebook.react.**
332
- -dontwarn com.facebook.jni.**
333
- -dontwarn com.facebook.soloader.**
334
- -dontwarn com.facebook.yoga.**
335
- -dontwarn javax.annotation.**
336
-
337
- # Keep gRPC-related classes
338
- -keep class io.grpc.** { *; }
339
- -keep class com.google.android.libraries.places.** { *; }
340
-
341
-
342
- -keepnames class io.grpc.internal.**
343
- -keepclassmembers class io.grpc.internal.** { *; }
344
- -dontwarn io.grpc.**
345
-
346
-
347
- -keep class com.dojah.kyc_sdk_kotlin.domain.** { *; }
348
- -keep class com.dojah.kyc_sdk_kotlin.core.Result
349
-
350
- #For retrofit
351
- -keepattributes Signature, InnerClasses, EnclosingMethod
352
- -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
353
- -keepattributes AnnotationDefault
354
- -keepclassmembers,allowshrinking,allowobfuscation interface * {
355
- @retrofit2.http.* <methods>;
356
- }
357
- -dontwarn javax.annotation.**
358
- -dontwarn kotlin.Unit
359
- -dontwarn retrofit2.KotlinExtensions
360
- -dontwarn retrofit2.KotlinExtensions$*
361
- -if interface * { @retrofit2.http.* <methods>; }
362
- -keep,allowobfuscation interface <1>
363
- -keep,allowobfuscation,allowshrinking interface retrofit2.Call
364
- -keep,allowobfuscation,allowshrinking class retrofit2.Response
365
- -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
366
-
367
- #For Okio
368
- -dontwarn org.codehaus.mojo.animal_sniffer.*
369
-
370
- #For Gson
371
- -keep class sun.misc.Unsafe { *; }
372
- -keep class com.google.gson.examples.android.model.** { *; }
373
-
374
- #For Glide
375
- -keep public class * implements com.bumptech.glide.module.GlideModule
376
- -keep class * extends com.bumptech.glide.module.AppGlideModule {
377
- <init>(...);
378
- }
379
- -keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
380
- **[] $VALUES;
381
- public *;
382
- }
383
- -keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder {
384
- *** rewind();
385
- }
386
- ```
387
-
388
- Ensure ProGuard is enabled: Verify that proguardFiles is pointing to the default Android ProGuard rules and your custom proguard-rules.pro file. This tells R8 to use your added rules.
389
- Your release build type block should look similar to this:
390
-
391
- ``` groovy
392
- android {
393
- buildTypes {
394
- release {
395
- // ... other configurations like signingConfig
396
- minifyEnabled true
397
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
398
- }
399
- }
400
- }
401
- ```
@@ -55,7 +55,7 @@ def supportsNamespace() {
55
55
 
56
56
  android {
57
57
  if (supportsNamespace()) {
58
- namespace "com.dojahkyc.rn"
58
+ namespace "com.dojahkyc"
59
59
 
60
60
  sourceSets {
61
61
  main {
@@ -74,8 +74,6 @@ android {
74
74
 
75
75
  buildTypes {
76
76
  release {
77
- proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
78
-
79
77
  minifyEnabled true
80
78
  }
81
79
  }
@@ -107,8 +105,8 @@ dependencies {
107
105
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
108
106
 
109
107
  // implementation 'com.github.dojah-inc:sdk-kotlin:v0.0.1-dev'
110
- implementation 'com.github.dojah-inc:sdk-kotlin:v0.1.3-dev'
111
-
108
+ // implementation 'com.github.dojah-inc:sdk-kotlin:v0.0.4-dev'
109
+ implementation 'com.github.dojah-inc:sdk-kotlin:v0.2.0'
112
110
 
113
111
  }
114
112
 
@@ -1,3 +1,3 @@
1
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
- package="com.dojahkyc.rn">
2
+ package="com.dojahkyc">
3
3
  </manifest>
@@ -1,7 +1,9 @@
1
- package com.dojahkyc.rn
1
+ package com.dojahkyc
2
2
 
3
3
  import android.app.Activity
4
+ import android.app.Activity.RESULT_OK
4
5
  import android.content.Intent
6
+ import android.widget.Toast
5
7
  import com.dojah.kyc_sdk_kotlin.DojahSdk
6
8
  import com.dojah.kyc_sdk_kotlin.DOJAH_RESULT_KEY
7
9
  // import com.dojah.kyc_sdk_kotlin.BACKWARD_CALL_REQUEST_CODE
@@ -13,6 +15,9 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
13
15
  import com.facebook.react.bridge.ReactMethod
14
16
  import com.facebook.react.bridge.WritableMap
15
17
  import com.facebook.react.bridge.WritableNativeMap
18
+ import androidx.activity.result.ActivityResult
19
+ import androidx.activity.result.ActivityResultLauncher
20
+ import androidx.activity.result.contract.ActivityResultContracts
16
21
  import com.facebook.react.bridge.ReadableMap
17
22
  import com.dojah.kyc_sdk_kotlin.domain.UserData
18
23
  import com.dojah.kyc_sdk_kotlin.domain.GovData
@@ -41,13 +46,7 @@ class DojahKycModule(private val reactContext: ReactApplicationContext) :
41
46
  widgetId: String,
42
47
  referenceId: String? = null,
43
48
  email: String? = null,
44
- userData: ReadableMap? = null,
45
- govData: ReadableMap? = null,
46
- govId: ReadableMap? = null,
47
- location: ReadableMap? = null,
48
- businessData: ReadableMap? = null,
49
- address: String? = null,
50
- metadata: ReadableMap? = null,
49
+ extraData: ReadableMap? = null,
51
50
  promise: Promise
52
51
  ) {
53
52
  val activity = currentActivity
@@ -58,6 +57,15 @@ class DojahKycModule(private val reactContext: ReactApplicationContext) :
58
57
  }
59
58
  this.promise = promise
60
59
  try {
60
+ // Extract individual data from extraData object
61
+ val userData = extraData?.getMap("userData")
62
+ val govData = extraData?.getMap("govData")
63
+ val govId = extraData?.getMap("govId")
64
+ val location = extraData?.getMap("location")
65
+ val businessData = extraData?.getMap("businessData")
66
+ val address = extraData?.getString("address")
67
+ val metadata = extraData?.getMap("metadata")
68
+
61
69
  DojahSdk.with(reactContext)
62
70
  .launchWithBackwardCompatibility(activity, widgetId, referenceId, email, extraData = ExtraUserData(
63
71
  userData = UserData(
@@ -94,7 +102,7 @@ class DojahKycModule(private val reactContext: ReactApplicationContext) :
94
102
  // this.promise.reject("LAUNCH_ERROR", e.message, e)
95
103
  // this.promise = null
96
104
  }
97
-
105
+
98
106
  }
99
107
 
100
108
 
@@ -109,7 +117,7 @@ class DojahKycModule(private val reactContext: ReactApplicationContext) :
109
117
  }
110
118
 
111
119
 
112
- override fun onActivityResult(activity:Activity?,requestCode: Int, resultCode: Int, data: Intent?) {
120
+ override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
113
121
  if (requestCode == BACKWARD_CALL_REQUEST_CODE) {
114
122
  if (resultCode == Activity.RESULT_OK) {
115
123
  val result = data?.getStringExtra(DOJAH_RESULT_KEY)
@@ -121,7 +129,9 @@ class DojahKycModule(private val reactContext: ReactApplicationContext) :
121
129
  }
122
130
  }
123
131
 
124
- override fun onNewIntent(intent: Intent?) {
132
+ override fun onNewIntent(intent: Intent) {
133
+ // Intent is guaranteed to be non-null in React Native New Architecture
134
+ // No implementation needed for this use case
125
135
  }
126
136
 
127
137
  companion object {
@@ -1,4 +1,4 @@
1
- package com.dojahkyc.rn
1
+ package com.dojahkyc
2
2
 
3
3
  import com.facebook.react.ReactPackage
4
4
  import com.facebook.react.bridge.NativeModule
package/ios/DojahKyc.mm CHANGED
@@ -20,20 +20,13 @@
20
20
 
21
21
  RCT_EXTERN_METHOD(initialize:(NSString)appName)
22
22
 
23
- //launch:withReferenceId:withEmail:withUserData:withGovData:withGovId:withLocation:withBuisnessData:withAddress:withMetaData:resolver:rejecter:
24
- RCT_EXTERN_METHOD(
25
- launch:(NSString *)widgetId
26
- withReferenceId:(NSString *)referenceId
27
- withEmail:(NSString *)email
28
- withUserData:(NSDictionary *)userData
29
- withGovData:(NSDictionary *)govData
30
- withGovId:(NSDictionary *)govId
31
- withLocation:(NSDictionary *)location
32
- withBuisnessData:(NSDictionary *)businessData
33
- withAddress:(NSString *)address
34
- withMetaData:(NSDictionary *)metadata
35
- resolver:(RCTPromiseResolveBlock)resolve
36
- rejecter:(RCTPromiseRejectBlock)reject
37
- )
23
+
24
+ RCT_EXTERN_METHOD(launch:(NSString)widgetId withReferenceId:(id)referenceId withEmail:(id)email withExtraData:(id)extraData withResolver:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject)
25
+
26
+ + (BOOL)requiresMainQueueSetup
27
+ {
28
+ return NO;
29
+ }
30
+
38
31
  @end
39
32
 
@@ -1,81 +1,171 @@
1
-
2
1
  import UIKit
3
2
  import Foundation
4
3
  import DojahWidget
5
4
  import React
6
5
 
6
+ // Extension to convert dictionary to ExtraUserData (for React Native CLI compatibility)
7
+ extension Dictionary where Key == String, Value == Any {
8
+ func toExtraUserData() -> ExtraUserData {
9
+ let userDataDict = self["userData"] as? [String: Any]
10
+ let govDataDict = self["govData"] as? [String: Any]
11
+ let govIdDict = self["govId"] as? [String: Any]
12
+ let locationDict = self["location"] as? [String: Any]
13
+ let businessDataDict = self["businessData"] as? [String: Any]
14
+ let address = self["address"] as? String
15
+ let metadata = self["metadata"] as? [String: Any]
16
+
17
+ return ExtraUserData(
18
+ userData: UserBioData(
19
+ firstName: userDataDict?["firstName"] as? String,
20
+ lastName: userDataDict?["lastName"] as? String,
21
+ dob: userDataDict?["dob"] as? String,
22
+ email: userDataDict?["email"] as? String
23
+ ),
24
+ govData: ExtraGovData(
25
+ bvn: govDataDict?["bvn"] as? String,
26
+ dl: govDataDict?["dl"] as? String,
27
+ nin: govDataDict?["nin"] as? String,
28
+ vnin: govDataDict?["vnin"] as? String
29
+ ),
30
+ govId: ExtraGovIdData(
31
+ national: govIdDict?["national"] as? String,
32
+ passport: govIdDict?["passport"] as? String,
33
+ dl: govIdDict?["dl"] as? String,
34
+ voter: govIdDict?["voter"] as? String,
35
+ nin: govIdDict?["nin"] as? String,
36
+ others: govIdDict?["others"] as? String
37
+ ),
38
+ location: ExtraLocationData(
39
+ longitude: locationDict?["longitude"] as? String,
40
+ latitude: locationDict?["latitude"] as? String
41
+ ),
42
+ businessData: ExtraBusinessData(
43
+ cac: businessDataDict?["cac"] as? String
44
+ ),
45
+ address: address,
46
+ metadata: metadata
47
+ )
48
+ }
49
+ }
50
+
51
+
52
+ // Custom NavigationController that prevents duplicate presentations
53
+ class SafeDojahNavigationController: UINavigationController {
54
+ private var isPresenting = false
55
+
56
+ override func present(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)? = nil) {
57
+ // Check if we're already presenting something
58
+ if isPresenting {
59
+ print("⚠️ Already presenting, preventing duplicate: \(String(describing: type(of: viewControllerToPresent)))")
60
+ completion?()
61
+ return
62
+ }
63
+
64
+ // Check if this view controller is already in the navigation stack
65
+ if viewControllers.contains(where: {
66
+ type(of: $0) == type(of: viewControllerToPresent)
67
+ }) {
68
+ print("⚠️ ViewController already in navigation stack: \(String(describing: type(of: viewControllerToPresent)))")
69
+ completion?()
70
+ return
71
+ }
72
+
73
+ // Check if we're already presenting something
74
+ if presentedViewController != nil {
75
+ print("⚠️ NavigationController already has a presentedViewController")
76
+ completion?()
77
+ return
78
+ }
79
+
80
+ // Mark as presenting
81
+ isPresenting = true
82
+
83
+ // Call super to actually present
84
+ super.present(viewControllerToPresent, animated: animated) { [weak self] in
85
+ self?.isPresenting = false
86
+ completion?()
87
+ }
88
+ }
89
+
90
+ override func dismiss(animated: Bool, completion: (() -> Void)? = nil) {
91
+ isPresenting = false
92
+ super.dismiss(animated: animated, completion: completion)
93
+ }
94
+ }
7
95
 
8
96
  class DojahNavigationControllerDelegate: NSObject, UINavigationControllerDelegate {
9
97
  var onDidShow: (UIViewController) -> Void = { _ in }
98
+
10
99
  func navigationController(_ navigationController: UINavigationController,
11
100
  didShow viewController: UIViewController,
12
101
  animated: Bool) {
13
- print("Did show: \(viewController)")
102
+ print("📱 Did show: \(viewController)")
14
103
  onDidShow(viewController)
15
104
  }
16
-
17
- func navigationController(_ navigationController: UINavigationController,
18
- willShow viewController: UIViewController,
19
- animated: Bool) {
20
- print("Will show: \(viewController)")
21
- }
22
105
 
23
106
  func setOnDidShow(_ onDidShow: @escaping (UIViewController) -> Void) {
24
107
  self.onDidShow = onDidShow
25
108
  }
26
109
  }
27
110
 
111
+ class DojahPresentationControllerDelegate: NSObject, UIAdaptivePresentationControllerDelegate {
112
+ var onDidDismiss: () -> Void = { }
113
+
114
+ func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
115
+ print("🛑 Modal was dismissed manually")
116
+ onDidDismiss()
117
+ }
118
+
119
+ func setOnDidDismiss(_ onDidDismiss: @escaping () -> Void) {
120
+ self.onDidDismiss = onDidDismiss
121
+ }
122
+ }
123
+
28
124
  @objc(DojahKyc)
29
125
  class DojahKyc: RCTEventEmitter, RCTBridgeDelegate {
30
- @objc override static func requiresMainQueueSetup() -> Bool {
31
- return false
32
- }
33
-
34
- let navDelegate = DojahNavigationControllerDelegate()
35
-
36
- var navCtrl:UINavigationController? = nil
37
-
38
- var prevController:UIViewController? = nil
39
-
40
- override init() {
41
- super.init()
42
-
43
- DispatchQueue.main.async {
44
- self.navCtrl = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController
45
- if self.navCtrl != nil {
46
- self.navCtrl!.delegate = self.navDelegate
47
- }
48
- }
49
- }
50
-
51
- func sourceURL(for bridge: RCTBridge) -> URL? {
126
+
127
+ // Track Dojah state
128
+ private var isDojahActive = false
129
+ private var dojahNavController: SafeDojahNavigationController?
130
+ private var prevController: UIViewController? // Track previous controller for DJDisclaimer handling
131
+ private var hasSeenSDKInit = false // Track if we've seen SDKInitViewController before
132
+ private var navDelegate = DojahNavigationControllerDelegate()
133
+ private var presentationDelegate = DojahPresentationControllerDelegate()
134
+
135
+ func sourceURL(for bridge: RCTBridge) -> URL? {
52
136
  #if DEBUG
53
137
  return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index", fallbackExtension: nil)
54
138
  #else
55
139
  return Bundle.main.url(forResource: "main", withExtension: "jsbundle")!
56
140
  #endif
57
141
  }
58
-
59
-
142
+
60
143
  override var methodQueue: DispatchQueue {
61
144
  return DispatchQueue.main;
62
145
  }
63
-
64
-
146
+
147
+ override class func requiresMainQueueSetup() -> Bool {
148
+ return true;
149
+ }
150
+
151
+ override func supportedEvents() -> [String]! {
152
+ return ["onChange"]
153
+ }
154
+
65
155
  @objc(initialize:)
66
156
  func initialize(appName:String) -> Void {
67
157
  // Initialize the React Native bridge
68
158
  if let bridge = RCTBridge(delegate: self, launchOptions: nil) {
69
159
  // Create a React Native root view with the provided module name
70
160
  let rootView = RCTRootView(bridge: bridge, moduleName: appName, initialProperties: nil)
71
-
161
+
72
162
  // Create the initial view controller with the React Native view
73
163
  let rootViewController = UIViewController()
74
164
  rootViewController.view = rootView
75
-
165
+
76
166
  // Create a UINavigationController and set it as the window's rootViewController
77
167
  let navigationController = UINavigationController(rootViewController: rootViewController)
78
-
168
+
79
169
  // Set the window's rootViewController
80
170
  if let window = UIApplication.shared.delegate?.window {
81
171
  window?.rootViewController = navigationController
@@ -84,129 +174,283 @@ class DojahKyc: RCTEventEmitter, RCTBridgeDelegate {
84
174
  }else{
85
175
  print("bridge is null")
86
176
  }
87
-
88
-
89
177
  }
90
-
91
-
92
- @objc(launch:withReferenceId:withEmail:withUserData:withGovData:withGovId:withLocation:withBuisnessData:withAddress:withMetaData:resolver:rejecter:)
93
- func launch(
94
- _ widgetId:String,
95
- withReferenceId referenceId:String,
96
- withEmail email:String,
97
- withUserData userData : NSDictionary? = nil,
98
- withGovData govData: NSDictionary? = nil,
99
- withGovId govId: NSDictionary? = nil,
100
- withLocation location: NSDictionary? = nil,
101
- withBuisnessData businessData: NSDictionary? = nil,
102
- withAddress address: String = "",
103
- withMetaData metadata: NSDictionary? = nil,
104
- resolver resolve: @escaping RCTPromiseResolveBlock,
105
- rejecter reject: @escaping RCTPromiseRejectBlock
106
- ) {
107
- navDelegate.setOnDidShow { vc in
108
- print("onDidShow: \(vc)")
109
- //return result from DojahWidget once verification
110
- //is done,failed or cancel
111
- if(!String(describing:vc).contains("DojahWidget")){
112
- let vStatus = DojahWidgetSDK.getVerificationResultStatus()
113
- let status = if(vStatus.isEmpty){ "closed"} else {vStatus}
114
-
115
- resolve(status)
116
- print("resolve onDidShow: \(vc)")
117
-
118
-
119
- self.prevController = nil
120
- }else if(String(describing:vc).contains("DojahWidget.DJDisclaimer")
121
- && self.prevController != nil){
122
- self.navCtrl?.popToRootViewController(animated: false)
123
- }else if(!String(describing:vc).contains("DojahWidget.SDKInitViewController")){
124
- self.prevController = vc
178
+
179
+ private func getTopViewController() -> UIViewController? {
180
+ // Try multiple approaches to find the root view controller
181
+ // This handles React Native's window hierarchy setup
182
+
183
+ // Approach 1: Try window scene (iOS 13+)
184
+ if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
185
+ // Try the key window first
186
+ if let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }),
187
+ let rootViewController = keyWindow.rootViewController {
188
+ var topViewController = rootViewController
189
+ while let presentedViewController = topViewController.presentedViewController {
190
+ topViewController = presentedViewController
191
+ }
192
+ return topViewController
193
+ }
194
+
195
+ // Try any window with a root view controller
196
+ if let window = windowScene.windows.first(where: { $0.rootViewController != nil }),
197
+ let rootViewController = window.rootViewController {
198
+ var topViewController = rootViewController
199
+ while let presentedViewController = topViewController.presentedViewController {
200
+ topViewController = presentedViewController
201
+ }
202
+ return topViewController
125
203
  }
126
204
  }
127
-
128
-
129
- if(navCtrl != nil){
130
- do{
131
-
132
- DojahWidgetSDK.initialize(
133
- widgetID: widgetId,
134
- referenceID: referenceId,
135
- emailAddress: email,
136
- extraUserData: ExtraUserData(
137
- userData: mapToUserBioData(from: userData),
138
- govData: mapToExtraGovData(from: govData),
139
- govId: mapToExtraGovIdData(from: govId),
140
- location: mapToExtraLocationData(from: location),
141
- businessData: mapToExtraBusinessData(from: businessData),
142
- metadata: metadata as? [String : Any]
143
- ),
144
- navController: navCtrl!)
145
-
146
- }catch{
147
- reject("no-launch", "Could not launch Dojah Widget", error)
148
- }
149
- }else{
150
- reject("no-launch", "Could not launch Dojah Widget", nil)
151
- //throw error status to react native
152
- print("rootViewController is nil")
205
+
206
+ // Approach 2: Fallback to delegate's window (for older React Native setups)
207
+ if let delegate = UIApplication.shared.delegate,
208
+ let window = delegate.window,
209
+ let rootViewController = window?.rootViewController {
210
+ var topViewController = rootViewController
211
+ while let presentedViewController = topViewController.presentedViewController {
212
+ topViewController = presentedViewController
213
+ }
214
+ return topViewController
153
215
  }
216
+
217
+ print("⚠️ Could not find root view controller using any method")
218
+ return nil
154
219
  }
155
-
156
- }
157
-
158
-
159
-
160
- // Mapping functions for each sub-struct
161
- func mapToUserBioData(from dictionary: NSDictionary?) -> UserBioData? {
162
- guard let userData = dictionary else { return nil }
163
-
164
- return UserBioData(
165
- firstName: userData["first_name"] as? String,
166
- lastName: userData["last_name"] as? String,
167
- dob: userData["dob"] as? String,
168
- email: userData["email"] as? String
169
- )
170
- }
171
-
172
- func mapToExtraGovData(from dictionary: NSDictionary?) -> ExtraGovData? {
173
- guard let govData = dictionary else { return nil }
174
-
175
- return ExtraGovData(
176
- bvn: govData["bvn"] as? String,
177
- dl: govData["dl"] as? String,
178
- nin: govData["nin"] as? String,
179
- vnin: govData["vnin"] as? String
180
- )
181
- }
182
-
183
- func mapToExtraGovIdData(from dictionary: NSDictionary?) -> ExtraGovIdData? {
184
- guard let govId = dictionary else { return nil }
185
-
186
- return ExtraGovIdData(
187
- national: govId["national"] as? String,
188
- passport: govId["passport"] as? String,
189
- dl: govId["dl"] as? String,
190
- voter: govId["voter"] as? String,
191
- nin: govId["nin"] as? String,
192
- others: govId["others"] as? String
193
- )
194
- }
195
-
196
- func mapToExtraLocationData(from dictionary: NSDictionary?) -> ExtraLocationData? {
197
- guard let location = dictionary else { return nil }
198
220
 
199
- return ExtraLocationData(
200
- longitude: location["longitude"] as? String,
201
- latitude: location["latitude"] as? String
202
- )
203
- }
204
-
205
- func mapToExtraBusinessData(from dictionary: NSDictionary?) -> ExtraBusinessData? {
206
- guard let businessData = dictionary else { return nil }
221
+ private func resolveSdkResult() {
222
+ let vStatus = DojahWidgetSDK.getVerificationResultStatus()
223
+ let status = vStatus.isEmpty ? "closed" : vStatus
224
+
225
+ print("📊 Resolving SDK result: \(status)")
226
+
227
+ // Send event to React Native if bridge is valid
228
+ if self.bridge != nil && !self.bridge.isLoading {
229
+ self.sendEvent(withName: "onChange", body: ["status": status])
230
+ }
231
+
232
+ // Clear state
233
+ self.prevController = nil
234
+ self.hasSeenSDKInit = false
235
+
236
+ // Dismiss the navigation controller
237
+ self.dismissDojahController()
238
+
239
+ // Reset flag
240
+ self.isDojahActive = false
241
+ }
242
+
243
+ private func dismissDojahController() {
244
+ DispatchQueue.main.async { [weak self] in
245
+ self?.dojahNavController?.dismiss(animated: true) {
246
+ self?.dojahNavController = nil
247
+ }
248
+ }
249
+ }
207
250
 
208
- return ExtraBusinessData(
209
- cac: businessData["cac"] as? String
210
- )
251
+ @objc(launch:withReferenceId:withEmail:withExtraData:withResolver:withRejecter:)
252
+ func launch(
253
+ widgetId: String,
254
+ referenceId: Any?,
255
+ email: Any?,
256
+ extraData: Any?,
257
+ resolve: @escaping RCTPromiseResolveBlock,
258
+ reject: @escaping RCTPromiseRejectBlock
259
+ ) -> Void {
260
+ // Handle null values - JavaScript null becomes NSNull in Objective-C
261
+ // Convert NSNull or nil to empty string
262
+ let safeReferenceId: String = {
263
+ if referenceId is NSNull || referenceId == nil {
264
+ return ""
265
+ }
266
+ return (referenceId as? String) ?? ""
267
+ }()
268
+
269
+ let safeEmail: String = {
270
+ if email is NSNull || email == nil {
271
+ return ""
272
+ }
273
+ return (email as? String) ?? ""
274
+ }()
275
+
276
+ // Parse extraData from React Native
277
+ // extraData is a dictionary containing: userData, govData, govId, location, businessData, address, metadata
278
+ var parsedExtraData: [String: Any]? = nil
279
+
280
+ if let extraDataDict = extraData as? [String: Any], !extraDataDict.isEmpty {
281
+ parsedExtraData = [:]
282
+
283
+ // Parse userData
284
+ if let userData = extraDataDict["userData"] as? [String: Any], !userData.isEmpty {
285
+ var parsedUserData: [String: Any] = [:]
286
+ if let firstName = userData["firstName"] as? String { parsedUserData["firstName"] = firstName }
287
+ if let lastName = userData["lastName"] as? String { parsedUserData["lastName"] = lastName }
288
+ if let dob = userData["dob"] as? String { parsedUserData["dob"] = dob }
289
+ if let email = userData["email"] as? String { parsedUserData["email"] = email }
290
+ if !parsedUserData.isEmpty { parsedExtraData?["userData"] = parsedUserData }
291
+ }
292
+
293
+ // Parse govData
294
+ if let govData = extraDataDict["govData"] as? [String: Any], !govData.isEmpty {
295
+ var parsedGovData: [String: Any] = [:]
296
+ if let bvn = govData["bvn"] as? String { parsedGovData["bvn"] = bvn }
297
+ if let dl = govData["dl"] as? String { parsedGovData["dl"] = dl }
298
+ if let nin = govData["nin"] as? String { parsedGovData["nin"] = nin }
299
+ if let vnin = govData["vnin"] as? String { parsedGovData["vnin"] = vnin }
300
+ if !parsedGovData.isEmpty { parsedExtraData?["govData"] = parsedGovData }
301
+ }
302
+
303
+ // Parse govId
304
+ if let govId = extraDataDict["govId"] as? [String: Any], !govId.isEmpty {
305
+ var parsedGovId: [String: Any] = [:]
306
+ if let national = govId["national"] as? String { parsedGovId["national"] = national }
307
+ if let passport = govId["passport"] as? String { parsedGovId["passport"] = passport }
308
+ if let dl = govId["dl"] as? String { parsedGovId["dl"] = dl }
309
+ if let voter = govId["voter"] as? String { parsedGovId["voter"] = voter }
310
+ if let nin = govId["nin"] as? String { parsedGovId["nin"] = nin }
311
+ if let others = govId["others"] as? String { parsedGovId["others"] = others }
312
+ if !parsedGovId.isEmpty { parsedExtraData?["govId"] = parsedGovId }
313
+ }
314
+
315
+ // Parse location
316
+ if let location = extraDataDict["location"] as? [String: Any], !location.isEmpty {
317
+ var parsedLocation: [String: Any] = [:]
318
+ if let latitude = location["latitude"] as? String { parsedLocation["latitude"] = latitude }
319
+ if let longitude = location["longitude"] as? String { parsedLocation["longitude"] = longitude }
320
+ if !parsedLocation.isEmpty { parsedExtraData?["location"] = parsedLocation }
321
+ }
322
+
323
+ // Parse businessData
324
+ if let businessData = extraDataDict["businessData"] as? [String: Any], !businessData.isEmpty {
325
+ var parsedBusinessData: [String: Any] = [:]
326
+ if let cac = businessData["cac"] as? String { parsedBusinessData["cac"] = cac }
327
+ if !parsedBusinessData.isEmpty { parsedExtraData?["businessData"] = parsedBusinessData }
328
+ }
329
+
330
+ // Parse address
331
+ if let address = extraDataDict["address"] {
332
+ if !(address is NSNull) {
333
+ if let addressString = address as? String {
334
+ parsedExtraData?["address"] = addressString
335
+ }
336
+ }
337
+ }
338
+
339
+ // Parse metadata
340
+ if let metadata = extraDataDict["metadata"] as? [String: Any], !metadata.isEmpty {
341
+ parsedExtraData?["metadata"] = metadata
342
+ }
343
+ }
344
+
345
+ // Use parsed extraData or nil if empty
346
+ let extraDataForSDK = (parsedExtraData != nil && !parsedExtraData!.isEmpty) ? parsedExtraData : nil
347
+
348
+ guard let rootVC = getTopViewController() else {
349
+ print("⚠️ Failed to get top view controller")
350
+ reject("NO_ROOT_VIEW_CONTROLLER", "Failed to get top view controller", nil)
351
+ return
352
+ }
353
+
354
+ DispatchQueue.main.async { [weak self] in
355
+ guard let self = self else { return }
356
+
357
+ // Reset state for new launch
358
+ self.prevController = nil
359
+ self.isDojahActive = false
360
+ self.hasSeenSDKInit = false
361
+
362
+ // Create safe navigation controller for Dojah (prevents duplicate presentations)
363
+ let dojahNavController = SafeDojahNavigationController()
364
+ dojahNavController.modalPresentationStyle = .fullScreen
365
+ self.dojahNavController = dojahNavController
366
+
367
+ // Set delegate BEFORE presenting (important!)
368
+ dojahNavController.delegate = self.navDelegate
369
+
370
+ // Detect modal dismissal (for cancel)
371
+ dojahNavController.presentationController?.delegate = self.presentationDelegate
372
+
373
+ // Set up presentation delegate callback
374
+ self.presentationDelegate.setOnDidDismiss { [weak self] in
375
+ guard let self = self else { return }
376
+ print("🛑 Modal was dismissed manually")
377
+ self.resolveSdkResult()
378
+ }
379
+
380
+ // Track Dojah flow - simplified like original but with proper closing logic
381
+ self.navDelegate.setOnDidShow { [weak self] vc in
382
+ guard let self = self else { return }
383
+
384
+ // Use String(describing: vc) like the original code
385
+ let vcName = String(describing: vc)
386
+ print("🔄 onDidShow: \(vcName)")
387
+
388
+ // Match original + Flutter logic:
389
+ // 1. If not DojahWidget, resolve (but only if we were in Dojah)
390
+ if !vcName.contains("DojahWidget") {
391
+ if self.isDojahActive {
392
+ print("🚪 Not DojahWidget - resolving")
393
+ self.resolveSdkResult()
394
+ }
395
+ return
396
+ }
397
+
398
+ // Mark as active when we see Dojah screens
399
+ self.isDojahActive = true
400
+
401
+ // 2. If DJDisclaimer with prevController, pop to root (like original)
402
+ if vcName.contains("DojahWidget.DJDisclaimer") && self.prevController != nil {
403
+ print("📱 DJDisclaimer with prevController - popping to root")
404
+ self.dojahNavController?.popToRootViewController(animated: false)
405
+ return
406
+ }
407
+
408
+ // 3. If not SDKInitViewController, track as prevController (like original)
409
+ if !vcName.contains("DojahWidget.SDKInitViewController") {
410
+ self.prevController = vc
411
+ print("✅ Tracking prevController: \(vcName)")
412
+ } else {
413
+ // 4. SDKInitViewController - resolve (matches Flutter's "else" case)
414
+ // Resolve if we've seen it before OR if we've progressed
415
+ if self.hasSeenSDKInit || self.prevController != nil {
416
+ print("📱 SDKInitViewController - resolving")
417
+ self.resolveSdkResult()
418
+ } else {
419
+ // First time seeing SDKInitViewController - allow to continue
420
+ print("📱 SDKInitViewController on initial launch - allowing to continue")
421
+ self.hasSeenSDKInit = true
422
+ }
423
+ }
424
+ }
425
+
426
+ // Present modally and wait for completion to ensure view hierarchy is ready
427
+ rootVC.present(dojahNavController, animated: true) {
428
+ // Add a small delay to ensure view hierarchy is fully laid out
429
+ // This helps with camera session initialization timing
430
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
431
+ // Initialize SDK after presentation completes and view is laid out
432
+ // This ensures the view hierarchy is fully set up before camera access
433
+ // Convert dictionary to ExtraUserData if method is available in SDK
434
+ // If toExtraUserData() doesn't exist, this will need to be handled differently
435
+ let extraUserDataForSDK: ExtraUserData? = {
436
+ guard let extraDataDict = extraDataForSDK else { return ExtraUserData() }
437
+ // Try to use toExtraUserData() if available in SDK (works in Expo)
438
+ return extraDataDict.toExtraUserData()
439
+ }()
440
+
441
+ DojahWidgetSDK.initialize(
442
+ widgetID: widgetId,
443
+ referenceID: safeReferenceId,
444
+ emailAddress: safeEmail,
445
+ extraUserData: extraUserDataForSDK ?? ExtraUserData(),
446
+ source: "ios_react_native_cli",
447
+ navController: dojahNavController
448
+ )
449
+ print("🎯 Dojah SDK initialized: widgetId=\(widgetId), referenceId=\(safeReferenceId), email=\(safeEmail)")
450
+ // Resolve promise after successful initialization
451
+ resolve("launched")
452
+ }
453
+ }
454
+ }
455
+ }
211
456
  }
212
-
@@ -79,8 +79,13 @@ const DojahKyc = _reactNative.NativeModules.DojahKyc ? _reactNative.NativeModule
79
79
  * ```
80
80
  **/
81
81
 
82
- function launchDojahKyc(widgetId, referenceId, email, userData = null, govData = null, govId = null, location = null, businessData = null, address = null, metadata = null) {
83
- return DojahKyc.launch(widgetId, referenceId, email, userData, govData, govId, location, businessData, address, metadata);
82
+ function launchDojahKyc(widgetId, referenceId, email, extraData) {
83
+ if (_reactNative.Platform.OS === 'ios') {
84
+ return DojahKyc.launch(widgetId, referenceId ?? '', email ?? '', extraData);
85
+ } else {
86
+ // Android now also uses extraData object (matching docs structure)
87
+ return DojahKyc.launch(widgetId, referenceId, email, extraData);
88
+ }
84
89
  }
85
90
  function getIdHistory() {
86
91
  return DojahKyc.getIdHistory();
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","DojahKyc","NativeModules","Proxy","get","Error","launchDojahKyc","widgetId","referenceId","email","userData","govData","govId","location","businessData","address","metadata","launch","getIdHistory"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GACjB,qFAAqF,GACrFC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,QAAQ,GAAGC,0BAAa,CAACD,QAAQ,GACnCC,0BAAa,CAACD,QAAQ,GACtB,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO,SAASU,cAAcA,CAC5BC,QAAgB,EAChBC,WAA2B,EAC3BC,KAAqB,EACrBC,QAAuB,GAAG,IAAI,EAC9BC,OAAsB,GAAG,IAAI,EAC7BC,KAAoB,GAAG,IAAI,EAC3BC,QAAuB,GAAG,IAAI,EAC9BC,YAA2B,GAAG,IAAI,EAClCC,OAAsB,GAAG,IAAI,EAC7BC,QAAuB,GAAG,IAAI,EACN;EACxB,OAAOf,QAAQ,CAACgB,MAAM,CACpBV,QAAQ,EACRC,WAAW,EACXC,KAAK,EACLC,QAAQ,EACRC,OAAO,EACPC,KAAK,EACLC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACPC,QACF,CAAC;AACH;AAEO,SAASE,YAAYA,CAAA,EAAwC;EAClE,OAAOjB,QAAQ,CAACiB,YAAY,CAAC,CAAC;AAChC","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","DojahKyc","NativeModules","Proxy","get","Error","launchDojahKyc","widgetId","referenceId","email","extraData","OS","launch","getIdHistory"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GACjB,qFAAqF,GACrFC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,QAAQ,GAAGC,0BAAa,CAACD,QAAQ,GACnCC,0BAAa,CAACD,QAAQ,GACtB,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACT,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO,SAASU,cAAcA,CAC5BC,QAAgB,EAChBC,WAA2B,EAC3BC,KAAqB,EACrBC,SAQQ,EACgB;EACxB,IAAIb,qBAAQ,CAACc,EAAE,KAAK,KAAK,EAAE;IACzB,OAAOV,QAAQ,CAACW,MAAM,CAACL,QAAQ,EAAEC,WAAW,IAAI,EAAE,EAAEC,KAAK,IAAI,EAAE,EAAEC,SAAS,CAAC;EAC7E,CAAC,MAAM;IACL;IACA,OAAOT,QAAQ,CAACW,MAAM,CAACL,QAAQ,EAAEC,WAAW,EAAEC,KAAK,EAAEC,SAAS,CAAC;EACjE;AACF;AAEO,SAASG,YAAYA,CAAA,EAAwC;EAClE,OAAOZ,QAAQ,CAACY,YAAY,CAAC,CAAC;AAChC","ignoreList":[]}
@@ -72,8 +72,13 @@ const DojahKyc = NativeModules.DojahKyc ? NativeModules.DojahKyc : new Proxy({},
72
72
  * ```
73
73
  **/
74
74
 
75
- export function launchDojahKyc(widgetId, referenceId, email, userData = null, govData = null, govId = null, location = null, businessData = null, address = null, metadata = null) {
76
- return DojahKyc.launch(widgetId, referenceId, email, userData, govData, govId, location, businessData, address, metadata);
75
+ export function launchDojahKyc(widgetId, referenceId, email, extraData) {
76
+ if (Platform.OS === 'ios') {
77
+ return DojahKyc.launch(widgetId, referenceId ?? '', email ?? '', extraData);
78
+ } else {
79
+ // Android now also uses extraData object (matching docs structure)
80
+ return DojahKyc.launch(widgetId, referenceId, email, extraData);
81
+ }
77
82
  }
78
83
  export function getIdHistory() {
79
84
  return DojahKyc.getIdHistory();
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","DojahKyc","Proxy","get","Error","launchDojahKyc","widgetId","referenceId","email","userData","govData","govId","location","businessData","address","metadata","launch","getIdHistory"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,MAAMC,aAAa,GACjB,qFAAqF,GACrFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,QAAQ,GAAGN,aAAa,CAACM,QAAQ,GACnCN,aAAa,CAACM,QAAQ,GACtB,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASQ,cAAcA,CAC5BC,QAAgB,EAChBC,WAA2B,EAC3BC,KAAqB,EACrBC,QAAuB,GAAG,IAAI,EAC9BC,OAAsB,GAAG,IAAI,EAC7BC,KAAoB,GAAG,IAAI,EAC3BC,QAAuB,GAAG,IAAI,EAC9BC,YAA2B,GAAG,IAAI,EAClCC,OAAsB,GAAG,IAAI,EAC7BC,QAAuB,GAAG,IAAI,EACN;EACxB,OAAOd,QAAQ,CAACe,MAAM,CACpBV,QAAQ,EACRC,WAAW,EACXC,KAAK,EACLC,QAAQ,EACRC,OAAO,EACPC,KAAK,EACLC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACPC,QACF,CAAC;AACH;AAEA,OAAO,SAASE,YAAYA,CAAA,EAAwC;EAClE,OAAOhB,QAAQ,CAACgB,YAAY,CAAC,CAAC;AAChC","ignoreList":[]}
1
+ {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","DojahKyc","Proxy","get","Error","launchDojahKyc","widgetId","referenceId","email","extraData","OS","launch","getIdHistory"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAEtD,MAAMC,aAAa,GACjB,qFAAqF,GACrFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,QAAQ,GAAGN,aAAa,CAACM,QAAQ,GACnCN,aAAa,CAACM,QAAQ,GACtB,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAO,SAASQ,cAAcA,CAC5BC,QAAgB,EAChBC,WAA2B,EAC3BC,KAAqB,EACrBC,SAQQ,EACgB;EACxB,IAAIb,QAAQ,CAACc,EAAE,KAAK,KAAK,EAAE;IACzB,OAAOT,QAAQ,CAACU,MAAM,CAACL,QAAQ,EAAEC,WAAW,IAAI,EAAE,EAAEC,KAAK,IAAI,EAAE,EAAEC,SAAS,CAAC;EAC7E,CAAC,MAAM;IACL;IACA,OAAOR,QAAQ,CAACU,MAAM,CAACL,QAAQ,EAAEC,WAAW,EAAEC,KAAK,EAAEC,SAAS,CAAC;EACjE;AACF;AAEA,OAAO,SAASG,YAAYA,CAAA,EAAwC;EAClE,OAAOX,QAAQ,CAACW,YAAY,CAAC,CAAC;AAChC","ignoreList":[]}
@@ -60,6 +60,14 @@
60
60
  * });
61
61
  * ```
62
62
  **/
63
- export declare function launchDojahKyc(widgetId: string, referenceId?: string | null, email?: string | null, userData?: Object | null, govData?: Object | null, govId?: Object | null, location?: Object | null, businessData?: Object | null, address?: string | null, metadata?: Object | null): Promise<string | null>;
63
+ export declare function launchDojahKyc(widgetId: string, referenceId?: string | null, email?: string | null, extraData?: {
64
+ userData?: Object | null;
65
+ govData?: Object | null;
66
+ govId?: Object | null;
67
+ location?: Object | null;
68
+ businessData?: Object | null;
69
+ address?: string | null;
70
+ metadata?: Object | null;
71
+ } | null): Promise<string | null>;
64
72
  export declare function getIdHistory(): Promise<Map<string, string> | null>;
65
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6DI;AAEJ,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,EAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,EACrB,QAAQ,GAAE,MAAM,GAAG,IAAW,EAC9B,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,KAAK,GAAE,MAAM,GAAG,IAAW,EAC3B,QAAQ,GAAE,MAAM,GAAG,IAAW,EAC9B,YAAY,GAAE,MAAM,GAAG,IAAW,EAClC,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,QAAQ,GAAE,MAAM,GAAG,IAAW,GAC7B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAaxB;AAED,wBAAgB,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAElE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA6DI;AAEJ,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,EAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,EACrB,SAAS,CAAC,EAAE;IACV,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,IAAI,GACP,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAED,wBAAgB,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAElE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dojah-kyc-sdk-react_native",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Dojah SDK",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/index.tsx CHANGED
@@ -84,26 +84,22 @@ export function launchDojahKyc(
84
84
  widgetId: string,
85
85
  referenceId?: string | null,
86
86
  email?: string | null,
87
- userData: Object | null = null,
88
- govData: Object | null = null,
89
- govId: Object | null = null,
90
- location: Object | null = null,
91
- businessData: Object | null = null,
92
- address: string | null = null,
93
- metadata: Object | null = null
87
+ extraData?: {
88
+ userData?: Object | null;
89
+ govData?: Object | null;
90
+ govId?: Object | null;
91
+ location?: Object | null;
92
+ businessData?: Object | null;
93
+ address?: string | null;
94
+ metadata?: Object | null;
95
+ } | null
94
96
  ): Promise<string | null> {
95
- return DojahKyc.launch(
96
- widgetId,
97
- referenceId,
98
- email,
99
- userData,
100
- govData,
101
- govId,
102
- location,
103
- businessData,
104
- address,
105
- metadata
106
- );
97
+ if (Platform.OS === 'ios') {
98
+ return DojahKyc.launch(widgetId, referenceId ?? '', email ?? '', extraData);
99
+ } else {
100
+ // Android now also uses extraData object (matching docs structure)
101
+ return DojahKyc.launch(widgetId, referenceId, email, extraData);
102
+ }
107
103
  }
108
104
 
109
105
  export function getIdHistory(): Promise<Map<string, string> | null> {
@@ -1,50 +0,0 @@
1
- # These are essential for React Native's internal mechanisms and module linking.
2
- -keepclassmembers class com.facebook.react.bridge.JavaModule$$Props { *; }
3
- -keepclassmembers class com.facebook.react.bridge.ModuleSpec { *; }
4
- -keepclassmembers class * implements com.facebook.react.bridge.JavaScriptModule { *; }
5
- -keepclassmembers class * implements com.facebook.react.bridge.NativeModule { *; }
6
-
7
- # Prevents the stripping of unused methods in classes that are accessed dynamically.
8
- -keep public class * extends com.facebook.react.bridge.ViewManager { *; }
9
- -keep public class * extends com.facebook.react.uimanager.ViewManager { *; } # Older versions might use this
10
-
11
- # Keep React Native module classes and their constructors.
12
- # This is crucial for autolinking and manual linking.
13
- -keep class * implements com.facebook.react.bridge.NativeModule {
14
- <init>(...);
15
- }
16
- -keep class * extends com.facebook.react.bridge.BaseJavaModule {
17
- <init>(...);
18
- }
19
- -keep class * extends com.facebook.react.uimanager.ViewManager {
20
- <init>(...);
21
- }
22
-
23
- # Standard dontwarn rules for common React Native dependencies
24
- -dontwarn com.facebook.react.**
25
- -dontwarn com.facebook.jni.**
26
- -dontwarn com.facebook.soloader.**
27
- -dontwarn com.facebook.yoga.**
28
- -dontwarn javax.annotation.**
29
-
30
-
31
- # Keep your SDK's core Kotlin classes and interfaces (likely in kyc_sdk_kotlin)
32
- -keep class com.dojah.kyc_sdk_kotlin.domain.** { *; }
33
- -keep class com.dojah.kyc_sdk_kotlin.core.Result
34
- -keep interface com.dojah.** { *; }
35
-
36
- # IMPORTANT: Keep React Native module and package classes.
37
- -keep class com.dojahkyc.rn.** {*;}
38
-
39
-
40
- # Keep gRPC classes
41
- -keep class io.grpc.** { *; }
42
-
43
- # Keep BouncyCastle classes
44
- -keep class org.bouncycastle.** { *; }
45
-
46
- # Keep Conscrypt classes
47
- -keep class org.conscrypt.** { *; }
48
-
49
- # Keep OpenJSSE classes
50
- -keep class org.openjsse.** { *; }