|
| 1 | +# Para Wallet Integration |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This integration automatically creates and manages Para wallets for users, enabling server-side blockchain operations within workflow steps. |
| 6 | + |
| 7 | +## What This Does |
| 8 | + |
| 9 | +1. **Automatic Wallet Creation**: When a user signs up, a Para wallet is automatically created for them |
| 10 | +2. **Secure Storage**: Wallet keyshares are encrypted with AES-256-GCM and stored securely in the database |
| 11 | +3. **Server-Side Access**: Workflow steps can use the user's wallet to perform blockchain operations (sending transactions, signing messages, interacting with smart contracts, etc.) |
| 12 | +4. **User Visibility**: Users can see their wallet address displayed in the user dropdown menu |
| 13 | + |
| 14 | +## How It Works |
| 15 | + |
| 16 | +### Wallet Creation Flow |
| 17 | +1. **User signs up** → Better Auth triggers a database hook |
| 18 | + - File: `lib/auth.ts` |
| 19 | + - Hook: `databaseHooks.user.create.after` |
| 20 | + |
| 21 | +2. **Database hook calls Para SDK** to create a pregenerated wallet |
| 22 | + - `const wallet = await paraClient.createPregenWallet({ type: "EVM", pregenId: { email } })` |
| 23 | + - Returns: `{ id, address, ... }` |
| 24 | + |
| 25 | +3. **Wallet keyshare is encrypted** and stored in database |
| 26 | + - File: `lib/encryption.ts` |
| 27 | + - Function: `encryptUserShare(userShare)` |
| 28 | + - Stored in: `para_wallets` table |
| 29 | + |
| 30 | +4. **Wallet address is displayed** to the user |
| 31 | + - File: `components/workflows/user-menu.tsx` |
| 32 | + - Shown in user dropdown menu |
| 33 | + |
| 34 | +### Workflow Step Usage |
| 35 | +When a workflow step needs to use the wallet: |
| 36 | +1. Fetch encrypted keyshare from database (using authenticated userId) |
| 37 | +2. Decrypt the keyshare |
| 38 | +3. Initialize Para signer for blockchain operations |
| 39 | +4. Perform the operation (send transaction, sign message, call smart contract, etc.) |
| 40 | + |
| 41 | +## Key Components |
| 42 | + |
| 43 | +### Database |
| 44 | +- **Table**: `para_wallets` |
| 45 | +- **Fields**: userId (unique), email, walletId, walletAddress, encrypted userShare, createdAt |
| 46 | +- **Security**: One wallet per user, foreign key to users table, cascading delete |
| 47 | + |
| 48 | +### Encryption |
| 49 | +- **Algorithm**: AES-256-GCM (authenticated encryption) |
| 50 | +- **Key Storage**: Environment variable `WALLET_ENCRYPTION_KEY` |
| 51 | +- **Format**: `iv:authTag:encryptedData` (prevents tampering) |
| 52 | + |
| 53 | +### Helper Functions |
| 54 | +- `getUserWallet(userId)` - Retrieve wallet from database |
| 55 | +- `initializeParaSigner(userId, rpcUrl)` - Get ready-to-use signer for transactions |
| 56 | +- `getUserWalletAddress(userId)` - Get wallet address for display |
| 57 | +- `userHasWallet(userId)` - Check if user has wallet |
| 58 | + |
| 59 | +## What You Can Build |
| 60 | + |
| 61 | +Workflow steps that use the user's wallet can: |
| 62 | +- Send ETH or ERC-20 tokens |
| 63 | +- Interact with smart contracts (DeFi, NFTs, DAOs) |
| 64 | +- Sign messages or data |
| 65 | +- Check balances and token ownership |
| 66 | +- Execute any blockchain operation the user authorizes |
| 67 | + |
| 68 | +## Key Files |
| 69 | + |
| 70 | +- `lib/auth.ts` - Better Auth configuration with wallet creation hook |
| 71 | +- `lib/db/schema.ts` - Database schema for `para_wallets` table |
| 72 | +- `lib/encryption.ts` - AES-256-GCM encryption/decryption utilities |
| 73 | +- `lib/para/wallet-helpers.ts` - Helper functions for wallet operations |
| 74 | +- `app/api/user/route.ts` - API endpoint that includes wallet address |
| 75 | +- `components/workflows/user-menu.tsx` - UI component displaying wallet address |
| 76 | + |
| 77 | +## Environment Variables Required |
| 78 | + |
| 79 | +```env |
| 80 | +PARA_API_KEY=your-para-api-key |
| 81 | +PARA_ENVIRONMENT=beta # or 'prod' |
| 82 | +WALLET_ENCRYPTION_KEY=64-character-hex-string |
| 83 | +``` |
| 84 | + |
| 85 | +## Security Notes |
| 86 | + |
| 87 | +- All Para SDK operations happen server-side only |
| 88 | +- userShare never transmitted to browser |
| 89 | +- Encryption key stored only in environment variables |
| 90 | +- Each user can only access their own wallet (enforced by userId authentication) |
0 commit comments