Connect to Solana using Dynamic SDK
This quickstart gets you up and running with MetaMask Connect Solana inside Dynamic SDK. Dynamic handles wallet discovery and connection UI, and MetaMask Connect Solana adds reliable cross-platform support for MetaMask. Download the template to start quickly, or set up manually in an existing project.
Prerequisites
- Node.js version 19 or later installed.
- A package manager installed, such as npm, Yarn, pnpm, or bun.
- MetaMask installed in your browser or on mobile.
- A Dynamic Environment ID.
Set up using a template
-
Download the MetaMask Connect + Dynamic SDK template:
npx degit MetaMask/metamask-sdk-examples/partners/dynamic metamask-dynamic -
Navigate into the repository:
cd metamask-dynamicDegit vs. Git clone
degitis a tool that enables cloning only the directory structure from a GitHub repository, without retrieving the entire repository.Alternatively, use
git cloneto download the entire repository. Clone the MetaMask Connect examples repository and navigate into thepartners/dynamicdirectory:git clone https://github.com/MetaMask/metamask-sdk-examples
cd metamask-sdk-examples/partners/dynamic -
Install dependencies:
pnpm install -
Create a
.env.localfile:touch .env.local -
In
.env.local, add aNEXT_PUBLIC_DYNAMIC_ENVIRONMENT_IDenvironment variable, replacing<YOUR-ENVIRONMENT-ID>with your Dynamic Environment ID:.env.localNEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID=<YOUR-ENVIRONMENT-ID> -
Run the project:
pnpm dev
You've successfully set up MetaMask Connect Solana and Dynamic SDK. See how to use the combined SDKs.
Set up manually
1. Install dependencies
Install Dynamic SDK with the Solana extension and Solana web3.js:
- npm
- Yarn
- pnpm
- Bun
npm install @dynamic-labs/client @dynamic-labs/solana-extension @solana/web3.js
yarn add @dynamic-labs/client @dynamic-labs/solana-extension @solana/web3.js
pnpm add @dynamic-labs/client @dynamic-labs/solana-extension @solana/web3.js
bun add @dynamic-labs/client @dynamic-labs/solana-extension @solana/web3.js
2. Create the Dynamic client
Create a Dynamic client extended with Solana support in lib/dynamic.ts:
import { createClient } from '@dynamic-labs/client'
import { SolanaExtension } from '@dynamic-labs/solana-extension'
export const dynamicClient = createClient({
environmentId: process.env.NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID!,
}).extend(SolanaExtension())
3. Set up environment variables
Create a .env.local file.
In .env.local, add a NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID environment variable, replacing <YOUR-ENVIRONMENT-ID> with your Dynamic Environment ID:
NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID=<YOUR-ENVIRONMENT-ID>
Test your dapp by running pnpm run dev.
Usage
Connect wallet
Use the Dynamic Widget in your components:
"use client";
import { DynamicWidget } from "@dynamic-labs/sdk-react-core";
export const Navbar = () => {
return (
<nav>
<DynamicWidget />
</nav>
);
};
Check wallet status
Use the Dynamic client to check the primary wallet:
"use client";
import { dynamicClient } from '@/lib/dynamic'
export const WalletStatus = () => {
const wallet = dynamicClient.wallets.primary
return (
<div>
{wallet ? (
<p>Connected: {wallet.address}</p>
) : (
<p>Not connected</p>
)}
</div>
);
};
Send a SOL transfer
Use the Solana extension's getConnection and getSigner methods to build and send a transaction:
"use client";
import { dynamicClient } from '@/lib/dynamic'
import {
LAMPORTS_PER_SOL,
PublicKey,
SystemProgram,
TransactionMessage,
VersionedTransaction,
} from '@solana/web3.js'
export const SendSol = () => {
const send = async () => {
const wallet = dynamicClient.wallets.primary
if (!wallet) return
const connection = dynamicClient.solana.getConnection({
commitment: 'singleGossip',
})
const signer = dynamicClient.solana.getSigner({ wallet })
const { blockhash } = await connection.getLatestBlockhash()
const fromKey = new PublicKey(wallet.address)
const toKey = new PublicKey('DESTINATION_PUBLIC_KEY')
const instructions = [
SystemProgram.transfer({
fromPubkey: fromKey,
toPubkey: toKey,
lamports: 0.01 * LAMPORTS_PER_SOL,
}),
]
const messageV0 = new TransactionMessage({
payerKey: fromKey,
recentBlockhash: blockhash,
instructions,
}).compileToV0Message()
const transaction = new VersionedTransaction(messageV0)
const { signature } = await signer.signAndSendTransaction(transaction)
console.log('Transaction signature:', signature)
}
return <button onClick={send}>Send 0.01 SOL</button>
};
Production readiness
Before deploying your project to production:
- Update your
next.config.tswith production domains. - Set up proper environment variables.
- Configure your Dynamic SDK environment ID.
- Ensure MetaMask Connect Solana is properly initialized.
Troubleshooting
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 app installation.