# SMS Authentication

> How to authenticate users with phone number and SMS OTP code

<Info>
  SMS auth is currently in closed alpha. If you'd like early access please reach
  out to [wallets@alchemy.com](mailto:wallets@alchemy.com).
</Info>

Authenticate users with their phone number by sending verification codes via SMS.

## How It Works

SMS authentication is a two-step process:

1. *Send the verification code:* the user enters their phone number and requests a verification code.
2. *Submit the verification code:* the user enters the 6-digit code they receive via SMS to complete authentication.

The SDK will handle phone number validation, code generation, and delivery automatically.

Smart Wallets supports all major countries across Europe, Asia, North and South America.

Pricing varies by country and requires specific area codes to be enabled for your account.

## Prerequisites

* Early access to SMS auth configured on your account: [Request early access!](mailto:wallets@alchemy.com)
* A configured app with [smart wallets](/docs/wallets/pages/react/quickstart.mdx) and a [gas sponsorship policy](https://dashboard.alchemy.com/gas-manager/policy/create).
* SDK version ≥v4.53.0

## Implementation

<Tabs>
  <Tab title="React" language="react">
    <Info>
      SMS auth is not yet supported with pre-built UI components. Please follow [this guide](/docs/wallets/pages/react/react-hooks) to set up custom UI and configure authentication with hooks.
    </Info>

    ### Step 1: Send the SMS verification code

    Ensure you pass the phone number including the country code in the format `+<country code><phone number>` (i.e. \`+15553219876).

    ```tsx twoslash
    import { useAuthenticate } from "@account-kit/react"

    const { authenticate } = useAuthenticate()

    const handleSendCode = (phone: string) => {
        authenticate(
            { type: "sms", phone: "+123456789" },
            {
                onSuccess: () => {
                    // onSuccess only fires once the entire flow is done (SMS OTP + optional MFA).
                    // It still runs even if the final step completes in another tab/window.
                },
                onError: (error) => {
                    // Handle error
                },
            },
        );
    };
    ```

    ### Step 2: Show OTP input on status change

    Use the `useSignerStatus` hook to show the otp input once the code is sent:

    ```tsx twoslash
    import React from "react";
    import { useSignerStatus } from "@account-kit/react";
    import { AlchemySignerStatus } from "@account-kit/signer";

    const TrackStatus = () => {
    const { status } = useSignerStatus();

    return (
        <>
            {status === AlchemySignerStatus.AWAITING_SMS_AUTH && (
                <div>Prompt the user to enter the OTP code received via SMS</div>
            )}
        </>
    );
    };
    ```

    ### Step 3: Verify the OTP code

    ```tsx twoslash
    import { useAuthenticate } from "@account-kit/react";

    const { authenticate } = useAuthenticate();

    // When the user submits the OTP code
    const handleVerifyCode = (otpCode: string) => {
        authenticate(
            {
                type: "otp",
                otpCode,
            },
            {
                onSuccess: () => {
                    // onSuccess only fires once the entire flow is done (SMS OTP).
                },
                onError: (error) => {
                    // Handle invalid code error
                },
            },
        );
    };
    ```

    ### Step 4: Check authentication status

    Use the `useSignerStatus` hook we set up before to wait until the user is authenticated:

    ```tsx twoslash
    import { useSignerStatus } from "@account-kit/react";

    // Inside your component
    const { isConnected } = useSignerStatus();

    // You can use isConnected to conditionally render UI
    ```
  </Tab>

  <Tab title="React Native">
    <Info>
      SMS auth is not yet supported with pre-built UI components. Please follow
      [this guide](/docs/wallets/pages/react-native/overview) to
      set up custom UI and configure authentication with hooks.
    </Info>

    ### Step 1: Send the SMS verification code

    Ensure you pass the phone number including the country code in the format `+<country code><phone number>` (i.e. \`+15553219876).

    ```tsx twoslash
    import { useAuthenticate } from "@account-kit/react-native"

    const { authenticate } = useAuthenticate()

    const handleSendCode = (phone: string) => {
        authenticate(
            { type: "sms", phone: "+123456789" },
            {
                onSuccess: () => {
                    // onSuccess only fires once the entire flow is done (SMS OTP + optional MFA).
                    // It still runs even if the final step completes in another tab/window.
                },
                onError: (error) => {
                    // Handle error
                },
            },
        );
    };
    ```

    ### Step 2: Show OTP input on status change

    Use the `useSignerStatus` hook to show the otp input once the code is sent:

    ```tsx twoslash
    import React from "react";
    import { useAuthenticate, useSignerStatus } from "@account-kit/react-native"
    import { AlchemySignerStatus } from "@account-kit/signer";
    import { View } from "react-native";

    const TrackStatus = () => {
    const { status } = useSignerStatus();

    return (
        <>
            {status === AlchemySignerStatus.AWAITING_SMS_AUTH && (
                <View>Prompt the user to enter the OTP code received via SMS</View>
            )}
        </>
    );
    };
    ```

    ### Step 3: Verify the OTP code

    ```tsx twoslash
    import { useAuthenticate } from "@account-kit/react-native"

    const { authenticate } = useAuthenticate();

    // When the user submits the OTP code
    const handleVerifyCode = (otpCode: string) => {
        authenticate(
            {
                type: "otp",
                otpCode,
            },
            {
                onSuccess: () => {
                    // onSuccess only fires once the entire flow is done (SMS OTP).
                },
                onError: (error) => {
                    // Handle invalid code error
                },
            },
        );
    };
    ```

    ### Step 4: Check authentication status

    Use the `useSignerStatus` hook we set up before to wait until the user is authenticated:

    ```tsx twoslash
    import { useAuthenticate, useSignerStatus } from "@account-kit/react-native"

    // Inside your component
    const { isConnected } = useSignerStatus();

    // You can use isConnected to conditionally render UI
    ```
  </Tab>

  <Tab title="JavaScript" language="typescript">
    <Info>Ensure you've set up your project by following [this](/docs/wallets/pages/core/quickstart) guide first.</Info>

    ```ts
    import { AlchemyWebSigner } from "@account-kit/signer"
    const signer = new AlchemyWebSigner(...)

    // send sms verification code
    await signer.authenticate({ type: "sms", phone: "+123456789" })
    ...
    // verify sms verification code
    await signer.authenticate({ type: "otp", otpCode: "123456" })
    ```
  </Tab>
</Tabs>

## Next Steps

* Send [transactions](/docs/wallets/pages/transactions/send-transactions/index.mdx)