Prerequisites

⚠️ Backend Required: This authentication method requires a backend service that handles Stytch Email OTP operations. The auth service already has the implementation in place with the /stytch/email/send-otp and /stytch/email/verify-otp endpoints, but they are disabled by default. Simply run your auth service at the configured URL to enable Stytch Email OTP functionality.
Lit Auth Server URLs. Please refer to Auth Services section.

(Prerequisite) TOTP Registration

Existing Stytch User Account required. (from primary authentication methods, such as Email, SMS, or WhatsApp) This step must be completed before you can authenticate with TOTP 2FA.
1

Create TOTP Registration

Create TOTP registration with the user ID from your email/sms/whatsapp auth
import { StytchTotp2FAAuthenticator } from "@lit-protocol/auth";

const registrationData = await StytchTotp2FAAuthenticator.initiateTotpRegistration({
  userId:authData?.metadata?.userId // from your email/sms/whatsapp auth
  authServiceBaseUrl: "https://naga-auth-service.onrender.com"
});
2

Verify TOTP Setup

Verify TOTP setup with code from authenticator app
const verifyResult = await StytchTotp2FAAuthenticator.verifyTotpRegistration({
  userId:authData?.metadata?.userId
  totpRegistrationId: registrationData.totpRegistrationId,
  totpCode: "123456", // from authenticator app
  authServiceBaseUrl: "https://naga-auth-service.onrender.com"
});

TOTP Authentication

1

Authenticate with TOTP 2FA

Enter your Stytch User ID (from your primary authentication) and the current 6-digit TOTP code from your authenticator app to authenticate and generate authentication data.
import { StytchTotp2FAAuthenticator } from "@lit-protocol/auth";

const authData = await StytchTotp2FAAuthenticator.authenticate({
  userId: "user-test-uuid-1234", // Stytch user ID from primary auth
  totpCode: "123456", // 6-digit code from authenticator app
  authServiceBaseUrl: "https://naga-auth-service.onrender.com",
});
2

Verify OTP

Enter the OTP code sent to your WhatsApp to verify your identity and generate authentication data.
import { StytchWhatsAppOtpAuthenticator } from "@lit-protocol/auth";

const authData = await StytchWhatsAppOtpAuthenticator.authenticate({
  methodId: methodId, // from sendOtp step
  code: "123456", // user-entered OTP code
  authServiceBaseUrl: "https://naga-auth-service.onrender.com",
});
3

Get or Mint a PKP

You can select an existing PKP associated with your account or mint a new one.
const res = await litClient.authService.mintWithAuth({
  authData: authData,
});
4

Generate Auth Context

Use your newly minted PKP to create an AuthContext. This method will cache two things:
  1. session key pair - a temporary cryptographic key pair generated on the client side that acts as a temporary identity for the client application. It consists of:
    • A public key - shared with the Lit nodes
    • A secret key (private key) - kept securely on the client
  2. Delegation AuthSig aka. the inner auth sig - a cryptographic attestation from the Lit Protocol nodes that authorises your session key to act on behalf of your PKP.
const authContext = await authManager.createPkpAuthContext({
  authData: authData, // <-- Retrieved earlier
  pkpPublicKey: pkpInfo.pubkey, // <-- Minted earlier
  authConfig: {
    resources: [
      ["pkp-signing", "*"],
      ["lit-action-execution", "*"],
    ],
    expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(),
    statement: "",
    domain: window.location.origin,
  },
  litClient: litClient,
});