Skip to content

feat: add MetaMask and Dynamic SDK integration guide #1972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ of the [MetaMask developer page](https://metamask.io/developer/).

## April 2025

- Documented [MetaMask SDK + Dynamic SDK integration](/sdk/quickstart/javascript-dynamic).
([#1972](https://github.com/MetaMask/metamask-docs/pull/1972))
- Documented [Snaps bundle analyzer option](/snaps/reference/cli/subcommands/#analyze).
([#1955](https://github.com/MetaMask/metamask-docs/pull/1955))

Expand Down
21 changes: 10 additions & 11 deletions sdk-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const sidebar = {
{
type: 'category',
label: 'Introduction',
collapsible: false,
collapsible: false,
collapsed: false,
items: [
'introduction/welcome',
Expand All @@ -23,18 +23,19 @@ const sidebar = {
{
type: 'category',
label: 'Quickstart',
collapsible: false,
collapsible: false,
collapsed: false,
items: [
'quickstart/javascript-wagmi',
'quickstart/javascript',
'quickstart/javascript-dynamic',
'quickstart/react-native',
],
},
{
type: 'category',
label: 'Guides',
collapsible: false,
collapsible: false,
collapsed: false,
items: [
'guides/authenticate-users',
Expand All @@ -44,7 +45,7 @@ const sidebar = {
{
type: 'category',
label: 'Advanced',
collapsible: true,
collapsible: true,
collapsed: true,
items: [
'guides/advanced/connect-and-sign',
Expand All @@ -57,13 +58,11 @@ const sidebar = {
{
type: 'category',
label: 'Reference',
collapsible: false,
collapsible: false,
collapsed: false,
items: [
'reference/sdk-options'
],
}
items: ['reference/sdk-options'],
},
],
};
}

module.exports = sidebar;
module.exports = sidebar
1 change: 1 addition & 0 deletions sdk/introduction/welcome.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ You can get started quickly with the following dapp platforms:

- [JavaScript + Wagmi (recommended)](quickstart/javascript-wagmi.md)
- [JavaScript](quickstart/javascript.md)
- [Dynamic SDK integration](quickstart/javascript-dynamic.md)
- [React Native](quickstart/react-native.md)
206 changes: 206 additions & 0 deletions sdk/quickstart/javascript-dynamic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
---
sidebar_label: Dynamic SDK integration
description: MetaMask + Dynamic SDK Integration
toc_max_heading_level: 2
---

# MetaMask SDK + Dynamic SDK integration

Get started with MetaMask SDK and [Dynamic SDK](https://docs.dynamic.xyz/introduction/welcome).
You can [use the quickstart template](#set-up-using-a-template), which automatically sets up both SDKs with a [Next.js](https://nextjs.org/docs) and [Wagmi](https://wagmi.sh/) dapp.
You can also [manually set up the SDK](#set-up-manually) in an existing dapp.

Features include:

- **Dual SDK integration** - Seamlessly combine MetaMask and Dynamic SDKs.
- **Wallet connection** - Connect to MetaMask wallet with enhanced features.
- **Mobile experience** - Optimized for both desktop and mobile users.
- **TypeScript support** - Full type safety and modern development experience.
- **Next.js integration** - Built with Next.js 14 and App Router.

## Project structure

The project you will set up has the following structure:

```
├── app/
│ ├── providers.tsx # Main providers configuration
│ └── layout.tsx # Root layout with providers
├── components/
│ ├── Navbar.tsx # Navigation with wallet connection
│ └── Hero.tsx # Hero section with wallet status
├── wagmi.config.ts # Wagmi configuration
├── next.config.ts # Next.js configuration
└── package.json # Project dependencies
```

## Set up using a template

1. Download the [MetaMask SDK + Dynamic SDK template](https://github.com/MetaMask/metamask-dynamic):

```bash
git clone https://github.com/MetaMask/metamask-dynamic
```

2. Navigate into the repository:

```bash
cd metamask-dynamic
```

3. Install dependencies:

```bash
pnpm install
```

4. Run the project:

```bash
pnpm dev
```

You've successfully set up MetaMask SDK and Dynamic SDK.
See how to [use the combined SDKs](#usage).

## Set up manually

### 1. Install dependencies

Install the SDK and the required dependencies to an existing project:

```bash
pnpm i @dynamic-labs/sdk-react-core @dynamic-labs/ethereum @dynamic-labs/wagmi-connector wagmi viem @tanstack/react-query
```

### 2. Configure providers

Set up your providers in `app/providers.tsx`:

```typescript title="providers.tsx"
"use client";

import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { EthereumWalletConnectors, IEthereum } from "@dynamic-labs/ethereum";
import { DynamicWagmiConnector } from "@dynamic-labs/wagmi-connector";
import { MetaMaskSDK } from "@metamask/sdk";
import { WagmiProvider } from "wagmi";
import { config } from "@/wagmi.config";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useEffect } from "react";

export function Providers({ children }: { children: React.ReactNode }) {

const queryClient = new QueryClient();

useEffect(() => {
if (typeof window === "undefined") return;

const MMSDK = new MetaMaskSDK({
dappMetadata: {
name: "MetaMask Dynamic Integration",
url: window.location.href,
},
});

const ethereum = MMSDK.getProvider();
if (ethereum) {
window.ethereum = ethereum as unknown as IEthereum;
}
}, []);

return (
<DynamicContextProvider
settings={{
mobileExperience: "redirect",
environmentId: process.env.NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID!,
walletConnectors: [EthereumWalletConnectors],
appName: "MetaMask Dynamic Integration",
}}
>
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<DynamicWagmiConnector>{children}</DynamicWagmiConnector>
</QueryClientProvider>
</WagmiProvider>
</DynamicContextProvider>
);
}
```

### 3. Set up environment variables

Create a `.env.local` file:

```text title=".env.local"
NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID=your_dynamic_environment_id
```

## Usage

### Connect wallet

Use the Dynamic Widget in your components:

```typescript
"use client";

import { DynamicWidget } from "@dynamic-labs/sdk-react-core";

export const Navbar = () => {
return (
<nav>
<DynamicWidget />
</nav>
);
};
```

### Check wallet status

Use the `useAccount` hook from Wagmi:

```typescript
"use client";

import { useAccount } from "wagmi";

export const Hero = () => {
const { address, isConnected } = useAccount();

return (
<div>
{isConnected ? (
<p>Connected: {address}</p>
) : (
<p>Not connected</p>
)}
</div>
);
};
```

## Production readiness

Before deploying your project to production:

1. Update your `next.config.ts` with production domains.
2. Set up proper environment variables.
3. Configure your Dynamic SDK environment ID.
4. Ensure MetaMask SDK is properly initialized.

## Troubleshoot

Common issues and solutions include:

- **SDK initialization error:**
- Ensure MetaMask is installed.
- Check environment variables.
- Verify network connectivity.
- **TypeScript errors:**
- Update type definitions.
- Check SDK versions compatibility.
- **Mobile experience issues:**
- Test on actual mobile devices.
- Verify redirect URLs.
- Check MetaMask Mobile installation.
Loading