Migrating from Privy to WaaP
A step-by-step guide for migrating your application from Privy embedded wallets to WaaP. Covers all three Privy wallet types, with account pregeneration for zero-friction user migration.
Before You Start
Contact our team to get started with migration. We’ll set you up with:
- An API key for account pregeneration (bulk wallet creation for your users)
- A dedicated migration support channel
- Revenue share terms for your integration
Identify your Privy wallet types. Your application may use one or more of these:
| Wallet Type | How to Identify | Migration Complexity |
|---|---|---|
| Client-side EOA | Created via Privy SDK in user’s browser | Medium — requires user action |
| Server-side EOA | Created via Privy server API | Low — fully automatable |
| Smart Wallet (ERC-4337) | On-chain smart contract account | Medium — ownership transfer per account |
Step 1: Pre-Generate WaaP Accounts
Before changing anything in your application, pre-generate WaaP wallets for your existing users. This means every user will have a wallet waiting for them when they first log in through WaaP.
Our team will provide you with an API key for the Account Pregeneration API. For each user:
curl -X POST https://auth.waap.xyz/pregen-account \
-H "X-Pregen-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'Response:
{
"address": "0x1234...abcd"
}The endpoint is idempotent — calling it twice with the same email returns the same address. Safe for batch retries. This can run well in advance of any user-facing changes.
Store the email → WaaP address mapping. You’ll need it for asset transfers and on-chain reference updates.
Don’t have an API key yet? Get in touch →
Step 2: Integrate the WaaP SDK
WaaP’s SDK is EIP-1193 compliant. If your app uses wagmi, ethers.js, or viem, the swap is straightforward.
Install
npm install @human.tech/waap-sdkInitialize
import { initWaaP } from '@human.tech/waap-sdk';
initWaaP({
config: {
// Configure auth methods — match what your Privy integration used
authenticationMethods: ['email', 'social'],
allowedSocials: ['google', 'discord'],
styles: { darkMode: true }
}
});Connect with wagmi
Before (Privy)
import { usePrivy } from '@privy-io/react-auth';
const { login } = usePrivy();The WaaP SDK provides window.waap as an EIP-1193 provider. Any library that works with MetaMask works with WaaP — no code changes beyond initialization.
Use the Playground to visually configure auth methods, styling, and social providers, then copy the generated config.
Step 3: Migrate Wallets by Type
Client-Side EOA Wallets
These require user participation — the user must transfer assets from their old Privy wallet to their new WaaP wallet.
What to build:
- A migration prompt in your app UI that shows the user their new WaaP wallet address.
- An asset transfer flow — either manual (user sends assets themselves) or assisted (you build a transfer helper using Privy’s
exportWallet()and a signing flow).
User experience:
- User logs into your app → WaaP authentication matches them to their pre-generated account via email.
- Your app shows: “Your new wallet address is
0x1234.... Transfer your assets from your previous wallet.” - User transfers tokens, NFTs, and positions from old Privy address to new WaaP address.
- Done — user continues using your app with WaaP.
Remind users to check all chains (L2s included), staked positions, and token approvals. Assets left at the old Privy address will remain there.
Developer checklist:
- Map Privy user IDs → WaaP user IDs in your backend
- Update any on-chain references to user addresses (allow-lists, vesting schedules, etc.)
- Build migration UI with clear instructions and address display
- Send migration emails/notifications to users who haven’t migrated after N days
Server-Side EOA Wallets
These are fully automatable. The user never held the key directly, so you can orchestrate the entire migration programmatically.
Migration script (pseudocode):
for (const user of serverSideWalletUsers) {
// 1. Get user's new WaaP address (already pre-generated in Step 1)
const waapAddress = addressMap[user.email];
// 2. Export key from Privy (server-side API)
const privyKey = await privy.exportWallet(user.privyWalletId);
// 3. Transfer all assets from old address to new address
await transferAllAssets(privyKey, waapAddress);
// 4. Securely dispose of the exported key
privyKey.destroy(); // Never persist to disk or logs
}Exported private keys must be handled in a secure environment (HSM, ephemeral memory). Never log them. Never write them to disk. Destroy after transfer.
Developer checklist:
- Script batch export → transfer flow
- Handle multi-chain assets (run transfers on each chain where user has balances)
- Notify users that their wallet address has changed
- Update backend references and any dependent integrations
Smart Wallets (ERC-4337)
Smart wallets are on-chain contracts — the address doesn’t change. Instead of transferring assets, you transfer ownership of the smart contract to the new WaaP wallet.
Create WaaP wallets
Get the user’s new WaaP address (pre-generated in Step 1).
Transfer ownership
Using the current Privy EOA signer, call the ownership transfer function:
// Interface depends on your smart account implementation
// SimpleAccount / Kernel / Safe each have different functions
// Example: SimpleAccount-style
function transferOwnership(address newOwner) external onlyOwner;Verify
Confirm the new WaaP address is the registered owner and can sign UserOperations. Update your bundler and paymaster configuration to accept signatures from the new WaaP wallet.
Since the smart wallet address does not change, users keep all on-chain balances, positions, and reputation. No asset transfers needed. No on-chain reference updates.
Developer checklist:
- Identify which smart account implementation you use (SimpleAccount, Kernel, Safe, Biconomy, etc.)
- Execute ownership transfer for each smart wallet
- Update bundler/paymaster to accept WaaP-signed UserOperations
- Test signing, gas sponsorship, and all smart account features end-to-end
Step 4: Migrate Agent Wallets (If Applicable)
If you’re using Privy server wallets for AI agent operations, the migration path is:
- Pre-generate agent wallets via the Account Pregeneration API (same as Step 1).
- Install waap-cli in your agent’s runtime:
npm install -g @human.tech/waap-cli@latest - Transfer agent funds from Privy server wallet addresses to new WaaP addresses.
- Replace Privy SDK calls with waap-cli commands:
# Sign and send a transaction waap-cli send-tx --to 0x... --value 0.01 --chain-id 1 # Sign EIP-712 typed data (e.g., Polymarket orders) waap-cli sign-typed-data --data '{...}' # Check balance waap-cli request eth_getBalance '["0x...","latest"]' --chain-id 1 - Configure security policies:
# Set daily spend limit waap-cli policy set --daily-spend-limit 500 # Enable 2FA via Telegram for high-risk operations waap-cli 2fa enable --telegram <chat_id> - Set up Permission Tokens for routine agent operations that should bypass 2FA (max 2 hours, scoped to specific actions).
For full CLI documentation, see WaaP for Agents.
waap-cli agent usage is free through April 2026.
Migration Summary
| Client-Side EOA | Server-Side EOA | Smart Wallet | Agent Wallet | |
|---|---|---|---|---|
| Address changes? | Yes | Yes | No | Yes |
| Asset transfer needed? | Yes | Yes | No | Yes |
| User action required? | Yes | Minimal | Depends on owner | No |
| Pre-generated accounts? | Yes | Yes | Yes (new owner) | Yes |
| Automation potential | Low | High | Medium | High |
Recommended Timeline
| Phase | Duration | Actions |
|---|---|---|
| Preparation | 1-2 weeks | Inventory wallet types, request API key, map on-chain positions and credentials |
| Pre-generation | 1 day | Run account pregeneration for all users. Store address mappings. |
| SDK integration | 1-2 weeks | Swap Privy SDK for WaaP SDK. Test auth flows, signing, and transaction submission. |
| Server-side + agent migration | 1 week | Batch-migrate server-side EOAs and agent wallets (fully automated). |
| Smart wallet migration | 1-2 weeks | Execute ownership transfers per account. Test bundler/paymaster with new signers. |
| Client-side EOA migration | 2-4 weeks (long tail) | Launch migration UI. Prompt users. Send reminders for stragglers. |
| Sunset | 1 week | Monitor for leftover balances. Send final reminders. Disable Privy integration. |
Ready to get started? Talk to our team → — we’ll help you scope the migration, set up account pregeneration, and build a custom timeline.
Need Help?
- Get in touch — Migration support, API key setup, and custom timeline planning.
- Documentation — Full SDK and CLI reference throughout this site.
- Live examples — See working integration recipes.