react-native-smallcase-gateway 6.0.0-rc.7 → 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 (36) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/android/build.gradle +2 -2
  3. package/android/gradle.properties +18 -4
  4. package/android/src/main/java/com/reactnativesmallcasegateway/SCGatewayBridgeEmitter.kt +112 -0
  5. package/android/src/main/java/com/reactnativesmallcasegateway/SCLoansBridgeEmitter.kt +117 -0
  6. package/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayModule.kt +9 -10
  7. package/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayPackage.kt +5 -1
  8. package/ios/SCGatewayBridgeEmitter.m +20 -0
  9. package/ios/SCGatewayEmitter.swift +117 -0
  10. package/ios/SCLoansBridgeEmitter.m +20 -0
  11. package/ios/SCLoansEmitter.swift +115 -0
  12. package/ios/SmallcaseGateway-Bridging-Header.h +7 -0
  13. package/ios/SmallcaseGateway.m +20 -4
  14. package/lib/commonjs/SCGatewayEventEmitter.js +107 -0
  15. package/lib/commonjs/SCGatewayEventEmitter.js.map +1 -0
  16. package/lib/commonjs/SCLoansEventEmitter.js +103 -0
  17. package/lib/commonjs/SCLoansEventEmitter.js.map +1 -0
  18. package/lib/commonjs/SmallcaseGateway.js +1 -6
  19. package/lib/commonjs/SmallcaseGateway.js.map +1 -1
  20. package/lib/commonjs/index.js +27 -0
  21. package/lib/commonjs/index.js.map +1 -1
  22. package/lib/module/SCGatewayEventEmitter.js +102 -0
  23. package/lib/module/SCGatewayEventEmitter.js.map +1 -0
  24. package/lib/module/SCLoansEventEmitter.js +98 -0
  25. package/lib/module/SCLoansEventEmitter.js.map +1 -0
  26. package/lib/module/SmallcaseGateway.js +1 -6
  27. package/lib/module/SmallcaseGateway.js.map +1 -1
  28. package/lib/module/index.js +3 -1
  29. package/lib/module/index.js.map +1 -1
  30. package/package.json +9 -3
  31. package/react-native-smallcase-gateway.podspec +2 -2
  32. package/src/SCGatewayEventEmitter.js +121 -0
  33. package/src/SCLoansEventEmitter.js +116 -0
  34. package/src/SmallcaseGateway.js +2 -13
  35. package/src/index.js +3 -1
  36. package/types/index.d.ts +45 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,107 @@
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
+
9
+ ### [5.3.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.3.1...v5.3.2) (2025-11-13)
10
+
11
+ ### [5.3.1](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.2.0...v5.3.1) (2025-10-28)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * update loans SDK dependency to beta version for compatibility ([453385c](https://github.com/smallcase/react-native-smallcase-gateway/commit/453385c736ad57a85f255227dc87ef716e15c49a))
17
+
18
+ ### [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)
19
+
20
+ ## [5.3.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.2.0...v5.3.0) (2025-10-01)
21
+
22
+ ### [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)
23
+
24
+ ## [5.2.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.2-rc.2...v5.2.0) (2025-08-14)
25
+
26
+
27
+ ### Features
28
+
29
+ * add smart investing app w/ react-native-0.79.4 ([#102](https://github.com/smallcase/react-native-smallcase-gateway/issues/102)) ([180018e](https://github.com/smallcase/react-native-smallcase-gateway/commit/180018ef04183128fc6e78011ae34755eb5f9323))
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * update iOS bundle identifier and clean up build config ([363f457](https://github.com/smallcase/react-native-smallcase-gateway/commit/363f4576103bd57a301ad84fe773296288969e8c))
35
+
36
+ ## [6.0.0-rc.7](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.6...v6.0.0-rc.7) (2025-07-09)
37
+
38
+ ## [6.0.0-rc.6](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.5...v6.0.0-rc.6) (2025-07-09)
39
+
40
+ ## [6.0.0-rc.5](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.4...v6.0.0-rc.5) (2025-07-09)
41
+
42
+ ## [6.0.0-rc.4](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.3...v6.0.0-rc.4) (2025-07-09)
43
+
44
+ ## [6.0.0-rc.3](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.2...v6.0.0-rc.3) (2025-07-09)
45
+
46
+ ## [6.0.0-rc.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.0...v6.0.0-rc.2) (2025-07-09)
47
+
48
+ ## [6.0.0-rc.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.1.0-rc.3...v6.0.0-rc.0) (2025-07-09)
49
+
50
+
51
+ ### Features
52
+
53
+ * **release:** add 'release:major:rc' script for prerelease management ([5602fa6](https://github.com/smallcase/react-native-smallcase-gateway/commit/5602fa62bf7f0e24d27353b2b93ebdfaea11466d))
54
+
55
+ ## [5.1.0-rc.3](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.1.0-rc.2...v5.1.0-rc.3) (2025-07-01)
56
+
57
+ ## [5.1.0-rc.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.1.0-rc.1...v5.1.0-rc.2) (2025-07-01)
58
+
59
+ ## [5.1.0-rc.1](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.1-native-SCGateway-webview-4.1.3-389-release...v5.1.0-rc.1) (2025-06-20)
60
+
61
+ ### [5.0.1-native-SCGateway-webview-4.1.3-389-release](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.1-native-SCGateway-webview-4.1.3-388-release...v5.0.1-native-SCGateway-webview-4.1.3-389-release) (2025-06-18)
62
+
63
+ ### [5.0.1-native-SCGateway-webview-4.1.3-388-release](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.1...v5.0.1-native-SCGateway-webview-4.1.3-388-release) (2025-06-16)
64
+
65
+ ## [5.1.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.2-rc.2...v5.1.0) (2025-08-14)
66
+
67
+
68
+ ### Features
69
+
70
+ * add smart investing app w/ react-native-0.79.4 ([#102](https://github.com/smallcase/react-native-smallcase-gateway/issues/102)) ([180018e](https://github.com/smallcase/react-native-smallcase-gateway/commit/180018ef04183128fc6e78011ae34755eb5f9323))
71
+
72
+
73
+ ### Bug Fixes
74
+
75
+ * update iOS bundle identifier and clean up build config ([363f457](https://github.com/smallcase/react-native-smallcase-gateway/commit/363f4576103bd57a301ad84fe773296288969e8c))
76
+
77
+ ## [6.0.0-rc.7](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.6...v6.0.0-rc.7) (2025-07-09)
78
+
79
+ ## [6.0.0-rc.6](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.5...v6.0.0-rc.6) (2025-07-09)
80
+
81
+ ## [6.0.0-rc.5](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.4...v6.0.0-rc.5) (2025-07-09)
82
+
83
+ ## [6.0.0-rc.4](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.3...v6.0.0-rc.4) (2025-07-09)
84
+
85
+ ## [6.0.0-rc.3](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.2...v6.0.0-rc.3) (2025-07-09)
86
+
87
+ ## [6.0.0-rc.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.0...v6.0.0-rc.2) (2025-07-09)
88
+
89
+ ## [6.0.0-rc.0](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.1.0-rc.3...v6.0.0-rc.0) (2025-07-09)
90
+
91
+
92
+ ### Features
93
+
94
+ * **release:** add 'release:major:rc' script for prerelease management ([5602fa6](https://github.com/smallcase/react-native-smallcase-gateway/commit/5602fa62bf7f0e24d27353b2b93ebdfaea11466d))
95
+
96
+ ## [5.1.0-rc.3](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.1.0-rc.2...v5.1.0-rc.3) (2025-07-01)
97
+
98
+ ## [5.1.0-rc.2](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.1.0-rc.1...v5.1.0-rc.2) (2025-07-01)
99
+
100
+ ## [5.1.0-rc.1](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.1-native-SCGateway-webview-4.1.3-389-release...v5.1.0-rc.1) (2025-06-20)
101
+
102
+ ### [5.0.1-native-SCGateway-webview-4.1.3-389-release](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.1-native-SCGateway-webview-4.1.3-388-release...v5.0.1-native-SCGateway-webview-4.1.3-389-release) (2025-06-18)
103
+
104
+ ### [5.0.1-native-SCGateway-webview-4.1.3-388-release](https://github.com/smallcase/react-native-smallcase-gateway/compare/v5.0.1...v5.0.1-native-SCGateway-webview-4.1.3-388-release) (2025-06-16)
105
+
5
106
  ## [6.0.0-rc.7](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.6...v6.0.0-rc.7) (2025-07-09)
6
107
 
7
108
  ## [6.0.0-rc.6](https://github.com/smallcase/react-native-smallcase-gateway/compare/v6.0.0-rc.5...v6.0.0-rc.6) (2025-07-09)
@@ -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.2.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
  }
@@ -1,9 +1,23 @@
1
+ ## For more details on how to configure your build environment visit
2
+ # http://www.gradle.org/docs/current/userguide/build_environment.html
3
+ #
4
+ # Specifies the JVM arguments used for the daemon process.
5
+ # The setting is particularly useful for tweaking memory settings.
6
+ # Default value: -Xmx1024m -XX:MaxPermSize=256m
7
+ # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
8
+ #
9
+ # When configured, Gradle will run in incubating parallel mode.
10
+ # This option should only be used with decoupled projects. For more details, visit
11
+ # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
12
+ # org.gradle.parallel=true
13
+ #Wed Oct 01 13:43:28 IST 2025
14
+ SmallcaseGateway_compileSdkVersion=31
1
15
  SmallcaseGateway_kotlinVersion=1.7.0
2
16
  SmallcaseGateway_minSdkVersion=21
3
- SmallcaseGateway_targetSdkVersion=31
4
- SmallcaseGateway_compileSdkVersion=31
5
17
  SmallcaseGateway_ndkversion=21.4.7075529
6
-
18
+ SmallcaseGateway_targetSdkVersion=31
19
+ android.enableJetifier=true
20
+ android.useAndroidX=true
7
21
  artifactory_contextUrl=https\://artifactory.smallcase.com/artifactory
8
22
  artifactory_password=reactNativeUser123
9
- artifactory_user=react_native_user
23
+ artifactory_user=react_native_user
@@ -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) {
@@ -179,7 +176,14 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
179
176
  }
180
177
 
181
178
  @ReactMethod
182
- fun launchSmallplugWithBranding(targetEndpoint: String, params: String, readableMap: ReadableMap?, promise: Promise) {
179
+ fun launchSmallplugWithBranding(targetEndpoint: String, params: String, headerColor: String?, headerOpacity: Double?, backIconColor: String?, backIconOpacity: Double?, promise: Promise
180
+ ) {
181
+ val readableMap = Arguments.createMap().apply {
182
+ headerColor?.let { putString("headerColor", it) }
183
+ headerOpacity?.let { putDouble("headerOpacity", it) }
184
+ backIconColor?.let { putString("backIconColor", it) }
185
+ backIconOpacity?.let { putDouble("backIconOpacity", it) }
186
+ }
183
187
 
184
188
  fun getColorValue(value: Any?, defaultValue: String): String {
185
189
  return when (value) {
@@ -191,12 +195,11 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
191
195
  }
192
196
  }
193
197
  }
194
- Log.d(TAG, "launchSmallplugWithBranding: start")
195
198
 
196
199
  var partnerProps: SmallplugPartnerProps? = SmallplugPartnerProps(headerColor = "#2F363F", backIconColor = "ffffff")
197
200
 
198
201
  try {
199
- partnerProps = readableMap?.toHashMap()?.let { map ->
202
+ partnerProps = readableMap.toHashMap().let { map ->
200
203
  val hc = getColorValue(map["headerColor"], "#2F363F")
201
204
  val ho = map["headerOpacity"]?.let { if (it is Double) it else 1.0 } ?: 1.0
202
205
  val bc = getColorValue(map["backIconColor"], "#ffffff")
@@ -206,11 +209,9 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
206
209
  } catch (e: Throwable) {
207
210
  }
208
211
 
209
-
210
212
  SmallcaseGatewaySdk.launchSmallPlug(currentActivity!!, SmallplugData(targetEndpoint, params), object : SmallPlugResponseListener {
211
213
  override fun onFailure(errorCode: Int, errorMessage: String) {
212
214
  val err = createErrorJSON(errorCode, errorMessage, null)
213
-
214
215
  promise.reject("error", err)
215
216
  }
216
217
 
@@ -218,13 +219,11 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte
218
219
  val res = resultToWritableMap(smallPlugResult)
219
220
  promise.resolve(res)
220
221
  }
221
-
222
222
  }, partnerProps)
223
223
  }
224
224
 
225
225
  @ReactMethod
226
226
  fun archiveSmallcase(iscid: String, promise: Promise) {
227
- Log.d(TAG, "markSmallcaseArchive: start")
228
227
 
229
228
  SmallcaseGatewaySdk.markSmallcaseArchived(iscid, object : DataListener<SmallcaseGatewayDataResponse> {
230
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