> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MFA Enrollment

## Console Setup

MFA enrollment requires users to register a TOTP device or Passkey. Configure it in the Dynamic Console before implementing in your application. See [End-User MFA — Enrollment](https://docs.dynamic.xyz/docs/platform/console/end-user-mfa.md#enrollment) for console setup instructions.

## React

In React, drive the multi-step MFA flow (register → scan QR → verify) with the mutation hooks. `useRegisterTotpMfaDevice` exposes the QR URI as its `data`:

```tsx theme={"system"}
import {
  useAuthenticateTotpMfaDevice,
  useRegisterTotpMfaDevice,
} from '@dynamic-labs-sdk/react-hooks';
import { useState } from 'react';

function TotpEnrollment() {
  const [code, setCode] = useState('');

  const { mutate: registerDevice, data: registration, reset } = useRegisterTotpMfaDevice();
  const { mutate: authenticateDevice } = useAuthenticateTotpMfaDevice();

  const handleVerify = () => {
    authenticateDevice({ code }, { onSuccess: () => reset() });
  };

  if (registration) {
    return (
      <div>
        <p>Scan this QR code with your authenticator app:</p>
        {/* Render QR from registration.uri using a library like qrcode.react */}
        <input value={code} onChange={(e) => setCode(e.target.value)} placeholder="Enter code" />
        <button onClick={handleVerify}>Verify</button>
      </div>
    );
  }

  return <button onClick={() => registerDevice()}>Set up authenticator app</button>;
}
```

## Your UI SDK Implementation

> [tab] TOTP
>
> * **Register device**: `registerTotpMfaDevice()` returns a QR `uri` and `secret`.
> * **Authenticate**: `authenticateTotpMfaDevice({ code })` completes the challenge.
> * **Manage devices**: `getMfaDevices()` lists devices; `deleteMfaDevice()` deletes.
> * **Recovery codes**: `getMfaRecoveryCodes()` to display; `createNewMfaRecoveryCodes()` to rotate; `authenticateMfaRecoveryCode({ code })` to unblock login.
>
> ```javascript theme={"system"}
> import { registerTotpMfaDevice, authenticateTotpMfaDevice, getMfaDevices } from '@dynamic-labs-sdk/client';
>
> const register = async () => {
>   const { uri } = await registerTotpMfaDevice();
>   // Render QR code from `uri`
> };
>
> const verify = async (code) => {
>   await authenticateTotpMfaDevice({ code });
> };
>
> const listDevices = async () => {
>   const devices = await getMfaDevices();
>   console.log(devices);
> };
> ```
>
> ```javascript theme={"system"}
> import {
>   getMfaRecoveryCodes,
>   createNewMfaRecoveryCodes,
>   authenticateMfaRecoveryCode,
> } from '@dynamic-labs-sdk/client';
>
> const showCodes = async () => {
>   const { recoveryCodes } = await getMfaRecoveryCodes();
>   console.log(recoveryCodes);
> };
>
> const rotateCodes = async () => {
>   const { recoveryCodes } = await createNewMfaRecoveryCodes();
>   console.log(recoveryCodes);
> };
>
> const authWithRecovery = async (code) => {
>   await authenticateMfaRecoveryCode({ code });
> };
> ```
>
> ```javascript theme={"system"}
> import { authenticateTotpMfaDevice, deleteMfaDevice } from '@dynamic-labs-sdk/client';
>
> const deleteTotpDevice = async (deviceId, code) => {
>   // Create a single-use MFA token using the device to be deleted
>   await authenticateTotpMfaDevice({
>     code,
>     createMfaTokenOptions: { singleUse: true },
>   });
>
>   // Use the MFA token from the client to authorize deletion
>   const mfaToken = dynamicClient.mfaToken;
>   await deleteMfaDevice({ deviceId, mfaAuthToken: mfaToken });
> };
> ```

> [tab] Passkey
>
> * **Register**: `registerPasskey()` creates and registers a passkey.
> * **Authenticate**: `authenticatePasskeyMFA()` completes the MFA challenge.
> * **Manage**: `getPasskeys()` lists; `deletePasskey()` removes.
> * **Recovery codes**: `getMfaRecoveryCodes()` to display; `createNewMfaRecoveryCodes()` to rotate; `authenticateMfaRecoveryCode({ code })` to unblock login.
>
> ```javascript theme={"system"}
> import { registerPasskey, authenticatePasskeyMFA, getPasskeys } from '@dynamic-labs-sdk/client';
>
> const register = async () => {
>   await registerPasskey();
> };
>
> const mfa = async () => {
>   await authenticatePasskeyMFA();
> };
>
> const list = async () => {
>   const keys = await getPasskeys();
>   console.log(keys);
> };
> ```
>
> ```javascript theme={"system"}
> import {
>   getMfaRecoveryCodes,
>   createNewMfaRecoveryCodes,
>   authenticateMfaRecoveryCode,
> } from '@dynamic-labs-sdk/client';
>
> const showCodes = async () => {
>   const { recoveryCodes } = await getMfaRecoveryCodes();
>   console.log(recoveryCodes);
> };
>
> const rotateCodes = async () => {
>   const { recoveryCodes } = await createNewMfaRecoveryCodes();
>   console.log(recoveryCodes);
> };
>
> const authWithRecovery = async (code) => {
>   await authenticateMfaRecoveryCode({ code });
> };
> ```
>
> ```javascript theme={"system"}
> import { deletePasskey } from '@dynamic-labs-sdk/client';
>
> const removePasskey = async (passkeyId) => {
>   await deletePasskey({ passkeyId });
> };
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.