react-native-smallcase-gateway 5.3.2 → 6.0.0

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/com/reactnativesmallcasegateway/SCGatewayBridgeEmitter.kt +112 -0
  4. package/android/src/main/java/com/reactnativesmallcasegateway/SCLoansBridgeEmitter.kt +117 -0
  5. package/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayModule.kt +0 -5
  6. package/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayPackage.kt +5 -1
  7. package/ios/SCGatewayBridgeEmitter.m +20 -0
  8. package/ios/SCGatewayEmitter.swift +117 -0
  9. package/ios/SCLoansBridgeEmitter.m +20 -0
  10. package/ios/SCLoansEmitter.swift +115 -0
  11. package/ios/SmallcaseGateway-Bridging-Header.h +7 -0
  12. package/lib/commonjs/SCGatewayEventEmitter.js +107 -0
  13. package/lib/commonjs/SCGatewayEventEmitter.js.map +1 -0
  14. package/lib/commonjs/SCLoansEventEmitter.js +103 -0
  15. package/lib/commonjs/SCLoansEventEmitter.js.map +1 -0
  16. package/lib/commonjs/SmallcaseGateway.js.map +1 -1
  17. package/lib/commonjs/index.js +27 -0
  18. package/lib/commonjs/index.js.map +1 -1
  19. package/lib/module/SCGatewayEventEmitter.js +102 -0
  20. package/lib/module/SCGatewayEventEmitter.js.map +1 -0
  21. package/lib/module/SCLoansEventEmitter.js +98 -0
  22. package/lib/module/SCLoansEventEmitter.js.map +1 -0
  23. package/lib/module/SmallcaseGateway.js.map +1 -1
  24. package/lib/module/index.js +3 -1
  25. package/lib/module/index.js.map +1 -1
  26. package/package.json +1 -1
  27. package/react-native-smallcase-gateway.podspec +2 -2
  28. package/src/SCGatewayEventEmitter.js +121 -0
  29. package/src/SCLoansEventEmitter.js +116 -0
  30. package/src/SmallcaseGateway.js +1 -1
  31. package/src/index.js +3 -1
  32. package/types/index.d.ts +45 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [6.0.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.2.0...v6.0.0) (2025-11-20)
6
+
7
+ ### [5.0.2-rc.3](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.2-rc.2...v5.0.2-rc.3) (2025-07-22)
8
+
5
9
  ### [5.3.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.3.1...v5.3.2) (2025-11-13)
6
10
 
7
11
  ### [5.3.1](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.2.0...v5.3.1) (2025-10-28)
@@ -149,8 +149,8 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
149
149
  dependencies {
150
150
  //noinspection GradleDynamicVersion
151
151
  implementation 'com.facebook.react:react-native:+' // From node_modules
152
- implementation 'com.smallcase.gateway:sdk:4.4.2'
153
- implementation 'com.smallcase.loans:sdk:3.1.1'
152
+ implementation 'com.smallcase.gateway:sdk:5.0.0'
153
+ implementation 'com.smallcase.loans:sdk:4.0.0'
154
154
  implementation "androidx.core:core-ktx:1.3.1"
155
155
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
156
156
  }
@@ -0,0 +1,112 @@
1
+
2
+ // SCGatewayBridgeEmitter.kt
3
+ package com.reactnativesmallcasegateway
4
+
5
+ import android.util.Log
6
+ import com.facebook.react.bridge.*
7
+ import com.facebook.react.bridge.UiThreadUtil
8
+ import com.facebook.react.modules.core.DeviceEventManagerModule
9
+ import com.smallcase.gateway.data.listeners.Notification
10
+ import com.smallcase.gateway.data.listeners.NotificationCenter
11
+ import com.smallcase.gateway.portal.ScgNotification
12
+ import com.smallcase.gateway.portal.SmallcaseGatewaySdk
13
+
14
+ class SCGatewayBridgeEmitter(private val reactContext: ReactApplicationContext) :
15
+ ReactContextBaseJavaModule(reactContext) {
16
+
17
+ companion object {
18
+ const val TAG = "SCGatewayBridgeEmitter"
19
+ }
20
+
21
+ private var notificationObserver: ((Notification) -> Unit)? = null
22
+
23
+ private val isListening: Boolean
24
+ get() = notificationObserver != null
25
+
26
+ init {
27
+ UiThreadUtil.runOnUiThread { startListening() }
28
+ }
29
+
30
+ override fun getName(): String = "SCGatewayBridgeEmitter"
31
+
32
+ override fun onCatalystInstanceDestroy() {
33
+ super.onCatalystInstanceDestroy()
34
+ if (isListening) {
35
+ notificationObserver?.let { observer ->
36
+ NotificationCenter.removeObserver(observer)
37
+ }
38
+ notificationObserver = null
39
+ Log.d(TAG, "Successfully cleaned up notification observer")
40
+ }
41
+ }
42
+
43
+ @ReactMethod
44
+ fun startListening(promise: Promise? = null) {
45
+ Log.d(TAG, "startListening called")
46
+
47
+ if (isListening) {
48
+ Log.d(TAG, "Already listening to events")
49
+ promise?.resolve("Already listening")
50
+ return
51
+ }
52
+
53
+ UiThreadUtil.runOnUiThread {
54
+ Log.d(TAG, "Starting listener on thread: ${Thread.currentThread().name}")
55
+
56
+ notificationObserver = { notification ->
57
+ Log.d(TAG, "Received notification: ${notification.name}")
58
+ processScgNotification(notification)
59
+ }
60
+
61
+ notificationObserver?.let { observer ->
62
+ NotificationCenter.addObserver(observer)
63
+ Log.d(TAG, "Successfully started listening for notifications")
64
+ promise?.resolve("Started listening successfully")
65
+ } ?: run {
66
+ promise?.reject("START_LISTENING_ERROR", "Failed to create observer")
67
+ }
68
+ }
69
+ }
70
+
71
+ @ReactMethod
72
+ fun stopListening(promise: Promise) {
73
+ if (!isListening) {
74
+ promise.resolve("Not listening")
75
+ return
76
+ }
77
+
78
+ UiThreadUtil.runOnUiThread {
79
+ notificationObserver?.let { observer ->
80
+ NotificationCenter.removeObserver(observer)
81
+ notificationObserver = null
82
+ promise.resolve("Stopped listening successfully")
83
+ } ?: run {
84
+ promise.resolve("No observer to remove")
85
+ }
86
+ }
87
+ }
88
+
89
+ private fun processScgNotification(notification: Notification) {
90
+ val jsonString = notification.userInfo?.get(ScgNotification.STRINGIFIED_PAYLOAD_KEY) as? String
91
+ if (jsonString == null) {
92
+ Log.e(TAG, "SCGatewayBridgeEmitter: Invalid notification object - expected JSON string")
93
+ return
94
+ }
95
+
96
+ sendEvent(SmallcaseGatewaySdk.SCG_NOTIFICATION_NAME, jsonString)
97
+ }
98
+
99
+ private fun sendEvent(eventName: String, jsonString: String) {
100
+ try {
101
+ if (reactContext.hasActiveCatalystInstance()) {
102
+ reactContext
103
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
104
+ .emit(eventName, jsonString)
105
+ } else {
106
+ Log.w(TAG, "React context not active, cannot send event: $eventName")
107
+ }
108
+ } catch (e: Exception) {
109
+ Log.e(TAG, "Failed to send event: $eventName", e)
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,117 @@
1
+ // SCLoansBridgeEmitter.kt
2
+ package com.reactnativesmallcasegateway
3
+
4
+ import android.util.Log
5
+ import com.facebook.react.bridge.*
6
+ import com.facebook.react.bridge.UiThreadUtil
7
+ import com.facebook.react.modules.core.DeviceEventManagerModule
8
+ import com.smallcase.loans.core.external.ScLoan
9
+ import com.smallcase.loans.core.external.ScLoanNotification
10
+ import com.smallcase.loans.data.listeners.Notification
11
+ import com.smallcase.loans.data.listeners.NotificationCenter
12
+
13
+ class SCLoansBridgeEmitter(private val reactContext: ReactApplicationContext):
14
+ ReactContextBaseJavaModule(reactContext) {
15
+
16
+ companion object {
17
+ const val TAG = "SCLoansBridgeEmitter"
18
+ }
19
+
20
+ private var notificationObserver: ((Notification) -> Unit)? = null
21
+
22
+ private val isListening: Boolean
23
+ get() = notificationObserver != null
24
+
25
+ init {
26
+ UiThreadUtil.runOnUiThread {
27
+ startListening()
28
+ }
29
+ }
30
+
31
+ override fun getName(): String = "SCLoansBridgeEmitter"
32
+
33
+ override fun onCatalystInstanceDestroy() {
34
+ super.onCatalystInstanceDestroy()
35
+ if (isListening) {
36
+ notificationObserver?.let { observer ->
37
+ NotificationCenter.removeObserver(observer)
38
+ }
39
+ notificationObserver = null
40
+ Log.d(TAG, "Successfully cleaned up notification observer")
41
+ }
42
+ }
43
+
44
+ @ReactMethod
45
+ fun startListening(promise: Promise ? = null) {
46
+ Log.d(TAG, "startListening called")
47
+
48
+ if (isListening) {
49
+ Log.d(TAG, "Already listening to events")
50
+ promise?.resolve("Already listening")
51
+ return
52
+ }
53
+
54
+ UiThreadUtil.runOnUiThread {
55
+ Log.d(TAG, "Starting listener on thread: ${Thread.currentThread().name}")
56
+
57
+ notificationObserver = { notification ->
58
+ Log.d(TAG, "Received notification: ${notification.name}")
59
+ processScLoansNotification(notification)
60
+ }
61
+
62
+ notificationObserver?.let { observer ->
63
+ NotificationCenter.addObserver(observer)
64
+ Log.d(TAG, "Successfully started listening for notifications")
65
+ promise?.resolve("Started listening successfully")
66
+ } ?: run {
67
+ promise?.reject("START_LISTENING_ERROR", "Failed to create observer")
68
+ }
69
+ }
70
+ }
71
+
72
+ @ReactMethod
73
+ fun stopListening(promise: Promise) {
74
+ if (!isListening) {
75
+ promise.resolve("Not listening")
76
+ return
77
+ }
78
+
79
+ UiThreadUtil.runOnUiThread {
80
+ notificationObserver?.let { observer ->
81
+ NotificationCenter.removeObserver(observer)
82
+ notificationObserver = null
83
+ promise.resolve("Stopped listening successfully")
84
+ } ?: run {
85
+ promise.resolve("No observer to remove")
86
+ }
87
+ }
88
+ }
89
+
90
+ private fun processScLoansNotification(notification: Notification) {
91
+ val jsonString =
92
+ notification.userInfo?.get(ScLoanNotification.STRINGIFIED_PAYLOAD_KEY) as? String
93
+ if (jsonString == null) {
94
+ Log.e(
95
+ TAG,
96
+ "SCLoansBridgeEmitter: Invalid notification object - expected JSON string"
97
+ )
98
+ return
99
+ }
100
+
101
+ sendEvent(ScLoan.SCLOANS_NOTIFICATION_NAME, jsonString)
102
+ }
103
+
104
+ private fun sendEvent(eventName: String, jsonString: String) {
105
+ try {
106
+ if (reactContext.hasActiveCatalystInstance()) {
107
+ reactContext
108
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
109
+ .emit(eventName, jsonString)
110
+ } else {
111
+ Log.w(TAG, "React context not active, cannot send event: $eventName")
112
+ }
113
+ } catch (e: Exception) {
114
+ Log.e(TAG, "Failed to send event: $eventName", e)
115
+ }
116
+ }
117
+ }
@@ -67,7 +67,6 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
67
67
 
68
68
  @ReactMethod
69
69
  fun init(sdkToken: String, promise: Promise) {
70
- Log.d(TAG, "init: start")
71
70
 
72
71
  val initReq = InitRequest(sdkToken)
73
72
  SmallcaseGatewaySdk.init(authRequest = initReq, gatewayInitialisationListener = object : DataListener<InitialisationResponse> {
@@ -85,7 +84,6 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
85
84
 
86
85
  @ReactMethod
87
86
  fun triggerTransaction(transactionId: String, utmParams: ReadableMap?, brokerList: ReadableArray?, promise: Promise) {
88
- Log.d(TAG, "triggerTransaction: start")
89
87
 
90
88
  var safeBrokerList = listOf<String>()
91
89
 
@@ -161,7 +159,6 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
161
159
 
162
160
  @ReactMethod
163
161
  fun launchSmallplug(targetEndpoint: String, params: String, promise: Promise) {
164
- Log.d(TAG, "launchSmallplug: start")
165
162
 
166
163
  SmallcaseGatewaySdk.launchSmallPlug(currentActivity!!, SmallplugData(targetEndpoint, params), object : SmallPlugResponseListener {
167
164
  override fun onFailure(errorCode: Int, errorMessage: String) {
@@ -198,7 +195,6 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
198
195
  }
199
196
  }
200
197
  }
201
- Log.d(TAG, "launchSmallplugWithBranding: start")
202
198
 
203
199
  var partnerProps: SmallplugPartnerProps? = SmallplugPartnerProps(headerColor = "#2F363F", backIconColor = "ffffff")
204
200
 
@@ -228,7 +224,6 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
228
224
 
229
225
  @ReactMethod
230
226
  fun archiveSmallcase(iscid: String, promise: Promise) {
231
- Log.d(TAG, "markSmallcaseArchive: start")
232
227
 
233
228
  SmallcaseGatewaySdk.markSmallcaseArchived(iscid, object : DataListener<SmallcaseGatewayDataResponse> {
234
229
 
@@ -7,7 +7,11 @@ import com.facebook.react.uimanager.ViewManager
7
7
 
8
8
  class SmallcaseGatewayPackage : ReactPackage {
9
9
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
10
- return listOf(SmallcaseGatewayModule(reactContext))
10
+ return listOf(
11
+ SmallcaseGatewayModule(reactContext),
12
+ SCGatewayBridgeEmitter(reactContext),
13
+ SCLoansBridgeEmitter(reactContext)
14
+ )
11
15
  }
12
16
 
13
17
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
@@ -0,0 +1,20 @@
1
+ //
2
+ // SCGatewayBridgeEmitter.m
3
+ // SCGateway
4
+ //
5
+ // Created by Dhruv Porwal
6
+ // Copyright © 2025 smallcase. All rights reserved.
7
+ //
8
+
9
+ #import <React/RCTBridgeModule.h>
10
+ #import "SmallcaseGateway-Bridging-Header.h"
11
+
12
+ @interface RCT_EXTERN_REMAP_MODULE(SCGatewayBridgeEmitter, SCGatewayEmitter, NSObject)
13
+
14
+ RCT_EXTERN_METHOD(startListening:(RCTPromiseResolveBlock)resolve
15
+ rejecter:(RCTPromiseRejectBlock)reject)
16
+
17
+ RCT_EXTERN_METHOD(stopListening:(RCTPromiseResolveBlock)resolve
18
+ rejecter:(RCTPromiseRejectBlock)reject)
19
+
20
+ @end
@@ -0,0 +1,117 @@
1
+ import Foundation
2
+ import React
3
+ import SCGateway
4
+
5
+ @objc(SCGatewayEmitter)
6
+ class SCGatewayEmitter: RCTEventEmitter {
7
+
8
+ private static var shared: SCGatewayEmitter?
9
+
10
+ private var notificationObserver: NSObjectProtocol?
11
+
12
+ private var isListening: Bool {
13
+ return notificationObserver != nil
14
+ }
15
+
16
+ override init() {
17
+ super.init()
18
+ SCGatewayEmitter.shared = self
19
+ print("SCGatewayEmitter: Initialized.")
20
+ }
21
+
22
+ deinit {
23
+ print("SCGatewayEmitter: Deinitializing.")
24
+ stopListening()
25
+ }
26
+
27
+ override func supportedEvents() -> [String]! {
28
+ return [SCGateway.scgNotificationName.rawValue]
29
+ }
30
+
31
+ override func startObserving() {
32
+ super.startObserving()
33
+ print("SCGatewayEmitter: React Native bridge startObserving called.")
34
+ startListening()
35
+ }
36
+
37
+ override func stopObserving() {
38
+ super.stopObserving()
39
+ print("SCGatewayEmitter: React Native bridge stopObserving called.")
40
+ stopListening()
41
+ }
42
+
43
+ override static func requiresMainQueueSetup() -> Bool {
44
+ return true
45
+ }
46
+
47
+ @objc func startListening(
48
+ _ resolve: RCTPromiseResolveBlock? = nil,
49
+ rejecter reject: RCTPromiseRejectBlock? = nil
50
+ ) {
51
+ print("SCGatewayEmitter: Starting to listen for notifications.")
52
+
53
+ guard !isListening else {
54
+ print("SCGatewayEmitter: Already listening, no action needed.")
55
+ resolve?("Already listening")
56
+ return
57
+ }
58
+
59
+ DispatchQueue.main.async { [weak self] in
60
+ guard let self = self else {
61
+ reject?("START_LISTENING_FAILED", "Self deallocated", nil)
62
+ return
63
+ }
64
+
65
+ self.stopListening()
66
+
67
+ self.notificationObserver = NotificationCenter.default.addObserver(
68
+ forName: SCGateway.scgNotificationName,
69
+ object: nil,
70
+ queue: .main
71
+ ) { [weak self] notification in
72
+ self?.processScgNotification(notification)
73
+ }
74
+
75
+ print(
76
+ "SCGatewayEmitter: Started listening to notifications with name: \(SCGateway.scgNotificationName.rawValue)."
77
+ )
78
+ resolve?("Started listening to SCGateway events")
79
+ }
80
+ }
81
+
82
+ @objc func stopListening(
83
+ _ resolve: RCTPromiseResolveBlock? = nil,
84
+ rejecter reject: RCTPromiseRejectBlock? = nil
85
+ ) {
86
+ print("SCGatewayEmitter: Stopping listening for notifications.")
87
+
88
+ guard isListening, let observer = notificationObserver else {
89
+ print("SCGatewayEmitter: Not listening or no observer, no action needed.")
90
+ resolve?("Not listening")
91
+ return
92
+ }
93
+
94
+ NotificationCenter.default.removeObserver(observer)
95
+ notificationObserver = nil
96
+
97
+ print("SCGatewayEmitter: Stopped listening to notifications.")
98
+ resolve?("Stopped listening to SCGateway events")
99
+ }
100
+
101
+ private func processScgNotification(_ notification: Notification) {
102
+ let userInfo = notification.userInfo ?? [:]
103
+
104
+ print("SCGatewayEmitter: Received notification with userInfo keys: \(userInfo.keys)")
105
+
106
+ guard let jsonString = userInfo[SCGNotification.strigifiedPayloadKey] as? String else {
107
+ print(
108
+ "SCGatewayEmitter: No stringified payload found with key '\(SCGNotification.strigifiedPayloadKey)'"
109
+ )
110
+ return
111
+ }
112
+
113
+ print("SCGatewayEmitter: Received JSON string: \(jsonString).")
114
+ sendEvent(withName: SCGateway.scgNotificationName.rawValue, body: jsonString)
115
+ print("SCGatewayEmitter: Emitted event '\(SCGateway.scgNotificationName.rawValue)' with JSON string.")
116
+ }
117
+ }
@@ -0,0 +1,20 @@
1
+ //
2
+ // SCGatewayBridgeEmitter.m
3
+ // SCGateway
4
+ //
5
+ // Created by Dhruv Porwal
6
+ // Copyright © 2025 smallcase. All rights reserved.
7
+ //
8
+
9
+ #import <React/RCTBridgeModule.h>
10
+ #import "SmallcaseGateway-Bridging-Header.h"
11
+
12
+ @interface RCT_EXTERN_REMAP_MODULE(SCLoansBridgeEmitter, SCLoansEmitter, NSObject)
13
+
14
+ RCT_EXTERN_METHOD(startListening:(RCTPromiseResolveBlock)resolve
15
+ rejecter:(RCTPromiseRejectBlock)reject)
16
+
17
+ RCT_EXTERN_METHOD(stopListening:(RCTPromiseResolveBlock)resolve
18
+ rejecter:(RCTPromiseRejectBlock)reject)
19
+
20
+ @end
@@ -0,0 +1,115 @@
1
+ import Foundation
2
+ import React
3
+ import Loans
4
+
5
+ @objc(SCLoansEmitter)
6
+ class SCLoansEmitter: RCTEventEmitter {
7
+
8
+ private static var shared: SCLoansEmitter?
9
+
10
+ private var notificationObserver: NSObjectProtocol?
11
+
12
+ private var isListening: Bool {
13
+ return notificationObserver != nil
14
+ }
15
+
16
+ override init() {
17
+ super.init()
18
+ SCLoansEmitter.shared = self
19
+ print("SCLoansEmitter: Initialized.")
20
+ startListening()
21
+ }
22
+
23
+ deinit {
24
+ print("SCLoansEmitter: Deinitializing.")
25
+ stopListening()
26
+ }
27
+
28
+ override func supportedEvents() -> [String]! {
29
+ return [ScLoan.scLoansNotificationName.rawValue]
30
+ }
31
+
32
+ override func startObserving() {
33
+ super.startObserving()
34
+ print("SCLoansEmitter: startObserving called.")
35
+ startListening()
36
+ }
37
+
38
+ override func stopObserving() {
39
+ super.stopObserving()
40
+ print("SCLoansEmitter: stopObserving called.")
41
+ stopListening()
42
+ }
43
+
44
+ override static func requiresMainQueueSetup() -> Bool {
45
+ return true
46
+ }
47
+
48
+ @objc func startListening(
49
+ _ resolve: RCTPromiseResolveBlock? = nil,
50
+ rejecter reject: RCTPromiseRejectBlock? = nil
51
+ ) {
52
+ print("SCLoansEmitter: Starting to listen for notifications.")
53
+
54
+ guard !isListening else {
55
+ print("SCLoansEmitter: Already listening.")
56
+ resolve?("Already listening")
57
+ return
58
+ }
59
+
60
+ DispatchQueue.main.async { [weak self] in
61
+ guard let self = self else {
62
+ reject?("START_LISTENING_FAILED", "Self deallocated", nil)
63
+ return
64
+ }
65
+
66
+ self.stopListening()
67
+
68
+ self.notificationObserver = NotificationCenter.default.addObserver(
69
+ forName: ScLoan.scLoansNotificationName,
70
+ object: nil,
71
+ queue: .main
72
+ ) { [weak self] notification in
73
+ self?.processScLoansNotification(notification)
74
+ }
75
+
76
+ resolve?("Started listening to SCLoans events")
77
+ }
78
+ }
79
+
80
+ @objc func stopListening(
81
+ _ resolve: RCTPromiseResolveBlock? = nil,
82
+ rejecter reject: RCTPromiseRejectBlock? = nil
83
+ ) {
84
+ print("SCLoansEmitter: Stopping listening for notifications.")
85
+
86
+ guard isListening, let observer = notificationObserver else {
87
+ print("SCLoansEmitter: Not listening or no observer, no action needed.")
88
+ resolve?("Not listening")
89
+ return
90
+ }
91
+
92
+ NotificationCenter.default.removeObserver(observer)
93
+ notificationObserver = nil
94
+
95
+ print("SCLoansEmitter: Stopped listening.")
96
+ resolve?("Stopped listening to SCLoans events")
97
+ }
98
+
99
+ private func processScLoansNotification(_ notification: Notification) {
100
+ let userInfo = notification.userInfo ?? [:]
101
+
102
+ print("SCLoansEmitter: Received notification with userInfo keys: \(userInfo.keys)")
103
+
104
+ guard let jsonString = userInfo[ScLoanNotification.strigifiedPayloadKey] as? String else {
105
+ print(
106
+ "SCLoansEmitter: No stringified payload found with key '\(ScLoanNotification.strigifiedPayloadKey)'"
107
+ )
108
+ return
109
+ }
110
+
111
+ print("SCLoansEmitter: Received JSON string: \(jsonString).")
112
+ sendEvent(withName: ScLoan.scLoansNotificationName.rawValue, body: jsonString)
113
+ print("SCLoansEmitter: Emitted event '\(ScLoan.scLoansNotificationName)' with JSON string.")
114
+ }
115
+ }
@@ -1,2 +1,9 @@
1
1
  #import <React/RCTBridgeModule.h>
2
2
  #import <React/RCTViewManager.h>
3
+ #import <React/RCTEventEmitter.h>
4
+
5
+ @interface SCGatewayBridgeEmitter: NSObject
6
+ @end
7
+
8
+ @interface SCLoansBridgeEmitter: NSObject
9
+ @end