Wallet Pregeneration
Learn how to create and manage pregenerated wallets for users with Capsule’s SDK
Overview
Wallet Pregeneration allows you to create wallets for users before they set up a wallet with Capsule. This feature gives you control over when users claim and take ownership of their wallet. This guide will walk you through the process of creating, managing, and claiming pregenerated wallets using Capsule’s SDK.
Core Pregeneration Methods
Capsule provides several methods for handling pregenerated wallets:
Retrieve pregenerated wallets for a given identifier.
Check if a pregenerated wallet exists for an identifier.
Claim pregenerated wallets associated with an identifier.
Create a new pregenerated wallet.
Update the identifier of a pregenerated wallet.
Let’s explore each of these methods in detail.
Creating a Pregenerated Wallet
To create a pregenerated wallet, use the createWalletPreGen
method:
const pregenWallet = await capsule.createWalletPreGen(
pregenIdentifier,
useSolana,
pregenIdentifierType
);
A string that identifies the user (e.g., email, user ID).
Optional boolean to create a Solana wallet (default is false for EVM or Cosmos wallets).
Optional enum (EMAIL or PHONE) to specify the identifier type.
Example:
const userEmail = 'user@example.com';
const pregenWallet = await capsule.createWalletPreGen(userEmail);
console.log('Pregenerated Wallet ID:', pregenWallet.id);
It’s important to check if a pregenerated wallet already exists before creating a new one:
const hasWallet = await capsule.hasPregenWallet(userEmail);
if (!hasWallet) {
const pregenWallet = await capsule.createWalletPreGen(userEmail);
console.log('New pregenerated wallet created:', pregenWallet.id);
} else {
console.log('Pregenerated wallet already exists for this user');
}
The identifier doesn’t have to be an email. It can be any string specific to your application, such as a user ID.
Storing and Managing User Share
After creating a pregenerated wallet, it’s crucial to manage the user share so it remains accessible to either you or the user until the claim process. The user share is part of Capsule’s 2/2 MPC that is typically managed by users and protected by their auth+passkey. For pregenerated wallets, you need to handle this share until the wallet is claimed.
To get the user share:
const userShare = await capsule.getUserShare();
To set the user share (important before using the wallet for signing):
await capsule.setUserShare(userShare);
It’s important to safeguard this user share as it’s specific to your application until the wallet is claimed. Store it securely and associate it with the user’s identifier in your backend. If you lose this share, the wallet will no longer be accessible.
Best Practices for Storing the User Share
When temporarily managing the user share, it is critical to have a higher degree of operational excellence around storing this share. In disaster scenarios of widespread data compromise, key rotation is possible in coordination with the Capsule Team. However, Capsule does not store backups of this share in case of data loss.
To mitigate this category of risks, we’ve compiled a few best practices:
- Encrypt User Shares in-transit and at-rest.
- Ensure Your database has backups and periodic replicas to mitigate against data deletion risks.
- Complete a fire drill prior to going live, testing scenarios such as:
- You are unable to access your DB
- Your DB is deleted
- An internal team member’s credentials are compromised
Capsule is happy to offer pre-launch security reviews for teams in the Growth tier or above. Let us know if you need help!
Using a Pregenerated Wallet
To use a pregenerated wallet for signing, first set the user share, then you can sign messages or transactions:
await capsule.setUserShare(userShare);
const messageBase64 = btoa('Hello, World!');
const signature = await capsule.signMessage(walletId, messageBase64);
const rlpEncodedTxBase64 = '...'; // Your RLP encoded transaction
const chainId = '1'; // Ethereum mainnet
const txSignature = await capsule.signTransaction(walletId, rlpEncodedTxBase64, chainId);
You can also sign using popular Ethereum libraries like Ethers or Viem or Solana-Web3.js. These libraries provide a more familiar interface for developers working with transactions and messages.
For more detailed information on signing transactions and messages, please refer to our ecosystem guides. EVM Ecosystem, Solana Ecosystem, and Cosmos Ecosystem
Claiming a Pregenerated Wallet (Optional)
When you want to allow a user to claim their pregenerated wallet, you can use the
claimPregenWallets
method. This process typically involves user authentication and transfers
ownership of the wallet to the user’s Capsule account.
const recoverySecret = await capsule.claimPregenWallets(userEmail);
Before claiming, you might need to update the wallet’s identifier, especially if you used a non-email identifier initially:
await capsule.updateWalletIdentifierPreGen(userEmail, walletId);
The claiming process usually involves these steps:
- Authenticate the user (e.g., email verification, OAuth)
- Update the wallet identifier if necessary
- Claim the wallet
Example flow:
// Assume user is authenticated and we have their email
const userEmail = 'user@example.com';
// Update identifier if necessary
await capsule.updateWalletIdentifierPreGen(userEmail, walletId);
// Claim the wallet
const recoverySecret = await capsule.claimPregenWallets(userEmail);
console.log('Wallet claimed successfully. Recovery secret:', recoverySecret);
Best Practices and Considerations
Reference Example
For a complete example demonstrating the usage of pregeneration methods, refer to our Wallet Pregeneration Example.
This example provides a comprehensive flow of pregeneration method usage in a React application context.
Was this page helpful?