react-native-nami-sdk 3.2.10 → 3.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  name: CI PR Checks
2
-
2
+ env:
3
+ DEVELOPER_DIR: /Applications/Xcode_16.0.0.app/Contents/Developer
3
4
  on: pull_request
4
5
 
5
6
  jobs:
@@ -91,7 +92,7 @@ jobs:
91
92
  npx eslint . --ext .js,.jsx,.ts,.tsx
92
93
  working-directory: source/examples/TestNamiTV
93
94
  e2e-ios:
94
- runs-on: macos-13
95
+ runs-on: macos-15
95
96
  env:
96
97
  DETOX_CONFIGURATION: ios.sim.release
97
98
 
@@ -171,9 +172,10 @@ jobs:
171
172
 
172
173
  - name: Detox test
173
174
  run: |
175
+ export DETOX_SYNCHRONIZATION_DEBUG=1
174
176
  yarn start &
175
177
  METRO_BUNDLER_PID=$!
176
- yarn detox test --configuration ${{ env.DETOX_CONFIGURATION }} e2e/ios --cleanup --headless --record-logs all
178
+ yarn detox test --configuration ${{ env.DETOX_CONFIGURATION }} e2e/ios --cleanup --headless --record-logs all --loglevel trace
177
179
  DETOX_EXIT_CODE=$?
178
180
  kill $METRO_BUNDLER_PID
179
181
  exit $DETOX_EXIT_CODE
@@ -186,7 +188,7 @@ jobs:
186
188
  name: detox-artifacts
187
189
  path: artifacts
188
190
  e2e-android:
189
- runs-on: macos-13
191
+ runs-on: ubuntu-latest
190
192
  env:
191
193
  DETOX_CONFIGURATION: android.emu.release
192
194
 
@@ -223,7 +225,8 @@ jobs:
223
225
  - name: Update App Platform ID
224
226
  working-directory: source/examples/Basic/config/
225
227
  run: |
226
- sed -i '' -e "s/ANDROID_PROD_APP_PLATFORM_ID/$BASIC_ANDROID_PROD_APP_PLATFORM_ID/" index.ts
228
+ sed -i "s/ANDROID_PROD_APP_PLATFORM_ID/$BASIC_ANDROID_PROD_APP_PLATFORM_ID/" index.ts
229
+ #sed -i '' -e "s/ANDROID_PROD_APP_PLATFORM_ID/$BASIC_ANDROID_PROD_APP_PLATFORM_ID/" index.ts
227
230
  env:
228
231
  BASIC_ANDROID_PROD_APP_PLATFORM_ID: '${{ secrets.ANDROID_PROD_APP_PLATFORM_ID }}'
229
232
 
@@ -320,11 +323,14 @@ jobs:
320
323
  with:
321
324
  target: aosp_atd
322
325
  api-level: 30
323
- arch: x86
326
+ arch: x86_64
327
+ disable-animations: true
328
+ ram-size: 4096
329
+ heap-size: 512
324
330
  channel: canary
325
331
  profile: pixel
326
332
  avd-name: Pixel_4_API_34
327
- script: yarn detox test --configuration ${{ env.DETOX_CONFIGURATION }} e2e/android --headless --record-logs all
333
+ script: yarn detox test --configuration ${{ env.DETOX_CONFIGURATION }} e2e/android --headless --record-logs all --loglevel trace
328
334
  working-directory: source/examples/Basic
329
335
 
330
336
  - name: Upload artifacts
@@ -1,6 +1,6 @@
1
1
  name: Generate Test React PROD
2
2
  env:
3
- DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
3
+ DEVELOPER_DIR: /Applications/Xcode_16.0.0.app/Contents/Developer
4
4
  on:
5
5
  workflow_dispatch:
6
6
  inputs:
@@ -137,9 +137,9 @@ jobs:
137
137
  repository: namiml/appstoreconnect-build-tools
138
138
 
139
139
  - name: Set up Python
140
- uses: actions/setup-python@v1
140
+ uses: actions/setup-python@v5
141
141
  with:
142
- python-version: "3.10"
142
+ python-version: "3.13"
143
143
 
144
144
  - name: Get expected build number
145
145
  run: |
@@ -189,6 +189,8 @@ jobs:
189
189
  sed -i '' -e "s/CURRENT_PROJECT_VERSION = 1/CURRENT_PROJECT_VERSION = $BUILD_NUMBER/" ios/Basic.xcodeproj/project.pbxproj
190
190
  sed -i '' -e "s/MARKETING_VERSION = 1.0/MARKETING_VERSION = $CURRENT_VERSION/" ios/Basic.xcodeproj/project.pbxproj
191
191
  sed -i '' -e "s/<string>1<\/string>/<string>$BUILD_NUMBER<\/string>/" ios/Basic/Info.plist
192
+ echo "BUILD_NUMBER=$(cat ~/.next_build_number)" >> $GITHUB_ENV
193
+ echo "CURRENT_VERSION=$(cat ~/.current_version)" >> $GITHUB_ENV
192
194
  working-directory: source/examples/Basic
193
195
 
194
196
  - name: Install test app dependencies
@@ -230,13 +232,29 @@ jobs:
230
232
  env:
231
233
  APPSTORE_API_KEY_ID: "${{ secrets.APPSTORE_API_KEY_ID }}"
232
234
  APPSTORE_ISSUER_ID: "${{ secrets.APPSTORE_ISSUER_ID }}"
235
+
236
+ - name: Get PR info
237
+ id: pr
238
+ run: |
239
+ echo "PR_TITLE=${{ github.event.pull_request.title }}" >> $GITHUB_ENV
240
+
241
+ - name: Upload PR Title to TestFlight Whats New
242
+ working-directory: appstoreconnect-build-tools
243
+ run: |-
244
+ sleep 120
245
+ python3 upload_testflight_whats_new.py com.namiml.app.testreactnative --notes="${{ env.PR_TITLE }}" --version=${{ env.CURRENT_VERSION }} --platform=IOS --prerelease
246
+ env:
247
+ APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
248
+ APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }}
249
+ APPSTORE_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }}
250
+
233
251
  build-tvos-prod:
234
252
  name: Build TestNamiTV tvOS PROD
235
253
  permissions:
236
254
  actions: write
237
255
  contents: write
238
256
  id-token: write
239
- runs-on: macos-13
257
+ runs-on: macos-15
240
258
  timeout-minutes: 40
241
259
  steps:
242
260
  - uses: actions/setup-node@v3
@@ -257,9 +275,9 @@ jobs:
257
275
  repository: namiml/appstoreconnect-build-tools
258
276
 
259
277
  - name: Set up Python
260
- uses: actions/setup-python@v1
278
+ uses: actions/setup-python@v5
261
279
  with:
262
- python-version: "3.10"
280
+ python-version: "3.13"
263
281
 
264
282
  - name: Get expected build number
265
283
  run: |
@@ -309,6 +327,8 @@ jobs:
309
327
  sed -i '' -e "s/CURRENT_PROJECT_VERSION = 1/CURRENT_PROJECT_VERSION = $BUILD_NUMBER/" ios/Basic.xcodeproj/project.pbxproj
310
328
  sed -i '' -e "s/MARKETING_VERSION = 1.0/MARKETING_VERSION = $CURRENT_VERSION/" ios/Basic.xcodeproj/project.pbxproj
311
329
  sed -i '' -e "s/<string>1<\/string>/<string>$BUILD_NUMBER<\/string>/" ios/Info-PROD.plist
330
+ echo "BUILD_NUMBER=$(cat ~/.next_build_number)" >> $GITHUB_ENV
331
+ echo "CURRENT_VERSION=$(cat ~/.current_version)" >> $GITHUB_ENV
312
332
  working-directory: source/examples/TestNamiTV
313
333
 
314
334
  - name: Install test app dependencies
@@ -355,3 +375,13 @@ jobs:
355
375
  env:
356
376
  APPSTORE_API_KEY_ID: "${{ secrets.APPSTORE_API_KEY_ID }}"
357
377
  APPSTORE_ISSUER_ID: "${{ secrets.APPSTORE_ISSUER_ID }}"
378
+
379
+ - name: Upload PR Title to TestFlight Whats New
380
+ working-directory: appstoreconnect-build-tools
381
+ run: |-
382
+ sleep 120
383
+ python3 upload_testflight_whats_new.py com.namiml.app.testreactnative --notes="${{ env.PR_TITLE }}" --version=${{ env.CURRENT_VERSION }} --platform=TV_OS --prerelease
384
+ env:
385
+ APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
386
+ APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }}
387
+ APPSTORE_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }}
@@ -1,6 +1,6 @@
1
1
  name: Generate Test React STG
2
2
  env:
3
- DEVELOPER_DIR: /Applications/Xcode_15.0.1.app/Contents/Developer
3
+ DEVELOPER_DIR: /Applications/Xcode_16.0.0.app/Contents/Developer
4
4
  on:
5
5
  workflow_dispatch:
6
6
  inputs:
@@ -116,7 +116,7 @@ jobs:
116
116
  actions: write
117
117
  contents: write
118
118
  id-token: write
119
- runs-on: macos-13
119
+ runs-on: macos-15
120
120
  timeout-minutes: 40
121
121
  steps:
122
122
  - uses: actions/setup-node@v3
@@ -137,9 +137,9 @@ jobs:
137
137
  repository: namiml/appstoreconnect-build-tools
138
138
 
139
139
  - name: Set up Python
140
- uses: actions/setup-python@v1
140
+ uses: actions/setup-python@v5
141
141
  with:
142
- python-version: "3.10"
142
+ python-version: "3.13"
143
143
 
144
144
  - name: Get expected build number
145
145
  run: |
@@ -189,6 +189,8 @@ jobs:
189
189
  sed -i '' -e "s/CURRENT_PROJECT_VERSION = 1/CURRENT_PROJECT_VERSION = $BUILD_NUMBER/" ios/Basic.xcodeproj/project.pbxproj
190
190
  sed -i '' -e "s/MARKETING_VERSION = 1.0/MARKETING_VERSION = $CURRENT_VERSION/" ios/Basic.xcodeproj/project.pbxproj
191
191
  sed -i '' -e "s/<string>1<\/string>/<string>$BUILD_NUMBER<\/string>/" ios/Basic/Info.plist
192
+ echo "BUILD_NUMBER=$(cat ~/.next_build_number)" >> $GITHUB_ENV
193
+ echo "CURRENT_VERSION=$(cat ~/.current_version)" >> $GITHUB_ENV
192
194
  working-directory: source/examples/Basic
193
195
 
194
196
  - name: Install test app dependencies
@@ -208,10 +210,12 @@ jobs:
208
210
  pod install --repo-update
209
211
  working-directory: source/examples/Basic/ios
210
212
 
211
- # - name: Apply Patches
212
- # run: |
213
- # patch -p0 < *.patch
214
- # working-directory: source/examples/Basic/patches
213
+ - name: Add initial config
214
+ run: |
215
+ echo $INITIAL_CONFIG_APPLE_STG > nami_initial_config_apple_stg.json
216
+ working-directory: source/examples/Basic
217
+ env:
218
+ INITIAL_CONFIG_APPLE_STG: '${{ secrets.INITIAL_CONFIG_APPLE_STG }}'
215
219
 
216
220
  - name: Build resolve Swift dependencies
217
221
  run: |
@@ -235,13 +239,23 @@ jobs:
235
239
  env:
236
240
  APPSTORE_API_KEY_ID: "${{ secrets.APPSTORE_API_KEY_ID }}"
237
241
  APPSTORE_ISSUER_ID: "${{ secrets.APPSTORE_ISSUER_ID }}"
242
+
243
+ - name: Upload PR Title to TestFlight Whats New
244
+ working-directory: appstoreconnect-build-tools
245
+ run: |-
246
+ sleep 120
247
+ python3 upload_testflight_whats_new.py com.namiml.stg.testreactnative --notes="${{ env.PR_TITLE }}" --version=${{ env.CURRENT_VERSION }} --platform=IOS --prerelease
248
+ env:
249
+ APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
250
+ APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }}
251
+ APPSTORE_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }}
238
252
  build-tvos-stg:
239
253
  name: Build TestNamiTV tvOS STG
240
254
  permissions:
241
255
  actions: write
242
256
  contents: write
243
257
  id-token: write
244
- runs-on: macos-13
258
+ runs-on: macos-15
245
259
  timeout-minutes: 40
246
260
  steps:
247
261
  - uses: actions/setup-node@v3
@@ -262,9 +276,9 @@ jobs:
262
276
  repository: namiml/appstoreconnect-build-tools
263
277
 
264
278
  - name: Set up Python
265
- uses: actions/setup-python@v1
279
+ uses: actions/setup-python@v5
266
280
  with:
267
- python-version: "3.10"
281
+ python-version: "3.13"
268
282
 
269
283
  - name: Get expected build number
270
284
  run: |
@@ -314,6 +328,8 @@ jobs:
314
328
  sed -i '' -e "s/CURRENT_PROJECT_VERSION = 1/CURRENT_PROJECT_VERSION = $BUILD_NUMBER/" ios/Basic.xcodeproj/project.pbxproj
315
329
  sed -i '' -e "s/MARKETING_VERSION = 1.0/MARKETING_VERSION = $CURRENT_VERSION/" ios/Basic.xcodeproj/project.pbxproj
316
330
  sed -i '' -e "s/<string>1<\/string>/<string>$BUILD_NUMBER<\/string>/" ios/Info-STG.plist
331
+ echo "BUILD_NUMBER=$(cat ~/.next_build_number)" >> $GITHUB_ENV
332
+ echo "CURRENT_VERSION=$(cat ~/.current_version)" >> $GITHUB_ENV
317
333
  working-directory: source/examples/TestNamiTV
318
334
 
319
335
  - name: Install test app dependencies
@@ -360,3 +376,13 @@ jobs:
360
376
  env:
361
377
  APPSTORE_API_KEY_ID: "${{ secrets.APPSTORE_API_KEY_ID }}"
362
378
  APPSTORE_ISSUER_ID: "${{ secrets.APPSTORE_ISSUER_ID }}"
379
+
380
+ - name: Upload PR Title to TestFlight Whats New
381
+ working-directory: appstoreconnect-build-tools
382
+ run: |-
383
+ sleep 120
384
+ python3 upload_testflight_whats_new.py com.namiml.stg.testreactnative --notes="${{ env.PR_TITLE }}" --version=${{ env.CURRENT_VERSION }} --platform=TV_OS --prerelease
385
+ env:
386
+ APPSTORE_API_PRIVATE_KEY: ${{ secrets.APPSTORE_API_PRIVATE_KEY }}
387
+ APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }}
388
+ APPSTORE_ISSUER_ID: ${{ secrets.APPSTORE_ISSUER_ID }}
@@ -85,8 +85,8 @@ dependencies {
85
85
  implementation fileTree(dir: 'libs', include: ['*.jar'])
86
86
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
87
87
 
88
- playImplementation "com.namiml:sdk-android:3.2.10"
89
- amazonImplementation "com.namiml:sdk-amazon:3.2.10"
88
+ playImplementation "com.namiml:sdk-android:3.2.11"
89
+ amazonImplementation "com.namiml:sdk-amazon:3.2.11"
90
90
 
91
91
  implementation "com.facebook.react:react-native:+" // From node_modules
92
92
  coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
@@ -106,7 +106,7 @@ class NamiBridgeModule(reactContext: ReactApplicationContext) :
106
106
  } else {
107
107
  Arguments.createArray()
108
108
  }
109
- val settingsList = mutableListOf("extendedClientInfo:react-native:3.2.10")
109
+ val settingsList = mutableListOf("extendedClientInfo:react-native:3.3.0-beta.01")
110
110
  namiCommandsReact?.toArrayList()?.filterIsInstance<String>()?.let { commandsFromReact ->
111
111
  settingsList.addAll(commandsFromReact)
112
112
  }
@@ -27,6 +27,7 @@ public class NamiBridgePackage implements ReactPackage {
27
27
  moduleList.add(new NamiManagerBridgeModule(reactContext));
28
28
  moduleList.add(new NamiCustomerManagerBridgeModule(reactContext));
29
29
  moduleList.add(new NamiCampaignManagerBridgeModule(reactContext));
30
+ moduleList.add(new NamiFlowManagerBridgeModule(reactContext));
30
31
 
31
32
  return moduleList;
32
33
  }
@@ -0,0 +1,36 @@
1
+ package com.nami.reactlibrary
2
+
3
+ import com.facebook.react.bridge.*
4
+ import com.facebook.react.modules.core.DeviceEventManagerModule
5
+ //import com.namiml.customer.NamiFlowManager
6
+
7
+ class NamiFlowManagerBridgeModule(reactContext: ReactApplicationContext) :
8
+ ReactContextBaseJavaModule(reactContext) {
9
+
10
+ override fun getName(): String {
11
+ return "RNNamiFlowManager"
12
+ }
13
+
14
+ @ReactMethod
15
+ fun registerStepHandoff() {
16
+ //NamiFlowManager.registerStepHandoff { handoffTag, handoffData ->
17
+ // val payload = Arguments.createMap().apply {
18
+ // putString("handoffTag", handoffTag)
19
+ // putString("handoffData", handoffData)
20
+ // }
21
+ //
22
+ // sendEvent("RegisterStepHandoff", payload)
23
+ //}
24
+ }
25
+
26
+ @ReactMethod
27
+ fun resume() {
28
+ //NamiFlowManager.resume()
29
+ }
30
+
31
+ private fun sendEvent(eventName: String, params: WritableMap?) {
32
+ reactApplicationContext
33
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
34
+ .emit(eventName, params)
35
+ }
36
+ }
package/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export { NamiEntitlementManager } from './src/NamiEntitlementManager';
6
6
  export { NamiManager } from './src/NamiManager';
7
7
  export { NamiPurchaseManager } from './src/NamiPurchaseManager';
8
8
  export { NamiPaywallManager } from './src/NamiPaywallManager';
9
+ export { NamiFlowManager } from './src/NamiFlowManager';
9
10
  export * from './src/types';
package/index.ts CHANGED
@@ -6,4 +6,5 @@ export { NamiEntitlementManager } from './src/NamiEntitlementManager';
6
6
  export { NamiManager } from './src/NamiManager';
7
7
  export { NamiPurchaseManager } from './src/NamiPurchaseManager';
8
8
  export { NamiPaywallManager } from './src/NamiPaywallManager';
9
+ export { NamiFlowManager } from './src/NamiFlowManager';
9
10
  export * from './src/types';
package/ios/Nami.m CHANGED
@@ -50,7 +50,7 @@ RCT_EXPORT_METHOD(configure: (NSDictionary *)configDict completion: (RCTResponse
50
50
  }
51
51
 
52
52
  // Start commands with header iformation for Nami to let them know this is a React client.
53
- NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.2.10"]];
53
+ NSMutableArray *namiCommandStrings = [NSMutableArray arrayWithArray:@[@"extendedClientInfo:react-native:3.3.0-beta.1"]];
54
54
 
55
55
  // Add additional namiCommands app may have sent in.
56
56
  NSObject *appCommandStrings = configDict[@"namiCommands"];
@@ -238,8 +238,9 @@ class RNNamiCampaignManager: RCTEventEmitter {
238
238
  })
239
239
  }
240
240
  }
241
-
242
- launchMethod?()
241
+ DispatchQueue.main.async {
242
+ launchMethod?()
243
+ }
243
244
  }
244
245
 
245
246
  @objc(allCampaigns:rejecter:)
@@ -265,7 +266,7 @@ class RNNamiCampaignManager: RCTEventEmitter {
265
266
  isCampaignAvailable = NamiCampaignManager.isCampaignAvailable(label: source)
266
267
  }
267
268
  } else {
268
- isCampaignAvailable = NamiCampaignManager.isCampaignAvailable()
269
+ isCampaignAvailable = false
269
270
  }
270
271
  resolve(isCampaignAvailable)
271
272
  }
@@ -0,0 +1,19 @@
1
+ //
2
+ // NamiFlowManagerBridge.m
3
+ // RNNami
4
+ //
5
+ // Copyright © 2025 Nami ML Inc.. All rights reserved.
6
+ //
7
+
8
+ #import <React/RCTBridgeModule.h>
9
+ #import <React/RCTEventEmitter.h>
10
+
11
+ @interface RCT_EXTERN_MODULE(RNNamiFlowManager, RCTEventEmitter)
12
+ RCT_EXTERN_METHOD(registerStepHandoff)
13
+ RCT_EXTERN_METHOD(resume)
14
+
15
+ + (BOOL)requiresMainQueueSetup {
16
+ return YES;
17
+ }
18
+
19
+ @end
@@ -0,0 +1,43 @@
1
+ //
2
+ // NamiFlowManagerBridge.swift
3
+ // RNNami
4
+ //
5
+ // Copyright © 2025 Nami ML Inc.. All rights reserved.
6
+ //
7
+
8
+ import Foundation
9
+ import NamiApple
10
+ import React
11
+
12
+ @objc(RNNamiFlowManager)
13
+ class RNNamiFlowManager: RCTEventEmitter {
14
+ public static var shared: RNNamiFlowManager?
15
+
16
+ override init() {
17
+ super.init()
18
+ RNNamiFlowManager.shared = self
19
+ }
20
+
21
+ override static func requiresMainQueueSetup() -> Bool {
22
+ return true
23
+ }
24
+
25
+ override func supportedEvents() -> [String]! {
26
+ return ["RegisterStepHandoff"]
27
+ }
28
+
29
+ @objc func registerStepHandoff() {
30
+ NamiFlowManager.registerStepHandoff { tag, data in
31
+ let payload: [String: Any] = [
32
+ "handoffTag": tag,
33
+ "handoffData": data ?? "",
34
+ ]
35
+ print("handoff native \(tag) \(data)")
36
+ RNNamiFlowManager.shared?.sendEvent(withName: "RegisterStepHandoff", body: payload)
37
+ }
38
+ }
39
+
40
+ @objc func resume() {
41
+ NamiFlowManager.resume()
42
+ }
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nami-sdk",
3
- "version": "3.2.10",
3
+ "version": "3.3.0-beta.1",
4
4
  "description": "React Native Module for Nami - Easy subscriptions & in-app purchases, with powerful built-in paywalls and A/B testing.",
5
5
  "main": "index.ts",
6
6
  "types": "index.d.ts",
@@ -20,7 +20,7 @@ Pod::Spec.new do |s|
20
20
  s.source_files = "ios/**/*.{h,m,swift}"
21
21
  s.requires_arc = true
22
22
 
23
- s.dependency 'Nami', '3.2.10'
23
+ s.dependency 'Nami', '3.3.0-beta.02'
24
24
  s.dependency 'React'
25
25
 
26
26
  end
@@ -0,0 +1,30 @@
1
+ import { EmitterSubscription } from 'react-native';
2
+
3
+ export interface INamiFlowManager {
4
+ /**
5
+ * Register a callback that will be invoked when a Nami Flow step is handed off to the app.
6
+ * The callback receives the handoffTag (e.g., 'push', 'location') and optional handoffData.
7
+ *
8
+ * Returns a function to remove the listener.
9
+ */
10
+ registerStepHandoff: (
11
+ callback: (handoffTag: string, handoffData?: string) => void
12
+ ) => () => void;
13
+
14
+ /**
15
+ * Resume the Nami Flow after a handoff step is completed.
16
+ */
17
+ resume: () => void;
18
+ }
19
+
20
+ /**
21
+ * Event names emitted by the native NamiFlowManager module.
22
+ */
23
+ export enum NamiFlowManagerEvents {
24
+ RegisterStepHandoff = 'RegisterStepHandoff',
25
+ }
26
+
27
+ /**
28
+ * React Native bridge to the native Nami Flow Manager module.
29
+ */
30
+ export const NamiFlowManager: INamiFlowManager;
@@ -0,0 +1,59 @@
1
+ import {
2
+ NativeModules,
3
+ NativeEventEmitter,
4
+ EmitterSubscription,
5
+ } from 'react-native';
6
+
7
+ const { RNNamiFlowManager } = NativeModules;
8
+
9
+ export enum NamiFlowManagerEvents {
10
+ RegisterStepHandoff = 'RegisterStepHandoff',
11
+ }
12
+
13
+ export interface INamiFlowManager {
14
+ registerStepHandoff: (
15
+ callback: (handoffTag: string, handoffData?: string) => void,
16
+ ) => () => void;
17
+ resume: () => void;
18
+ }
19
+
20
+ if (typeof RNNamiFlowManager?.addListener !== 'function') {
21
+ RNNamiFlowManager.addListener = () => {};
22
+ }
23
+ if (typeof RNNamiFlowManager?.removeListeners !== 'function') {
24
+ RNNamiFlowManager.removeListeners = () => {};
25
+ }
26
+
27
+ const flowEmitter = new NativeEventEmitter(RNNamiFlowManager);
28
+
29
+ export const NamiFlowManager: INamiFlowManager = {
30
+ registerStepHandoff: (callback) => {
31
+ console.log('[NamiFlowManager] Registering handoff listener...');
32
+
33
+ const subscription: EmitterSubscription = flowEmitter.addListener(
34
+ NamiFlowManagerEvents.RegisterStepHandoff,
35
+ (event: { handoffTag: string; handoffData?: string }) => {
36
+ console.log('[NamiFlowManager] Received handoff event:', event);
37
+ callback(event.handoffTag, event.handoffData);
38
+ }
39
+ );
40
+
41
+ if (RNNamiFlowManager?.registerStepHandoff) {
42
+ RNNamiFlowManager.registerStepHandoff();
43
+ } else {
44
+ console.warn('[NamiFlowManager] Native method registerStepHandoff is not available.');
45
+ }
46
+
47
+ return () => {
48
+ subscription.remove();
49
+ };
50
+ },
51
+
52
+ resume: () => {
53
+ if (RNNamiFlowManager?.resume) {
54
+ RNNamiFlowManager.resume();
55
+ } else {
56
+ console.warn('[NamiFlowManager] Native method resume is not available.');
57
+ }
58
+ },
59
+ };