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

# Build a Wallet Picker

> Render every wallet a user can connect to, installed, URI-based (deeplink + QR), in-app browser, and install-only, from a single SDK call.

This guide shows our officially recommended pattern for building a wallet picker that surfaces **every** wallet a user can connect to (or install) through your dapp, in one ordered list.

You'll do the rendering and the click handling. The SDK does the merging, deduplication, and ordering.

> [!TIP]
>
> Building a React web app? The prebuilt [connect wallet widget](https://docs.dynamic.xyz/docs/javascript/building-ui/react-ui/connect-wallet-widget.md) renders the wallet list, chain choice, QR pairing, and error screens for you.

**Prerequisites:** A configured Dynamic client. Each connection path requires the client extension listed below. Add only the extensions for the paths you intend to surface:

| Connection option type | Required client extension(s) |
| - | - |
| `withWalletProvider` (installed) | Your chain extensions (`addEvmExtension`, `addSolanaExtension`, etc.) |
| `walletConnect` (URI deeplink/QR) | `addWalletConnect<Chain>Extension` for each chain you want to surface |
| `metamaskSdkUri` (mobile/QR) | `addMetaMask<Chain>Extension` for each chain you want to surface |
| `inAppBrowser` | None |
| Install-only entries | None |

See [Adding extensions](https://docs.dynamic.xyz/docs/javascript/reference/adding-extensions.md) for setup.

***

## 1. Fetch the catalogue

```typescript theme={"system"}
import { getWalletOptionsCatalogue } from '@dynamic-labs-sdk/client';

const walletOptions = await getWalletOptionsCatalogue({
  includeMobileOptions: true,
});
```

Each entry is a `WalletOption` with a `name`, `iconUrl`, an ordered `connectionOptions` array, and an optional `installationUrls` bag for wallets the user can install on this device. See the [reference](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-wallet-options-catalogue.md) for the full shape.

`includeMobileOptions: true` is what makes the catalogue include URI-based connection options (deeplinking and QR code), in-app browser entries, and install links alongside installed providers. Without it, you only get installed wallets.

***

## 2. Connect and verify when a wallet is clicked

Pass the wallet's catalogue key to `connectWalletOption`. The SDK chooses the connection path for that wallet, so you do not need to route by `connectionOptions` type. The returned wallet account is not verified, so pass it to `verifyWalletAccount`:

```typescript theme={"system"}
import {
  connectWalletOption,
  isMobile,
  redirectToInAppBrowser,
  verifyWalletAccount,
  type WalletOption,
} from '@dynamic-labs-sdk/client';

async function onWalletClick(walletOption: WalletOption) {
  if (walletOption.connectionOptions.length === 0) {
    return renderInstallationInstructions(walletOption);
  }

  const walletAccount = await connectWalletOption({
    handleWalletBrowserRedirect: ({ chain, walletKey }) =>
      redirectToInAppBrowser({
        appUrl: window.location.href,
        chain,
        walletKey,
      }),
    onConnectionUri: ({ uri }) => {
      if (isMobile()) {
        window.location.href = uri;
        return;
      }

      renderQrCode(uri);
    },
    walletKey: walletOption.key,
  });

  return verifyWalletAccount({ walletAccount });
}
```

The SDK uses an installed wallet provider when available. If the user does not have the wallet installed, it uses a URI pairing or the wallet's in-app browser. See [Connect a wallet by catalogue key](https://docs.dynamic.xyz/docs/javascript/reference/wallets/connect-wallet-option.md) for the full behavior and errors.

***

## 3. Render the pairing URI

Use the `onConnectionUri` handler shown in step 2 to open the URI on mobile or render it as a QR code on desktop. The SDK hands the handler the wallet's own deeplink with the pairing already included. It chooses a native scheme on mobile, a universal link on desktop, and the other variant as a fallback. For MetaMask SDK pairings, the URI is MetaMask's launch link. If the wallet does not publish a deeplink, the URI is the bare pairing URI.

Keep the connection promise pending until the user approves in the wallet. `connectWalletOption` resolves with the connected wallet account after approval.

***

## 4. Show install links for install-only wallets

No extension required.

When a wallet has no `connectionOptions` but has `installationUrls`, render an install affordance. The exact UI is yours: a button, a modal with platform-specific instructions, a pointer to the user's app store, or another option:

```typescript theme={"system"}
import {
  getInstallationLinkForCurrentPlatform,
  type WalletOption,
} from '@dynamic-labs-sdk/client';

function renderInstallationInstructions(walletOption: WalletOption) {
  const target = getInstallationLinkForCurrentPlatform({
    installationUrls: walletOption.installationUrls,
  });

  if (target) window.open(target, '_blank');
}
```

Use the helper for a single install button. It returns the install URL for the user's current platform, or `undefined` when the wallet does not publish a matching URL. You can also render several links from `installationUrls` when you want users to choose a platform.

***

## 5. Group installed vs other (optional)

The catalogue's default `'relevance'` ordering already buckets installed wallets first. If you want to render them under separate headings, split the list with `isWalletExtensionInstalled`:

```typescript theme={"system"}
import { isWalletExtensionInstalled } from '@dynamic-labs-sdk/client';

const installed = walletOptions.filter((walletOption) =>
  isWalletExtensionInstalled({ walletOption }),
);
const others = walletOptions.filter(
  (walletOption) => !isWalletExtensionInstalled({ walletOption }),
);
```

***

## See also

* [Connect a wallet by catalogue key](https://docs.dynamic.xyz/docs/javascript/reference/wallets/connect-wallet-option.md)
* [`getWalletOptionsCatalogue` reference](https://docs.dynamic.xyz/docs/javascript/reference/wallets/get-wallet-options-catalogue)
* [Connect and verify a wallet](https://docs.dynamic.xyz/docs/javascript/reference/wallets/connect-and-verify-wallet.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.