title: Authenticating Users via One-Time Password (OTP) description: Learn how to authenticate users via a one-time password (OTP), sent to their email
Authenticating Users via OTP
Authenticating a user is easy using the useAuthenticate()
hook from the @account-kit/react-native
package.
Set the Email Mode to One Time Password (OTP)
in your Account Kit Dashboard
In your Alchemy Accounts Dashboard:
-
Navigate to the Smart Wallets tab
-
Select the config you would be using for your project and click the Edit button
-
Scroll down to the Email Mode options in the Email section and select One Time Password (OTP)
-
Click the Save Changes button
Send a One-Time Password (OTP) to a User
To send an OTP to a user's email, use the authenticate()
function from the useAuthenticate()
hook with the type
set to email
and the emailMode
set to otp
.
import { useAuthenticate } from "@account-kit/react-native";
import React, { useState } from "react";
import { Alert, View, Text, TextInput, Button, Pressable } from "react-native";
function SignInWithOtp() {
const { authenticate } = useAuthenticate();
const [email, setEmail] = useState("");
const handleUserSignInWithOtp = () => {
try {
authenticate({
email,
type: "email",
});
// OTP sent to the user's email. Prompt the user to enter the OTP into your app.
} catch (e) {
Alert.alert("Error sending OTP Code. Check logs for more details.");
console.log("Error seding OTP CODE: ", e);
}
};
return (
<View>
<Text>Enter Your Email to Sign In</Text>
<View>
<TextInput
value={email}
onChangeText={(val) => setEmail(val.toLowerCase())}
placeholder="john@doe.com"
/>
<Pressable onPress={handleUserSignInWithOtp}>
{({ pressed }) => (
<View
style={[
{
opacity: pressed ? 0.5 : 1,
transform: [
{
scale: pressed ? 0.98 : 1,
},
],
},
]}
>
<Text>Sign In</Text>
</View>
)}
</Pressable>
</View>
</View>
);
}
Prompt the User to enter the One-Time Password to complete authentication
The user will receive an email with a one-time password (OTP) to enter into your app.
Provide a means for the user to enter the OTP into your app and then call the authenticate()
function from the useAuthenticate()
hook passing the OTP code to the otpCode
parameter, and the type
set to otp
.
import { useAuthenticate } from "@account-kit/react-native";
import React, { useState } from "react";
import { Alert, View, Text, TextInput, Button, Pressable } from "react-native";
function VerifyOtp() {
const { authenticate } = useAuthenticate();
const [otpCode, setOtpCode] = useState("");
const handleUserVerifyOtp = () => {
try {
authenticate({
otpCode,
type: "otp",
});
// OTP verified. User is authenticated.
} catch (e) {
Alert.alert("Error verifying OTP Code. Check logs for more details.");
console.log("Error verifying OTP CODE: ", e);
}
};
return (
<View>
<View>
<Text>Enter Your OTP Code</Text>
<View>
<TextInput
value={otpCode}
onChangeText={setOtpCode}
placeholder="123456"
/>
<Pressable onPress={handleUserVerifyOtp}>
{({ pressed }) => (
<View
style={[
{
opacity: pressed ? 0.5 : 1,
transform: [
{
scale: pressed ? 0.98 : 1,
},
],
},
]}
>
<Text>Submit OTP</Text>
</View>
)}
</Pressable>
</View>
</View>
</View>
);
}
Here's an example of a Sign In component using OTP. Feel free to embed this into your application to give it a try!
import React, { useCallback, useState } from "react";
import { View, Text, TextInput, Button } from "react-native";
import { useAuthenticate, useUser } from "@account-kit/react-native";
import { OtpPopUp } from "./otp-popup";
export const SignInWithOtp = () => {
const [email, setEmail] = useState<string>("");
const [showOtp, setShowOtp] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(false);
const { authenticate } = useAuthenticate();
const { user } = useUser();
// Make an authentication request to a user's email
const performAuthRequest = useCallback(
(email: string) => {
try {
authenticate({
email,
type: "email",
emailMode: "otp",
});
setLoading(true);
setShowOtp(true);
} catch (e) {
Alert.alert("Error sending OTP Code. Check logs for more details.");
console.log("Error seding OTP CODE: ", e);
}
},
[authenticate]
);
const completeAuth = useCallback(() => {
setLoading(false);
setShowOtp(false);
}, []);
return (
<View>
{user && (
<>
<Text>User Authenticated As: {user.email}</Text>
<Text>{user.address}</Text>
</>
)}
<Text style={{ fontSize: 16 }}>Enter Email</Text>
<TextInput
value={email}
style={{ fontSize: 20 }}
onChangeText={setEmail}
placeholder="Enter Email"
autoCapitalize="none"
/>
<Button
title={loading ? "Loading" : "Sign In"}
disabled={loading}
onPress={() => performAuthRequest(email)}
/>
<OtpPopUp
show={showOtp}
completeAuth={completeAuth}
close={() => {
setShowOtp(false);
setLoading(false);
}}
/>
</View>
);
};