Wallet Adapter
Set up @solana/wallet-adapter-react hooks for connection and signing.
Recipe
npm install @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-wallets"use client";
import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import "@solana/wallet-adapter-react-ui/styles.css";When to reach for this:
- Existing apps using the de-facto React wallet hooks.
- Custom UI with
useWalletstate. - Libraries and tutorials still referencing wallet-adapter.
Working Example
"use client";
import { useMemo } from "react";
import { ConnectionProvider, WalletProvider } from "@solana/wallet-adapter-react";
import { WalletModalProvider } from "@solana/wallet-adapter-react-ui";
import { PhantomWalletAdapter, SolflareWalletAdapter } from "@solana/wallet-adapter-wallets";
export function SolanaProviders({ children }: { children: React.ReactNode }) {
const endpoint = process.env.NEXT_PUBLIC_RPC_URL!;
const wallets = useMemo(
() => [new PhantomWalletAdapter(), new SolflareWalletAdapter()],
[]
);
return (
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect>
<WalletModalProvider>{children}</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
}What this demonstrates:
ConnectionProviderstill wraps HTTP endpoint (migrate reads to kit separately).autoConnectrestores prior session.- Wallet modal CSS is optional but speeds onboarding.
Deep Dive
How It Works
- Adapters translate Wallet Standard events into React context.
useWalletexposespublicKey,connected,signTransaction.- Pair with kit by converting wallet signers for message pipeline.
- create-solana-dapp may prefer @wallet-ui/react - both are valid.
Gotchas
- SSR importing wallet-adapter - window errors. Fix:
"use client"boundary only. - Empty wallets array - no options in modal. Fix: register popular adapters.
- autoConnect without UX - surprise connections. Fix: loading skeleton + disconnect.
- Stale @solana/web3.js Connection - dual stack. Fix: kit RPC for reads, adapter for sign.
- Mainnet endpoint on devnet demo - user confusion. Fix: env-driven endpoint.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| @wallet-ui/react | New create-solana-dapp templates | Heavy investment in adapter hooks |
| Wallet Standard direct | Custom modal, no UI pkg | Need quick modal |
FAQs
Devnet or mainnet?
Match RPC URL, wallet network, and program IDs to one cluster.
kit vs web3.js?
Use @solana/kit 7.0.0 for new frontend code.
Testing?
Surfpool 0.12.0 or devnet with faucet SOL.
Commitment level?
confirmed for UX; finalized for high-value reads.
Next.js App Router?
Providers in client layout; reads can be server-side.
Wallet rejected sign?
Show retry; never assume approval.
Priority fees?
Compute budget instructions on congested mainnet.
Mobile?
Use Mobile Wallet Adapter for React Native apps.
Security?
Never expose server keypairs to the browser.
IDL changes?
Regenerate typed clients in CI.
Related
- Connecting & Disconnecting - connection state
- @wallet-ui/react - modern UI kit
- Providers & App Router - Next.js wiring
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.