react-native-nitro-sms-user-consent
v0.1.1
Published
react-native-nitro-sms-user-consent — Android SMS User Consent API (one-tap OTP reading) for React Native, built with Nitro
Maintainers
Readme
react-native-nitro-sms-user-consent
One-tap OTP reading on Android with Google's SMS User Consent API, built on Nitro Modules. No app hash, no SMS permissions.
Features
- 📩 Reads the OTP SMS after a one-tap user consent on Android
- 🔓 No app hash in the SMS template, and no
READ_SMS/RECEIVE_SMSpermissions - ⚡ Built with Nitro Modules: no bridge overhead
- 🪝 Drop-in
useOtpVerifyhook (same shape asreact-native-nitro-otp-verify) - ⏱️ Reports allow, deny, timeout and error outcomes
- 🍎 iOS-safe: no-op on iOS, where the system autofill handles OTPs
Requirements
| | Minimum |
| ---------------------------- | ------------------------ |
| React Native | 0.76.0 (New Architecture) |
| Android | API 23+ with Google Play services |
| react-native-nitro-modules | 0.35.0+ |
Installation
npm install react-native-nitro-sms-user-consent react-native-nitro-modules
# or
bun add react-native-nitro-sms-user-consent react-native-nitro-modulesNo extra setup is needed. The Play services dependency is included automatically.
Usage
import { useOtpVerify } from 'react-native-nitro-sms-user-consent'
export default function OtpScreen() {
const { otp, denied, timeoutError, startListener } = useOtpVerify({
numberOfDigits: 6,
})
useEffect(() => {
if (otp) submitCode(otp)
}, [otp])
// Render your own OTP input. Pass `otp` into it when it arrives.
// Show a "Try again" button that calls startListener() when `denied`/`timeoutError`.
}How it works
- On mount, the hook starts a 5-minute SMS User Consent session.
- When an SMS with a code arrives, Google Play services shows a bottom sheet: "Allow <App> to read the message below and enter the code?"
- If the user taps Allow, the full SMS text is returned and the code is extracted into
otp. - One message per session. After allow, deny or timeout the session ends. Call
startListener()to listen again.
If the SMS arrives while the app is in the background, the consent sheet opens when the user returns to the app.
Hook API
const {
otp, // string | null: extracted code
message, // string | null: full SMS text
denied, // boolean: user tapped "Deny"
timeoutError, // boolean: no SMS within 5 minutes
error, // string | null: e.g. no Play services
isSupported, // boolean: false on iOS / without Play services
isListening, // boolean
startListener,
stopListener,
hash, // always null: kept for migration, deprecated
} = useOtpVerify({
numberOfDigits: 6, // length of the code to extract (default 6)
senderPhoneNumber: '+94...', // only accept SMS from this sender (optional)
autoStart: true, // start on mount (default true)
extractOtp: (sms) => ..., // custom extraction (optional)
})Module API
import { NitroSmsUserConsent } from 'react-native-nitro-sms-user-consent'
NitroSmsUserConsent.isSupported // boolean
await NitroSmsUserConsent.startOtpListener((event) => {
// event.status: 'received' | 'denied' | 'timeout' | 'error'
// event.message: full SMS text when 'received'
// event.error: reason when 'error'
}, senderPhoneNumber /* optional */)
await NitroSmsUserConsent.stopOtpListener() // safe to call any timeSMS requirements
The consent sheet is shown only if the SMS:
- contains a 4–10 character alphanumeric code with at least one digit;
- comes from a sender not in the user's contacts;
- matches
senderPhoneNumber, if you set it.
Your verification code is 123456No app hash is needed.
iOS
iOS has no API for apps to read SMS. The system detects the code itself and offers it above the keyboard. Enable it on your own OTP input:
<TextInput
textContentType="oneTimeCode"
autoComplete={Platform.OS === 'android' ? 'sms-otp' : 'one-time-code'}
keyboardType="number-pad"
/>Optionally end the SMS with a domain-bound code line so iOS only offers it on your domain:
Your verification code is 123456
@yourdomain.com #123456On iOS the hook is a no-op (isSupported: false), so the same screen code runs on both platforms.
Migrating from react-native-nitro-otp-verify
- Swap the package and the import:
- import { useOtpVerify } from 'react-native-nitro-otp-verify' + import { useOtpVerify } from 'react-native-nitro-sms-user-consent' - Remove the 11-character app hash from your SMS template.
hashis now alwaysnull. - Handle
denied: the user can decline the consent sheet. Offer a retry withstartListener(). - Remember that each session reads one message. Call
startListener()again for "Resend code".
Permissions
None. Google Play services reads the SMS, and the app only receives the message the user approves. The library's broadcast receiver is protected by com.google.android.gms.auth.api.phone.permission.SEND, so only Play services can deliver to it.
Platform Support
| Platform | Status |
| -------- | ---------------------------------------------- |
| Android | ✅ SMS User Consent API |
| iOS | ✅ Safe no-op; use textContentType="oneTimeCode" |
AI agent skill
skills/react-native-nitro-sms-user-consent is an agent skill (Claude Code and other SKILL.md-compatible agents). It covers the hook, the SMS format, iOS autofill, migrating from otp-verify, and troubleshooting. To install it, copy or symlink the folder into ~/.claude/skills/:
npx degit hexhad/react-native-nitro-sms-user-consent/skills/react-native-nitro-sms-user-consent ~/.claude/skills/react-native-nitro-sms-user-consentCredits
Bootstrapped with create-nitro-module.
License
MIT
