Generate wallet addresses
Learn how to programmatically generate wallet addresses for your users using viem library or smart contract wallet providers
If your users don't have wallet addresses yet, you can generate them programmatically. This guide covers two main approaches for creating wallet addresses for your users.
Wallet addresses are required to create users in Snag. If you're migrating existing users, see our migration guide for step-by-step instructions.
Option 1: Generate with viem Library
For backend wallet generation, you can use the viem library to create new EVM wallet addresses. This approach gives you full control over wallet generation and is ideal for server-side implementations.
Installation
npm install viem
Generate a Wallet
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
// Generate a new wallet
const privateKey = generatePrivateKey()
const account = privateKeyToAccount(privateKey)
const walletAddress = account.address
// Use walletAddress to create the Snag user
await client.users.createMetadata({
walletAddress: walletAddress,
externalIdentifier: 'your-internal-user-id',
})
Complete Integration Example
Here's a full example showing how to generate a wallet and create a Snag user:
import SnagSolutions from '@snagsolutions/sdk'
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
const client = new SnagSolutions({
apiKey: 'your-api-key-here',
})
async function createUserWithWallet(userId: string, email: string) {
// Generate new wallet
const privateKey = generatePrivateKey()
const account = privateKeyToAccount(privateKey)
// Store private key securely in your database
await yourDatabase.savePrivateKey({
userId: userId,
encryptedPrivateKey: await encryptPrivateKey(privateKey),
})
// Create Snag user with the generated wallet address
const user = await client.users.createMetadata({
walletAddress: account.address,
externalIdentifier: userId,
emailAddress: email,
})
return user
}
Critical Security Requirements:
- Store private keys in an encrypted database or Key Management Service (KMS)
- Never expose private keys in client-side code or logs
- Use AWS KMS, Google Cloud KMS, or HashiCorp Vault for production
- Never commit private keys to version control
- Implement proper access controls for private key retrieval
Option 2: Smart Contract Wallet Providers
For a managed solution, use embedded wallet providers that handle wallet creation and key management automatically. These providers abstract away the complexity of private key management and provide a better user experience.
Recommended Providers
Advantages of Smart Wallet Providers
These providers offer several advantages over self-managed wallet generation:
- Automatic key management - No need to handle private keys yourself
- Social login integration - Email or social login → wallet address mapping
- Better UX - Seamless onboarding for Web2 users
- Built-in security - Industry best practices implemented out of the box
- Account recovery - Users can recover access without managing seed phrases
- Multi-chain support - Easy support for multiple blockchain networks
Smart contract wallet providers are recommended if you want to abstract wallet complexity from your users and provide a Web2-like experience.
Integration Example with Dynamic
Here's a basic example of how you might integrate Dynamic's embedded wallets:
import { DynamicContextProvider } from '@dynamic-labs/sdk-react-core'
// On your frontend
function App() {
return (
<DynamicContextProvider
settings={{
environmentId: 'your-environment-id',
walletConnectors: ['embedded'],
}}
>
{/* Your app */}
</DynamicContextProvider>
)
}
// After user logs in, get their wallet address
const walletAddress = user.verifiedCredentials[0].address
// Then create the Snag user on your backend
await client.users.createMetadata({
walletAddress: walletAddress,
externalIdentifier: user.id,
})
Best Practices
Regardless of which approach you choose, follow these best practices:
Always use the externalIdentifier field to link Snag users to your internal user ID system. This makes it easy to query and manage users across your systems.
For self-managed wallets, implement a secure backup and recovery mechanism. Consider using deterministic wallet generation (HD wallets) for easier recovery.
Separate wallet generation between development, staging, and production environments. Never use production keys in development.
Log and monitor all access to private keys. Implement alerts for unusual access patterns.
Be aware of regulatory requirements in your jurisdiction regarding custody of user assets and key management.