diff --git a/android/build.gradle b/android/build.gradle index 8e4e4dc2..9c116ccd 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -149,7 +149,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion') dependencies { //noinspection GradleDynamicVersion implementation 'com.facebook.react:react-native:+' // From node_modules - implementation 'com.smallcase.gateway:sdk:6.0.0' + implementation 'com.smallcase.gateway:sdk:6.0.1' implementation 'com.smallcase.loans:sdk:4.0.0' implementation "androidx.core:core-ktx:1.3.1" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" diff --git a/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayModule.kt b/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayModule.kt index a2fa9e9e..b2b45085 100644 --- a/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayModule.kt +++ b/android/src/main/java/com/reactnativesmallcasegateway/SmallcaseGatewayModule.kt @@ -25,7 +25,6 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte @ReactMethod fun setConfigEnvironment(envName: String, gateway: String, isLeprechaunActive: Boolean, isAmoEnabled: Boolean, preProvidedBrokers: ReadableArray, promise: Promise) { - try { val brokerList = ArrayList() for (index in 0 until preProvidedBrokers.size()) { @@ -38,6 +37,11 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte val protocol = getProtocol(envName) val env = Environment(gateway = gateway, buildType = protocol, isAmoEnabled = isAmoEnabled, preProvidedBrokers = brokerList, isLeprachaunActive = isLeprechaunActive) + + // Set userIdentification if provided - For Now, we are not accepting this on Gateway SDK + // if (!userId.isNullOrEmpty()) { + // env.userId = userIdentification + // } SmallcaseGatewaySdk.setConfigEnvironment(environment = env, smallcaseGatewayListeners = object : SmallcaseGatewayListeners { override fun onGatewaySetupSuccessfull() { @@ -66,8 +70,9 @@ class SmallcaseGatewayModule(reactContext: ReactApplicationContext) : ReactConte } @ReactMethod - fun init(sdkToken: String, promise: Promise) { - + fun init(sdkToken: String, externalMeta: ReadableMap?, promise: Promise) { + // externalMeta is accepted but not used on Android (iOS only feature) + // Extract externalIdentifier if needed in future val initReq = InitRequest(sdkToken) SmallcaseGatewaySdk.init(authRequest = initReq, gatewayInitialisationListener = object : DataListener { override fun onFailure(errorCode: Int, errorMessage: String, data: String?) { diff --git a/ios/SmallcaseGateway.m b/ios/SmallcaseGateway.m index 554efaf3..bc8d7699 100644 --- a/ios/SmallcaseGateway.m +++ b/ios/SmallcaseGateway.m @@ -53,7 +53,7 @@ @interface RCT_EXTERN_MODULE(SmallcaseGateway, NSObject) isLeprechaunActive:isLeprechaunActive isAmoEnabled:isAmoEnabled]; - [SCGateway.shared setupWithConfig: config completion:^(BOOL success,NSError * error) { + [SCGateway.shared setupWithConfig:config completion:^(BOOL success, NSError *error) { if(success) { resolve(@(YES)); } else { @@ -65,16 +65,19 @@ @interface RCT_EXTERN_MODULE(SmallcaseGateway, NSObject) reject(@"setConfigEnvironment", @"Env setup failed", err); } - }]; } //MARK: SDK init RCT_REMAP_METHOD(init, sdkToken:(NSString *)sdkToken + externalMeta:(NSDictionary *)externalMeta initWithResolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - [SCGateway.shared initializeGatewayWithSdkToken:sdkToken completion:^(BOOL success, NSError * error) { + + [SCGateway.shared initializeGatewayWithSdkToken:sdkToken + externalMeta:externalMeta + completion:^(BOOL success, NSError *error) { if(success) { resolve(@(YES)); } else { diff --git a/react-native-smallcase-gateway.podspec b/react-native-smallcase-gateway.podspec index 97040b27..40136e06 100644 --- a/react-native-smallcase-gateway.podspec +++ b/react-native-smallcase-gateway.podspec @@ -33,6 +33,6 @@ Pod::Spec.new do |s| s.dependency "ReactCommon/turbomodule/core" end - s.dependency 'SCGateway', '7.0.0' + s.dependency 'SCGateway', '7.0.1' s.dependency 'SCLoans', '6.0.2' end diff --git a/smart_investing_react_native/app/apis/Functions.tsx b/smart_investing_react_native/app/apis/Functions.tsx index 159d6a2a..10fead11 100644 --- a/smart_investing_react_native/app/apis/Functions.tsx +++ b/smart_investing_react_native/app/apis/Functions.tsx @@ -73,6 +73,11 @@ async function setEnvironment( } const initGatewayResponse = await SmallcaseGateway.init( authJwtResult.authJwt, + { + externalIdentifier: { + userId: "testValue", // Replace with actual userId if needed + }, + }, ); console.log('initGatewayResponse: ' + initGatewayResponse); alert('Set Environment', 'Successful!!'); @@ -94,6 +99,7 @@ async function connect(env: Environment, userId: string): Promise { null, null, ); + console.log(`Transaction ID: ${transactionId}, Intent: ${transactionType.connect}`); console.log('transactionId: ' + transactionId); const transactionResponse = await SmallcaseGateway.triggerTransaction( transactionId, @@ -123,6 +129,7 @@ async function connect(env: Environment, userId: string): Promise { async function triggerMftxn(env: Environment, transactionId: string) { try { + console.log(`Transaction ID: ${transactionId}, Intent: MF_HOLDINGS_IMPORT`); console.log('triggerMftxn txn id: ' + transactionId); const res = await SmallcaseGateway.triggerMfTransaction(transactionId); console.log('triggerMftxn res: ' + JSON.stringify(res)); @@ -148,6 +155,7 @@ async function placeSstOrder( null, null, ); + console.log(`Transaction ID: ${transactionId}, Intent: ${transactionType.transaction}`); console.log('sst txn id: ' + transactionId); const res = await SmallcaseGateway.triggerTransaction(transactionId, { test: 'test', @@ -180,6 +188,7 @@ async function authorizeHoldings(env: Environment, userId: string) { null, null, ); + console.log(`Transaction ID: ${transactionId}, Intent: ${transactionType.authorizeHoldings}`); console.log('authorizeHoldings txn id: ' + transactionId); const res = await SmallcaseGateway.triggerTransaction(transactionId, { test: 'test', @@ -204,6 +213,7 @@ async function reconcileHoldings(env: Environment, userId: string) { null, null, ); + console.log(`Transaction ID: ${transactionId}, Intent: ${transactionType.transaction} (RECONCILIATION)`); const res = await SmallcaseGateway.triggerTransaction(transactionId); console.log('reconcileHoldings res: ' + JSON.stringify(res)); alert('Reconcile Holdings', JSON.stringify(res)); @@ -238,6 +248,7 @@ async function importHoldings( assetConfig, null, ); + console.log(`Transaction ID: ${transactionId}, Intent: ${transactionType.holdingsImport}`); console.log('importHoldings txn id: ' + transactionId); const res = await SmallcaseGateway.triggerTransaction(transactionId, { test: 'test', @@ -396,6 +407,7 @@ async function fetchFunds(env: Environment, userId: string): Promise { null, null, ); + console.log(`Transaction ID: ${transactionId}, Intent: ${transactionType.fetchFunds}`); console.log('fetchFunds txn id: ' + transactionId); const res = await SmallcaseGateway.triggerTransaction(transactionId, { test: 'test', @@ -504,6 +516,7 @@ async function logout() { async function triggerTxn(txnId: string) { try { + console.log(`Transaction ID: ${txnId}, Intent: MANUAL_TRIGGER`); const res = await SmallcaseGateway.triggerTransaction(txnId, { test: 'test', }); diff --git a/src/SmallcaseGateway.js b/src/SmallcaseGateway.js index 61f34fe3..36a0aa94 100644 --- a/src/SmallcaseGateway.js +++ b/src/SmallcaseGateway.js @@ -85,10 +85,14 @@ const setConfigEnvironment = async (envConfig) => { * * note: this must be called after `setConfigEnvironment()` * @param {string} sdkToken + * @param {Object} [externalMeta] - external metadata (iOS only, optional) + * @param {Object} [externalMeta.externalIdentifier] - key-value pairs for external identifiers (e.g., { userId: '123' }) */ -const init = async (sdkToken) => { +const init = async (sdkToken, externalMeta) => { const safeToken = typeof sdkToken === 'string' ? sdkToken : ''; - return SmallcaseGatewayNative.init(safeToken); + const safeExternalMeta = externalMeta && typeof externalMeta === 'object' ? externalMeta : null; + + return SmallcaseGatewayNative.init(safeToken, safeExternalMeta); }; /** diff --git a/src/__tests__/init.test.js b/src/__tests__/init.test.js index c40fb918..1b06f93c 100644 --- a/src/__tests__/init.test.js +++ b/src/__tests__/init.test.js @@ -8,22 +8,32 @@ describe('init', () => { test('valid', async () => { await SmallcaseGateway.init('test-token'); - expect(initFn).toHaveBeenNthCalledWith(1, 'test-token'); + expect(initFn).toHaveBeenNthCalledWith(1, 'test-token', null); + }); + + test('valid with externalMeta', async () => { + const externalMeta = { + externalIdentifier: { + userId: 'user123' + } + }; + await SmallcaseGateway.init('test-token', externalMeta); + expect(initFn).toHaveBeenNthCalledWith(2, 'test-token', externalMeta); }); test('empty', async () => { await SmallcaseGateway.init(); - expect(initFn).toHaveBeenNthCalledWith(2, ''); + expect(initFn).toHaveBeenNthCalledWith(3, '', null); }); test('invalid', async () => { await SmallcaseGateway.init(undefined); - expect(initFn).toHaveBeenNthCalledWith(3, ''); + expect(initFn).toHaveBeenNthCalledWith(4, '', null); - await SmallcaseGateway.init({}); - expect(initFn).toHaveBeenNthCalledWith(4, ''); + await SmallcaseGateway.init('test-token', {}); + expect(initFn).toHaveBeenNthCalledWith(5, 'test-token', {}); await SmallcaseGateway.init(123); - expect(initFn).toHaveBeenNthCalledWith(5, ''); + expect(initFn).toHaveBeenNthCalledWith(6, '', null); }); }); diff --git a/types/SmallcaseGateway.d.ts b/types/SmallcaseGateway.d.ts index 8b892487..666eec11 100644 --- a/types/SmallcaseGateway.d.ts +++ b/types/SmallcaseGateway.d.ts @@ -95,8 +95,10 @@ declare namespace SmallcaseGateway { * * note: this must be called after `setConfigEnvironment()` * @param {string} sdkToken + * @param {Object} [externalMeta] - external metadata (iOS only, optional) + * @param {Object} [externalMeta.externalIdentifier] - key-value pairs for external identifiers (e.g., { userId: '123' }) */ -declare function init(sdkToken: string): unknown; +declare function init(sdkToken: string, externalMeta?: { externalIdentifier?: { [key: string]: string } }): unknown; /** * Logs the user out and removes the web session. * diff --git a/types/index.d.ts b/types/index.d.ts index 68e21b06..66417fb5 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -67,7 +67,7 @@ declare const _default: { authorizeHoldings: string; mfHoldingsImport: string; }; - init: (sdkToken: string) => unknown; + init: (sdkToken: string, externalMeta?: { externalIdentifier?: { [key: string]: string } }) => unknown; logoutUser: () => Promise; triggerLeadGen: (userDetails?: import("./SmallcaseGateway").userDetails, utmParams?: any) => any; triggerLeadGenWithStatus: (userDetails?: import("./SmallcaseGateway").userDetails) => Promise;