Skip to main content
Enrolling in MFA does not automatically verify the user for wallet operations. Once enrolled, subsequent wallet actions will require MFA verification. See the verification guides for how to complete MFA verification.
Enroll users in MFA using passkeys, where they verify with a previously registered passkey through biometric authentication on their device.
In order to use passkeys as an MFA method, make sure a valid passkey is linked to the user. You can set this up by following the steps here!

Setup

To enroll users in MFA with passkeys, use the initEnrollmentWithPasskey and submitEnrollmentWithPasskey methods returned by the useMfaEnrollment hook:
import {useMfaEnrollment} from '@privy-io/react-auth';

const {initEnrollmentWithPasskey, submitEnrollmentWithPasskey} = useMfaEnrollment();

Initiating enrollment

First, initiate enrollment by calling Privy’s initEnrollmentWithPasskey method with no parameters. This method returns a Promise that will resolve to void indicating success.
await initEnrollmentWithPasskey();

Completing enrollment

Then, to have the user enroll, you must call Privy’s submitEnrollmentWithPasskey method with a list of the user’s passkey account credentialIds. You can find this list by querying the user’s linkedAccounts array for all accounts of type: 'passkey':
import {usePrivy} from '@privy-io/react-auth';

const {user} = usePrivy();

// ...

const credentialIds = user.linkedAccounts
  .filter((account): account is PasskeyWithMetadata => account.type === 'passkey')
  .map((x) => x.credentialId);

await submitEnrollmentWithPasskey({credentialIds});
The component below serves as a reference implementation for how to enroll your users in MFA with passkeys!
Example enrolling passkeys for MFA
import {useMfaEnrollment, usePrivy} from '@privy-io/react-auth';

export default function MfaEnrollmentWithPasskey() {
  const {user} = usePrivy();
  const {initEnrollmentWithPasskey, submitEnrollmentWithPasskey} = useMfaEnrollment();

  const handleEnrollmentWithPasskey = async () => {
    await initEnrollmentWithPasskey();

    const credentialIds = user.linkedAccounts
      .filter((account): account is PasskeyWithMetadata => account.type === 'passkey')
      .map((x) => x.credentialId);

    await submitEnrollmentWithPasskey({credentialIds});
  };

  return (
    <div>
      <div>Enable your passkeys for MFA</div>
      {user.linkedAccounts
        .filter((account): account is PasskeyWithMetadata => account.type === 'passkey')
        .map((account) => (
          <div key={account.id}>{account.credentialId}</div>
        ))}
      <button onClick={handleEnrollmentWithPasskey}>Enroll</button>
    </div>
  );
}