usePhoneOtpAuth
Authenticate users with phone OTP (SMS one-time password) for passwordless login.
Usage
import { usePhoneOtpAuth } from '@openfort/react';
function PhoneOtpLogin() {
const { requestPhoneOtp, logInWithPhoneOtp, isRequesting, isLoading } = usePhoneOtpAuth();
const [phoneNumber, setPhoneNumber] = useState('');
const [otp, setOtp] = useState('');
const [otpSent, setOtpSent] = useState(false);
const handleRequestOtp = async () => {
const { error } = await requestPhoneOtp({ phoneNumber });
if (!error) setOtpSent(true);
};
const handleSignIn = async () => {
const { user, error } = await logInWithPhoneOtp({ phoneNumber, otp });
if (user) console.log('Signed in:', user.id);
};
return (
<div>
<input value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} placeholder="+1234567890" />
{otpSent && (
<input value={otp} onChange={(e) => setOtp(e.target.value)} placeholder="Enter OTP" />
)}
{!otpSent ? (
<button onClick={handleRequestOtp} disabled={isRequesting}>
{isRequesting ? 'Sending...' : 'Send OTP'}
</button>
) : (
<button onClick={handleSignIn} disabled={isLoading}>
{isLoading ? 'Signing in...' : 'Sign In'}
</button>
)}
</div>
);
}Return type
type PhoneOtpAuthReturn = {
requestPhoneOtp(options: RequestPhoneOtpOptions): Promise<PhoneAuthResult>
logInWithPhoneOtp(options: LoginWithPhoneOtpOptions): Promise<PhoneAuthResult>
linkPhoneOtp(options: LoginWithPhoneOtpOptions): Promise<PhoneAuthResult>
reset(): void
isRequesting: boolean
isLoading: boolean
isError: boolean
isSuccess: boolean
isAwaitingInput: boolean
error?: OpenfortError | null
}
type PhoneAuthResult = {
user?: User
wallet?: UserWallet
error?: OpenfortError
}Hook options
Configure default behavior when initializing the hook.
type UsePhoneHookOptions = {
// Log out the user if wallet recovery fails. Defaults to true.
logoutOnError?: boolean
// Automatically recover the wallet after authentication. Defaults to true.
recoverWalletAutomatically?: boolean
onSuccess?: (data: PhoneAuthResult) => void
onError?: (error: OpenfortError) => void
}Parameters
requestPhoneOtp
Request an OTP code to be sent to the user's phone via SMS.
type RequestPhoneOtpOptions = {
phoneNumber: string
onSuccess?: (data: PhoneAuthResult) => void
onError?: (error: OpenfortError) => void
}logInWithPhoneOtp
Sign in with the phone number and OTP code.
type LoginWithPhoneOtpOptions = {
phoneNumber: string
otp: string
// Overrides the hook-level default.
logoutOnError?: boolean
// Overrides the hook-level default.
recoverWalletAutomatically?: boolean
onSuccess?: (data: PhoneAuthResult) => void
onError?: (error: OpenfortError) => void
}linkPhoneOtp
Link a phone number to an existing authenticated user. The user must already be authenticated (for example, via email or OAuth) before linking a phone number.
type LinkPhoneOtpOptions = {
phoneNumber: string
otp: string
onSuccess?: (data: PhoneAuthResult) => void
onError?: (error: OpenfortError) => void
}Note: Unlike logInWithPhoneOtp, the linkPhoneOtp function does not create or recover a wallet—it only links the phone number to the existing user account.
Link phone example
import { usePhoneOtpAuth, useUser } from '@openfort/react';
function LinkPhoneNumber() {
const { user } = useUser();
const { requestPhoneOtp, linkPhoneOtp, isRequesting, isLoading } = usePhoneOtpAuth();
const [phoneNumber, setPhoneNumber] = useState('');
const [otp, setOtp] = useState('');
const [otpSent, setOtpSent] = useState(false);
if (!user) return <p>Please sign in first</p>;
const handleRequestOtp = async () => {
const { error } = await requestPhoneOtp({ phoneNumber });
if (!error) setOtpSent(true);
};
const handleLinkPhone = async () => {
const { user, error } = await linkPhoneOtp({ phoneNumber, otp });
if (user) console.log('Phone linked successfully');
};
return (
<div>
<input value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} placeholder="+1234567890" />
{otpSent && (
<input value={otp} onChange={(e) => setOtp(e.target.value)} placeholder="Enter OTP" />
)}
{!otpSent ? (
<button onClick={handleRequestOtp} disabled={isRequesting}>
{isRequesting ? 'Sending...' : 'Send OTP'}
</button>
) : (
<button onClick={handleLinkPhone} disabled={isLoading}>
{isLoading ? 'Linking...' : 'Link Phone'}
</button>
)}
</div>
);
}Related
- useEmailOtpAuth - Email OTP authentication
- useEmailAuth - Email/password authentication