Skip to main content

Connect to Solana using Embedded Wallets SDK

This quickstart gets you up and running with MetaMask Connect Solana inside Embedded Wallets SDK (previously Web3Auth), enabling users to sign in with an email or social media account. Download the template to start quickly, or set up the SDKs manually in an existing project.

Prerequisites

Set up using a template

  1. Download the MetaMask Connect + Web3Auth SDK template:

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

    cd metamask-web3auth
    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/web3auth directory:

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

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

    touch .env.local
  5. In .env.local, add a NEXT_PUBLIC_WEB3AUTH_CLIENT_ID environment variable, replacing <YOUR-CLIENT-ID> with your Web3Auth Client ID:

    .env.local
    NEXT_PUBLIC_WEB3AUTH_CLIENT_ID=<YOUR-CLIENT-ID>
  6. Run the project:

    pnpm dev

You've successfully set up MetaMask Connect Solana and MetaMask Embedded Wallets. See how to use Embedded Wallets.

Set up manually

1. Install dependencies

Install Embedded Wallets SDK and Solana web3.js:

npm install @web3auth/modal@10 @solana/web3.js

2. Configure providers

Set up your providers in app/providers.tsx with Solana chain configuration:

providers.tsx
"use client";

import { type ReactNode } from "react";
import { Web3AuthProvider } from "@web3auth/modal/react";

type Props = {
children: ReactNode;
};

export function Providers({ children }: Props) {
return (
<Web3AuthProvider
config={{
web3AuthOptions: {
clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID!,
web3AuthNetwork: "sapphire_devnet",
chainConfig: {
chainNamespace: "SOLANA",
chainId: "0x3",
rpcTarget: "https://api.devnet.solana.com",
displayName: "Solana Devnet",
blockExplorerUrl: "https://explorer.solana.com/?cluster=devnet",
ticker: "SOL",
tickerName: "Solana",
logo: "https://images.toruswallet.io/solana.svg",
},
},
}}
>
<div className="container">{children}</div>
</Web3AuthProvider>
);
}

3. Set up environment variables

Create a .env.local file. In .env.local, add a NEXT_PUBLIC_WEB3AUTH_CLIENT_ID environment variable, replacing <YOUR-CLIENT-ID> with your Web3Auth Client ID:

.env.local
NEXT_PUBLIC_WEB3AUTH_CLIENT_ID=<YOUR-CLIENT-ID>

Test your dapp by running pnpm run dev.

Usage

Connect or sign in

Use the useWeb3AuthConnect hook to enable users to connect or sign in to their wallet:

"use client";

import { useWeb3AuthConnect } from "@web3auth/modal/react";

export const Navbar = () => {
const { connect } = useWeb3AuthConnect();

return (
<nav>
<button onClick={() => connect()}>Connect or Sign in</button>
</nav>
);
};

Check wallet status

Use the useSolanaWallet hook to access the Solana wallet state:

"use client";

import { useSolanaWallet } from "@web3auth/modal/react/solana";

export const WalletStatus = () => {
const { address, connected } = useSolanaWallet();

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

Sign a message

Use the useSignMessage hook to request a signed message:

"use client";

import { useSignMessage } from "@web3auth/modal/react/solana";

export const SignMessage = () => {
const { signMessage, isPending } = useSignMessage();

const handleSign = async () => {
try {
const message = new TextEncoder().encode("Hello from Solana!");
const signature = await signMessage(message);
console.log("Signature:", signature);
} catch (err) {
console.error("Error signing message:", err);
}
};

return (
<button onClick={handleSign} disabled={isPending}>
{isPending ? "Signing..." : "Sign message"}
</button>
);
};

Send a transaction

Use the useSignAndSendTransaction hook to sign and send a Solana transaction:

"use client";

import { useSignAndSendTransaction } from "@web3auth/modal/react/solana";
import { Transaction, SystemProgram, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";

export const SendTransaction = () => {
const { signAndSendTransaction, isPending } = useSignAndSendTransaction();

const handleSend = async () => {
try {
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: new PublicKey("YOUR_PUBLIC_KEY"),
toPubkey: new PublicKey("DESTINATION_PUBLIC_KEY"),
lamports: 0.01 * LAMPORTS_PER_SOL,
})
);

const signature = await signAndSendTransaction(transaction);
console.log("Transaction signature:", signature);
} catch (err) {
console.error("Error sending transaction:", err);
}
};

return (
<button onClick={handleSend} disabled={isPending}>
{isPending ? "Sending..." : "Send 0.01 SOL"}
</button>
);
};

Live example