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

# Get User Wallets

MoonKey makes it easy to access a user's embedded wallet so you can help them take onchain actions. Every authenticated user with an embedded wallet has access to their wallet through the SDK.

<Info>
  MoonKey currently supports embedded wallets only. Each user can have one embedded wallet per chain type (Ethereum or Solana).
</Info>

<Tip>
  **Import paths:**

  * `useMoonKey` comes from `@moon-key/react-auth` (the base package)
  * `useWallets` comes from `@moon-key/react-auth/ethereum` for Ethereum or `@moon-key/react-auth/solana` for Solana
</Tip>

## React SDK

### Usage

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

function MyComponent() {
  const { user, ready } = useMoonKey();
  
  if (!ready) {
    return <div>Loading...</div>;
  }
  
  if (!user) {
    return <div>Please sign in</div>;
  }
  
  if (!user.wallet) {
    return <div>No wallet found</div>;
  }
  
  // Access the wallet
  const wallet = user.wallet;
  console.log('Wallet address:', wallet.address);
  
  return (
    <div>
      <p>Your wallet: {wallet.address}</p>
    </div>
  );
}
```

### Wallet properties

The `user.wallet` object contains the following properties:

<ResponseField name="address" type="string">
  The wallet's Ethereum address (e.g., `0x1234...5678`)
</ResponseField>

<ResponseField name="chainType" type="string">
  The chain type, always `'ethereum'` for Ethereum wallets
</ResponseField>

<ResponseField name="walletClient" type="WalletClient">
  The wallet client instance from `viem` for performing operations
</ResponseField>

### Alternative: Using useWallets

You can also access Ethereum wallets using the `useWallets` hook from `@moon-key/react-auth/ethereum`, which returns an array of all wallets:

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

function MyComponent() {
  const { wallets, ready } = useWallets();
  
  if (!ready) {
    return <div>Loading...</div>;
  }
  
  if (wallets.length === 0) {
    return <div>No wallets found</div>;
  }
  
  // Get the first (and typically only) wallet
  const wallet = wallets[0];
  console.log('Wallet address:', wallet.address);
  
  return (
    <div>
      {wallets.map((wallet) => (
        <div key={wallet.address}>
          <p>Wallet: {wallet.address}</p>
        </div>
      ))}
    </div>
  );
}
```

## Waiting for wallets to be ready

When your page loads in the user's browser, the MoonKey SDK determines what wallet the user has by loading the secure wallet infrastructure. This process happens asynchronously.

To determine if MoonKey has fully loaded the user's wallet information, use the `ready` boolean returned by the `useMoonKey` or `useWallets` hooks.

The `ready` flag will be:

* `false` while MoonKey is loading wallet information
* `true` once MoonKey has determined the current wallet state

### Example with ready state

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

function WalletDisplay() {
  const { user, ready, isAuthenticated } = useMoonKey();
  
  // SDK is still loading
  if (!ready) {
    return (
      <div className="loading">
        <Spinner />
        <p>Loading wallet...</p>
      </div>
    );
  }
  
  // User is not authenticated
  if (!isAuthenticated || !user) {
    return <div>Please sign in to view your wallet</div>;
  }
  
  // User doesn't have a wallet yet
  if (!user.wallet) {
    return (
      <div>
        <p>You don't have a wallet yet.</p>
        <CreateWalletButton />
      </div>
    );
  }
  
  // Wallet is ready to use
  return (
    <div>
      <h2>Your Wallet</h2>
      <p>Address: {user.wallet.address}</p>
      <WalletActions wallet={user.wallet} />
    </div>
  );
}
```

## useMoonKey vs useWallets

Both hooks provide access to wallet information, but they serve slightly different purposes and have different import paths:

### useMoonKey

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

const { user, ready, isAuthenticated } = useMoonKey();
const wallet = user?.wallet;
```

**Import from:** `@moon-key/react-auth` (base package)

**Use when:**

* You need access to the full user object
* You want authentication state (`isAuthenticated`)
* You need user profile information
* You're working with a single wallet per user

**Returns:**

* Complete user object with all linked accounts
* Authentication state
* Wallet as part of the user object

### useWallets

<Tabs>
  <Tab title="Ethereum">
    ```tsx theme={null}
    import { useWallets } from '@moon-key/react-auth/ethereum';

    const { wallets, ready } = useWallets();
    const wallet = wallets[0];
    ```

    **Import from:** `@moon-key/react-auth/ethereum` (for Ethereum wallets)
  </Tab>

  <Tab title="Solana">
    ```tsx theme={null}
    import { useWallets } from '@moon-key/react-auth/solana';

    const { wallets, ready } = useWallets();
    const wallet = wallets[0];
    ```

    **Import from:** `@moon-key/react-auth/solana` (for Solana wallets)
  </Tab>
</Tabs>

**Use when:**

* You only need wallet information
* You want to work with an array of wallets
* You prefer a wallet-centric API
* Future-proofing for multiple wallets per user

**Returns:**

* Array of wallet objects (chain-specific)
* Ready state for wallet loading

<Tip>
  For most use cases, `useMoonKey` is recommended as it provides both user and wallet information in a single hook.
</Tip>

## Common patterns

### Checking for wallet existence

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

function WalletRequired() {
  const { user, ready } = useMoonKey();
  
  const hasWallet = user?.wallet !== undefined;
  
  if (!ready) {
    return <LoadingSpinner />;
  }
  
  if (!hasWallet) {
    return (
      <div>
        <h2>Wallet Required</h2>
        <p>You need a wallet to access this feature</p>
        <CreateWalletButton />
      </div>
    );
  }
  
  return <WalletFeatures wallet={user.wallet} />;
}
```

### Getting wallet for transactions

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

function SendEthButton() {
  const { user } = useMoonKey();
  const { sendTransaction } = useSendTransaction();
  
  const handleSend = async () => {
    if (!user?.wallet) {
      alert('No wallet found');
      return;
    }
    
    const result = await sendTransaction({
      transaction: {
        to: '0xRecipient...',
        value: '0x38d7ea4c68000'
      },
      wallet: user.wallet
    });
    
    console.log('Transaction hash:', result.transactionHash);
  };
  
  return (
    <button onClick={handleSend} disabled={!user?.wallet}>
      Send 0.001 ETH
    </button>
  );
}
```

### Displaying wallet information

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

function WalletInfo() {
  const { user, ready } = useMoonKey();
  
  if (!ready) return <div>Loading...</div>;
  if (!user?.wallet) return <div>No wallet</div>;
  
  const { address, chainType } = user.wallet;
  
  // Format address for display
  const shortAddress = `${address.slice(0, 6)}...${address.slice(-4)}`;
  
  return (
    <div className="wallet-info">
      <div className="wallet-badge">
        <span className="chain-type">{chainType}</span>
        <span className="address" title={address}>
          {shortAddress}
        </span>
      </div>
      <button onClick={() => navigator.clipboard.writeText(address)}>
        Copy Address
      </button>
    </div>
  );
}
```

### Finding a specific wallet (Ethereum)

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

function FindWalletByAddress({ targetAddress }: { targetAddress: string }) {
  const { wallets, ready } = useWallets();
  
  if (!ready) return <div>Loading...</div>;
  
  const wallet = wallets.find(w => w.address === targetAddress);
  
  if (!wallet) {
    return <div>Wallet not found: {targetAddress}</div>;
  }
  
  return <div>Found wallet: {wallet.address}</div>;
}
```

## Complete example

Here's a complete example showing wallet access and usage:

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

export default function WalletDashboard() {
  const { user, ready, isAuthenticated } = useMoonKey();
  const { sendTransaction } = useSendTransaction();
  const [isSending, setIsSending] = useState(false);
  
  // Loading state
  if (!ready) {
    return (
      <div className="loading-container">
        <div className="spinner" />
        <p>Loading wallet information...</p>
      </div>
    );
  }
  
  // Not authenticated
  if (!isAuthenticated || !user) {
    return (
      <div className="auth-prompt">
        <h2>Sign In Required</h2>
        <p>Please sign in to access your wallet</p>
        <LoginButton />
      </div>
    );
  }
  
  // No wallet
  if (!user.wallet) {
    return (
      <div className="no-wallet">
        <h2>Create Your Wallet</h2>
        <p>You don't have a wallet yet. Create one to get started.</p>
        <CreateWalletButton />
      </div>
    );
  }
  
  // Has wallet
  const { wallet } = user;
  const shortAddress = `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}`;
  
  const handleSendTest = async () => {
    setIsSending(true);
    try {
      const result = await sendTransaction({
        transaction: {
          to: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
          value: '0x38d7ea4c68000' // 0.001 ETH
        },
        wallet
      });
      
      alert(`Transaction sent! Hash: ${result.transactionHash}`);
    } catch (error) {
      console.error('Transaction failed:', error);
      alert('Transaction failed');
    } finally {
      setIsSending(false);
    }
  };
  
  return (
    <div className="wallet-dashboard">
      <div className="wallet-header">
        <h2>Your Wallet</h2>
        <div className="wallet-address">
          <span className="address" title={wallet.address}>
            {shortAddress}
          </span>
          <button
            className="copy-btn"
            onClick={() => {
              navigator.clipboard.writeText(wallet.address);
              alert('Address copied!');
            }}
          >
            Copy
          </button>
        </div>
      </div>
      
      <div className="wallet-info">
        <div className="info-row">
          <span className="label">Chain Type:</span>
          <span className="value">{wallet.chainType}</span>
        </div>
        <div className="info-row">
          <span className="label">Full Address:</span>
          <span className="value mono">{wallet.address}</span>
        </div>
      </div>
      
      <div className="wallet-actions">
        <button
          className="primary-btn"
          onClick={handleSendTest}
          disabled={isSending}
        >
          {isSending ? 'Sending...' : 'Send Test Transaction'}
        </button>
        <button className="secondary-btn">
          View on Explorer
        </button>
      </div>
    </div>
  );
}
```

## Best practices

<AccordionGroup>
  <Accordion title="Always check the ready state">
    Wait for the SDK to be ready before accessing wallet information:

    ```tsx theme={null}
    const { user, ready } = useMoonKey();

    if (!ready) {
      return <LoadingSpinner />;
    }

    // Now safe to access user.wallet
    ```
  </Accordion>

  <Accordion title="Handle missing wallets gracefully">
    Not all users will have wallets. Provide clear next steps:

    ```tsx theme={null}
    if (!user?.wallet) {
      return (
        <div>
          <p>You don't have a wallet yet</p>
          <CreateWalletButton />
        </div>
      );
    }
    ```
  </Accordion>

  <Accordion title="Pass wallet to transaction hooks">
    Always pass the wallet object to transaction methods:

    ```tsx theme={null}
    await sendTransaction({
      transaction: txData,
      wallet: user.wallet // Required
    });
    ```
  </Accordion>

  <Accordion title="Use TypeScript for type safety">
    TypeScript helps catch wallet-related errors:

    ```tsx theme={null}
    const wallet: Wallet | undefined = user?.wallet;

    if (wallet) {
      // TypeScript knows wallet exists here
      console.log(wallet.address);
    }
    ```
  </Accordion>

  <Accordion title="Format addresses for display">
    Show shortened addresses in UI for better UX:

    ```tsx theme={null}
    const formatAddress = (address: string) => {
      return `${address.slice(0, 6)}...${address.slice(-4)}`;
    };

    <p>{formatAddress(wallet.address)}</p>
    ```
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Wallet is undefined">
    If `user.wallet` is undefined:

    * Check if the user is authenticated
    * Verify the SDK is ready (`ready === true`)
    * Confirm the user has created a wallet
    * Check automatic wallet creation configuration
  </Accordion>

  <Accordion title="Ready state never becomes true">
    If `ready` stays false:

    * Verify MoonKeyProvider is properly configured
    * Check browser console for errors
    * Ensure appId is correct
    * Try refreshing the page
  </Accordion>

  <Accordion title="Cannot access wallet properties">
    If wallet properties are inaccessible:

    * Verify you're using the correct import path
    * Check that you're using the right SDK for your chain (ethereum vs solana)
    * Ensure the user object has loaded
  </Accordion>
</AccordionGroup>
