Skip to main content
MoonKey can automatically create embedded wallets for your users during the authentication flow. This provides a seamless onboarding experience where users get a self-custodial wallet immediately upon logging in.

Configuration

Configure automatic wallet creation by setting the embeddedWallets.createOnLogin property in your MoonKeyProvider:
  • Ethereum
  • Solana
import { MoonKeyProvider } from '@moon-key/react-auth';

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    embeddedWallets: {
      createOnLogin: 'always'
    }
  }}
>
  {children}
</MoonKeyProvider>

Configuration Options

createOnLogin
'always' | 'none'
default:"none"
Determines when to create a wallet for the user.
  • 'always' — Create a wallet for every user on login
  • 'none' — Disable automatic wallet creation (create manually when needed)

When to Use Each Option

’always’

Create a wallet for every user, regardless of whether they already have one. Use cases:
  • Web3-first applications where every user needs a wallet
  • Applications that require blockchain transactions for core functionality
  • NFT platforms, DeFi apps, or blockchain games
Behavior:
  • New users get a wallet immediately upon first login
  • Returning users get a wallet on their next login if they don’t have one
  • Simple and straightforward approach for Web3 applications
import { MoonKeyProvider } from '@moon-key/react-auth';

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    embeddedWallets: {
      createOnLogin: 'always'
    }
  }}
>
  {children}
</MoonKeyProvider>

’none’

Disable automatic wallet creation entirely. Use cases:
  • Applications where wallet creation should be user-initiated
  • When you want full control over when wallets are created
  • Authentication-only implementations
Behavior:
  • No wallets are created automatically
  • You must manually create wallets using the useCreateWallet hook
  • Gives you complete control over the wallet creation flow
import { MoonKeyProvider } from '@moon-key/react-auth';

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    embeddedWallets: {
      createOnLogin: 'none'
    }
  }}
>
  {children}
</MoonKeyProvider>
When using 'none', create wallets manually:
import { useCreateWallet } from '@moon-key/react-auth/ethereum';

function CreateWalletButton() {
  const { createWallet } = useCreateWallet();

  const handleCreateWallet = async () => {
    const wallet = await createWallet();
    console.log('Wallet created:', wallet.address);
  };

  return <button onClick={handleCreateWallet}>Create Wallet</button>;
}

How It Works

When automatic wallet creation is enabled, MoonKey checks the following during the login flow:
  1. User authenticates — User completes authentication (email OTP, OAuth, wallet signature, etc.)
  2. Check configuration — MoonKey checks the createOnLogin setting
  3. Evaluate conditions — Based on the setting and user’s current wallet status
  4. Create wallet — If conditions are met, MoonKey generates a self-custodial embedded wallet
  5. User session — User’s session now includes wallet information
This happens seamlessly in the background without requiring additional user interaction.

Accessing Created Wallets

Once a wallet is created (automatically or manually), you can access it through the useMoonKey hook:
import { useMoonKey } from '@moon-key/react-auth';

function WalletInfo() {
  const { user, isAuthenticated } = useMoonKey();

  if (!isAuthenticated) {
    return <p>Please log in</p>;
  }

  if (!user?.wallet) {
    return <p>No wallet found</p>;
  }

  return (
    <div>
      <h3>Your Wallet</h3>
      <p>Address: {user.wallet.address}</p>
    </div>
  );
}

Best Practices

Choose the Right Strategy

Application TypeRecommended SettingReason
DeFi Platform'always'All users need wallets for trading
NFT Marketplace'always'Core functionality requires wallets
Gaming'always'In-game assets need wallet storage
Social + Crypto'always'Ensure all users can access Web3 features
Hybrid App'always' or 'none'Choose based on how central wallets are
Auth Only'none'Manual wallet creation on demand

Consider User Experience

For Web3-native applications:
  • Use 'always' for immediate wallet access
  • Users expect wallets to be available immediately
  • Reduces friction in the onboarding flow
For authentication-focused applications:
  • Use 'none' and create wallets when users need them
  • Allow users to understand your app before getting a wallet
  • Provide education about what a wallet is and why they need it when you create it manually

Environment-Specific Configuration

You can configure different automatic wallet creation settings for different environments:
import { MoonKeyProvider } from '@moon-key/react-auth';

const isDevelopment = process.env.NODE_ENV === 'development';

<MoonKeyProvider
  publishableKey="your-moonkey-publishableKey"
  config={{
    embeddedWallets: {
      // Always create in development for easier testing
      // Manual creation in production for more control
      createOnLogin: isDevelopment ? 'always' : 'none'
    }
  }}
>
  {children}
</MoonKeyProvider>

Combining with Manual Creation

You can combine automatic wallet creation with manual creation for more complex flows:
import { useMoonKey } from '@moon-key/react-auth';
import { useCreateWallet } from '@moon-key/react-auth/ethereum';

function WalletSetup() {
  const { user } = useMoonKey();
  const { createWallet } = useCreateWallet();

  // Automatic creation is disabled (createOnLogin: 'none')
  // Show onboarding and let user create wallet when ready
  
  const handleGetStarted = async () => {
    // Show onboarding modal/flow first
    await showOnboarding();
    
    // Then create wallet
    const wallet = await createWallet();
    console.log('Wallet ready:', wallet.address);
  };

  if (user?.wallet) {
    return <p>Wallet: {user.wallet.address}</p>;
  }

  return (
    <div>
      <h2>Welcome to Our App!</h2>
      <p>You'll need a wallet to get started.</p>
      <button onClick={handleGetStarted}>Get Started</button>
    </div>
  );
}

Troubleshooting

Wallet not created after login

Possible causes:
  • createOnLogin is set to 'none'
  • Authentication didn’t complete successfully
  • Configuration error in the provider
Solution: Check your configuration and user’s wallet status:
const { user } = useMoonKey();
console.log('User has wallet:', !!user?.wallet);

Multiple wallets created

Possible causes:
  • Using 'always' creates a wallet on every login
  • User logged in multiple times during development/testing
Solution: This is expected behavior with 'always'. Each authentication creates a new wallet. If you want to prevent multiple wallets, use 'none' and create wallets manually with checks:
import { useMoonKey } from '@moon-key/react-auth';
import { useCreateWallet } from '@moon-key/react-auth/ethereum';

function EnsureSingleWallet() {
  const { user } = useMoonKey();
  const { createWallet } = useCreateWallet();

  const ensureWallet = async () => {
    if (!user?.wallet) {
      await createWallet();
    }
  };

  return <button onClick={ensureWallet}>Get Wallet</button>;
}

Need to create wallet immediately

Possible causes:
  • Automatic creation is disabled
  • Need wallet before user completes authentication
Solution: Enable automatic creation with 'always':
config={{
  embeddedWallets: {
    createOnLogin: 'always'
  }
}}