Skip to main content

Migrate from Privy to Web3Auth

mobilewebmpccorekitWeb3Auth Team | June 18, 2024

In this guide, we'll compare Privy and Web3Auth and explain how to migrate your existing users from Privy to Web3Auth.

We'll start by comparing both services based on several key parameters: wallet management architecture, authentication options, and multi-chain and multi-platform support. If you're ready to jump straight to the migration process, you can find the instructions here.

Why choose Web3Auth?

Both Web3Auth and Privy have made significant strides in addressing the Web3 onboarding challenge. However, Web3Auth stands out by offering more customizable authentication options, along with superior support for multi-chain and multi-platform integrations.

Wallet ManagementPrivy only supports the SSS, and doesn't have MPC TSS support.Web3Auth supports both SSS and MPC TSS to manage user's private key.
Multi-chain supportPrivy as of now only supports secp256k1 curve.Web3Auth is chain agnostic. Moreover, Web3Auth MPC TSS also supports both curves to integrate all supported chains using secp256k1 and ed25519 curves.
Multi-platform supportPrivy only supports Web, React Native, and Swift.Web3Auth supports multiple platforms, including Web, React Native, Unity, Unreal, Flutter, Swift, and Android. Checkout documentation for more details.
Additional FeaturesPrivy doesn't have any additional features apart from embedded wallet.Web3Auth also offers additional services such as NFT checkout, Fiat On Ramp, and Prebuilt Wallet UI. All of these services could be added in your project with few lines code.
Ease of IntegrationPrivy is easy to integrate where basic integration takes less than 15 minutesWeb3Auth is also easy to integrate where basic integration takes less than 15 minutes.
WhitelabelPrivy has limited white-labelling options.Web3Auth has end to end white-labelling options. Web3Auth also has advanced integration options where it can be totally hidden which is not possible with Privy.

How to migrate to Web3Auth

Now that we've discussed the advantages of Web3Auth, let's explore the steps to migrate from Privy to Web3Auth. We'll cover most scenarios, but if we miss any, please don't hesitate to reach out to us in comments.

Embedded Wallet

If you are using Privy embedded wallet, there are couple of options which can be preferred for the migration.

Using Plug And Play SDK

If you want to use the Plug and Play SDK, you can first check whether the user is an existing user or if they have any wallet balance. For new users or those with empty wallets, you can simply generate a new wallet for them to replace the old one.

For existing users with non-empty wallets, you have two options:

Migration tool

You can create a migration tool to transfer funds to the newly generated Web3Auth embedded wallet. To facilitate the fund transfer using the migration tool, you can utilize our Wallet Pregeneration feature to determine the user's wallet address without integrating our SDKs. By leveraging wallet pregeneration, you can handle the migration in the backend seamlessly. Afterward, you can use the PnP/ SFA SDK to log users in through Web3Auth.

Let's see how you can use the Wallet Pregeneration API.

const apiUrl = "";

const params = new URLSearchParams({
verifierId: "YOUR_VERIFIER_ID",
web3AuthNetwork: "sapphire_mainnet",

const url = `${apiUrl}?${params.toString()}`;

// Response
// {
// "data": {
// "evmAddress": "0x172b0Ca9405BcE41A0D6FB3B44f91098d3a4AB14",
// "X": "a3350640a380f772434a18952fa53c6a8c200e9e3d30e1097edbd92be6dd9fe0",
// "Y": "1ded08adccba8e394f9a9d7ee55658aab8f2aef17866983c0bdcd68d31b59341",
// "isMfaEnabled": false
// },
// "success": true
// }

Please ensure that the useCoreKitKey parameter is set to true when using the Wallet Pregeneration API and the PnP SDK. This will ensure that the same address is generated when user logs in for the first time.

const chainConfig = YOUR_CUSTOM_CHAIN_CONFIG;

const ethereumPrivateKeyProvider = EthereumPrivateKeyProvider({
config: { chainConfig },

const web3auth = new Web3Auth({
privateKeyProvider: ethereumPrivateKeyProvider,
useCoreKitKey: true,
Manual Migration

The other option would be to show a prompt to users, asking them to migrate their funds from the old wallet to the new Web3Auth embedded wallet. It's totally upto users how they want to migrate.

You can also suggest your users to use tools like Token Bulksender. Again, DYOR.

Using MPC Core Kit SDK

If you have existing users with a Privy embedded wallet, you can seamlessly transition them to Web3Auth while retaining the same account.


Using the MPC Core Kit is the recommended approach for migrating users from Privy embedded wallet to Web3Auth.

The first step is to export the Privy embedded wallet private key. To do this, you can use the exportWallet method, which requires the wallet address of the account. If no wallet address is provided, it will default to the wallet at index 0. For more details on HD wallets and exporting accounts, learn more here.

Please note that there is no internal method to export the private key in Privy. Only the user can access their full private key. When you use the exportWallet method, it will display an iframe for the user to copy their private key. Once the key is copied, you can prompt them to import it using an input field.

import { usePrivy } from "@privy-io/react-auth";

function ExportWalletButton() {
const { ready, authenticated, user, exportWallet } = usePrivy();
// Check that your user is authenticated
const isAuthenticated = ready && authenticated;
// Check that your user has an embedded wallet
const hasEmbeddedWallet = !!user.linkedAccounts.find(
(account) => account.type === "wallet" && account.walletClient === "privy",

return (
<button onClick={exportWallet} disabled={!isAuthenticated || !hasEmbeddedWallet}>
Export my wallet

You can now show the prompt to enter the private key they copied. Once you have the private key, you can simply import it into Web3AuthMpCoreKit. When you import the private key, it is split into multiple partial keys, which are never stored together in one place. Furthermore, in the MPC architecture, the private key is never reconstructed, enhancing security. The partial keys are stored in different locations and the user's device. These partial keys are used to create partial signatures for messages and transactions. These partial signatures are then combined using Threshold Signature Scheme (TSS) to produce a final signature, which can be used for transactions on the blockchain. MPC Core Kit supports both secp256k1 and ed25519 curves, so you can generate both ECDSA and EdDSA signatures.

Learn more about MPC Core Kit.

// Your own logic to retrive google login id Token
const idTokenLoginParams = {
verifier: "w3a-google-demo",
idToken: parsedIdToken,
// Use the exported private key from previous step
importTssKey: privateKey,
} as IdTokenLoginParams;

const coreKitInstance = new Web3AuthMPCCoreKit({
web3AuthClientId: "YOUR_WEB3AUTH_CLIENT_ID",
baseUrl: "http://localhost:3000",

await coreKitInstance.init();
await coreKitInstance.loginWithJWT(idTokenLoginParams);

AA Wallet

Web3Auth is compatible with all major Account Abstraction (AA) SDKs, including Alchemy, Biconomy, Pimlico, ZeroDev, and Safe. To learn more, please check out our AA Demo.

If you are using a Privy embedded wallet as a signer for an ERC 4337 (Account Abstraction) wallet, you can easily add the Web3Auth embedded wallet as an additional signer. This will enable existing users to seamlessly migrate to the Web3Auth embedded wallet. Alternatively, you can prompt users to remove the Privy signer if preferred.

Considering you have already created the ECDSAProvider instance using Privy signer, you can simply use the changeOwner method to change the Smart Account owner.

Learn more about transfering ownership of Smart account in ZeroDev.

import { providerToSmartAccountSigner } from "permissionless";
import { EIP1193Provider } from "viem";

const { hash } = await privyEcdsaProvider.changeOwner("WEB3AUTH_EMBEDDED_WALLET_ADDRESS");

// Considering you have setup the Web3Auth instance
const web3authProvider = web3auth.provider;

if (!web3authProvider) {
throw new Error("No provider found");

// Create the smart account signer from the provider and signer address
const smartAccountSigner = await providerToSmartAccountSigner(web3authProvider as EIP1193Provider);

// Generate the ZeroDev wallet for new signer.
const web3AuthEcdsaProvider = await signerToEcdsaValidator(publicClient, {
signer: smartAccountSigner,

If we have missed any AA provider, please don't hesitate to reach out to us in comments.

External Wallets

If you are using Privy with external wallets and are looking to integrate with Web3Auth, the migration process is quite straightforward. Web3Auth offers external wallet adapters to connect with external wallets, along with social login options for added convenience. Along with external wallets, Web3Auth also supports application wallets like Torus wallet.

If you are using EVM external wallets previously with Privy, you can simply configure the @web3auth/default-evm-adapter for your Web3Auth instance. Read more about default-evm-adapter.

import { getDefaultExternalAdapters } from "@web3auth/default-evm-adapter";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";

// This can be your custom chain as well.
const chainConfig = {
chainId: "0x1",
rpcTarget: "",
displayName: "Ethereum Mainnet",
blockExplorerUrl: "",
ticker: "ETH",
tickerName: "Ethereum",
logo: "",

const privateKeyProvider = new EthereumPrivateKeyProvider({ config: { chainConfig } });

const web3AuthOptions: Web3AuthOptions = {
chainConfig: { ...chainConfig, chainNamespace: CHAIN_NAMESPACES.EIP155 },
privateKeyProvider: privateKeyProvider,

const web3Auth = new Web3Auth(web3AuthOptions);

const adapters = await getDefaultExternalAdapters({ options: web3AuthOptions });

adapters.forEach((adapter) => {

If you are a fan boy of wagmi-connector, we have got your covered. You can use our web3auth-wagmi-connector to initialize a wagmi client that will seamlessly manage the interaction of your dApp with Web3Auth.Read more about web3auth-wagmi-connector.

import { Web3AuthConnector } from "@web3auth/web3auth-wagmi-connector";
import { Web3Auth } from "@web3auth/modal";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { Chain } from "wagmi/chains";
import { WalletServicesPlugin } from "@web3auth/wallet-services-plugin";

export default function Web3AuthConnectorInstance(chains: Chain[]) {
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x" + chains[0].id.toString(16),
rpcTarget: chains[0].rpcUrls.default.http[0],
displayName: chains[0].name,
tickerName: chains[0].nativeCurrency?.name,
ticker: chains[0].nativeCurrency?.symbol,
blockExplorerUrl: chains[0].blockExplorers?.default.url[0] as string,

const privateKeyProvider = new EthereumPrivateKeyProvider({ config: { chainConfig } });

const web3AuthInstance = new Web3Auth({
enableLogging: true,

const modalConfig = {
label: "openlogin",
loginMethods: {
facebook: {
// It will hide the facebook option from the Web3Auth modal.
name: "facebook login",
showOnModal: false,
// Setting it to false will hide all social login methods from modal.
showOnModal: true,

return Web3AuthConnector({

The above code snippet is for Web3Auth Modal SDK, if you are looking No Modal SDK, you can checkout wagmi no modal sample.


In conclusion, migrating from Privy to Web3Auth offers enhanced security through Multi-Party Computation, broader multi-chain and multi-platform support, and additional features like NFT services and wallet UI integrations. For any specific migration scenarios not covered, book a call with the Web3Auth team, we are happy to assist you.