Skip to main content

Wallet Integration

This guide explains how to integrate Solana wallets into your Next.js application using wallet adapters.

Overview

The template uses the official Solana wallet adapter libraries:
  • @solana/wallet-adapter-react - React hooks and context
  • @solana/wallet-adapter-react-ui - Pre-built UI components
  • @solana/wallet-adapter-wallets - Wallet implementations

Wallet Provider Setup

Create wallet/provider.tsx:
"use client";

import {
  WalletProvider,
  ConnectionProvider,
} from "@solana/wallet-adapter-react";
import {
  PhantomWalletAdapter,
  SolflareWalletAdapter,
  LedgerWalletAdapter,
} from "@solana/wallet-adapter-wallets";
import { useMemo } from "react";
import { clusterApiUrl, Commitment } from "@solana/web3.js";
import dynamic from "next/dynamic";

// Import wallet adapter styles
import "@solana/wallet-adapter-react-ui/styles.css";

// Dynamic import to avoid SSR issues
const WalletModalProvider = dynamic(
  () =>
    import("@solana/wallet-adapter-react-ui").then(
      ({ WalletModalProvider }) => WalletModalProvider
    ),
  { ssr: false }
);

export const Wallet = ({ children }: { children: React.ReactNode }) => {
  // Use environment variable or default to devnet
  const endpoint =
    process.env.NEXT_PUBLIC_SOLANA_RPC_URL || clusterApiUrl("devnet");

  // Connection configuration
  const config: {
    commitment: Commitment;
    wsEndpoint: string;
    confirmTransactionInitialTimeout: number;
  } = {
    commitment: "confirmed",
    wsEndpoint: endpoint.replace("https", "wss"),
    confirmTransactionInitialTimeout: 60000,
  };

  // Initialize wallet adapters
  const wallets = useMemo(
    () => [
      new PhantomWalletAdapter(),
      new SolflareWalletAdapter(),
      new LedgerWalletAdapter(),
    ],
    []
  );

  return (
    <ConnectionProvider endpoint={endpoint} config={config}>
      <WalletProvider wallets={wallets} autoConnect={true}>
        <WalletModalProvider>
          {children}
        </WalletModalProvider>
      </WalletProvider>
    </ConnectionProvider>
  );
};

export default Wallet;

Key Concepts

ConnectionProvider

Provides the Solana connection to all child components:
<ConnectionProvider endpoint={endpoint} config={config}>
  {/* Your app */}
</ConnectionProvider>

WalletProvider

Manages wallet state and provides hooks:
<WalletProvider wallets={wallets} autoConnect={true}>
  {/* Your app */}
</WalletProvider>
Options:
  • wallets - Array of wallet adapters to support
  • autoConnect - Automatically reconnect on page load

WalletModalProvider

Provides the wallet selection modal:
<WalletModalProvider>
  {/* Your app */}
</WalletModalProvider>

Using Wallet Hooks

useWallet

Access wallet state and methods:
import { useWallet } from "@solana/wallet-adapter-react";

function MyComponent() {
  const { 
    publicKey,      // Connected wallet's public key
    connected,      // Boolean: is wallet connected?
    disconnect,     // Function: disconnect wallet
    signMessage,    // Function: sign arbitrary messages
    sendTransaction // Function: send transactions
  } = useWallet();
  
  if (!connected) {
    return <p>Please connect your wallet</p>;
  }
  
  return <p>Connected: {publicKey?.toBase58()}</p>;
}

useConnection

Access the Solana connection:
import { useConnection } from "@solana/wallet-adapter-react";

function MyComponent() {
  const { connection } = useConnection();
  
  // Use connection for RPC calls
  const balance = await connection.getBalance(publicKey);
}

useAnchorWallet

Get a wallet compatible with Anchor:
import { useAnchorWallet } from "@solana/wallet-adapter-react";

function MyComponent() {
  const wallet = useAnchorWallet();
  
  if (!wallet) return null;
  
  // Use with Anchor provider
  const provider = new AnchorProvider(connection, wallet, {
    commitment: "confirmed",
  });
}

useWalletModal

Control the wallet selection modal:
import { useWalletModal } from "@solana/wallet-adapter-react-ui";

function ConnectButton() {
  const { setVisible } = useWalletModal();
  
  return (
    <button onClick={() => setVisible(true)}>
      Connect Wallet
    </button>
  );
}

Header Component with Wallet

Here’s the complete header component with wallet connection:
import { useWalletModal } from "@solana/wallet-adapter-react-ui";
import { useWallet } from "@solana/wallet-adapter-react";

const Header = () => {
  const { publicKey, disconnect } = useWallet();
  const { setVisible } = useWalletModal();

  // Format address for display
  const formatAddress = (address: string) => {
    return `${address.slice(0, 4)}...${address.slice(-4)}`;
  };

  return (
    <div className="flex items-center justify-between">
      <img src="/inco.svg" alt="Inco" width={139} height={40} />
      
      <div className="flex items-center gap-4">
        {publicKey ? (
          <>
            <span className="text-sm font-medium text-gray-700">
              {formatAddress(publicKey.toBase58())}
            </span>
            <button
              onClick={disconnect}
              className="rounded-full bg-gray-200 px-4 py-2 hover:bg-gray-300"
            >
              Disconnect
            </button>
          </>
        ) : (
          <button
            onClick={() => setVisible(true)}
            className="rounded-full bg-blue-500 text-white px-6 py-3 hover:bg-blue-600"
          >
            Connect Wallet
          </button>
        )}
      </div>
    </div>
  );
};

export default Header;

Supported Wallets

The template supports these wallets out of the box:
WalletAdapter
PhantomPhantomWalletAdapter
SolflareSolflareWalletAdapter
LedgerLedgerWalletAdapter
To add more wallets:
import {
  BackpackWalletAdapter,
  GlowWalletAdapter,
} from "@solana/wallet-adapter-wallets";

const wallets = useMemo(
  () => [
    new PhantomWalletAdapter(),
    new SolflareWalletAdapter(),
    new BackpackWalletAdapter(),
    new GlowWalletAdapter(),
  ],
  []
);

Handling SSR

Next.js renders on the server, but wallets only work in the browser. Use dynamic imports:
import dynamic from "next/dynamic";

const WalletModalProvider = dynamic(
  () =>
    import("@solana/wallet-adapter-react-ui").then(
      ({ WalletModalProvider }) => WalletModalProvider
    ),
  { ssr: false }
);

Next Steps

Learn how to build the Components for encryption and balance display.