Overview
Authentication is the process by which users verify their identity to access your application. In web3, providing users with seamless login experiences for their decentralized applications and blockchain wallets is essential for creating exceptional user experiences that drive adoption.
Why Seamless Authentication Matters in Web3
Traditional blockchain authentication creates significant barriers to user adoption that generally don’t exist in web2 experiences:
- Complex private key management - Users must securely store and manage cryptographic keys
- Wallet installation requirements - Additional software downloads and setup
- Technical knowledge barriers - Understanding of blockchain concepts and wallet security
- Poor user experience - Lengthy onboarding flows and confusing interfaces
Alchemy Smart Wallets solves these challenges by providing seamless and familiar login methods while maintaining the security and decentralization benefits of blockchain technology.
Features
Multiple Login Methods
Choose from a variety of authentication options to match your users’ preferences:
- Email OTP - Passwordless login with 6-digit verification codes
- Email Magic Links - One-click authentication via secure email links
- Social Login - OAuth with Google, Apple, Discord, Twitter, and more
- Passkey Authentication - Biometric and hardware-based passwordless login
- Bring Your Own Auth - Integrate existing JWT/OIDC authentication systems
- And more!
Flexible Implementation Options
Implement authentication in the way that best fits your application:
- Pre-built UI Components - Deploy quickly with minimal code using
<AuthCard />
or<AuthModal />
- Custom UI Integration - Build completely custom experiences with headless React hooks
- Modal or Embedded Flows - Choose between popup modals or embedded authentication forms
- Whitelabel Solutions - Customize theming and branding to match your application
Framework Support
Alchemy Smart Wallets authentication works across multiple platforms:
- React - Full-featured hooks, components, and TypeScript support
- React Native - Mobile-optimized authentication flows for iOS and Android
- Other JavaScript Frameworks - Svelte, Vue, and vanilla JavaScript support
- Backend Integration - Server-side authentication validation and user management
Enterprise-Grade Security
- Non-custodial Architecture - Users maintain full control over their private keys
- Secure Enclave Storage - Keys generated and stored in hardware security modules
- Multi-Factor Authentication (MFA) - Additional security layers for high-value operations
- Account Recovery - Flexible recovery options through trusted contacts or backup methods
Multi-Factor Authentication (MFA)
Add additional security layers for sensitive operations:
- Email OTP MFA - Secondary verification via email codes
- Email Magic Link MFA - Additional verification via email links
- Social Login MFA - Secondary authentication through social providers
Implementation Approaches
Quick Start with Pre-built Components
Deploy authentication in minutes with minimal code:
import { const AuthCard: (props: AuthCardProps) => JSX.ElementReact component containing an Auth view with configured auth methods and options based on the config passed to the AlchemyAccountProvider
AuthCard } from "@account-kit/react";
function function App(): JSX.ElementApp() {
return (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
<React.JSX.IntrinsicElements.h1: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>h1>Welcome to My App</React.JSX.IntrinsicElements.h1: React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>h1>
<const AuthCard: (props: AuthCardProps) => JSX.ElementReact component containing an Auth view with configured auth methods and options based on the config passed to the AlchemyAccountProvider
AuthCard />
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
);
}
Custom UI with React Hooks
Build completely custom authentication experiences:
import {
function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate,
const useSignerStatus: (override?: AlchemyAccountContextProps) => UseSignerStatusResultHook to get the signer status, optionally using an override configuration, useful if you’re building your own login.
useSignerStatus,
const useAuthModal: () => {
isOpen: boolean;
openAuthModal: () => void;
closeAuthModal: () => void;
}A hook that returns the open and close functions for the Auth Modal if uiConfig is enabled on the Account Provider
useAuthModal,
} from "@account-kit/react";
function function CustomAuth(): JSX.ElementCustomAuth() {
const { const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>authenticate } = function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResultHook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.
This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.
useAuthenticate();
const { const isInitializing: booleanisInitializing, const isConnected: booleanisConnected } = function useSignerStatus(override?: AlchemyAccountContextProps): UseSignerStatusResultHook to get the signer status, optionally using an override configuration, useful if you’re building your own login.
useSignerStatus();
const { const openAuthModal: () => voidopenAuthModal } = function useAuthModal(): {
isOpen: boolean;
openAuthModal: () => void;
closeAuthModal: () => void;
}A hook that returns the open and close functions for the Auth Modal if uiConfig is enabled on the Account Provider
useAuthModal();
const const handleEmailAuth: () => Promise<void>handleEmailAuth = async () => {
await const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => voidauthenticate({
type: "email"type: "email",
email: stringemail: "[email protected]",
});
};
if (const isInitializing: booleanisInitializing) return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>Loading...</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
if (const isConnected: booleanisConnected) return <React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>Welcome back!</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>;
return (
<React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>button React.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefinedonClick={const handleEmailAuth: () => Promise<void>handleEmailAuth}>Login with Email</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>button>
<React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>button React.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefinedonClick={const openAuthModal: () => voidopenAuthModal}>Show Auth Modal</React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>button>
</React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>div>
);
}
Next Steps
Ready to implement authentication? Start with these guides:
- React Quickstart - Complete React setup with authentication
- Email OTP Guide - Implement email-based authentication
- Social Login Setup - Configure OAuth providers
- Custom UI Implementation - Build custom authentication experiences
After authenticating users, you can generate wallets for them and they can start sending transactions with just a few clicks.