Skip to content

Authenticating Users via OTP

This guide assumes you have already followed the Setup Guide and have a basic understanding of how to use the Signer in your project.

Create a Signer Instance

import { RNAlchemySigner } from "@account-kit/react-native-signer";
 
export const signer = RNAlchemySigner({
  client: { connection: { apiKey: "API_KEY" } },
  // optional param to override session settings
  sessionConfig: {
    // sets the expiration to 60 minutes
    expirationTimeMs: 1000 * 60 * 60,
  },
});

Authenticate a User

Next, you'll need to authenticate your user before you can use the Signer as an owner on the account

Send a One-Time Password (OTP) to a User

To send an OTP to a user's email, use the signer.authenticate() method with the emailMode set to otp.

example.ts
import { signer } from "./signer";
 
signer
  .authenticate({
    email: "user@example.com",
    type: "email",
    emailMode: "otp",
  })
  .catch((error) => {
    console.error(error);
  });

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 signer.authenticate() method using the otpCode parameter to complete the authentication process.


Here's an example of a Sign In component using OTP. Feel free to embed this into your application to give it a try!

sign-in-with-otp.tsx
import React, { useCallback, useState } from "react";
import {
  View,
  Text,
  TextInput,
  Button,
  Modal,
  SafeAreaView,
} from "react-native";
import { User } from "@account-kit/signer";
 
import { OtpPopUp } from "./otp-popup";
import { signer } from "./signer";
 
export const SignInWithOtp = () => {
  const [email, setEmail] = useState<string>("");
  const [showOtp, setShowOtp] = useState<boolean>(false);
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState<boolean>(false);
 
  // Make an authentication request to a user's email
  const performAuthRequest = useCallback(async (email: string) => {
    signer.authenticate({
      email,
      type: "email",
      emailMode: "otp",
    });
    setLoading(true);
    setShowOtp(true);
  }, []);
 
  const handleUserAuth = useCallback(async (user: User) => {
    setUser(user);
    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}
        handleUserAuth={handleUserAuth}
        close={() => {
          setShowOtp(false);
          setLoading(false);
        }}
      />
    </View>
  );
};