> ## 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

## Dashboard Setup

MFA enrollment requires users to register a TOTP device or Passkey. Configure it in the dashboard before implementing in your application. See [End-User MFA - Enrollment](/overview/developer-dashboard/end-user-mfa#enrollment) for dashboard 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

<Tabs>
  <Tab title="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>

  <Tab title="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 });
    };
    ```
  </Tab>
</Tabs>
