Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@solana/client

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solana/client

Framework-agnostic Solana client orchestration layer powering higher-level experiences

latest
Source
npmnpm
Version
1.7.0
Version published
Weekly downloads
3.5K
-26.05%
Maintainers
1
Weekly downloads
 
Created
Source

@solana/client

Framework-agnostic building blocks for Solana RPC, subscriptions, wallets, and transactions. Works in any runtime (React, Svelte, API routes, workers, etc.).

Status: Experimental – expect rapid iteration.

Install

npm install @solana/client

ConnectorKit (optional)

ConnectorKit integration is available as a stable, opt-in entrypoint: @solana/client/connectorkit.

This requires installing @solana/connector (an optional peer dependency of @solana/client):

npm install @solana/connector
import { connectorKit } from "@solana/client/connectorkit";

const walletConnectors = connectorKit({ defaultConfig: { /* ... */ } });

Quickstart

  • Choose Wallet Standard connectors (auto-discovery is the fastest way to start).
  • Create a Solana client.
  • Call actions, watchers, and helpers anywhere in your app (React, APIs, workers, etc.).
import { autoDiscover, createClient } from "@solana/client";

const client = createClient({
  endpoint: "https://api.devnet.solana.com",
  websocketEndpoint: "wss://api.devnet.solana.com",
  walletConnectors: autoDiscover(),
});

// Connect Wallet Standard apps via their connector ids.
// Recommended: use canonical ids like "wallet-standard:phantom" (aliases like "phantom" also work).
await client.actions.connectWallet("wallet-standard:phantom");

// Fetch an account once.
const wallet = client.store.getState().wallet;
if (wallet.status === "connected") {
  const account = await client.actions.fetchAccount(wallet.session.account.address);
  console.log(account.lamports?.toString());
}

Common Solana flows (copy/paste)

Connect, disconnect, and inspect wallet state

const connectors = client.connectors.all; // Wallet Standard-aware connectors

await client.actions.connectWallet(connectors[0].id);

const wallet = client.store.getState().wallet;
if (wallet.status === "connected") {
  console.log(wallet.session.account.address.toString());
}

await client.actions.disconnectWallet();

Fetch and watch lamports

import { toAddress } from "@solana/client";

const address = toAddress("Fg6PaFpoGXkYsidMpWFKfwtz6DhFVyG4dL1x8kj7ZJup");

const lamports = await client.actions.fetchBalance(address);
console.log(`Lamports: ${lamports.toString()}`);

const watcher = client.watchers.watchBalance({ address }, (nextLamports) => {
  console.log("Updated balance:", nextLamports.toString());
});

// Later…
watcher.abort();

Request an airdrop (devnet/testnet)

const signature = await client.actions.requestAirdrop(address, 1_000_000_000n); // 1 SOL
console.log(signature.toString());

Send SOL

const wallet = client.store.getState().wallet;
if (wallet.status !== "connected") throw new Error("Connect wallet first");

const signature = await client.solTransfer.sendTransfer({
  amount: 100_000_000n, // 0.1 SOL
  authority: wallet.session, // Wallet Standard session
  destination: "Ff34MXWdgNsEJ1kJFj9cXmrEe7y2P93b95mGu5CJjBQJ",
});
console.log(signature.toString());

SPL token balance + transfer

const wallet = client.store.getState().wallet;
if (wallet.status !== "connected") throw new Error("Connect wallet first");

const usdc = client.splToken({ mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" }); // USDC

const balance = await usdc.fetchBalance(wallet.session.account.address);
console.log(`Balance: ${balance.uiAmount}`);

const signature = await usdc.sendTransfer({
  amount: 1n,
  authority: wallet.session,
  destinationOwner: "Ff34MXWdgNsEJ1kJFj9cXmrEe7y2P93b95mGu5CJjBQJ",
});
console.log(signature.toString());

Token 2022 support

Token 2022 mints are supported via the tokenProgram option:

// Auto-detect Token or Token 2022 (recommended)
const token = client.splToken({
  mint: "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", // PYUSD
  tokenProgram: "auto",
});

// Or explicitly specify Token 2022 program
import { TOKEN_2022_PROGRAM_ADDRESS } from "@solana/client";

const token2022 = client.splToken({
  mint: mintAddress,
  tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
});

// Balance and transfers work the same way
const balance = await token.fetchBalance(wallet.session.account.address);
const signature = await token.sendTransfer({
  amount: 10,
  authority: wallet.session,
  destinationOwner: recipientAddress,
});

Fetch address lookup tables

import { toAddress } from "@solana/client";

// Single lookup table
const lut = await client.actions.fetchLookupTable(
  toAddress("AddressLookupTab1e1111111111111111111111111"),
);
console.log(`Addresses in LUT: ${lut.addresses.length}`);

// Multiple lookup tables
const luts = await client.actions.fetchLookupTables([lutAddress1, lutAddress2]);

Fetch nonce accounts

const nonce = await client.actions.fetchNonceAccount(
  toAddress("NonceAccountAddress111111111111111111111111"),
);
console.log(`Nonce: ${nonce.blockhash}`);
console.log(`Authority: ${nonce.authority}`);

Build and send arbitrary transactions

import { getTransferSolInstruction } from "@solana-program/system";

const wallet = client.store.getState().wallet;
if (wallet.status !== "connected") throw new Error("Connect wallet first");

const prepared = await client.transaction.prepare({
  authority: wallet.session,
  instructions: [
    getTransferSolInstruction({
      destination: "Ff34MXWdgNsEJ1kJFj9cXmrEe7y2P93b95mGu5CJjBQJ",
      lamports: 10_000n,
      source: wallet.session.account.address,
    }),
  ],
  version: "auto", // defaults to 0 when lookups exist, otherwise 'legacy'
});

// Inspect or serialize first.
const wire = await client.transaction.toWire(prepared);

// Submit.
const signature = await client.transaction.send(prepared);
console.log(signature.toString());

Watch signature confirmations

const watcher = client.watchers.watchSignature(
  { signature, commitment: "confirmed" },
  (notification) => console.log("Signature update:", notification),
);

// Later…
watcher.abort();

Cluster monikers and endpoints

Pass a cluster moniker to auto-resolve RPC + WebSocket URLs. Monikers map to:

  • mainnet / mainnet-betahttps://api.mainnet-beta.solana.com
  • testnethttps://api.testnet.solana.com
  • devnet (default) → https://api.devnet.solana.com
  • localnet / localhosthttp://127.0.0.1:8899

WebSocket URLs are inferred (wss:// or ws://) when not supplied. Override with endpoint/rpc or websocket/websocketEndpoint when you need a custom host.

import { autoDiscover, createClient } from "@solana/client";

const client = createClient({
  cluster: "mainnet", // or 'devnet' | 'testnet' | 'localnet' | 'localhost'
  walletConnectors: autoDiscover(),
});

Custom endpoint with inferred WebSocket:

const client = createClient({
  endpoint: "http://127.0.0.1:8899", // websocket inferred as ws://127.0.0.1:8900
});

Use resolveCluster directly when you need the resolved URLs without creating a client:

import { resolveCluster } from "@solana/client";

const resolved = resolveCluster({ moniker: "testnet" });
console.log(resolved.endpoint, resolved.websocketEndpoint);

Notes:

  • Default moniker is devnet when nothing is provided; moniker becomes custom when you pass a raw endpoint.
  • createClient, createDefaultClient (resolveClientConfig), and SolanaProvider all use resolveCluster under the hood, so the moniker/endpoint behavior is consistent across entrypoints.

Wallet connector filtering

Use filterByNames with autoDiscover() to filter wallets by name without wallet-specific code:

import { autoDiscover, filterByNames } from "@solana/client";

// Only show Phantom and Solflare
const connectors = autoDiscover({
  filter: filterByNames("phantom", "solflare"),
});

const client = createClient({
  cluster: "devnet",
  walletConnectors: connectors,
});

This approach follows Wallet Standard's wallet-agnostic discovery pattern while still allowing you to curate which wallets appear in your app.

You can also write custom filter functions:

const connectors = autoDiscover({
  filter: (wallet) => wallet.name.toLowerCase().includes("phantom"),
});

Notes and defaults

  • Wallet connectors: autoDiscover() picks up Wallet Standard injectables; use filterByNames() to filter by name, or compose phantom(), solflare(), backpack(), etc. when you need explicit control.
  • Store: built on Zustand; pass createStore to createClient for custom persistence or server-side stores. serializeSolanaState / deserializeSolanaState help save and restore cluster + wallet metadata.
  • Actions: fetchAccount, fetchBalance, fetchLookupTable, fetchLookupTables, fetchNonceAccount, setCluster, requestAirdrop, sendTransaction, and wallet connect/disconnect keep the store in sync.
  • Watchers: watchAccount, watchBalance, and watchSignature stream updates into the store and return an abort() handle for cleanup.
  • Helpers: solTransfer, splToken, and transaction cover common transfers plus low-level prepare/sign/toWire flows. Transaction versions default to 0 when any instruction references address lookup tables, otherwise legacy; override with version when needed.

Scripts

  • pnpm build – compile JS and type definitions
  • pnpm test:typecheck – strict type-checking
  • pnpm lint / pnpm format – Biome-powered linting and formatting

More resources

  • Documentation — full guides and API reference
  • Playground: examples/vite-react (run with pnpm install && pnpm dev).
  • Next.js reference app: examples/nextjs.
  • Client APIs live in src/actions.ts, src/watchers, and src/features/* for helper internals.

Keywords

solana

FAQs

Package last updated on 16 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts