Skip to main content

Overview

The CrossmintAuthClient class provides client-side authentication functionality including OAuth, email OTP, Farcaster, and smart wallet authentication. It handles token management, automatic refresh, and secure storage of authentication credentials.

Installation

npm install @crossmint/client-sdk-auth

Creating an Instance

import { CrossmintAuthClient } from '@crossmint/client-sdk-auth';
import { Crossmint } from '@crossmint/common-sdk-base';

const crossmint = new Crossmint({ apiKey: 'your-api-key' });

const authClient = CrossmintAuthClient.from(crossmint, {
  callbacks: {
    onTokenRefresh: (authMaterial) => console.log('Token refreshed'),
    onLogout: () => console.log('User logged out')
  },
  logoutRoute: '/api/auth/logout',
  refreshRoute: '/api/auth/refresh'
});

Configuration

config
CrossmintAuthClientConfig
Configuration object for the auth client

Methods

getUser

Retrieves the currently authenticated user’s information.
const user = await authClient.getUser();
console.log(user.email, user.id);
Returns: Promise<User> Throws: CrossmintAuthenticationError if the user is not authenticated or request fails

getOAuthUrl

Generates an OAuth URL for the specified provider.
const oauthUrl = await authClient.getOAuthUrl('google', {
  appSchema: 'myapp://'
});
window.location.href = oauthUrl;
provider
OAuthProvider
required
OAuth provider: 'google', 'twitter', 'facebook', etc.
options
object
Returns: Promise<string> - The OAuth authorization URL Throws: CrossmintAuthenticationError if the origin is unauthorized or request fails

sendEmailOtp

Sends a one-time password to the specified email address.
const result = await authClient.sendEmailOtp('[email protected]');
console.log('Email ID:', result.emailId);
email
string
required
Email address to send the OTP to
Returns: Promise<{ emailId: string }> - Contains the email ID needed for confirmation Throws: CrossmintAuthenticationError if sending fails

confirmEmailOtp

Confirms an email OTP and completes authentication.
const oneTimeSecret = await authClient.confirmEmailOtp(
  '[email protected]',
  emailId,
  '123456'
);
email
string
required
Email address that received the OTP
emailId
string
required
Email ID returned from sendEmailOtp
token
string
required
The 6-digit OTP code
Returns: Promise<string> - One-time secret for completing authentication Throws: CrossmintAuthenticationError if verification fails

signInWithFarcaster

Authenticates a user using Farcaster.
import { useSignIn } from '@farcaster/auth-kit';

const { signIn, data } = useSignIn();
await signIn();

if (data) {
  const oneTimeSecret = await authClient.signInWithFarcaster(data);
}
data
UseSignInData
required
Farcaster sign-in data from @farcaster/auth-kit
Returns: Promise<string> - One-time secret for completing authentication Throws: CrossmintAuthenticationError if authentication fails

signInWithSmartWallet

Initiates smart wallet authentication by requesting a signature challenge.
const { message, nonce } = await authClient.signInWithSmartWallet(
  '0x1234...5678',
  'evm'
);

// Sign the message with the wallet
const signature = await wallet.signMessage(message);

// Complete authentication
await authClient.authenticateSmartWallet(
  '0x1234...5678',
  'evm',
  signature
);
address
string
required
Wallet address
type
'evm' | 'solana'
required
Blockchain type
Returns: Promise<{ message: string; nonce: string }> - Challenge data to sign Throws: CrossmintAuthenticationError if request fails

authenticateSmartWallet

Completes smart wallet authentication with a signed message.
const result = await authClient.authenticateSmartWallet(
  '0x1234...5678',
  'evm',
  signature
);
address
string
required
Wallet address
type
'evm' | 'solana'
required
Blockchain type
signature
string
required
Signed message from the wallet
Returns: Promise<{ oneTimeSecret: string }> - One-time secret for session establishment Throws: CrossmintAuthenticationError if authentication fails

handleRefreshAuthMaterial

Manually triggers token refresh. This is automatically scheduled before token expiration.
const authMaterial = await authClient.handleRefreshAuthMaterial();
refreshTokenSecret
string
Custom refresh token secret. If not provided, uses stored token.
Returns: Promise<AuthMaterialWithUser | null> - New auth material or null if refresh fails

logout

Logs out the current user and clears all stored credentials.
await authClient.logout();
Returns: Promise<void>

Types

AuthMaterialWithUser

interface AuthMaterialWithUser {
  jwt: string;
  refreshToken: {
    secret: string;
    expiresAt: string;
  };
  user: {
    id: string;
    email?: string;
    userId: string;
  };
}

OAuthProvider

type OAuthProvider = 'google' | 'twitter' | 'facebook' | 'discord' | 'apple';

Error Handling

import { CrossmintAuthenticationError } from '@crossmint/common-sdk-auth';

try {
  await authClient.sendEmailOtp(email);
} catch (error) {
  if (error instanceof CrossmintAuthenticationError) {
    console.error('Auth error:', error.message);
  }
}

Best Practices

  1. Token Refresh: The client automatically refreshes tokens before expiration. Don’t manually refresh unless necessary.
  2. Storage: Use custom storage providers for React Native or other non-browser environments.
  3. Error Handling: Always handle CrossmintAuthenticationError for authentication failures.
  4. Server Routes: For Next.js or other server frameworks, provide custom refreshRoute and logoutRoute for secure cookie handling.

Example: Complete Email OTP Flow

import { CrossmintAuthClient } from '@crossmint/client-sdk-auth';

const authClient = CrossmintAuthClient.from(crossmint, {
  callbacks: {
    onTokenRefresh: (authMaterial) => {
      console.log('Session refreshed');
    }
  }
});

// Step 1: Send OTP
const { emailId } = await authClient.sendEmailOtp('[email protected]');

// Step 2: User enters code from email
const otpCode = '123456'; // From user input

// Step 3: Verify OTP
const oneTimeSecret = await authClient.confirmEmailOtp(
  '[email protected]',
  emailId,
  otpCode
);

// Step 4: Get user info
const user = await authClient.getUser();
console.log('Logged in as:', user.email);

Build docs developers (and LLMs) love