Enrolling users in MFA

Once you have enabled MFA for your app, to prompt your users to enroll in MFA for their embedded wallet, use the showMfaEnrollmentModal method from the useMfaEnrollment hook.

Example button for enrolling in wallet MFA
import {useMfaEnrollment} from '@privy-io/react-auth';

function MfaEnrollmentButton() {
  const {showMfaEnrollmentModal} = useMfaEnrollment();
  return <button onClick={showMfaEnrollmentModal}>Enroll in MFA</button>;
}

When invoked, will open a Privy modal that prompts the user to select their desired MFA method from the ones you’ve enabled for your app, and will guide them through the enrollment process.

Once a user has successfully enrolled an MFA method, the user’s enrolled method will appear under the field of their object:

const {user} = usePrivy();
console.log(user.mfaMethods);
// ['sms', 'totp', 'passkey'] for a user who has enrolled in all of SMS, TOTP, and passkey MFA

Managing MFA methods

To allow your users to modify their MFA methods, simply invoke the showMfaEnrollmentModal method from the useMfaEnrollment hook. This is the same method you would use to prompt your user to enroll in MFA for the first time.

Within this modal, users can remove existing MFA methods or enroll in additional ones for their embedded wallet. Prior to making changes to their MFA methods, users will be prompted to re-verify their identity using one of their existing MFA methods.

By default, removing a passkey as MFA will also unlink it as a valid login method. In order to modify this behavior, you can set the shouldUnlinkOnUnenrollMfa option to false under the passkeys config in PrivyProvider.

<PrivyProvider
  appId="your-privy-app-id"
  config={{
    ...theRestOfYourConfig,
    passkeys: {
      // Set this to `false` if you wish to keep the passkey as a login method after unenrolling from MFA.
      shouldUnlinkOnUnenrollMfa: false,
    },
  }}
>
  {/* your app's content */}
</PrivyProvider>

Authorizing signatures and transactions

Once a user has enrolled in MFA, every attempt to use the wallet’s private key (every signature or transaction) will require the user to complete MFA using their method. This logic is automatic; you do not need to do anything else once your user has enrolled in wallet MFA.

When your app requests a signature or a transaction from the embedded wallet, Privy will show the user a modal prompting them to enter a 6-digit MFA code sent to their MFA method. If the user has enrolled in multiple MFA methods, they can choose which method they’d like to use for this given request.

Users must enter their MFA code within 5 minutes of receiving it, and are allowed up to a maximum of 4 code attempts if they incorrectly enter their code.

If the user correctly enters their MFA code, the signature or transaction request will be processed by the wallet. Additionally, their MFA verification status will be cached for 15 minutes. This means that for additional signatures or transactions requested within this window, Privy will not prompt the user to re-complete MFA.

If the user does not complete MFA or enters in an incorrect code 4 times or more, the signature or transaction will raise an error as if the user rejected the request.