Skip to content

Documentation / react-auth / useMfa

Function: useMfa()

useMfa(): Object

Use this hook to execute the MFA flow with Privy.

Returns

Object

promptMfa - prompts the user to complete MFA verification

init - starts the MFA verification flow

submit - completes the MFA verification flow

cancel - cancels the MFA verification flow

mfaMethods - list of all available mfa methods

cancel

cancel: () => void

Returns

void

init

init: (mfaMethod) => Promise<void | PublicKeyCredentialRequestOptionsJSON>

Parameters

mfaMethod: "sms" | "totp" | "passkey"

Returns

Promise<void | PublicKeyCredentialRequestOptionsJSON>

mfaMethods

mfaMethods: ("sms" | "totp" | "passkey")[]

promptMfa

promptMfa: () => Promise<void>

Returns

Promise<void>

submit

submit: (mfaMethod, mfaCode) => Promise<void>

Parameters

mfaMethod: "sms" | "totp" | "passkey"

mfaCode: string | PublicKeyCredentialRequestOptionsJSON

Returns

Promise<void>

Example

ts
// MFA flow

const MFAModal = ({ mfaMethods, isOpen, setIsOpen }: Props) => {
  const {init, submit, cancel} = useMfa();
  const [selectedMethod, setSelectedMethod] = useState(null)
  const [mfaCode, setMfaCode] = useState('')

  const handleClose = () => {
    cancel();
    setIsOpen(false);
  };

  return (
    <Modal isOpen={isOpen} onClose={handleClose}>
      // Capture the user's MFA code
      {selectedMethod && (
        <button
          onClick={async () => {
            await submit(selectedMethod, mfsCode)
            setSelectedMethod(null)
            setIsOpen(false)
          }}
        />
      )}
      {mfaMethods.map(method => (
        <button
          onClick={async () => {
            await init(method);
            setSelectedMethod(method)
          }}
        >
          Choose {method} for MFA
        </button>
      ))}
    </Modal>
  )
};

Example

ts
// Error handling

import {
  errorIndicatesMfaVerificationFailed,
  errorIndicatesMfaTimeout,
  errorIndicatesMfaMaxAttempts
} from '@privy-io/react-auth';
const {submit} = useMfa();
const [errorState, setErrorState] = useState<string | null>(null);

<button
  onClick={async () => {
    try {
      submit('sms', '<user-mfa-code>');
    }
    catch (e) {
      if (errorIndicatesMfaVerificationFailed(e)) {
        setErrorState('Verification failed, resubmit.')
      }
      else if (errorIndicatesMfaMaxAttempts(e)) {
        setErrorState('Max attempts reached, re-initialize MFA.')
      }
      else if (errorIndicatesMfaTimeout(e)) {
        setErrorState('Timeout reached, re-initialize MFA.')
      }
  }}
>
  {errorState ?? 'Verify SMS MFA Code'}
</button>