> ## Documentation Index
> Fetch the complete documentation index at: https://docs.streambird.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Export a Wallet

**MoonKey enables your users to export the private key for their embedded wallet**. This allows them to use their embedded wallet address with another wallet client, such as MetaMask or Phantom, or to back up their wallet for recovery purposes.

<Warning>
  Exporting private keys is a sensitive operation. Once exported, the private key gives complete control over the wallet and all its assets. Users should be educated about proper key storage and security practices.
</Warning>

## Overview

When users export their wallet, they receive:

* **Full private key** for their embedded wallet
* **Complete control** over their wallet, even outside your application
* **Ability to import** into other wallet clients (MetaMask, Phantom, etc.)
* **Self-custody** of their assets

<Info>
  When your user exports their embedded wallet, their private key is assembled in a secure environment separate from your app. This means **neither you nor MoonKey can ever access your user's full private key**. Your user is the only party that can ever access it.
</Info>

## React SDK

MoonKey provides a simple hook-based API for wallet export in React applications.

<Tabs>
  <Tab title="Ethereum">
    To enable wallet export for Ethereum wallets, use the `useExportKey` hook from `@moon-key/react-auth/ethereum`:

    ### Basic Usage

    ```tsx theme={null}
    import { useMoonKey } from '@moon-key/react-auth';
    import { useExportKey } from '@moon-key/react-auth/ethereum';

    function ExportWalletButton() {
      const { user, isAuthenticated, ready } = useMoonKey();
      const { exportKey } = useExportKey();

      const handleExport = async () => {
        if (!user?.wallet) {
          alert('No wallet found');
          return;
        }

        try {
          await exportKey({
            wallet: user.wallet
          });
          console.log('Export initiated');
        } catch (error) {
          console.error('Export failed:', error);
        }
      };

      // Check if user has a wallet
      const hasWallet = user?.wallet !== undefined;

      return (
        <button 
          onClick={handleExport} 
          disabled={!ready || !isAuthenticated || !hasWallet}
        >
          Export Wallet
        </button>
      );
    }
    ```

    ### With Custom UI Configuration

    You can customize the export modal's appearance by passing a `uiConfig` object:

    ```tsx theme={null}
    import { useMoonKey } from '@moon-key/react-auth';
    import { useExportKey } from '@moon-key/react-auth/ethereum';

    function ExportWalletButton() {
      const { user } = useMoonKey();
      const { exportKey } = useExportKey();

      const handleExport = async () => {
        if (!user?.wallet) return;

        try {
          await exportKey({
            wallet: user.wallet,
            uiConfig: {
              title: 'Backup Your Wallet',
              privateKeyDescription: 'Your private key provides complete control over this wallet. Store it securely.',
              neverShareDescription: 'Never share your private key with anyone, including MoonKey support.',
              loadingExportOptionsText: 'Preparing secure export...'
            }
          });
        } catch (error) {
          console.error('Export cancelled or failed:', error);
        }
      };

      return (
        <button onClick={handleExport}>
          Export Private Key
        </button>
      );
    }
    ```

    ### Complete Example

    Here's a complete example with proper validation and error handling:

    ```tsx theme={null}
    'use client';
    import { useMoonKey } from '@moon-key/react-auth';
    import { useExportKey } from '@moon-key/react-auth/ethereum';
    import { useState } from 'react';

    export default function WalletExportSection() {
      const { user, isAuthenticated, ready } = useMoonKey();
      const { exportKey } = useExportKey();
      const [isExporting, setIsExporting] = useState(false);
      const [error, setError] = useState<string | null>(null);

      const handleExport = async () => {
        // Clear previous errors
        setError(null);

        // Validate user has a wallet
        if (!user?.wallet) {
          setError('No wallet found. Please create a wallet first.');
          return;
        }

        // Confirm user intent
        const confirmed = window.confirm(
          'WARNING: Your private key gives complete control of your wallet. ' +
          'Make sure you store it in a secure location. Continue?'
        );

        if (!confirmed) return;

        setIsExporting(true);

        try {
          await exportKey({
            wallet: user.wallet,
            uiConfig: {
              title: 'Export Private Key',
              privateKeyDescription: 'This key provides full access to your wallet and funds. Keep it safe and offline.',
              neverShareDescription: 'Never share this key. MoonKey will never ask for it.',
              loadingExportOptionsText: 'Loading secure export options...'
            }
          });

          alert('Private key export initiated. Follow the instructions on screen.');
        } catch (err: any) {
          console.error('Export error:', err);
          setError(err.message || 'Failed to export wallet. Please try again.');
        } finally {
          setIsExporting(false);
        }
      };

      // Loading state
      if (!ready) {
        return <div>Loading...</div>;
      }

      // Not authenticated
      if (!isAuthenticated || !user) {
        return (
          <div className="export-section">
            <p>Please sign in to export your wallet</p>
          </div>
        );
      }

      // No wallet
      if (!user.wallet) {
        return (
          <div className="export-section">
            <p>No wallet found. Create a wallet to enable export.</p>
          </div>
        );
      }

      return (
        <div className="export-section">
          <h3>Export Wallet</h3>
          <p className="warning-text">
            ⚠️ Exporting your private key gives you complete control of your wallet, 
            but also complete responsibility for its security.
          </p>

          <button
            onClick={handleExport}
            disabled={isExporting}
            className="export-button"
          >
            {isExporting ? 'Exporting...' : 'Export Private Key'}
          </button>

          {error && (
            <div className="error-message">
              {error}
            </div>
          )}

          <div className="info-box">
            <h4>What you'll receive:</h4>
            <ul>
              <li>Your wallet's private key</li>
              <li>Instructions for importing into MetaMask</li>
              <li>Security best practices</li>
            </ul>
          </div>
        </div>
      );
    }
    ```
  </Tab>

  <Tab title="Solana">
    To enable wallet export for Solana wallets, use the `useExportKey` hook from `@moon-key/react-auth/solana`:

    ### Basic Usage

    ```tsx theme={null}
    import { useMoonKey } from '@moon-key/react-auth';
    import { useExportKey } from '@moon-key/react-auth/solana';

    function ExportWalletButton() {
      const { user, isAuthenticated, ready } = useMoonKey();
      const { exportKey } = useExportKey();

      const handleExport = async () => {
        if (!user?.wallet) {
          alert('No wallet found');
          return;
        }

        try {
          await exportKey({
            wallet: user.wallet
          });
          console.log('Export initiated');
        } catch (error) {
          console.error('Export failed:', error);
        }
      };

      // Check if user has a wallet
      const hasWallet = user?.wallet !== undefined;

      return (
        <button 
          onClick={handleExport} 
          disabled={!ready || !isAuthenticated || !hasWallet}
        >
          Export Wallet
        </button>
      );
    }
    ```

    ### With Custom UI Configuration

    ```tsx theme={null}
    import { useMoonKey } from '@moon-key/react-auth';
    import { useExportKey } from '@moon-key/react-auth/solana';

    function ExportWalletButton() {
      const { user } = useMoonKey();
      const { exportKey } = useExportKey();

      const handleExport = async () => {
        if (!user?.wallet) return;

        try {
          await exportKey({
            wallet: user.wallet,
            uiConfig: {
              title: 'Backup Your Solana Wallet',
              privateKeyDescription: 'Your private key provides complete control over this Solana wallet. Store it securely.',
              neverShareDescription: 'Never share your private key with anyone, including MoonKey support.',
              loadingExportOptionsText: 'Preparing secure export...'
            }
          });
        } catch (error) {
          console.error('Export cancelled or failed:', error);
        }
      };

      return (
        <button onClick={handleExport}>
          Export Private Key
        </button>
      );
    }
    ```

    ### Complete Example

    ```tsx theme={null}
    'use client';
    import { useMoonKey } from '@moon-key/react-auth';
    import { useExportKey } from '@moon-key/react-auth/solana';
    import { useState } from 'react';

    export default function SolanaWalletExport() {
      const { user, isAuthenticated, ready } = useMoonKey();
      const { exportKey } = useExportKey();
      const [isExporting, setIsExporting] = useState(false);

      const handleExport = async () => {
        if (!user?.wallet) return;

        const confirmed = window.confirm(
          'Your private key gives complete control of your Solana wallet. ' +
          'Store it securely. Continue?'
        );

        if (!confirmed) return;

        setIsExporting(true);

        try {
          await exportKey({
            wallet: user.wallet,
            uiConfig: {
              title: 'Export Solana Wallet',
              privateKeyDescription: 'Use this key to import your wallet into Phantom or other Solana wallets.',
              neverShareDescription: 'Keep this key private. Anyone with it can access your funds.',
            }
          });
        } catch (error) {
          console.error('Export failed:', error);
        } finally {
          setIsExporting(false);
        }
      };

      if (!ready || !isAuthenticated || !user?.wallet) {
        return null;
      }

      return (
        <button
          onClick={handleExport}
          disabled={isExporting}
          className="export-button"
        >
          {isExporting ? 'Exporting...' : 'Export Private Key'}
        </button>
      );
    }
    ```
  </Tab>
</Tabs>

## UI Configuration Options

The `exportKey` method accepts an optional `uiConfig` object to customize the export modal:

<ParamField path="title" type="string">
  Custom title displayed at the top of the export modal.

  **Example:**

  ```tsx theme={null}
  uiConfig: {
    title: 'Backup Your Wallet'
  }
  ```
</ParamField>

<ParamField path="privateKeyDescription" type="string">
  Description explaining what the private key is and its importance.

  **Example:**

  ```tsx theme={null}
  uiConfig: {
    privateKeyDescription: 'Your private key gives full control of your wallet. Store it securely offline.'
  }
  ```
</ParamField>

<ParamField path="neverShareDescription" type="string">
  Warning message emphasizing that the key should never be shared.

  **Example:**

  ```tsx theme={null}
  uiConfig: {
    neverShareDescription: 'Never share your private key with anyone, including MoonKey support.'
  }
  ```
</ParamField>

<ParamField path="loadingExportOptionsText" type="string">
  Loading text displayed while the export modal is initializing.

  **Example:**

  ```tsx theme={null}
  uiConfig: {
    loadingExportOptionsText: 'Preparing secure export...'
  }
  ```
</ParamField>

<ParamField path="hdDescription" type="string">
  Description for HD (Hierarchical Deterministic) wallet exports.

  **Example:**

  ```tsx theme={null}
  uiConfig: {
    hdDescription: 'Your seed phrase can restore all wallets derived from this account.'
  }
  ```
</ParamField>

<ParamField path="logoUrl" type="string">
  URL to your application's logo to display in the export modal.

  **Example:**

  ```tsx theme={null}
  uiConfig: {
    logoUrl: 'https://myapp.com/logo.png'
  }
  ```
</ParamField>

## Common Use Cases

### Wallet Backup

Allow users to back up their wallet for recovery:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';
import { useExportKey } from '@moon-key/react-auth/ethereum';

function BackupWalletButton() {
  const { user } = useMoonKey();
  const { exportKey } = useExportKey();

  const handleBackup = async () => {
    if (!user?.wallet) return;

    await exportKey({
      wallet: user.wallet,
      uiConfig: {
        title: 'Backup Your Wallet',
        privateKeyDescription: 'Save your private key in a secure location for wallet recovery.',
        neverShareDescription: 'Store this key offline. Never share it with anyone.'
      }
    });
  };

  return (
    <button onClick={handleBackup} className="backup-btn">
      Backup Wallet
    </button>
  );
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always confirm user intent">
    Use confirmation dialogs before exporting to ensure users understand the implications:

    ```tsx theme={null}
    const confirmed = window.confirm(
      'WARNING: Your private key gives complete control of your wallet. ' +
      'Make sure you store it securely. Continue?'
    );

    if (!confirmed) return;
    ```
  </Accordion>

  <Accordion title="Educate users about security">
    Provide clear warnings and best practices:

    ```tsx theme={null}
    <div className="security-notice">
      <h4>Security Best Practices:</h4>
      <ul>
        <li>Store your private key in a password manager or offline</li>
        <li>Never share your key with anyone</li>
        <li>Be cautious of phishing attempts</li>
        <li>Consider using a hardware wallet for large amounts</li>
      </ul>
    </div>
    ```
  </Accordion>

  <Accordion title="Validate wallet existence">
    Always check that a wallet exists before attempting export:

    ```tsx theme={null}
    if (!user?.wallet) {
      setError('No wallet found. Create a wallet first.');
      return;
    }
    ```
  </Accordion>

  <Accordion title="Handle errors gracefully">
    Provide clear error messages and recovery options:

    ```tsx theme={null}
    try {
      await exportKey({ wallet: user.wallet });
    } catch (error: any) {
      if (error.code === 'USER_CANCELLED') {
        console.log('User cancelled export');
      } else {
        setError('Export failed. Please try again or contact support.');
      }
    }
    ```
  </Accordion>

  <Accordion title="Never log or store exported keys">
    Your application should never log, store, or transmit exported private keys:

    ```tsx theme={null}
    // ❌ NEVER DO THIS
    const key = await exportKey({ wallet: user.wallet });
    console.log('Private key:', key); // NEVER LOG KEYS
    localStorage.setItem('key', key); // NEVER STORE KEYS
    await fetch('/api/save-key', { body: key }); // NEVER SEND KEYS

    // ✅ CORRECT - Just trigger the export UI
    await exportKey({ wallet: user.wallet });
    // MoonKey handles key display securely
    ```
  </Accordion>

  <Accordion title="Customize for your brand">
    Use `uiConfig` to match your application's branding:

    ```tsx theme={null}
    uiConfig: {
      title: 'Backup Your Wallet',
      logoUrl: 'https://myapp.com/logo.png',
      privateKeyDescription: 'Custom message for your users...'
    }
    ```
  </Accordion>
</AccordionGroup>

## Security Considerations

<Warning>
  **Private key export is a high-risk operation.** Ensure your users understand:

  * Anyone with the private key has **complete control** of the wallet
  * Lost private keys **cannot be recovered**
  * Stolen private keys can result in **permanent loss of funds**
  * Private keys should **never be shared** with anyone
</Warning>

### What happens during export

1. **User initiates export** through your application
2. **MoonKey opens secure modal** in an isolated environment
3. **Private key is assembled** client-side in a separate origin
4. **User copies key** directly from the secure modal
5. **No logging or storage** occurs in your application or MoonKey's servers

### Security features

* **Isolated origin**: Keys are displayed in a separate security context
* **No server access**: Neither your app nor MoonKey can access the full key
* **User-only access**: Only the user can view their exported key
* **No automatic storage**: Keys are never automatically saved anywhere
* **Ephemeral display**: Keys are only shown during the export flow

## Troubleshooting

<AccordionGroup>
  <Accordion title="Export button is disabled">
    Check these conditions:

    * SDK is ready (`ready === true`)
    * User is authenticated (`isAuthenticated === true`)
    * User has a wallet (`user?.wallet !== undefined`)

    ```tsx theme={null}
    console.log('SDK ready:', ready);
    console.log('Is authenticated:', isAuthenticated);
    console.log('Has wallet:', !!user?.wallet);
    ```
  </Accordion>

  <Accordion title="Export fails with error">
    Common causes and solutions:

    * **User cancelled**: User closed the modal - this is expected behavior
    * **No wallet found**: Ensure wallet creation is complete before export
    * **Network error**: Check internet connection and try again
    * **SDK not ready**: Wait for `ready` state before calling export
  </Accordion>

  <Accordion title="Modal doesn't appear">
    Verify:

    * Correct import path for your chain type
    * `useExportKey` is called within a component
    * Component is wrapped by `MoonKeyProvider`
    * No popup blockers are interfering
  </Accordion>

  <Accordion title="Can't import exported key into MetaMask">
    Ensure:

    * Copying the complete private key (including `0x` prefix for Ethereum)
    * Using correct import method in MetaMask (Import Account → Private Key)
    * Private key format matches wallet type (hex for Ethereum, base58 for Solana)
  </Accordion>
</AccordionGroup>

## Importing Exported Wallets

After exporting, users can import their wallet into various wallet clients:

### MetaMask (Ethereum)

1. Open MetaMask
2. Click account icon → "Import Account"
3. Select "Private Key" option
4. Paste the exported private key (with `0x` prefix)
5. Click "Import"

### Phantom (Solana)

1. Open Phantom
2. Settings → Add / Connect Wallet
3. Select "Import Private Key"
4. Paste the exported private key
5. Click "Import"

### Other Wallet Clients

Most wallet clients support private key import through similar flows. Consult the specific wallet's documentation for detailed instructions.

## Related Documentation

<CardGroup cols={2}>
  <Card title="Export Key UI Component" icon="key" href="/authentication/user-authentication/ui-components/export-key">
    Detailed UI component documentation and customization
  </Card>

  <Card title="Get User Wallets" icon="wallet" href="/wallet-as-a-service/embedded-wallets/get-a-wallet/get-user-connected-wallets">
    Learn how to access user wallets
  </Card>

  <Card title="Create a Wallet" icon="plus" href="/wallet-as-a-service/embedded-wallets/create-a-wallet/overview">
    Create embedded wallets for users
  </Card>

  <Card title="Wallets Overview" icon="book" href="/wallet-as-a-service/wallets-overview">
    Complete guide to MoonKey's wallet infrastructure
  </Card>
</CardGroup>

## Next Steps

After implementing wallet export:

1. **Test the flow** with test wallets on testnet
2. **Educate your users** about private key security
3. **Provide support documentation** for common issues
4. **Consider adding** recovery mechanisms for users who lose keys
5. **Monitor usage** to understand how users interact with export

<Tip>
  For more details on customizing the export UI, see the [Export Key UI Component](/authentication/user-authentication/ui-components/export-key) documentation.
</Tip>
