react-native-otp-auto-verify 0.2.1 → 0.2.2

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.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # react-native-otp-auto-verify
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/react-native-otp-auto-verify.svg?style=flat-square)](https://www.npmjs.com/package/react-native-otp-auto-verify) [![npm downloads](https://img.shields.io/npm/dm/react-native-otp-auto-verify.svg?style=flat-square)](https://www.npmjs.com/package/react-native-otp-auto-verify) [![license](https://img.shields.io/npm/l/react-native-otp-auto-verify.svg?style=flat-square)](https://github.com/kailas-rathod/react-native-otp-auto-verify/blob/main/LICENSE) [![typescript](https://img.shields.io/badge/TypeScript-Ready-blue.svg?style=flat-square)](https://www.typescriptlang.org/)
4
- <img width="1496" height="165" alt="Screenshot 2026-04-02 at 3 11 15 PM" src="https://github.com/user-attachments/assets/1428947c-d120-4552-873b-c63f4e8c671a" />
4
+
5
5
  **react-native-otp-auto-verify** is a lightweight and secure React Native OTP auto-verification library for Android, built on the official Google SMS Retriever API. It enables automatic OTP detection without requiring READ_SMS or RECEIVE_SMS permissions, ensuring full Google Play Store compliance and enhanced user trust. Designed for modern authentication flows, this library is ideal for fintech apps, banking applications, e-commerce platforms, and secure login systems.
6
6
 
7
7
  - **No permissions**: It requires zero SMS permissions from the user, making it compliant with strict Google Play Store policies.
@@ -1,148 +1,148 @@
1
- package com.otpautoverify
2
-
3
- import android.annotation.SuppressLint
4
- import android.content.IntentFilter
5
- import android.os.Build
6
- import android.util.Log
7
- import com.facebook.react.bridge.Arguments
8
- import com.facebook.react.bridge.LifecycleEventListener
9
- import com.facebook.react.bridge.Promise
10
- import com.facebook.react.bridge.ReactApplicationContext
11
- import com.google.android.gms.auth.api.phone.SmsRetriever
12
- import com.google.android.gms.tasks.OnFailureListener
13
- import com.google.android.gms.tasks.OnSuccessListener
14
- class OtpAutoVerifyModule(reactContext: ReactApplicationContext) :
15
- NativeOtpAutoVerifySpec(reactContext), LifecycleEventListener {
16
-
17
- companion object {
18
- const val NAME = NativeOtpAutoVerifySpec.NAME
19
- private const val TAG = "OtpAutoVerifyModule"
20
- const val OTP_RECEIVED_EVENT = "otpReceived"
21
- }
22
-
23
- private var smsReceiver: SmsRetrieverBroadcastReceiver? = null
24
- private var isReceiverRegistered = false
25
- private var isListening = false
26
-
27
- init {
28
- reactContext.addLifecycleEventListener(this)
29
- }
30
-
31
- override fun getTypedExportedConstants(): MutableMap<String, Any> {
32
- return mutableMapOf("OTP_RECEIVED_EVENT" to OTP_RECEIVED_EVENT)
33
- }
34
-
35
- override fun getHash(promise: Promise) {
36
- try {
37
- val helper = AppSignatureHelper(reactApplicationContext)
38
- val signatures = helper.getAppSignatures()
39
- val arr = Arguments.createArray()
40
- for (s in signatures) {
41
- arr.pushString(s)
42
- }
43
- promise.resolve(arr)
44
- } catch (e: Exception) {
45
- Log.e(TAG, "getHash failed", e)
46
- promise.reject("GET_HASH_ERROR", e.message, e)
47
- }
48
- }
49
-
50
- override fun startSmsRetriever(promise: Promise) {
51
- val activity = currentActivity
52
- if (activity == null) {
53
- promise.reject("NO_ACTIVITY", "No current activity. Ensure the app is in the foreground.")
54
- return
55
- }
56
-
57
- registerReceiverIfNecessary(activity)
58
-
59
- val client = SmsRetriever.getClient(reactApplicationContext)
60
- client.startSmsRetriever()
61
- .addOnSuccessListener(OnSuccessListener {
62
- Log.d(TAG, "SMS retriever started")
63
- isListening = true
64
- promise.resolve(true)
65
- })
66
- .addOnFailureListener(OnFailureListener { e ->
67
- Log.e(TAG, "Failed to start SMS retriever", e)
68
- promise.reject("START_SMS_RETRIEVER_ERROR", e.message, e)
69
- })
70
- }
71
-
72
- @SuppressLint("UnspecifiedRegisterReceiverFlag")
73
- private fun registerReceiverIfNecessary(activity: android.app.Activity) {
74
- if (isReceiverRegistered) return
75
- try {
76
- smsReceiver = SmsRetrieverBroadcastReceiver(reactApplicationContext, OTP_RECEIVED_EVENT)
77
- val filter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
78
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
79
- activity.registerReceiver(
80
- smsReceiver,
81
- filter,
82
- SmsRetriever.SEND_PERMISSION,
83
- null,
84
- android.content.Context.RECEIVER_EXPORTED
85
- )
86
- } else {
87
- activity.registerReceiver(smsReceiver, filter)
88
- }
89
- isReceiverRegistered = true
90
- Log.d(TAG, "SMS receiver registered")
91
- } catch (e: Exception) {
92
- Log.e(TAG, "Failed to register SMS receiver", e)
93
- }
94
- }
95
-
96
- private fun unregisterReceiver() {
97
- if (!isReceiverRegistered || smsReceiver == null) {
98
- isListening = false
99
- return
100
- }
101
- val activity = currentActivity
102
- try {
103
- if (activity != null) {
104
- activity.unregisterReceiver(smsReceiver)
105
- Log.d(TAG, "SMS receiver unregistered")
106
- }
107
- } catch (e: IllegalArgumentException) {
108
- Log.w(TAG, "Receiver already unregistered", e)
109
- } catch (e: Exception) {
110
- Log.e(TAG, "Failed to unregister SMS receiver", e)
111
- } finally {
112
- isReceiverRegistered = false
113
- smsReceiver = null
114
- isListening = false
115
- }
116
- }
117
-
118
- override fun addListener(eventName: String) {
119
- // Required for NativeEventEmitter; no-op.
120
- }
121
-
122
- override fun removeListeners(count: Double) {
123
- unregisterReceiver()
124
- }
125
-
126
- override fun onHostResume() {
127
- // Optionally re-register if we were listening and activity was recreated.
128
- if (isListening && currentActivity != null && !isReceiverRegistered) {
129
- currentActivity?.let { registerReceiverIfNecessary(it) }
130
- }
131
- }
132
-
133
- override fun onHostPause() {
134
- // Keep the SMS receiver registered while paused so OTP can still arrive if the user
135
- // briefly switches away (e.g. to read the SMS). Teardown happens in onHostDestroy / invalidate.
136
- }
137
-
138
- override fun onHostDestroy() {
139
- unregisterReceiver()
140
- reactApplicationContext.removeLifecycleEventListener(this)
141
- }
142
-
143
- override fun invalidate() {
144
- unregisterReceiver()
145
- reactApplicationContext.removeLifecycleEventListener(this)
146
- super.invalidate()
147
- }
148
- }
1
+ package com.otpautoverify
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.IntentFilter
5
+ import android.os.Build
6
+ import android.util.Log
7
+ import com.facebook.react.bridge.Arguments
8
+ import com.facebook.react.bridge.LifecycleEventListener
9
+ import com.facebook.react.bridge.Promise
10
+ import com.facebook.react.bridge.ReactApplicationContext
11
+ import com.google.android.gms.auth.api.phone.SmsRetriever
12
+ import com.google.android.gms.tasks.OnFailureListener
13
+ import com.google.android.gms.tasks.OnSuccessListener
14
+ class OtpAutoVerifyModule(reactContext: ReactApplicationContext) :
15
+ NativeOtpAutoVerifySpec(reactContext), LifecycleEventListener {
16
+
17
+ companion object {
18
+ const val NAME = NativeOtpAutoVerifySpec.NAME
19
+ private const val TAG = "OtpAutoVerifyModule"
20
+ const val OTP_RECEIVED_EVENT = "otpReceived"
21
+ }
22
+
23
+ private var smsReceiver: SmsRetrieverBroadcastReceiver? = null
24
+ private var isReceiverRegistered = false
25
+ private var isListening = false
26
+
27
+ init {
28
+ reactContext.addLifecycleEventListener(this)
29
+ }
30
+
31
+ override fun getTypedExportedConstants(): MutableMap<String, Any> {
32
+ return mutableMapOf("OTP_RECEIVED_EVENT" to OTP_RECEIVED_EVENT)
33
+ }
34
+
35
+ override fun getHash(promise: Promise) {
36
+ try {
37
+ val helper = AppSignatureHelper(reactApplicationContext)
38
+ val signatures = helper.getAppSignatures()
39
+ val arr = Arguments.createArray()
40
+ for (s in signatures) {
41
+ arr.pushString(s)
42
+ }
43
+ promise.resolve(arr)
44
+ } catch (e: Exception) {
45
+ Log.e(TAG, "getHash failed", e)
46
+ promise.reject("GET_HASH_ERROR", e.message, e)
47
+ }
48
+ }
49
+
50
+ override fun startSmsRetriever(promise: Promise) {
51
+ val activity = currentActivity
52
+ if (activity == null) {
53
+ promise.reject("NO_ACTIVITY", "No current activity. Ensure the app is in the foreground.")
54
+ return
55
+ }
56
+
57
+ registerReceiverIfNecessary(activity)
58
+
59
+ val client = SmsRetriever.getClient(reactApplicationContext)
60
+ client.startSmsRetriever()
61
+ .addOnSuccessListener(OnSuccessListener {
62
+ Log.d(TAG, "SMS retriever started")
63
+ isListening = true
64
+ promise.resolve(true)
65
+ })
66
+ .addOnFailureListener(OnFailureListener { e ->
67
+ Log.e(TAG, "Failed to start SMS retriever", e)
68
+ promise.reject("START_SMS_RETRIEVER_ERROR", e.message, e)
69
+ })
70
+ }
71
+
72
+ @SuppressLint("UnspecifiedRegisterReceiverFlag")
73
+ private fun registerReceiverIfNecessary(activity: android.app.Activity) {
74
+ if (isReceiverRegistered) return
75
+ try {
76
+ smsReceiver = SmsRetrieverBroadcastReceiver(reactApplicationContext, OTP_RECEIVED_EVENT)
77
+ val filter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
78
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
79
+ activity.registerReceiver(
80
+ smsReceiver,
81
+ filter,
82
+ SmsRetriever.SEND_PERMISSION,
83
+ null,
84
+ android.content.Context.RECEIVER_EXPORTED
85
+ )
86
+ } else {
87
+ activity.registerReceiver(smsReceiver, filter)
88
+ }
89
+ isReceiverRegistered = true
90
+ Log.d(TAG, "SMS receiver registered")
91
+ } catch (e: Exception) {
92
+ Log.e(TAG, "Failed to register SMS receiver", e)
93
+ }
94
+ }
95
+
96
+ private fun unregisterReceiver() {
97
+ if (!isReceiverRegistered || smsReceiver == null) {
98
+ isListening = false
99
+ return
100
+ }
101
+ val activity = currentActivity
102
+ try {
103
+ if (activity != null) {
104
+ activity.unregisterReceiver(smsReceiver)
105
+ Log.d(TAG, "SMS receiver unregistered")
106
+ }
107
+ } catch (e: IllegalArgumentException) {
108
+ Log.w(TAG, "Receiver already unregistered", e)
109
+ } catch (e: Exception) {
110
+ Log.e(TAG, "Failed to unregister SMS receiver", e)
111
+ } finally {
112
+ isReceiverRegistered = false
113
+ smsReceiver = null
114
+ isListening = false
115
+ }
116
+ }
117
+
118
+ override fun addListener(eventName: String) {
119
+ // Required for NativeEventEmitter; no-op.
120
+ }
121
+
122
+ override fun removeListeners(count: Double) {
123
+ unregisterReceiver()
124
+ }
125
+
126
+ override fun onHostResume() {
127
+ // Optionally re-register if we were listening and activity was recreated.
128
+ if (isListening && currentActivity != null && !isReceiverRegistered) {
129
+ currentActivity?.let { registerReceiverIfNecessary(it) }
130
+ }
131
+ }
132
+
133
+ override fun onHostPause() {
134
+ // Keep the SMS receiver registered while paused so OTP can still arrive if the user
135
+ // briefly switches away (e.g. to read the SMS). Teardown happens in onHostDestroy / invalidate.
136
+ }
137
+
138
+ override fun onHostDestroy() {
139
+ unregisterReceiver()
140
+ reactApplicationContext.removeLifecycleEventListener(this)
141
+ }
142
+
143
+ override fun invalidate() {
144
+ unregisterReceiver()
145
+ reactApplicationContext.removeLifecycleEventListener(this)
146
+ super.invalidate()
147
+ }
148
+ }
@@ -1,37 +1,37 @@
1
- import {
2
- NativeModules,
3
- TurboModuleRegistry,
4
- type TurboModule,
5
- } from 'react-native';
6
-
7
- export interface Spec extends TurboModule {
8
- getConstants(): { OTP_RECEIVED_EVENT: string };
9
- getHash(): Promise<ReadonlyArray<string>>;
10
- startSmsRetriever(): Promise<boolean>;
11
- addListener(eventName: string): void;
12
- removeListeners(count: number): void;
13
- }
14
-
15
- function loadNativeModule(): Spec {
16
- try {
17
- return TurboModuleRegistry.getEnforcing<Spec>('OtpAutoVerify');
18
- } catch {
19
- const legacy = NativeModules.OtpAutoVerify;
20
- if (!legacy) {
21
- throw new Error(
22
- 'OtpAutoVerify native module is not available. Ensure the library is properly linked.'
23
- );
24
- }
25
- return legacy as Spec;
26
- }
27
- }
28
-
29
- let cachedModule: Spec | null = null;
30
-
31
- /** Resolves the native module on first use so importing this package does not throw before APIs run. */
32
- export function getOtpNativeModule(): Spec {
33
- if (cachedModule === null) {
34
- cachedModule = loadNativeModule();
35
- }
36
- return cachedModule;
37
- }
1
+ import {
2
+ NativeModules,
3
+ TurboModuleRegistry,
4
+ type TurboModule,
5
+ } from 'react-native';
6
+
7
+ export interface Spec extends TurboModule {
8
+ getConstants(): { OTP_RECEIVED_EVENT: string };
9
+ getHash(): Promise<ReadonlyArray<string>>;
10
+ startSmsRetriever(): Promise<boolean>;
11
+ addListener(eventName: string): void;
12
+ removeListeners(count: number): void;
13
+ }
14
+
15
+ function loadNativeModule(): Spec {
16
+ try {
17
+ return TurboModuleRegistry.getEnforcing<Spec>('OtpAutoVerify');
18
+ } catch {
19
+ const legacy = NativeModules.OtpAutoVerify;
20
+ if (!legacy) {
21
+ throw new Error(
22
+ 'OtpAutoVerify native module is not available. Ensure the library is properly linked.'
23
+ );
24
+ }
25
+ return legacy as Spec;
26
+ }
27
+ }
28
+
29
+ let cachedModule: Spec | null = null;
30
+
31
+ /** Resolves the native module on first use so importing this package does not throw before APIs run. */
32
+ export function getOtpNativeModule(): Spec {
33
+ if (cachedModule === null) {
34
+ cachedModule = loadNativeModule();
35
+ }
36
+ return cachedModule;
37
+ }
package/package.json CHANGED
@@ -1,183 +1,183 @@
1
- {
2
- "name": "react-native-otp-auto-verify",
3
- "version": "0.2.1",
4
- "description": "react-native-otp-auto-verify is a React Native library for automatic OTP verification on Android and iOS. It uses the Google SMS Retriever API to detect OTP codes automatically without requiring the READ_SMS permission. The library is fully Play Store compliant, improves user login experience, supports TurboModule, and works with the React Native New Architecture",
5
- "keywords": [
6
- "react-native",
7
- "react-native-library",
8
- "react-native-otp",
9
- "react-native-otp-auto-verify",
10
- "react-native-sms",
11
- "otp",
12
- "otp-verification",
13
- "otp-auto-verify",
14
- "otp-auto-read",
15
- "sms",
16
- "sms-retriever",
17
- "google-sms-retriever",
18
- "android-otp",
19
- "ios-otp",
20
- "otp-without-permission",
21
- "play-store-compliant",
22
- "react-native-new-architecture",
23
- "turbo-module"
24
- ],
25
- "homepage": "https://github.com/kailas-rathod/react-native-otp-auto-verify?tab=readme-ov-file",
26
- "bugs": {
27
- "url": "https://github.com/kailas-rathod/react-native-otp-auto-verify/issues"
28
- },
29
- "repository": {
30
- "type": "git",
31
- "url": "git+https://github.com/kailas-rathod/react-native-otp-auto-verify.git"
32
- },
33
- "license": "MIT",
34
- "author": "Kailas Rathod (https://github.com/kailas-rathod)",
35
- "type": "commonjs",
36
- "main": "./lib/module/index.js",
37
- "types": "./lib/typescript/src/index.d.ts",
38
- "files": [
39
- "src",
40
- "lib",
41
- "android",
42
- "ios",
43
- "*.podspec",
44
- "react-native.config.js",
45
- "!ios/build",
46
- "!android/build",
47
- "!android/gradle",
48
- "!android/gradlew",
49
- "!android/gradlew.bat",
50
- "!android/local.properties",
51
- "!**/__tests__",
52
- "!**/__fixtures__",
53
- "!**/__mocks__",
54
- "!**/.*"
55
- ],
56
- "scripts": {
57
- "prepare": "bob build",
58
- "typecheck": "tsc",
59
- "lint": "eslint \"**/*.{js,ts,tsx}\"",
60
- "test": "jest",
61
- "check": "yarn typecheck && yarn lint && yarn test",
62
- "release": "release-it --only-version"
63
- },
64
- "devDependencies": {
65
- "@babel/eslint-parser": "^7.28.0",
66
- "@commitlint/config-conventional": "^19.8.1",
67
- "@eslint/eslintrc": "^3.3.4",
68
- "@eslint/js": "9.35.0",
69
- "@react-native-community/eslint-config": "^3.2.0",
70
- "@react-native-community/eslint-plugin": "^1.1.0",
71
- "@typescript-eslint/eslint-plugin": "^8.15.0",
72
- "@typescript-eslint/parser": "^8.15.0",
73
- "@react-native/babel-preset": "0.83.3",
74
- "@release-it/conventional-changelog": "^10.0.6",
75
- "@types/jest": "^29.5.14",
76
- "@types/react": "^19.2.0",
77
- "commitlint": "^19.8.1",
78
- "eslint": "9.35.0",
79
- "eslint-config-prettier": "^9.1.0",
80
- "eslint-plugin-eslint-comments": "^3.2.0",
81
- "eslint-plugin-ft-flow": "^2.0.1",
82
- "eslint-plugin-jest": "^28.11.0",
83
- "eslint-plugin-prettier": "^5.5.4",
84
- "eslint-plugin-react": "^7.37.0",
85
- "eslint-plugin-react-hooks": "^4.6.0",
86
- "eslint-plugin-react-native": "^5.0.0",
87
- "jest": "^30.3.0",
88
- "prettier": "^3.4.2",
89
- "react": "19.2.5",
90
- "react-native": "0.83.3",
91
- "react-native-builder-bob": "0.39.1",
92
- "release-it": "^19.0.4",
93
- "typescript": "^5.9.3"
94
- },
95
- "peerDependencies": {
96
- "react": "*",
97
- "react-native": "*"
98
- },
99
- "publishConfig": {
100
- "registry": "https://registry.npmjs.org/"
101
- },
102
- "eslintConfig": {
103
- "root": true,
104
- "extends": [
105
- "@react-native-community",
106
- "prettier"
107
- ],
108
- "rules": {
109
- "prettier/prettier": [
110
- "error",
111
- {
112
- "quoteProps": "consistent",
113
- "singleQuote": true,
114
- "tabWidth": 2,
115
- "trailingComma": "es5",
116
- "useTabs": false
117
- }
118
- ]
119
- }
120
- },
121
- "eslintIgnore": [
122
- "node_modules/",
123
- "lib/"
124
- ],
125
- "packageManager": "yarn@4.11.0",
126
- "react-native-builder-bob": {
127
- "source": "src",
128
- "output": "lib",
129
- "targets": [
130
- [
131
- "module",
132
- {
133
- "esm": true
134
- }
135
- ],
136
- [
137
- "typescript",
138
- {
139
- "project": "tsconfig.build.json"
140
- }
141
- ]
142
- ]
143
- },
144
- "codegenConfig": {
145
- "name": "OtpAutoVerifySpec",
146
- "type": "modules",
147
- "jsSrcsDir": "src",
148
- "android": {
149
- "javaPackageName": "com.otpautoverify"
150
- }
151
- },
152
- "prettier": {
153
- "quoteProps": "consistent",
154
- "singleQuote": true,
155
- "tabWidth": 2,
156
- "trailingComma": "es5",
157
- "useTabs": false
158
- },
159
- "commitlint": {
160
- "extends": [
161
- "@commitlint/config-conventional"
162
- ]
163
- },
164
- "release-it": {
165
- "git": {
166
- "commitMessage": "chore: release ${version}",
167
- "tagName": "v${version}"
168
- },
169
- "npm": {
170
- "publish": true
171
- },
172
- "github": {
173
- "release": true
174
- },
175
- "plugins": {
176
- "@release-it/conventional-changelog": {
177
- "preset": {
178
- "name": "angular"
179
- }
180
- }
181
- }
182
- }
183
- }
1
+ {
2
+ "name": "react-native-otp-auto-verify",
3
+ "version": "0.2.2",
4
+ "description": "react-native-otp-auto-verify is a React Native library for automatic OTP verification on Android and iOS. It uses the Google SMS Retriever API to detect OTP codes automatically without requiring the READ_SMS permission. The library is fully Play Store compliant, improves user login experience, supports TurboModule, and works with the React Native New Architecture",
5
+ "keywords": [
6
+ "react-native",
7
+ "react-native-library",
8
+ "react-native-otp",
9
+ "react-native-otp-auto-verify",
10
+ "react-native-sms",
11
+ "otp",
12
+ "otp-verification",
13
+ "otp-auto-verify",
14
+ "otp-auto-read",
15
+ "sms",
16
+ "sms-retriever",
17
+ "google-sms-retriever",
18
+ "android-otp",
19
+ "ios-otp",
20
+ "otp-without-permission",
21
+ "play-store-compliant",
22
+ "react-native-new-architecture",
23
+ "turbo-module"
24
+ ],
25
+ "homepage": "https://github.com/kailas-rathod/react-native-otp-auto-verify?tab=readme-ov-file",
26
+ "bugs": {
27
+ "url": "https://github.com/kailas-rathod/react-native-otp-auto-verify/issues"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/kailas-rathod/react-native-otp-auto-verify.git"
32
+ },
33
+ "license": "MIT",
34
+ "author": "Kailas Rathod (https://github.com/kailas-rathod)",
35
+ "type": "commonjs",
36
+ "main": "./lib/module/index.js",
37
+ "types": "./lib/typescript/src/index.d.ts",
38
+ "files": [
39
+ "src",
40
+ "lib",
41
+ "android",
42
+ "ios",
43
+ "*.podspec",
44
+ "react-native.config.js",
45
+ "!ios/build",
46
+ "!android/build",
47
+ "!android/gradle",
48
+ "!android/gradlew",
49
+ "!android/gradlew.bat",
50
+ "!android/local.properties",
51
+ "!**/__tests__",
52
+ "!**/__fixtures__",
53
+ "!**/__mocks__",
54
+ "!**/.*"
55
+ ],
56
+ "scripts": {
57
+ "prepare": "bob build",
58
+ "typecheck": "tsc",
59
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
60
+ "test": "jest",
61
+ "check": "yarn typecheck && yarn lint && yarn test",
62
+ "release": "release-it --only-version"
63
+ },
64
+ "devDependencies": {
65
+ "@babel/eslint-parser": "^7.28.0",
66
+ "@commitlint/config-conventional": "^19.8.1",
67
+ "@eslint/eslintrc": "^3.3.4",
68
+ "@eslint/js": "9.35.0",
69
+ "@react-native-community/eslint-config": "^3.2.0",
70
+ "@react-native-community/eslint-plugin": "^1.1.0",
71
+ "@typescript-eslint/eslint-plugin": "^8.15.0",
72
+ "@typescript-eslint/parser": "^8.15.0",
73
+ "@react-native/babel-preset": "0.83.3",
74
+ "@release-it/conventional-changelog": "^10.0.6",
75
+ "@types/jest": "^29.5.14",
76
+ "@types/react": "^19.2.0",
77
+ "commitlint": "^19.8.1",
78
+ "eslint": "9.35.0",
79
+ "eslint-config-prettier": "^9.1.0",
80
+ "eslint-plugin-eslint-comments": "^3.2.0",
81
+ "eslint-plugin-ft-flow": "^2.0.1",
82
+ "eslint-plugin-jest": "^28.11.0",
83
+ "eslint-plugin-prettier": "^5.5.4",
84
+ "eslint-plugin-react": "^7.37.0",
85
+ "eslint-plugin-react-hooks": "^4.6.0",
86
+ "eslint-plugin-react-native": "^5.0.0",
87
+ "jest": "^30.3.0",
88
+ "prettier": "^3.4.2",
89
+ "react": "19.2.5",
90
+ "react-native": "0.83.3",
91
+ "react-native-builder-bob": "0.39.1",
92
+ "release-it": "^19.0.4",
93
+ "typescript": "^5.9.3"
94
+ },
95
+ "peerDependencies": {
96
+ "react": "*",
97
+ "react-native": "*"
98
+ },
99
+ "publishConfig": {
100
+ "registry": "https://registry.npmjs.org/"
101
+ },
102
+ "eslintConfig": {
103
+ "root": true,
104
+ "extends": [
105
+ "@react-native-community",
106
+ "prettier"
107
+ ],
108
+ "rules": {
109
+ "prettier/prettier": [
110
+ "error",
111
+ {
112
+ "quoteProps": "consistent",
113
+ "singleQuote": true,
114
+ "tabWidth": 2,
115
+ "trailingComma": "es5",
116
+ "useTabs": false
117
+ }
118
+ ]
119
+ }
120
+ },
121
+ "eslintIgnore": [
122
+ "node_modules/",
123
+ "lib/"
124
+ ],
125
+ "packageManager": "yarn@4.11.0",
126
+ "react-native-builder-bob": {
127
+ "source": "src",
128
+ "output": "lib",
129
+ "targets": [
130
+ [
131
+ "module",
132
+ {
133
+ "esm": true
134
+ }
135
+ ],
136
+ [
137
+ "typescript",
138
+ {
139
+ "project": "tsconfig.build.json"
140
+ }
141
+ ]
142
+ ]
143
+ },
144
+ "codegenConfig": {
145
+ "name": "OtpAutoVerifySpec",
146
+ "type": "modules",
147
+ "jsSrcsDir": "src",
148
+ "android": {
149
+ "javaPackageName": "com.otpautoverify"
150
+ }
151
+ },
152
+ "prettier": {
153
+ "quoteProps": "consistent",
154
+ "singleQuote": true,
155
+ "tabWidth": 2,
156
+ "trailingComma": "es5",
157
+ "useTabs": false
158
+ },
159
+ "commitlint": {
160
+ "extends": [
161
+ "@commitlint/config-conventional"
162
+ ]
163
+ },
164
+ "release-it": {
165
+ "git": {
166
+ "commitMessage": "chore: release ${version}",
167
+ "tagName": "v${version}"
168
+ },
169
+ "npm": {
170
+ "publish": true
171
+ },
172
+ "github": {
173
+ "release": true
174
+ },
175
+ "plugins": {
176
+ "@release-it/conventional-changelog": {
177
+ "preset": {
178
+ "name": "angular"
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
@@ -1,37 +1,37 @@
1
- import {
2
- NativeModules,
3
- TurboModuleRegistry,
4
- type TurboModule,
5
- } from 'react-native';
6
-
7
- export interface Spec extends TurboModule {
8
- getConstants(): { OTP_RECEIVED_EVENT: string };
9
- getHash(): Promise<ReadonlyArray<string>>;
10
- startSmsRetriever(): Promise<boolean>;
11
- addListener(eventName: string): void;
12
- removeListeners(count: number): void;
13
- }
14
-
15
- function loadNativeModule(): Spec {
16
- try {
17
- return TurboModuleRegistry.getEnforcing<Spec>('OtpAutoVerify');
18
- } catch {
19
- const legacy = NativeModules.OtpAutoVerify;
20
- if (!legacy) {
21
- throw new Error(
22
- 'OtpAutoVerify native module is not available. Ensure the library is properly linked.'
23
- );
24
- }
25
- return legacy as Spec;
26
- }
27
- }
28
-
29
- let cachedModule: Spec | null = null;
30
-
31
- /** Resolves the native module on first use so importing this package does not throw before APIs run. */
32
- export function getOtpNativeModule(): Spec {
33
- if (cachedModule === null) {
34
- cachedModule = loadNativeModule();
35
- }
36
- return cachedModule;
37
- }
1
+ import {
2
+ NativeModules,
3
+ TurboModuleRegistry,
4
+ type TurboModule,
5
+ } from 'react-native';
6
+
7
+ export interface Spec extends TurboModule {
8
+ getConstants(): { OTP_RECEIVED_EVENT: string };
9
+ getHash(): Promise<ReadonlyArray<string>>;
10
+ startSmsRetriever(): Promise<boolean>;
11
+ addListener(eventName: string): void;
12
+ removeListeners(count: number): void;
13
+ }
14
+
15
+ function loadNativeModule(): Spec {
16
+ try {
17
+ return TurboModuleRegistry.getEnforcing<Spec>('OtpAutoVerify');
18
+ } catch {
19
+ const legacy = NativeModules.OtpAutoVerify;
20
+ if (!legacy) {
21
+ throw new Error(
22
+ 'OtpAutoVerify native module is not available. Ensure the library is properly linked.'
23
+ );
24
+ }
25
+ return legacy as Spec;
26
+ }
27
+ }
28
+
29
+ let cachedModule: Spec | null = null;
30
+
31
+ /** Resolves the native module on first use so importing this package does not throw before APIs run. */
32
+ export function getOtpNativeModule(): Spec {
33
+ if (cachedModule === null) {
34
+ cachedModule = loadNativeModule();
35
+ }
36
+ return cachedModule;
37
+ }