Migrate from Web3Auth
This guide walks you through migrating from Web3Auth (now MetaMask Embedded Wallets) to Openfort. The migration involves updating your SDK dependencies, provider configuration, authentication flows, and wallet interactions.
Before you begin
Before starting the migration:
- Complete the Openfort quickstart to understand the SDK structure.
- Obtain your API keys from the Openfort dashboard.
- Set up a recovery endpoint (for automatic recovery).
Feature mapping
| Web3Auth feature | Openfort equivalent | Notes |
|---|---|---|
| Social login (Google, Facebook) | AuthProvider.GOOGLE, AuthProvider.FACEBOOK | Configure in dashboard |
| Email passwordless | AuthProvider.EMAIL_OTP | OTP-based authentication |
| SMS passwordless | AuthProvider.PHONE | OTP-based authentication |
| External wallets | AuthProvider.WALLET | WalletConnect support |
| MFA management | Passkey recovery | Alternative security model |
| Whitelabeling | uiConfig prop | Customizable UI |
Install Openfort dependencies
Remove Web3Auth packages and install Openfort with its peer dependencies:
Update provider configuration
Replace the Web3Auth provider with Openfort's layered provider structure.
Before (Web3Auth):
import { Web3AuthProvider } from '@web3auth/modal/react';
import { WEB3AUTH_NETWORK } from '@web3auth/modal';
const web3AuthConfig = {
clientId: 'YOUR_WEB3AUTH_CLIENT_ID',
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
chainConfig: {
chainNamespace: 'eip155',
chainId: '0x1',
},
};
function App() {
return (
<Web3AuthProvider config={web3AuthConfig}>
<YourApp />
</Web3AuthProvider>
);
}After (Openfort):
import {
AuthProvider,
OpenfortProvider,
getDefaultConfig,
RecoveryMethod,
} from "@openfort/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { WagmiProvider, createConfig } from "wagmi";
import { mainnet, sepolia } from "viem/chains";
const config = createConfig(
getDefaultConfig({
appName: "Your App Name",
chains: [mainnet, sepolia],
ssr: true,
})
);
const queryClient = new QueryClient();
function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<OpenfortProvider
publishableKey="YOUR_OPENFORT_PUBLISHABLE_KEY"
walletConfig={{
shieldPublishableKey: "YOUR_SHIELD_PUBLISHABLE_KEY",
createEncryptedSessionEndpoint: "YOUR_RECOVERY_ENDPOINT",
}}
uiConfig={{
authProviders: [
AuthProvider.EMAIL_OTP,
AuthProvider.GOOGLE,
AuthProvider.WALLET,
],
walletRecovery: {
defaultMethod: RecoveryMethod.AUTOMATIC,
},
}}
>
{children}
</OpenfortProvider>
</QueryClientProvider>
</WagmiProvider>
);
}Update authentication code
Replace Web3Auth connection hooks with Openfort authentication hooks.
Before (Web3Auth):
import { useWeb3AuthConnect, useWeb3AuthDisconnect, useWeb3AuthUser } from '@web3auth/modal/react';
import { AUTH_CONNECTION, WALLET_CONNECTORS } from '@web3auth/modal';
function LoginButton() {
const { isConnected, connectTo } = useWeb3AuthConnect();
const { userInfo } = useWeb3AuthUser();
const { disconnect } = useWeb3AuthDisconnect();
if (isConnected) {
return (
<div>
<p>Welcome, {userInfo?.email}</p>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
);
}
return (
<button onClick={() => connectTo(WALLET_CONNECTORS.AUTH, {
authConnection: AUTH_CONNECTION.GOOGLE,
})}>
Connect with Web3Auth
</button>
);
}After (Openfort):
import { useUser, useSignOut, OpenfortButton } from "@openfort/react";
function LoginButton() {
const { user, isLoading } = useUser();
const { signOut } = useSignOut();
if (isLoading) return <div>Loading...</div>;
if (user) {
return (
<div>
<p>Welcome, {user.email}</p>
<button onClick={signOut}>Sign Out</button>
</div>
);
}
// Use the pre-built button component
return <OpenfortButton />;
}Alternatively, use individual auth hooks for custom UI:
import { useEmailOtpAuth, useOAuth, AuthProvider } from "@openfort/react";
function CustomLogin() {
const { sendOtp, verifyOtp, state } = useEmailOtpAuth();
const { initOAuth } = useOAuth();
const [email, setEmail] = useState("");
const [otp, setOtp] = useState("");
const handleEmailLogin = async () => {
if (state === "initial") {
await sendOtp({ email });
} else if (state === "awaiting_otp") {
await verifyOtp({ otp });
}
};
return (
<div>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
{state === "awaiting_otp" && (
<input
value={otp}
onChange={(e) => setOtp(e.target.value)}
placeholder="Enter OTP"
/>
)}
<button onClick={handleEmailLogin}>
{state === "initial" ? "Send OTP" : "Verify"}
</button>
<button onClick={() => initOAuth({ provider: AuthProvider.GOOGLE })}>
Sign in with Google
</button>
</div>
);
}Keep your wallet and transaction code
Both Web3Auth v10 and Openfort use Wagmi for blockchain interactions. Your existing Wagmi hooks for wallet access and transactions work without changes.
import { useAccount } from "wagmi";
function WalletInfo() {
const { address, isConnected } = useAccount();
if (!isConnected) return null;
return <p>Wallet: {address}</p>; // Returns the smart wallet address with Openfort
}import { useSendTransaction, useAccount } from "wagmi";
import { parseEther } from "viem";
function SendTransaction() {
const { address } = useAccount();
const { sendTransaction, isPending } = useSendTransaction();
const sendTx = () => {
sendTransaction({
to: '0x...',
value: parseEther('0.001'),
});
};
return (
<button onClick={sendTx} disabled={isPending || !address}>
{isPending ? 'Sending...' : 'Send'}
</button>
);
}Hook mapping reference
| Web3Auth hook | Openfort equivalent |
|---|---|
useWeb3AuthConnect | useEmailOtpAuth, useOAuth, useGuestAuth |
useWeb3AuthDisconnect | useSignOut |
useWeb3AuthUser | useUser |
useAccount (wagmi) | useAccount (wagmi) |
useSendTransaction (wagmi) | useSendTransaction (wagmi) |
useSwitchChain (wagmi) | useSwitchChain (wagmi) |
Considerations
Session handling
Web3Auth sessions are invalidated during migration. Users need to re-authenticate with Openfort.
Wallet addresses
Users receive new wallet addresses. Communicate this to users before migration so they can:
- Export any assets from their Web3Auth wallet.
- Import or transfer assets to their new Openfort wallet after migration.
MFA and recovery
Web3Auth uses MPC-based key management. Openfort provides three recovery options:
- Automatic recovery: Backend-managed, seamless user experience.
- Password recovery: User sets a password for wallet recovery.
- Passkey recovery: Biometric authentication for recovery.
Smart wallet features
Openfort wallets are smart contract accounts by default. You gain access to:
- Gas sponsorship via paymasters.
- Transaction batching.
- Session keys for delegated signing.
Configure gas policies in the Openfort dashboard.