---
title: "Generate wallet addresses"
description: "Learn how to programmatically generate wallet addresses for your users using viem library or smart contract wallet providers"
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

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.

<Info>
  Wallet addresses are required to create users in Snag. If you're migrating existing users, see our [migration guide](/loyalty/development/migrate-users) for step-by-step instructions.
</Info>

## Option 1: Generate with viem Library

For backend wallet generation, you can use the [viem](https://viem.sh) library to create new EVM wallet addresses. This approach gives you full control over wallet generation and is ideal for server-side implementations.

### Installation

```bash
npm install viem
```

### Generate a Wallet

```typescript
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:

```typescript
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
}
```

<Warning>
  **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
</Warning>

## 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

<Columns cols={2}>
  <Card title="Dynamic" icon="wallet" href="https://docs.dynamic.xyz/embedded-wallets/overview">
    Easy-to-integrate embedded wallets with email/social login support
  </Card>
  <Card title="Privy" icon="key" href="https://docs.privy.io/guide/embedded-wallets">
    Embedded wallets with excellent UX for Web2 users transitioning to Web3
  </Card>
  <Card title="Biconomy" icon="shield" href="https://docs.biconomy.io/">
    Smart account infrastructure with gasless transactions and account abstraction
  </Card>
  <Card title="Thirdweb" icon="cube" href="https://portal.thirdweb.com/wallets/embedded-wallet/overview">
    Comprehensive wallet SDK with smart accounts and social login
  </Card>
</Columns>

### 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

<Tip>
  Smart contract wallet providers are recommended if you want to abstract wallet complexity from your users and provide a Web2-like experience.
</Tip>

### Integration Example with Dynamic

Here's a basic example of how you might integrate Dynamic's embedded wallets:

```typescript
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:

<AccordionGroup>
  <Accordion title="Link to Internal User IDs">
    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.
  </Accordion>
  
  <Accordion title="Implement Backup and Recovery">
    For self-managed wallets, implement a secure backup and recovery mechanism. Consider using deterministic wallet generation (HD wallets) for easier recovery.
  </Accordion>
  
  <Accordion title="Use Environment-Specific Keys">
    Separate wallet generation between development, staging, and production environments. Never use production keys in development.
  </Accordion>
  
  <Accordion title="Audit Access to Private Keys">
    Log and monitor all access to private keys. Implement alerts for unusual access patterns.
  </Accordion>
  
  <Accordion title="Consider Regulatory Requirements">
    Be aware of regulatory requirements in your jurisdiction regarding custody of user assets and key management.
  </Accordion>
</AccordionGroup>

## Next Steps

<Columns cols={2}>
  <Card title="Migrate Users" icon="arrow-right-arrow-left" href="/loyalty/development/migrate-users">
    Learn how to migrate your existing users to Snag with wallet addresses
  </Card>
  <Card title="Create Users" icon="user-plus" href="/loyalty/development/create-users">
    Return to the user creation guide to create users with your generated wallet addresses
  </Card>
</Columns>
