@hawcx/react-native-sdk 1.0.8 → 1.1.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.
Files changed (137) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/HawcxReactNative.podspec +2 -2
  3. package/README.md +325 -109
  4. package/android/build.gradle +2 -2
  5. package/android/src/main/java/com/hawcx/reactnative/HawcxEventDispatcher.kt +4 -0
  6. package/android/src/main/java/com/hawcx/reactnative/HawcxReactNativeModule.kt +324 -1
  7. package/android/src/main/java/com/hawcx/reactnative/v6/HawcxV6Bridge.kt +402 -0
  8. package/ios/Frameworks/HawcxFramework.xcframework/Info.plist +5 -5
  9. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/HawcxFramework +0 -0
  10. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Info.plist +0 -0
  11. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.abi.json +22145 -2
  12. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.private.swiftinterface +628 -0
  13. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  14. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.swiftinterface +628 -0
  15. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.swiftmodule +0 -0
  16. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/HawcxFramework +0 -0
  17. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Info.plist +0 -0
  18. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.abi.json +22145 -2
  19. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +628 -0
  20. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  21. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.swiftinterface +628 -0
  22. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.swiftmodule +0 -0
  23. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.abi.json +22145 -2
  24. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +628 -0
  25. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  26. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +628 -0
  27. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.swiftmodule +0 -0
  28. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/_CodeSignature/CodeResources +21 -21
  29. package/ios/HawcxReactNative.m +56 -0
  30. package/ios/HawcxReactNative.swift +380 -1
  31. package/ios/HawcxV6BridgeSupport.swift +468 -0
  32. package/lib/commonjs/index.js +326 -3
  33. package/lib/commonjs/index.js.map +1 -1
  34. package/lib/commonjs/v6Normalization.js +325 -0
  35. package/lib/commonjs/v6Normalization.js.map +1 -0
  36. package/lib/commonjs/v6State.js +186 -0
  37. package/lib/commonjs/v6State.js.map +1 -0
  38. package/lib/commonjs/v6Types.js +2 -0
  39. package/lib/commonjs/v6Types.js.map +1 -0
  40. package/lib/commonjs/v6WebLogin.js +101 -0
  41. package/lib/commonjs/v6WebLogin.js.map +1 -0
  42. package/lib/module/index.js +287 -1
  43. package/lib/module/index.js.map +1 -1
  44. package/lib/module/v6Normalization.js +318 -0
  45. package/lib/module/v6Normalization.js.map +1 -0
  46. package/lib/module/v6State.js +173 -0
  47. package/lib/module/v6State.js.map +1 -0
  48. package/lib/module/v6Types.js +2 -0
  49. package/lib/module/v6Types.js.map +1 -0
  50. package/lib/module/v6WebLogin.js +92 -0
  51. package/lib/module/v6WebLogin.js.map +1 -0
  52. package/lib/typescript/index.d.ts +83 -0
  53. package/lib/typescript/index.d.ts.map +1 -1
  54. package/lib/typescript/v6Normalization.d.ts +3 -0
  55. package/lib/typescript/v6Normalization.d.ts.map +1 -0
  56. package/lib/typescript/v6State.d.ts +13 -0
  57. package/lib/typescript/v6State.d.ts.map +1 -0
  58. package/lib/typescript/v6Types.d.ts +157 -0
  59. package/lib/typescript/v6Types.d.ts.map +1 -0
  60. package/lib/typescript/v6WebLogin.d.ts +32 -0
  61. package/lib/typescript/v6WebLogin.d.ts.map +1 -0
  62. package/package.json +21 -9
  63. package/src/index.ts +477 -0
  64. package/src/v6Normalization.ts +356 -0
  65. package/src/v6State.ts +238 -0
  66. package/src/v6Types.ts +194 -0
  67. package/src/v6WebLogin.ts +154 -0
  68. package/android/.settings/org.eclipse.buildship.core.prefs +0 -2
  69. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  70. package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
  71. package/android/gradlew +0 -185
  72. package/android/gradlew.bat +0 -89
  73. package/android/libs/hawcx-5.1.4.aar +0 -0
  74. package/docs/RELEASE.md +0 -129
  75. package/example/README.md +0 -59
  76. package/example/android/app/build.gradle +0 -126
  77. package/example/android/app/debug.keystore +0 -0
  78. package/example/android/app/proguard-rules.pro +0 -10
  79. package/example/android/app/src/debug/AndroidManifest.xml +0 -9
  80. package/example/android/app/src/main/AndroidManifest.xml +0 -27
  81. package/example/android/app/src/main/java/com/hawcx/example/MainActivity.kt +0 -22
  82. package/example/android/app/src/main/java/com/hawcx/example/MainApplication.kt +0 -45
  83. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -36
  84. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  85. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  86. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  87. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  88. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  89. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  90. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  91. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  92. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  93. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  94. package/example/android/app/src/main/res/values/strings.xml +0 -3
  95. package/example/android/app/src/main/res/values/styles.xml +0 -9
  96. package/example/android/build.gradle +0 -35
  97. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  98. package/example/android/gradle/wrapper/gradle-wrapper.properties +0 -7
  99. package/example/android/gradle.properties +0 -41
  100. package/example/android/gradlew +0 -249
  101. package/example/android/gradlew.bat +0 -92
  102. package/example/android/local.properties +0 -2
  103. package/example/android/settings.gradle +0 -38
  104. package/example/app.json +0 -4
  105. package/example/babel.config.js +0 -3
  106. package/example/e2e/README.md +0 -17
  107. package/example/e2e/hawcx-login.yaml +0 -14
  108. package/example/index.js +0 -5
  109. package/example/ios/.xcode.env +0 -11
  110. package/example/ios/HawcxExampleApp/AppDelegate.h +0 -6
  111. package/example/ios/HawcxExampleApp/AppDelegate.mm +0 -31
  112. package/example/ios/HawcxExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json +0 -53
  113. package/example/ios/HawcxExampleApp/Images.xcassets/Contents.json +0 -6
  114. package/example/ios/HawcxExampleApp/Info.plist +0 -55
  115. package/example/ios/HawcxExampleApp/LaunchScreen.storyboard +0 -47
  116. package/example/ios/HawcxExampleApp/PrivacyInfo.xcprivacy +0 -37
  117. package/example/ios/HawcxExampleApp/main.m +0 -10
  118. package/example/ios/HawcxExampleApp.xcodeproj/project.pbxproj +0 -704
  119. package/example/ios/HawcxExampleApp.xcodeproj/project.xcworkspace/xcuserdata/agambhullar.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  120. package/example/ios/HawcxExampleApp.xcodeproj/xcshareddata/xcschemes/HawcxExampleApp.xcscheme +0 -90
  121. package/example/ios/HawcxExampleApp.xcodeproj/xcuserdata/agambhullar.xcuserdatad/xcschemes/xcschememanagement.plist +0 -16
  122. package/example/ios/HawcxExampleApp.xcworkspace/contents.xcworkspacedata +0 -10
  123. package/example/ios/HawcxExampleAppTests/HawcxExampleAppTests.m +0 -66
  124. package/example/ios/HawcxExampleAppTests/Info.plist +0 -24
  125. package/example/ios/Podfile +0 -79
  126. package/example/ios/Podfile.lock +0 -1290
  127. package/example/metro.config.js +0 -16
  128. package/example/package-lock.json +0 -13220
  129. package/example/package.json +0 -30
  130. package/example/src/App.tsx +0 -755
  131. package/example/src/hawcx.config.ts +0 -25
  132. package/example/tsconfig.json +0 -8
  133. package/ios/Frameworks/.keep +0 -0
  134. package/lib/typescript/__tests__/index.test.d.ts +0 -2
  135. package/lib/typescript/__tests__/index.test.d.ts.map +0 -1
  136. package/react_mobile_sdk_plan.md +0 -242
  137. package/src/__tests__/index.test.ts +0 -206
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.1] - 2026-04-12
4
+ - Refresh the bundled iOS Hawcx framework to native iOS SDK `6.0.3`.
5
+ - Fix iOS consumer builds by shipping compiled Swift module binaries in the vendored XCFramework.
6
+
7
+ ## [1.1.0] - 2026-04-12
8
+ - Add the public V6 adaptive authentication flow for React Native.
9
+ - Ship V6-ready example apps, docs, and README guidance across iOS and Android.
10
+ - Publish `HawcxReactNative` to CocoaPods in addition to the npm package release.
11
+
3
12
  ## [1.0.8] - 2026-01-21
4
13
  - Android biometrics restriction issue fixed
5
14
 
@@ -20,4 +29,4 @@
20
29
 
21
30
  ## [0.0.1] - 2025-11-15
22
31
  - Initial React Native bridge for Hawcx V5 authentication
23
- - Added HawcxClient helpers, hooks, push support, and example app
32
+ - Added HawcxClient helpers, hooks, push support, and example app
@@ -4,10 +4,10 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
4
  Pod::Spec.new do |s|
5
5
  s.name = 'HawcxReactNative'
6
6
  s.version = package['version']
7
- s.summary = 'React Native bindings for the Hawcx V5 mobile authentication framework.'
7
+ s.summary = 'React Native bindings for the Hawcx mobile authentication SDKs (V5 + V6).'
8
8
  s.description = <<-DESC
9
9
  Production-grade React Native bridge that wraps HawcxFramework (iOS) to expose
10
- V5 authentication, OTP, push, and web session flows to JavaScript callers.
10
+ Hawcx V5 and V6 authentication, device trust, push, and web session flows to JavaScript callers.
11
11
  DESC
12
12
  s.homepage = 'https://github.com/hawcx/reactnative_sdk'
13
13
  s.license = { :type => 'MIT', :file => 'LICENSE' }
package/README.md CHANGED
@@ -1,176 +1,392 @@
1
1
  # Hawcx React Native SDK
2
2
 
3
- Official React Native bindings for the Hawcx V5 mobile authentication platform. The package wraps the production Hawcx iOS and Android SDKs so you can deliver Smart‑Connect (OTP + device trust + push approvals) inside a single cross‑platform API.
3
+ Official React Native bindings for the Hawcx mobile authentication platform. The package
4
+ wraps the production Hawcx iOS and Android SDKs so you can ship the current V6 adaptive
5
+ flow in a single cross-platform API while keeping existing V5 utilities available during
6
+ migration.
7
+
8
+ ## What This Package Includes
9
+
10
+ - V6 adaptive authentication via `useHawcxV6Auth`, `startV6Flow`, and `hawcxV6Client`
11
+ - Production native iOS and Android SDK integrations under the hood
12
+ - Redirect, approval polling, and QR approval helpers for V6 flows
13
+ - Existing V5 auth and push/session helpers for apps already in production
4
14
 
5
15
  ## Requirements
6
16
 
7
- * React Native 0.73 (Hermes enabled by default)
8
- * iOS 17+ / Android 8+ (SDK requires API level 26 for Android)
9
- * OAuth client credentials **must stay on your backend**.
17
+ - React Native 0.73+
18
+ - iOS 17.5+
19
+ - Android API 26+
20
+ - OAuth client credentials kept on your backend
10
21
 
11
22
  ## Installation
12
23
 
24
+ Add the package:
25
+
13
26
  ```bash
14
- npm install @hawcx/react-native-sdk@1.0.8
15
- # or yarn add @hawcx/react-native-sdk
27
+ npm install @hawcx/react-native-sdk@1.1.1
16
28
  ```
17
29
 
18
30
  ### iOS
19
31
 
20
- ```
32
+ Install pods after adding the package:
33
+
34
+ ```bash
21
35
  cd ios
22
36
  pod install
23
37
  cd ..
24
38
  ```
25
39
 
26
- Open the workspace (`ios/*.xcworkspace`) in Xcode when you need to run on a device. The pod installs the vendored HawcxFramework.xcframework automatically.
40
+ The Podspec vendors `HawcxFramework.xcframework` automatically, so no manual iOS
41
+ framework setup is required.
27
42
 
28
43
  ### Android
29
44
 
30
- No manual steps are required—Gradle picks up the bundled `hawcx-*.aar`. Make sure the Android SDK is installed and `ANDROID_HOME`/`adb` are on your path, then run `npm run android`. If you upgrade from an older package version, run `cd android && ./gradlew clean` once before rebuilding so React Native re-links the native module.
45
+ The React Native package depends on the released Hawcx Android SDK, so your Android app
46
+ must be able to resolve the Hawcx Maven repository.
47
+
48
+ Add the repository in `android/settings.gradle`:
49
+
50
+ ```groovy
51
+ dependencyResolutionManagement {
52
+ repositories {
53
+ google()
54
+ mavenCentral()
55
+ maven {
56
+ url = uri("https://raw.githubusercontent.com/hawcx/hawcx_android_sdk/main/maven")
57
+ metadataSources {
58
+ mavenPom()
59
+ artifact()
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ The hosted Hawcx Maven repository is public. You do not need a GitHub token for the
67
+ standard React Native setup.
68
+
69
+ If your Android project still bundles a local `hawcx-*.aar` or uses `flatDir { dirs("libs") }`,
70
+ remove that and let Gradle resolve the native SDK from Maven.
31
71
 
32
- ## Quick Start
72
+ If Gradle has cached an older dependency graph, run:
73
+
74
+ ```bash
75
+ cd android
76
+ ./gradlew clean
77
+ cd ..
78
+ ```
79
+
80
+ ## V6 Quick Start
81
+
82
+ Initialize the SDK once during app bootstrap:
33
83
 
34
84
  ```tsx
35
- import { useEffect } from 'react';
36
- import { initialize, addAuthListener } from '@hawcx/react-native-sdk';
37
-
38
- export function bootstrapHawcx() {
39
- return initialize({
40
- projectApiKey: 'YOUR_PROJECT_API_KEY',
41
- baseUrl: 'https://your-hawcx-host.example.com',
42
- }).then(() => {
43
- const subscription = addAuthListener(event => {
44
- if (event.type === 'auth_error') {
45
- console.warn('Hawcx error', event.payload);
46
- }
47
- });
48
- return () => subscription.remove();
49
- });
85
+ import { initialize } from '@hawcx/react-native-sdk';
86
+
87
+ await initialize({
88
+ projectApiKey: '<YOUR_CONFIG_ID>',
89
+ baseUrl: 'https://stage-api.hawcx.com',
90
+ autoPollApprovals: true,
91
+ });
92
+ ```
93
+
94
+ ### Initialization Notes
95
+
96
+ - `projectApiKey` is the Hawcx value provisioned for this integration. In current public
97
+ releases, this is the same value you may receive as your project API key / Config ID.
98
+ - `baseUrl` should point to your Hawcx tenant host root. Do not append `/v1`, `/auth`,
99
+ or `/hc_auth` yourself.
100
+ - `autoPollApprovals` defaults to `true`, which is the right choice for most apps.
101
+ - `relyingParty` is optional. Set it only when your backend expects the
102
+ `X-Relying-Party` header for this integration.
103
+ - `oauthConfig` is not required for the recommended V6 flow. Keep OAuth credentials on
104
+ your backend.
105
+
106
+ ## How V6 Works
107
+
108
+ 1. Initialize the package with your Config ID and tenant host.
109
+ 2. Start a flow, usually `signin`, with the user's identifier.
110
+ 3. Render the next prompt Hawcx returns.
111
+ 4. Send the user's input back to the SDK.
112
+ 5. When the flow completes, send the authorization code to your backend.
113
+ 6. Let your backend exchange the code and create the app session.
114
+
115
+ The native SDKs handle protocol requests, PKCE when needed, trusted-device storage,
116
+ device-trust processing, and approval polling.
117
+
118
+ ## Build an Auth Screen
119
+
120
+ The recommended React Native integration shape is a screen or coordinator that:
121
+
122
+ 1. holds the current `HawcxV6AuthState`
123
+ 2. starts the flow
124
+ 3. reacts to the current prompt
125
+ 4. forwards the user's input back to the SDK
126
+
127
+ ```tsx
128
+ import { useState } from 'react';
129
+ import { Button, Text, TextInput, View } from 'react-native';
130
+ import {
131
+ useHawcxV6Auth,
132
+ type HawcxV6Method,
133
+ } from '@hawcx/react-native-sdk';
134
+
135
+ export function V6AuthScreen() {
136
+ const [identifier, setIdentifier] = useState('');
137
+ const [code, setCode] = useState('');
138
+ const [totp, setTotp] = useState('');
139
+ const v6 = useHawcxV6Auth(undefined, { flowType: 'signin' });
140
+
141
+ const renderPrompt = () => {
142
+ switch (v6.state.status) {
143
+ case 'select_method':
144
+ return v6.state.prompt?.prompt.type === 'select_method'
145
+ ? v6.state.prompt.prompt.methods.map((method: HawcxV6Method) => (
146
+ <Button
147
+ key={method.id}
148
+ title={method.label}
149
+ onPress={() => void v6.selectMethod(method.id)}
150
+ />
151
+ ))
152
+ : null;
153
+
154
+ case 'enter_code':
155
+ return (
156
+ <>
157
+ <TextInput value={code} onChangeText={setCode} keyboardType="number-pad" />
158
+ <Button title="Continue" onPress={() => void v6.submitCode(code)} />
159
+ </>
160
+ );
161
+
162
+ case 'enter_totp':
163
+ return (
164
+ <>
165
+ <TextInput value={totp} onChangeText={setTotp} />
166
+ <Button title="Continue" onPress={() => void v6.submitTotp(totp)} />
167
+ </>
168
+ );
169
+
170
+ case 'await_approval':
171
+ return <Text>Waiting for approval...</Text>;
172
+
173
+ case 'redirect':
174
+ return <Text>Continue in the browser to finish this step.</Text>;
175
+
176
+ default:
177
+ return null;
178
+ }
179
+ };
180
+
181
+ return (
182
+ <View>
183
+ <TextInput value={identifier} onChangeText={setIdentifier} />
184
+ <Button
185
+ title="Continue"
186
+ onPress={() =>
187
+ void v6.start({
188
+ flowType: 'signin',
189
+ identifier: identifier.trim(),
190
+ })
191
+ }
192
+ />
193
+ {renderPrompt()}
194
+ </View>
195
+ );
50
196
  }
51
197
  ```
52
198
 
53
- Call `bootstrapHawcx()` once when your app starts (e.g., inside your root component or Redux saga). After that you can use hooks or imperative helpers to drive Smart‑Connect.
199
+ ### V6 Flow Types
200
+
201
+ `flowType` supports:
202
+
203
+ - `signin`
204
+ - `signup`
205
+ - `account_manage`
54
206
 
55
- > **Note:** `baseUrl` must be the tenant-specific Hawcx host (e.g., `https://hawcx-api.hawcx.com`). The native SDK appends `/hc_auth` internally and routes all APIs through that cluster.
207
+ Most apps should start with `signin`.
56
208
 
57
- ### Authentication flow (OTP + authorization code)
209
+ ## Redirect Handling
58
210
 
59
- The SDK now always returns an authorization code. Your frontend must forward it to your backend, which redeems it with Hawcx using the OAuth client credentials we issued for your project.
211
+ When the current prompt is `redirect`, open the provided URL in the browser and forward
212
+ the return URL back into the SDK:
60
213
 
61
214
  ```tsx
62
- import React, { useEffect, useState } from 'react';
63
- import { useHawcxAuth, storeBackendOAuthTokens } from '@hawcx/react-native-sdk';
215
+ import { useEffect } from 'react';
216
+ import { Linking } from 'react-native';
217
+
218
+ useEffect(() => {
219
+ const subscription = Linking.addEventListener('url', ({ url }) => {
220
+ void v6.handleRedirectUrl(url);
221
+ });
64
222
 
65
- export function SmartConnectScreen() {
66
- const { state, authenticate, submitOtp, reset } = useHawcxAuth();
67
- const [email, setEmail] = useState('');
68
- const [otp, setOtp] = useState('');
223
+ return () => subscription.remove();
224
+ }, [v6.handleRedirectUrl]);
69
225
 
70
- useEffect(() => {
71
- if (state.status === 'authorization_code') {
72
- void exchangeCode(state.payload).finally(() => reset());
73
- }
74
- }, [state, reset]);
226
+ const openRedirect = async () => {
227
+ if (v6.state.prompt?.prompt.type !== 'redirect') {
228
+ return;
229
+ }
230
+
231
+ await Linking.openURL(v6.state.prompt.prompt.url);
232
+ };
233
+ ```
234
+
235
+ React Native handles the JavaScript callback side, but you still need to register your
236
+ callback scheme natively on iOS and Android so the app receives the return URL.
237
+
238
+ ## Backend Exchange
239
+
240
+ When the flow completes, the SDK returns:
241
+
242
+ - `session`
243
+ - `authCode`
244
+ - `expiresAt`
245
+ - `codeVerifier` when PKCE was generated by the SDK
246
+ - `traceId` for support and correlation
247
+
248
+ For most apps, send `authCode` and `codeVerifier` to your backend immediately over HTTPS
249
+ and perform the exchange there. Keep OAuth client credentials and token verification on
250
+ the server, not in the React Native app.
251
+
252
+ Recommended payload shape:
253
+
254
+ ```json
255
+ {
256
+ "authCode": "<authCode>",
257
+ "codeVerifier": "<optional-codeVerifier>",
258
+ "identifier": "user@example.com",
259
+ "session": "<optional-session>"
260
+ }
261
+ ```
262
+
263
+ Your backend should:
264
+
265
+ 1. exchange `authCode` and `codeVerifier` with the Hawcx backend SDK
266
+ 2. verify the returned claims
267
+ 3. create your app session or tokens
268
+ 4. return the app auth result your app needs
269
+
270
+ ### React Native app-to-backend example
271
+
272
+ ```tsx
273
+ import { useEffect } from 'react';
274
+ import {
275
+ storeBackendOAuthTokens,
276
+ useHawcxV6Auth,
277
+ } from '@hawcx/react-native-sdk';
278
+
279
+ useEffect(() => {
280
+ if (v6.state.status !== 'completed' || !v6.state.completed) {
281
+ return;
282
+ }
75
283
 
76
- const exchangeCode = async ({ code, expiresIn }) => {
77
- const response = await fetch('https://your-backend.example.com/api/hawcx/login', {
284
+ const run = async () => {
285
+ const response = await fetch('https://your-backend.example.com/api/hawcx/exchange', {
78
286
  method: 'POST',
79
287
  headers: { 'Content-Type': 'application/json' },
80
- body: JSON.stringify({ email: email.trim(), code, expires_in: expiresIn }),
288
+ body: JSON.stringify({
289
+ authCode: v6.state.completed.authCode,
290
+ codeVerifier: v6.state.completed.codeVerifier,
291
+ identifier,
292
+ session: v6.state.completed.session,
293
+ }),
81
294
  });
295
+
82
296
  if (!response.ok) {
83
- throw new Error('Backend verification failed');
297
+ throw new Error('Backend exchange failed');
298
+ }
299
+
300
+ const result = await response.json();
301
+
302
+ if (result.accessToken) {
303
+ await storeBackendOAuthTokens(
304
+ identifier,
305
+ result.accessToken,
306
+ result.refreshToken,
307
+ );
84
308
  }
85
- const { access_token, refresh_token } = await response.json();
86
- await storeBackendOAuthTokens(email.trim(), access_token, refresh_token);
87
309
  };
88
310
 
89
- return (
90
- <>
91
- {/* Collect identifier */}
92
- <Button title="Continue" onPress={() => authenticate(email.trim())} />
93
-
94
- {state.status === 'otp' && (
95
- <>
96
- <TextInput value={otp} onChangeText={setOtp} keyboardType="number-pad" />
97
- <Button title="Verify OTP" onPress={() => submitOtp(otp)} />
98
- </>
99
- )}
100
-
101
- {state.status === 'authorization_code' && <Text>Sending authorization code…</Text>}
102
- {state.status === 'additional_verification_required' && (
103
- <Text>Additional verification required: {state.payload.detail ?? state.payload.sessionId}</Text>
104
- )}
105
- {state.status === 'error' && <Text>{state.error.message}</Text>}
106
- </>
107
- );
108
- }
311
+ void run();
312
+ }, [identifier, v6.state]);
109
313
  ```
110
314
 
111
- ### Backend exchange
315
+ `storeBackendOAuthTokens` is optional for the core V6 flow. Use it when your backend
316
+ returns tokens that the shared native session and push helpers should persist.
112
317
 
113
- Redeem the authorization code on your server using the hawcx/oauth-client package or your preferred language SDK. Never ship `clientId`, token endpoint, private keys, or Hawcx public keys inside your mobile app.
318
+ For backend implementation details, see:
114
319
 
115
- ```ts
116
- import express from 'express';
117
- import { exchangeCodeForTokenAndClaims } from '@hawcx/oauth-client';
320
+ - [Node.js backend quickstart](https://docs.hawcx.com/docs/v1/sdk-reference/backend/nodejs/quickstart)
321
+ - [Python backend quickstart](https://docs.hawcx.com/docs/v1/sdk-reference/backend/python/quickstart)
118
322
 
119
- const app = express();
120
- app.use(express.json());
323
+ ## QR Approvals and Web Login Helpers
121
324
 
122
- app.post('/api/hawcx/login', async (req, res) => {
123
- const { email, code, expires_in } = req.body ?? {};
124
- if (!email || !code) {
125
- return res.status(400).json({ success: false, error: 'Missing email or code' });
126
- }
325
+ The package also exposes helpers for QR approval and legacy web-login scans:
127
326
 
128
- try {
129
- const [claims, idToken] = await exchangeCodeForTokenAndClaims({
130
- code,
131
- oauthTokenUrl: process.env.HAWCX_OAUTH_TOKEN_ENDPOINT!,
132
- clientId: process.env.HAWCX_OAUTH_CLIENT_ID!,
133
- publicKey: process.env.HAWCX_OAUTH_PUBLIC_KEY_PEM!,
134
- audience: process.env.HAWCX_OAUTH_CLIENT_ID,
135
- issuer: process.env.HAWCX_OAUTH_ISSUER,
136
- });
327
+ - `routeWebLoginScan(raw)`
328
+ - `approveV6Qr(rawPayload, identifier, options)`
329
+ - `useHawcxWebLogin()`
137
330
 
138
- return res.json({
139
- success: true,
140
- message: `Verified ${claims.email}`,
141
- access_token: idToken,
142
- refresh_token: idToken,
143
- });
144
- } catch (error) {
145
- return res.status(401).json({ success: false, error: error.message });
146
- }
147
- });
331
+ For protocol QR payloads, you can approve directly from React Native:
332
+
333
+ ```tsx
334
+ import { approveV6Qr, routeWebLoginScan } from '@hawcx/react-native-sdk';
335
+
336
+ const route = routeWebLoginScan(scanValue);
337
+ if (route.kind === 'protocol_qr') {
338
+ const result = await approveV6Qr(route.payload.raw, identifier, {
339
+ rememberDevice: true,
340
+ });
341
+
342
+ console.log(result.outcome, result.payloadType);
343
+ }
148
344
  ```
149
345
 
150
- Once the backend responds, call `storeBackendOAuthTokens(userId, tokens)` so the Hawcx SDK saves them securely and can continue handling push registration and device sessions.
346
+ ## Existing V5 and Shared Helpers
347
+
348
+ The package still includes the older V5 auth surface for apps that already use it,
349
+ including:
151
350
 
152
- ## Hooks & Helpers
351
+ - `authenticate`, `submitOtp`, `useHawcxAuth`
352
+ - `useHawcxWebLogin`
353
+ - `setPushDeviceToken`
354
+ - `notifyUserAuthenticated`
355
+ - `handlePushNotification`, `approvePushRequest`, `declinePushRequest`
153
356
 
154
- * `useHawcxAuth()` React hook that exposes the current auth state and helpers (`authenticate`, `submitOtp`, `reset`).
155
- * `useHawcxWebLogin()` Drive QR/PIN based approvals.
156
- * `addAuthListener` / `addSessionListener` / `addPushListener` – Lower-level event APIs if you prefer an imperative approach.
157
- * `setPushDeviceToken` / `notifyUserAuthenticated` – Wire push login approvals.
357
+ Shared helpers such as `initialize` and `storeBackendOAuthTokens` remain available across
358
+ the current package surface.
158
359
 
159
- Refer to the updated [React Quickstart documentation](https://docs.hawcx.com/react/quickstart) for details on each API, push approvals, and device session management.
360
+ That makes incremental migration possible: new V6 flows can live on
361
+ `useHawcxV6Auth` while existing utilities remain available in the same package.
160
362
 
161
363
  ## Example App
162
364
 
163
- `/example` contains a full React Native app wired to the SDK with logging, OTP UI, push harness, and a backend toggle. To run it:
365
+ The `example/` directory contains the in-repo React Native reference app used during SDK
366
+ development:
164
367
 
165
368
  ```bash
166
369
  cd example
167
370
  npm install
168
- npm run ios # or npm run android
371
+ npm run ios
372
+ # or
373
+ npm run android
169
374
  ```
170
375
 
171
- Add your Project API key in `example/src/hawcx.config.ts` or paste it into the in-app form. The **Authorization Code & Backend Exchange** card runs in demo mode by default (codes complete locally). Set `BACKEND_FLOW_ENABLED = true` in `example/src/App.tsx` when you have a tunnel or backend ready to receive `{ code, email, expires_in }`.
376
+ Use it to validate V6 auth flows against your environment before integrating into your
377
+ own app.
378
+
379
+ ## Documentation
380
+
381
+ - [V6 React Native guide](https://docs.hawcx.com/docs/v1/sdk-reference/frontend/react-native/sdk-v6)
382
+ - [V5 React Native guide](https://docs.hawcx.com/docs/v1/sdk-reference/frontend/react-native/sdk)
383
+ - [V6 iOS guide](https://docs.hawcx.com/docs/v1/sdk-reference/frontend/ios/sdk-v6)
384
+ - [V6 Android guide](https://docs.hawcx.com/docs/v1/sdk-reference/frontend/android/sdk-v6)
385
+ - [Node.js backend quickstart](https://docs.hawcx.com/docs/v1/sdk-reference/backend/nodejs/quickstart)
386
+ - [Python backend quickstart](https://docs.hawcx.com/docs/v1/sdk-reference/backend/python/quickstart)
387
+ - [Documentation home](https://docs.hawcx.com)
172
388
 
173
389
  ## Support
174
390
 
175
- * Documentation: [React Quickstart](https://docs.hawcx.com/react/quickstart)
176
- * Questions? Reach out to your Hawcx solutions engineer or info@hawcx.com.
391
+ - [Website](https://www.hawcx.com)
392
+ - [Support Email](mailto:info@hawcx.com)
@@ -22,7 +22,7 @@ def safeExtGet(prop, fallback) {
22
22
  }
23
23
 
24
24
  group = 'com.hawcx.reactnative'
25
- version = project.findProperty('HAWCX_REACT_NATIVE_ANDROID_VERSION') ?: '1.0.8'
25
+ version = project.findProperty('HAWCX_REACT_NATIVE_ANDROID_VERSION') ?: '1.1.1'
26
26
 
27
27
  repositories {
28
28
  mavenCentral()
@@ -124,7 +124,7 @@ afterEvaluate {
124
124
  }
125
125
 
126
126
  dependencies {
127
- api("api.hawcx:hawcx:5.1.4")
127
+ api("api.hawcx:hawcx:6.0.2")
128
128
  def reactNativeVersion = safeExtGet('reactNativeAndroidVersion', '0.73.9')
129
129
  implementation "com.facebook.react:react-android:$reactNativeVersion"
130
130
  implementation 'androidx.annotation:annotation:1.8.1'
@@ -21,6 +21,10 @@ internal class HawcxEventDispatcher(
21
21
  emitEvent(PUSH_EVENT_NAME, type, payload)
22
22
  }
23
23
 
24
+ fun emitV6FlowEvent(type: String, payload: WritableMap? = null) {
25
+ emitEvent(V6_FLOW_EVENT_NAME, type, payload)
26
+ }
27
+
24
28
  private fun emitEvent(eventName: String, type: String, payload: WritableMap?) {
25
29
  val map = Arguments.createMap().apply {
26
30
  putString("type", type)