expo-otp-autofill-consent
v0.1.5
Published
A native Expo module for Android that enables easy OTP autofill using the SMS User Consent API. It requires no special SMS formatting or app hashes, providing a seamless one-tap verification experience.
Maintainers
Readme
expo-otp-autofill-consent 
A native Expo module for Android that enables easy OTP autofill using the SMS User Consent API.
[!IMPORTANT] This module is designed specifically for Android. On iOS, native OTP autofill is handled automatically by the system keyboard when using
textContentType="oneTimeCode".
Features
- One-Tap Consent: Triggers the standard Android system dialog to read the SMS.
- No Permissions Needed: Uses Google Play Services, so you don't need to ask the user for
READ_SMSpermissions. - Easy Integration: Simple event-based API for both capturing the OTP and handling timeouts.
- [x] Expo Managed/Development Builds: Compatible with Expo SDK 54+ (managed and development builds).
Preview
Installation
npx expo install expo-otp-autofill-consentUsage
This example shows how to use the module with React Hook Form and a ref to automatically set the OTP value. It works for both TypeScript and JavaScript.
import React, { useEffect, useRef } from 'react';
import { useForm } from 'react-hook-form';
import {
startSmsUserConsent,
addSmsListener,
removeSmsListener
} from 'expo-otp-autofill-consent';
export default function OtpScreen() {
const { setValue } = useForm();
const otpInputRef = useRef(null);
useEffect(() => {
// 1. Start listening for SMS
startSmsUserConsent();
// 2. Listen for SMS and auto-extract OTP
const subscription = addSmsListener((event) => {
const otp = event.message.match(/\b\d{6}\b/)?.[0];
if (otp) {
// Option A: Set value in React Hook Form
setValue('otp', otp, { shouldValidate: true });
// Option B: Set value using ref directly (Easy & recommended for custom inputs)
otpInputRef.current?.setValue(otp);
}
});
// 3. Cleanup on unmount
return () => {
subscription.remove();
removeSmsListener();
};
}, [setValue]);
return (
// Your OTP input UI
// <OtpInput ref={otpInputRef} ... />
);
}API Reference
startSmsUserConsent(senderPhoneNumber?: string): Promise<void>
Starts listening for incoming SMS messages. Optionally filter by sender phone number.
addSmsListener(callback: (event: { message: string }) => void): EventSubscription
Registers a listener for when an SMS is successfully retrieved.
addSmsTimeoutListener(callback: (event: { message: string }) => void): EventSubscription
Registers a listener for timeout or error events.
removeSmsListener(): void
Stops listening for SMS messages. Call this in cleanup.
How it works (Android)
- Your app calls
startSmsUserConsent(). - When an SMS arrives, Google Play Services checks if it contains a one-time code.
- If it does, a system-level popup asks: "Allow [App Name] to read the code?".
- Once the user taps Allow, the module emits the
onSmsReceivedevent with the full message.
License
MIT
