Skip to main content
This page has been updated for Wallets SDK V1. If you are using the previous version, see the previous version docs or the V1 migration guide.
A recovery signer lets users regain access to their wallet when their primary (device) signer is no longer available — for example, when they switch to a new phone or clear their browser data. The recovery signer authorizes the enrollment of a new device signer on the new device. Recovery signers are configured at wallet creation time. You can choose from email OTP, SMS OTP, or a server signer depending on your application’s needs.
Recovery signers can also sign transactions when needed — they are not limited to recovery only. However, they involve higher friction (OTP verification or server-side signing), so they are best reserved for recovery flows and as a fallback.

Prerequisites

  • A Crossmint API key with wallets.create scope
  • For email OTP: the user’s email address
  • For SMS OTP: the user’s phone number in E.164 format (e.g., +1234567890)
  • For server signer: a signer secret stored on your server

Email OTP Recovery

The user verifies ownership of their email address via a one-time password sent by Crossmint. This is the most common recovery method for consumer applications.
Using createOnLogin on the provider (recommended):
import {
    CrossmintProvider,
    CrossmintAuthProvider,
    CrossmintWalletProvider,
} from "@crossmint/client-sdk-react-ui";

function App({ children }) {
    return (
        <CrossmintProvider apiKey="YOUR_CLIENT_API_KEY">
            <CrossmintAuthProvider
                loginMethods={["email", "google"]}
            >
                <CrossmintWalletProvider
                    createOnLogin={{
                        chain: "base-sepolia",
                        recovery: { type: "email" },
                    }}
                >
                    {children}
                </CrossmintWalletProvider>
            </CrossmintAuthProvider>
        </CrossmintProvider>
    );
}
Or using createWallet directly:
import { useWallet } from "@crossmint/client-sdk-react-ui";

const { createWallet } = useWallet();

const wallet = await createWallet({
    chain: "base-sepolia",
    recovery: {
        type: "email",
        email: "user@example.com",
    },
});

SMS OTP Recovery

The user verifies ownership of their phone number via a one-time password delivered by SMS (or optionally WhatsApp). This is ideal for mobile-first applications.
Using createOnLogin on the provider:
import {
    CrossmintProvider,
    CrossmintAuthProvider,
    CrossmintWalletProvider,
} from "@crossmint/client-sdk-react-ui";

function App({ children }) {
    return (
        <CrossmintProvider apiKey="YOUR_CLIENT_API_KEY">
            <CrossmintAuthProvider
                loginMethods={["email", "google"]}
            >
                <CrossmintWalletProvider
                    createOnLogin={{
                        chain: "base-sepolia",
                        recovery: {
                            type: "phone",
                            phone: "+1234567890",
                        },
                    }}
                >
                    {children}
                </CrossmintWalletProvider>
            </CrossmintAuthProvider>
        </CrossmintProvider>
    );
}
Or using createWallet directly:
import { useWallet } from "@crossmint/client-sdk-react-ui";

const { createWallet } = useWallet();

const wallet = await createWallet({
    chain: "base-sepolia",
    recovery: {
        type: "phone",
        phone: "+1234567890",
    },
});

Server Signer as Recovery

Use a server signer as the recovery signer when you want your backend to manage recovery without user-facing OTP flows. This is common for AI agents, backend automation, and hybrid architectures where the server creates wallets that clients later use.
import {
    createCrossmint,
    CrossmintWallets,
} from "@crossmint/wallets-sdk";

const crossmint = createCrossmint({
    apiKey: "YOUR_SERVER_API_KEY",
});
const crossmintWallets = CrossmintWallets.from(crossmint);

const wallet = await crossmintWallets.createWallet({
    chain: "base-sepolia",
    recovery: {
        type: "server",
        secret: process.env.CROSSMINT_SIGNER_SECRET,
    },
});
For more on generating and managing server signer secrets, see the Server Signer guide.

How Recovery Works on a New Device

When a user accesses their wallet from a new device where no device signer exists:
  1. The user authenticates via your app — the SDK retrieves the wallet
  2. The SDK detects no local device signer on this device
  3. On the first transaction (or when recover() is called), the SDK triggers the recovery flow:
    • Email OTP: Crossmint sends a one-time code to the user’s email
    • SMS OTP: Crossmint sends a one-time code to the user’s phone
    • Server signer: your backend signs the recovery approval automatically
  4. The recovery signer authorizes a new device signer for this device
  5. All subsequent transactions on the new device are frictionless
import { useWallet } from "@crossmint/client-sdk-react-ui";

const { wallet } = useWallet();

// Check if recovery is needed on this device
if (wallet.needsRecovery()) {
    // Trigger recovery proactively (optional)
    await wallet.recover();
}
The previous device’s signer remains valid. Each device maintains its own independent device signer.

Choosing a Recovery Method

MethodBest ForUser FrictionServer Required
Email OTPConsumer apps with email-based authMedium (OTP prompt)No
SMS OTPMobile-first appsMedium (OTP prompt)No
Server signerAI agents, backend automation, hybrid appsNone (automatic)Yes
Email and phone recovery signers can only be configured at wallet creation time. They cannot be added later via addSigner(). Plan your recovery strategy before creating wallets.

Next Steps

Device Signer

Understand how the default client-side signer works

Server Signer

Set up server-side signing with key derivation

Add Signers

Add passkeys or external wallets to an existing wallet