Skip to main content

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

Set up using a template

  1. Download the MetaMask Connect + Dynamic SDK template:

    npx degit MetaMask/metamask-sdk-examples/partners/dynamic metamask-dynamic
  2. Navigate into the repository:

    cd metamask-dynamic
    Degit vs. Git clone

    degit is a tool that enables cloning only the directory structure from a GitHub repository, without retrieving the entire repository.

    Alternatively, use git clone to download the entire repository. Clone the MetaMask Connect examples repository and navigate into the partners/dynamic directory:

    git clone https://github.com/MetaMask/metamask-sdk-examples
    cd metamask-sdk-examples/partners/dynamic
  3. Install dependencies:

    pnpm install
  4. Create a .env.local file:

    touch .env.local
  5. In .env.local, add a NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID environment variable, replacing <YOUR-ENVIRONMENT-ID> with your Dynamic Environment ID:

    .env.local
    NEXT_PUBLIC_DYNAMIC_ENVIRONMENT_ID=<YOUR-ENVIRONMENT-ID>
  6. 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 install @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:

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:

.env.local
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:

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

Live example