Modular wallets passkey recovery support for iOS and Android coming soon!
Modular wallets passkey recovery support for iOS and Android coming soon!
Passkey recovery allows users to regain access to their smart accounts if they lose their primary passkey. This mechanism enables users to register an Externally Owned Account (EOA) as a recovery key. The recovery key can later be used to generate a new passkey and restore access to the smart account—ensuring users maintain full control in a non-custodial setup. For a complete code sample, see the Passkey Recovery Example in the Modular Wallets Web SDK.
The recovery process includes two phases:
Registration: The user registers an EOA to act as a recovery key. This key is submitted to the network and added as a signer on the smart account.
Note: Registration must be completed while the user still has access to their original passkey. This ensures that the recovery key is securely authorized.
Recovery: If the primary passkey is lost, the user can use the recovery key to register a new passkey and resume access.
Before you implement passkey backup and recovery, make sure you have the following:
To set up passkey backup and recovery, use the following functions from the Modular Wallets SDK:
registerRecoveryAddress
: Registers an EOA as a recovery key.executeRecovery
: Adds a new WebAuthn credential using the recovery key.estimateRegisterRecoveryAddressGas
: Estimates gas for registering a recovery
key.estimateExecuteRecoveryGas
: Estimates gas for executing the recovery
process.These functions use ERC-4337 user operations to interact with the smart account.
To allow your users to recover their passkeys, your application should prompt them to associate a recovery address with their smart account while they still have access to their original passkey. The following code sample shows how to register a recovery address and generate a recovery mnemonic. This mnemonic can then be used later to recover their passkey and associated smart account.
Note: The user must store the generated mnemonic securely. It serves as the only credential for recovery if the passkey is lost.
import { english, generateMnemonic, mnemonicToAccount } from 'viem/accounts'
import { recoveryActions } from '@circle-fin/modular-wallets-core'
// Extend bundler client with recovery actions
const recoveryClient = bundlerClient.extend(recoveryActions)
// Generate recovery mnemonic (make sure the user stores this securely)
const mnemonic = generateMnemonic(english)
const recoveryEoa = mnemonicToAccount(mnemonic)
// Register recovery address with the smart account
await recoveryClient.registerRecoveryAddress({
account,
recoveryAddress: recoveryEoa.address,
paymaster: true, // Optional: use a paymaster to sponsor gas
})
This creates a mapping between the smart account and the recovery address.
If a user loses their passkey, they can use the mnemonic from the recovery address to start the recovery flow.
// Recreate the recovery account from the saved mnemonic
const localAccount = mnemonicToAccount(savedMnemonic)
// Initialize a temporary smart account using the recovery EOA
const newAccount = await toCircleSmartAccount({
client,
owner: localAccount,
})
// Register a new WebAuthn passkey credential
const newCredential = await toWebAuthnCredential({
transport: passkeyTransport,
mode: WebAuthnMode.Register,
username: '<RECOVERY_PASSKEY_USERNAME>',
})
This sets up a temporary account from the recovery key and prepares a new passkey to replace the lost one.
After registering the new passkey, call executeRecovery
to complete the
recovery and restore access to the smart account.
await recoveryClient.executeRecovery({
account: newAccount, // Temporary account used for signing
credential: newCredential, // New WebAuthn credential
paymaster: true, // Optional: use a paymaster to sponsor gas
})
This associates the new WebAuthn
credential with the smart account.
After a successful recovery, the user can access the smart account using their new passkey.
const recoveredAccount = await toCircleSmartAccount({
client,
owner: toWebAuthnAccount({ credential: newCredential }) as WebAuthnAccount,
})
// The user can now sign transactions and use the wallet as normal
Use the following tips to improve the reliability and user experience of your passkey recovery implementation.
Recovery operations require network gas fees. To improve the user experience, you can either sponsor the gas or estimate and display it to users in advance. Circle recommends using the Gas Station to sponsor gas, as it creates a smoother experience.
Recommended approaches:
const registerGasEstimate =
await recoveryClient.estimateRegisterRecoveryAddressGas({
account,
recoveryAddress: recoveryEoa.address,
})
const costInEth = formatEther(
registerGasEstimate.totalGas * registerGasEstimate.maxFeePerGas,
)
// Display cost to user
console.log(`Estimated cost: ${costInEth} ETH`)
The recovery implementation includes built-in validation and error handling for common edge cases:
Each recovery function uses a user operation that requires a valid smart account to sign the transaction. Validation occurs automatically, whether the account is passed directly or hoisted into the context.
Tip: Always wrap recovery logic in try/catch
blocks to handle errors
cleanly and provide actionable feedback to users.
Follow these best practices to increase user trust, security, and recoverability when implementing passkey backup and recovery.
The following user flows describe a possible implementation of the passkey backup and recovery process in your app. The flows are divided into two parts:
After the user signs in with their existing passkey, guide them to set up a recovery key. We recommend offering this option post-onboarding, with access placed under a Settings or Security section in your app.
The following steps outline a possible user flow for registering a recovery key:
After the user has securely stored a recovery key, they can use it to regain access if their original passkey is lost. This flow should be accessible from your app's sign-in screen or recovery page.
The following steps outline a possible user flow for recovering a smart account using a registered recovery key:
Passkey backup and recovery provides a secure, self-custodial way for users to regain access to their smart accounts. By implementing this feature, you give users a reliable recovery option if they lose access to their primary passkey. This approach reduces the risk of permanent account loss and maintains the core principle of user control. Circle recommends pairing recovery setup with strong user education, redundant recovery methods, and thorough testing to ensure a seamless experience in production.