Overview
This feature is currently only available to customers who request access. Please reach out for access here.
Magic offers Wallet PreGen, a feature that allows you to create non-custodial EVM wallets programmatically without requiring end users to start or complete an authentication flow. After the wallet is generated, a user can claim their PreGen wallet by authenticating through your application.
Neither Magic nor the developer can access the wallet’s private key; it can only be accessed by the end user after claiming the wallet.
Wallet PreGen is currently only available for EVM-compatible blockchains.
Use Cases
- Airdrop tokens or NFTs to users before they create an account
- Prepare wallets for onboarding campaigns
- Pre-fund wallets for new users
- Create wallets for batch user imports
- Generate wallets for rewards
API Reference
You can make the API call below to pregenerate a single wallet for a specific email address.
Request Parameters
The secret API key obtained from your Magic Dashboard. Keep this secure and never expose it in client-side code.
The email address associated with the PreGen wallet. The user must authenticate with this email to claim the wallet.
curl -X POST 'https://api.magic.link/v1/admin/pregen/wallet' \
--header 'X-Magic-Secret-Key: sk_live_...' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "[email protected]"
}'
Response
The Ethereum-compatible public wallet address generated for the specified email. This address can be used to send assets before the user claims the wallet.
Example Response:
{
"public_address": "0xBAcFD5E443eFDFECb9850a9d8a23C33701E66742"
}
Error Responses:
{
"error": "MALFORMED_EMAIL",
"status": "error"
}
{
"error": "MagicClient not found.",
"status": "error"
}
Claiming a PreGen Wallet
Once a wallet has been pregenereated, the user can claim it by authenticating through your application using the same email address.
User authenticates
The user logs in to your application using the same email address that was used to pregenerate the wallet.import { Magic } from 'magic-sdk';
const magic = new Magic('YOUR_PUBLISHABLE_API_KEY');
await magic.auth.loginWithEmailOTP({
email: '[email protected]'
});
Wallet is automatically claimed
Magic automatically links the PreGen wallet to the authenticated user. No additional steps required.The user now has full access to their wallet and any assets that were sent to it.
Verify wallet ownership
You can verify the user’s wallet address matches the PreGen one.const metadata = await magic.user.getInfo();
console.log('User wallet:', metadata.wallets.ethereum.publicAddress);
Complete Example
Here’s a complete example of pregenerating a wallet, funding it, and having the user claim it:
Backend: Pregenerate
Backend: Fund Wallet
Frontend: User Claims
async function pregenerateWalletForUser(email) {
const response = await fetch('https://api.magic.link/v1/admin/pregen/wallet', {
method: 'POST',
headers: {
'X-Magic-Secret-Key': process.env.MAGIC_SECRET_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({ email })
});
const { public_address } = await response.json();
await database.saveWallet({
email,
public_address,
claimed: false
});
return public_address;
}
const walletAddress = await pregenerateWalletForUser('[email protected]');
console.log(`Wallet created: ${walletAddress}`);
import { ethers } from 'ethers';
async function fundPregenWallet(toAddress, amount) {
const provider = new ethers.JsonRpcProvider(RPC_URL);
const wallet = new ethers.Wallet(FUNDING_PRIVATE_KEY, provider);
const tx = await wallet.sendTransaction({
to: toAddress,
value: ethers.parseEther(amount)
});
await tx.wait();
console.log(`Funded ${toAddress} with ${amount} ETH`);
}
await fundPregenWallet(walletAddress, '0.1');
import { Magic } from 'magic-sdk';
const magic = new Magic('YOUR_PUBLISHABLE_API_KEY');
async function claimWallet(email) {
await magic.auth.loginWithEmailOTP({ email });
const metadata = await magic.user.getInfo();
console.log('Claimed wallet:', metadata.wallets.ethereum.publicAddress);
const balance = await getBalance(metadata.wallets.ethereum.publicAddress);
console.log('Wallet balance:', balance);
}
await claimWallet('[email protected]');
Resources