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

# Wallet Provider

> Implement and register a custom WalletProvider with the Dynamic JavaScript SDK.

A `WalletProvider` connects a wallet to the SDK. At minimum it must implement `chain`, `key`, `groupKey`, `metadata`, `walletProviderType`, `getActiveNetworkId`, and `getConnectedAddresses`.

## Minimal WalletProvider

```typescript theme={"system"}
import { WalletProviderEnum } from "@dynamic-labs/sdk-api-core";
import type { WalletProvider } from "@dynamic-labs-sdk/client/core";
import {
  formatWalletProviderGroupKey,
  formatWalletProviderKey,
} from "@dynamic-labs-sdk/client/core";

const MY_WALLET_KEY = formatWalletProviderKey({
  chain: "EVM",
  displayName: "My Wallet",
  walletProviderType: WalletProviderEnum.BrowserExtension,
});

const myWalletProvider: WalletProvider = {
  chain: "EVM",
  key: MY_WALLET_KEY,
  groupKey: formatWalletProviderGroupKey("My Wallet"),
  metadata: {
    displayName: "My Wallet",
    icon: "https://example.com/icon.svg",
  },
  walletProviderType: WalletProviderEnum.BrowserExtension,

  // Replace with your wallet API calls.
  connect: async () => ({
    addresses: [{ address: "0x..." }],
  }),

  getConnectedAddresses: async () => ({
    addresses: ["0x..."],
  }),

  getActiveNetworkId: async () => ({
    networkId: "1",
  }),

  signMessage: async ({ message }) => ({
    signature: "0x...",
  }),
};
```

## Register the provider

Extensions register wallet providers through the `WalletProviderRegistry`. Set a priority that reflects how the wallet is integrated. Higher-priority registrations win when the same `key` is registered more than once.

```typescript theme={"system"}
import {
  getDefaultClient,
  getWalletProviderRegistry,
  hasExtension,
  registerExtension,
  WalletProviderPriority,
} from "@dynamic-labs-sdk/client/core";
import type { DynamicClient } from "@dynamic-labs-sdk/client";

const MY_WALLET_EXTENSION_KEY = "myWallet";

const myWalletProvider = {
  /* ... wallet provider from above ... */
};

export const addMyWalletExtension = (
  client: DynamicClient = getDefaultClient()
): void => {
  if (hasExtension({ extensionKey: MY_WALLET_EXTENSION_KEY }, client)) {
    return;
  }

  registerExtension({ extensionKey: MY_WALLET_EXTENSION_KEY }, client);

  getWalletProviderRegistry(client).register({
    priority: WalletProviderPriority.WALLET_SDK,
    walletProvider: myWalletProvider,
  });
};
```

* `WalletProviderPriority.WALLET_SDK` is the highest priority. Use it when you control the wallet's own SDK.
* `WALLET_SELF_ANNOUNCEMENT_STANDARD` is for standards such as EIP-6963 announcements.
* `WINDOW_INJECT` is for providers that rely on a global object such as `window.ethereum`.

<Warning>
  The registry stores one provider per `key`. If a provider with the same `key` is registered again, the higher-priority registration wins. Keep `key` stable by using `formatWalletProviderKey`.
</Warning>

## Connect the wallet

After the extension is registered, connect to the wallet using the same standard APIs as any other Dynamic wallet provider. Use the `walletProviderKey` directly, or discover it with `getAvailableWalletProvidersData` (the custom provider appears in that list alongside the built-in ones).

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

const walletAccount = await connectAndVerifyWithWalletProvider({
  walletProviderKey: MY_WALLET_KEY,
});

console.log("Connected and verified:", walletAccount.address);
```

Use `connectWithWalletProvider` instead of `connectAndVerifyWithWalletProvider` if you only want to connect without verifying ownership.
