Nitso Provider
Root provider for Nitso. Required before using any Nitso component.
Installation
npx shadcn@latest add https://nitso.fun/r/nitso-provider.jsonpnpm dlx shadcn@latest add https://nitso.fun/r/nitso-provider.jsonyarn dlx shadcn@latest add https://nitso.fun/r/nitso-provider.jsonbunx --bun shadcn@latest add https://nitso.fun/r/nitso-provider.jsonInstall dependencies
npm install @solana/connector @solana/web3.jspnpm add @solana/connector @solana/web3.jsyarn add @solana/connector @solana/web3.jsbun add @solana/connector @solana/web3.jsCopy the source code
import { getDefaultConfig } from "@solana/connector/headless";import { AppProvider } from "@solana/connector/react";import { type ReactNode, useMemo } from "react";interface SolanaCluster { id: "solana:mainnet" | "solana:devnet" | "solana:testnet" | "solana:localnet"; label: string; url: string;}interface WalletDisplayConfig { allowList?: string[]; denyList?: string[]; featured?: string[];}interface SimplifiedWalletConnectConfig { projectId?: string; defaultChain?: "solana:mainnet" | "solana:devnet" | "solana:testnet"; relayUrl?: string;}interface NitsoProviderProps { children: ReactNode; /** Application name shown in wallet connection prompts */ appName: string; /** * Application URL. * Only needed if you enable walletConnect. */ appUrl?: string; /** * Custom RPC endpoints per cluster. * Strongly recommended — public endpoints are rate limited. * * Define this OUTSIDE your component to keep the reference stable * and avoid unnecessary re-renders. * * @example * const clusters = [ * { id: 'solana:mainnet' as const, label: 'Mainnet Beta', url: 'https://mainnet.helius-rpc.com/?api-key=xxx' }, * { id: 'solana:devnet' as const, label: 'Devnet', url: 'https://api.devnet.solana.com' }, * { id: 'solana:testnet' as const, label: 'Testnet', url: 'https://api.testnet.solana.com' }, * ]; * * <NitsoProvider clusters={clusters} ... /> */ clusters?: SolanaCluster[]; /** * Control which wallets are shown. * Define OUTSIDE your component to keep the reference stable. * * @example * // Show only specific wallets * wallets={{ allowList: ['Phantom', 'Solflare'], featured: ['Phantom'] }} * * // Hide specific wallets * wallets={{ denyList: ['WalletConnect'] }} */ wallets?: WalletDisplayConfig; /** * Silently reconnect last wallet on page load. * @default true */ autoConnect?: boolean; /** * Human-readable names for program IDs. * Used to enrich transaction history labels. * * @example * programLabels={{ * 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4': 'Jupiter', * 'whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc': 'Orca', * }} */ programLabels?: Record<string, string>; /** * Enable WalletConnect for QR code / deep link connections. * Disabled by default. * * Requires: * npm install @walletconnect/universal-provider qrcode.react * * Also requires appUrl to be set for WalletConnect metadata. * * @example * walletConnect={{ projectId: process.env.WALLETCONNECT_PROJECT_ID }} // Next.js * walletConnect={{ projectId: import.meta.env.VITE_WALLETCONNECT_PROJECT_ID }} // Vite */ walletConnect?: SimplifiedWalletConnectConfig;}export function NitsoProvider({ children, appName, appUrl, clusters, wallets, autoConnect = true, programLabels, walletConnect,}: NitsoProviderProps) { const config = useMemo( () => getDefaultConfig({ appName, appUrl, clusters, wallets, autoConnect, programLabels, walletConnect, }), // Primitive values (string, boolean) are safe as deps. // Object values (clusters, wallets, programLabels) // must be defined OUTSIDE the component to stay stable. // eslint-disable-next-line react-hooks/exhaustive-deps [ appName, appUrl, autoConnect, wallets, walletConnect, programLabels, clusters, ], ); return <AppProvider connectorConfig={config}>{children}</AppProvider>;}Setup
Add NitsoProvider to your root layout. It must wrap all Nitso components.
Add Environment Variables
Public RPC endpoints are rate limited and not suitable for production. Get a dedicated key from Helius, QuickNode, or Alchemy.
RPC_MAINNET=https://mainnet.helius-rpc.com/?api-key=your-key
RPC_DEVNET=https://devnet.helius-rpc.com/?api-key=your-keyCreate the provider
NitsoProvider uses React hooks internally and requires "use client". To keep your root layout as a Server Component (needed for metadata exports and SEO), create a separate client boundary file:
"use client";
import { NitsoProvider } from "@/components/nitso/nitso-provider";
const clusters = [
{
id: "solana:mainnet" as const,
label: "Mainnet Beta",
url: process.env.RPC_MAINNET!,
},
{
id: "solana:devnet" as const,
label: "Devnet",
url: process.env.RPC_DEVNET!,
},
{
id: "solana:testnet" as const,
label: "Testnet",
url: "https://api.testnet.solana.com",
},
];
export function Providers({ children }: { children: React.ReactNode }) {
return (
<NitsoProvider appName="My App" clusters={clusters}>
{children}
</NitsoProvider>
);
}Wrap your root layout
import { Providers } from "./provider";
export const metadata = {
title: "My App",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Add Environment Variables
Public RPC endpoints are rate limited and not suitable for production. Get a dedicated key from Helius, QuickNode, or Alchemy.
VITE_RPC_MAINNET=https://mainnet.helius-rpc.com/?api-key=your-key
VITE_RPC_DEVNET=https://devnet.helius-rpc.com/?api-key=your-keyAdd the provider
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { NitsoProvider } from "@/components/nitso/nitso-provider";
import App from "./App";
const clusters = [
{
id: "solana:mainnet" as const,
label: "Mainnet Beta",
url: import.meta.env.VITE_RPC_MAINNET,
},
{
id: "solana:devnet" as const,
label: "Devnet",
url: import.meta.env.VITE_RPC_DEVNET,
},
{
id: "solana:testnet" as const,
label: "Testnet",
url: "https://api.testnet.solana.com",
},
];
createRoot(document.getElementById("root")!).render(
<StrictMode>
<NitsoProvider appName="My App" clusters={clusters}>
<App />
</NitsoProvider>
</StrictMode>,
);WalletConnect
Enable QR code and deep link connections by setting walletConnect. This adds a "WalletConnect" option to the wallet modal.
Requires @walletconnect/universal-provider and qrcode.react to be installed:
npm install @walletconnect/universal-provider qrcode.reactpnpm add @walletconnect/universal-provider qrcode.reactyarn add @walletconnect/universal-provider qrcode.reactbun add @walletconnect/universal-provider qrcode.reactGet a project ID from WalletConnect Cloud, then add it to your environment:
WALLETCONNECT_PROJECT_ID=your-project-id<NitsoProvider
appName="My App"
appUrl="https://myapp.com"
clusters={clusters}
walletConnect={{
projectId: process.env.WALLETCONNECT_PROJECT_ID!,
}}
>
{children}
</NitsoProvider>VITE_WALLETCONNECT_PROJECT_ID=your-project-id<NitsoProvider
appName="My App"
appUrl="https://myapp.com"
clusters={clusters}
walletConnect={{
projectId: import.meta.env.VITE_WALLETCONNECT_PROJECT_ID,
}}
>
<App />
</NitsoProvider>Wallet Filtering
Control which detected wallets appear in the wallet modal.
// Show only specific wallets
const wallets = {
allowList: ["Phantom", "Solflare", "Backpack"],
featured: ["Phantom"],
};
// Hide specific wallets
const wallets = {
denyList: ["WalletConnect"],
};
<NitsoProvider appName="My App" clusters={clusters} wallets={wallets}>
{children}
</NitsoProvider>;Matching is case-insensitive. denyList wins over allowList when the same wallet appears in both. featured only reorders — it doesn't filter.
Define wallets outside your component to keep the reference stable and avoid unnecessary re-renders.
Program Labels
Add human-readable names for program IDs to enrich transaction history labels.
<NitsoProvider
appName="My App"
clusters={clusters}
programLabels={{
JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4: "Jupiter",
whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc: "Orca",
}}
>
{children}
</NitsoProvider>Props
| Prop | Type | Default | Description |
|---|---|---|---|
appName | string | — | Required. Shown in wallet connection prompts |
appUrl | string | — | Required when walletConnect is enabled |
clusters | SolanaCluster[] | — | Custom RPC endpoints per cluster |
wallets | WalletDisplayConfig | — | Filter and prioritize detected wallets |
autoConnect | boolean | true | Reconnect last wallet on page load |
programLabels | Record<string, string> | — | Human-readable names for program IDs |
walletConnect | SimplifiedWalletConnectConfig | — | Enable WalletConnect QR connections |