@solana/client 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,79 +8,233 @@ in any runtime (React, Svelte, API routes, workers, etc.).
8
8
  ## Install
9
9
 
10
10
  ```bash
11
- pnpm add @solana/client
11
+ npm install @solana/client
12
12
  ```
13
13
 
14
- ## Quick start
14
+ ## Quickstart
15
+
16
+ 1. Choose Wallet Standard connectors (auto-discovery is the fastest way to start).
17
+ 2. Create a Solana client.
18
+ 3. Call actions, watchers, and helpers anywhere in your app (React, APIs, workers, etc.).
15
19
 
16
20
  ```ts
17
- import { autoDiscover, backpack, createClient, phantom, solflare } from "@solana/client";
21
+ import { autoDiscover, createClient } from "@solana/client";
18
22
 
19
- const walletConnectors = [...phantom(), ...solflare(), ...backpack(), ...autoDiscover()];
20
23
  const client = createClient({
21
24
  endpoint: "https://api.devnet.solana.com",
22
25
  websocketEndpoint: "wss://api.devnet.solana.com",
23
- walletConnectors,
26
+ walletConnectors: autoDiscover(),
24
27
  });
25
28
 
26
29
  // Connect Wallet Standard apps via their connector ids.
27
30
  await client.actions.connectWallet("phantom");
28
31
 
29
32
  // Fetch an account once.
30
- const account = await client.actions.fetchAccount(address);
31
- console.log(account.lamports?.toString());
33
+ const wallet = client.store.getState().wallet;
34
+ if (wallet.status === "connected") {
35
+ const account = await client.actions.fetchAccount(wallet.session.account.address);
36
+ console.log(account.lamports?.toString());
37
+ }
38
+ ```
39
+
40
+ ## Common Solana flows (copy/paste)
41
+
42
+ ### Connect, disconnect, and inspect wallet state
43
+
44
+ ```ts
45
+ const connectors = client.connectors.all; // Wallet Standard-aware connectors
46
+
47
+ await client.actions.connectWallet(connectors[0].id);
48
+
49
+ const wallet = client.store.getState().wallet;
50
+ if (wallet.status === "connected") {
51
+ console.log(wallet.session.account.address.toString());
52
+ }
53
+
54
+ await client.actions.disconnectWallet();
55
+ ```
32
56
 
33
- // Watch lamports in real time.
34
- const watcher = client.watchers.watchBalance({ address }, (lamports) => {
35
- console.log("balance:", lamports.toString());
57
+ ### Fetch and watch lamports
58
+
59
+ ```ts
60
+ import { toAddress } from "@solana/client";
61
+
62
+ const address = toAddress("Fg6PaFpoGXkYsidMpWFKfwtz6DhFVyG4dL1x8kj7ZJup");
63
+
64
+ const lamports = await client.actions.fetchBalance(address);
65
+ console.log(`Lamports: ${lamports.toString()}`);
66
+
67
+ const watcher = client.watchers.watchBalance({ address }, (nextLamports) => {
68
+ console.log("Updated balance:", nextLamports.toString());
36
69
  });
37
70
 
38
71
  // Later…
39
72
  watcher.abort();
40
73
  ```
41
74
 
42
- ## Core pieces
75
+ ### Request an airdrop (devnet/testnet)
76
+
77
+ ```ts
78
+ const signature = await client.actions.requestAirdrop(address, 1_000_000_000n); // 1 SOL
79
+ console.log(signature.toString());
80
+ ```
81
+
82
+ ### Send SOL
83
+
84
+ ```ts
85
+ const wallet = client.store.getState().wallet;
86
+ if (wallet.status !== "connected") throw new Error("Connect wallet first");
87
+
88
+ const signature = await client.solTransfer.sendTransfer({
89
+ amount: 100_000_000n, // 0.1 SOL
90
+ authority: wallet.session, // Wallet Standard session
91
+ destination: "Ff34MXWdgNsEJ1kJFj9cXmrEe7y2P93b95mGu5CJjBQJ",
92
+ });
93
+ console.log(signature.toString());
94
+ ```
95
+
96
+ ### SPL token balance + transfer
97
+
98
+ ```ts
99
+ const wallet = client.store.getState().wallet;
100
+ if (wallet.status !== "connected") throw new Error("Connect wallet first");
101
+
102
+ const usdc = client.splToken({ mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" }); // USDC
103
+
104
+ const balance = await usdc.fetchBalance(wallet.session.account.address);
105
+ console.log(`Balance: ${balance.uiAmount}`);
106
+
107
+ const signature = await usdc.sendTransfer({
108
+ amount: 1n,
109
+ authority: wallet.session,
110
+ destinationOwner: "Ff34MXWdgNsEJ1kJFj9cXmrEe7y2P93b95mGu5CJjBQJ",
111
+ });
112
+ console.log(signature.toString());
113
+ ```
114
+
115
+ ### Fetch address lookup tables
116
+
117
+ ```ts
118
+ import { toAddress } from "@solana/client";
119
+
120
+ // Single lookup table
121
+ const lut = await client.actions.fetchLookupTable(
122
+ toAddress("AddressLookupTab1e1111111111111111111111111"),
123
+ );
124
+ console.log(`Addresses in LUT: ${lut.addresses.length}`);
43
125
 
44
- - **Client store** – Zustand store that tracks cluster status, accounts, subscriptions, transactions,
45
- and wallet state. Provide your own store if you need custom persistence.
46
- - **Actions** – Promise-based helpers (`fetchAccount`, `fetchBalance`, `sendTransaction`, `requestAirdrop`, `setCluster`, etc.) that wrap the RPC and keep the store in sync.
47
- - **Watchers** – Subscription helpers (`watchAccount`, `watchBalance`, `watchSignature`) that stream
48
- updates into the store and call your listeners.
49
- - **Helpers** – Opinionated utilities for SOL transfers, SPL tokens, and transactions. They handle
50
- mundane tasks like resolving fee payers, refreshing blockhashes, or signing with Wallet Standard
51
- sessions.
126
+ // Multiple lookup tables
127
+ const luts = await client.actions.fetchLookupTables([lutAddress1, lutAddress2]);
128
+ ```
52
129
 
53
- ## Transaction helper
130
+ ### Fetch nonce accounts
131
+
132
+ ```ts
133
+ const nonce = await client.actions.fetchNonceAccount(
134
+ toAddress("NonceAccountAddress111111111111111111111111"),
135
+ );
136
+ console.log(`Nonce: ${nonce.blockhash}`);
137
+ console.log(`Authority: ${nonce.authority}`);
138
+ ```
54
139
 
55
- `client.helpers.transaction` handles blockhashes, fee payers, and signing for you.
140
+ ### Build and send arbitrary transactions
56
141
 
57
142
  ```ts
58
- const prepared = await client.helpers.transaction.prepare({
59
- authority: walletSession,
60
- instructions: [instruction],
143
+ import { getTransferSolInstruction } from "@solana-program/system";
144
+
145
+ const wallet = client.store.getState().wallet;
146
+ if (wallet.status !== "connected") throw new Error("Connect wallet first");
147
+
148
+ const prepared = await client.transaction.prepare({
149
+ authority: wallet.session,
150
+ instructions: [
151
+ getTransferSolInstruction({
152
+ destination: "Ff34MXWdgNsEJ1kJFj9cXmrEe7y2P93b95mGu5CJjBQJ",
153
+ lamports: 10_000n,
154
+ source: wallet.session.account.address,
155
+ }),
156
+ ],
157
+ version: "auto", // defaults to 0 when lookups exist, otherwise 'legacy'
61
158
  });
62
159
 
63
- const signature = await client.helpers.transaction.send(prepared);
160
+ // Inspect or serialize first.
161
+ const wire = await client.transaction.toWire(prepared);
162
+
163
+ // Submit.
164
+ const signature = await client.transaction.send(prepared);
64
165
  console.log(signature.toString());
65
166
  ```
66
167
 
67
- - `prepare` builds a transaction message and refreshes the blockhash.
68
- - `sign` / `toWire` let you collect signatures or emit Base64 manually.
69
- - `send` submits the prepared transaction (or uses `signAndSend` if the wallet supports it).
70
- - `prepareAndSend` runs everything plus an optional simulation/logging pass via `prepareTransaction`.
71
- - Versions default to `0` automatically when any instruction references address lookup tables, otherwise `legacy`; pass `version` if you need to override.
168
+ ### Watch signature confirmations
72
169
 
73
- Need just the tuning step? Call `client.prepareTransaction` directly with your unsigned message.
170
+ ```ts
171
+ const watcher = client.watchers.watchSignature(
172
+ { signature, commitment: "confirmed" },
173
+ (notification) => console.log("Signature update:", notification),
174
+ );
74
175
 
75
- ## Wallet helpers
176
+ // Later…
177
+ watcher.abort();
178
+ ```
179
+
180
+ ## Cluster monikers and endpoints
181
+
182
+ Pass a cluster moniker to auto-resolve RPC + WebSocket URLs. Monikers map to:
76
183
 
77
- Start with connectors: `phantom()`, `solflare()`, `backpack()`, and `autoDiscover()` return Wallet Standard-aware
78
- connectors you can pass to `createClient` or `createWalletRegistry`. Wrap additional wallets with
79
- `createWalletStandardConnector` before registering. The registry powers `client.actions.connectWallet` and the
80
- React hooks package, but you can also query it directly to build your own selectors.
184
+ - `mainnet` / `mainnet-beta` `https://api.mainnet-beta.solana.com`
185
+ - `testnet` `https://api.testnet.solana.com`
186
+ - `devnet` (default) `https://api.devnet.solana.com`
187
+ - `localnet` / `localhost` `http://127.0.0.1:8899`
188
+
189
+ WebSocket URLs are inferred (`wss://` or `ws://`) when not supplied. Override with `endpoint`/`rpc` or `websocket`/`websocketEndpoint` when you need a custom host.
190
+
191
+ ```ts
192
+ import { autoDiscover, createClient } from "@solana/client";
193
+
194
+ const client = createClient({
195
+ cluster: "mainnet", // or 'devnet' | 'testnet' | 'localnet' | 'localhost'
196
+ walletConnectors: autoDiscover(),
197
+ });
198
+ ```
199
+
200
+ Custom endpoint with inferred WebSocket:
201
+
202
+ ```ts
203
+ const client = createClient({
204
+ endpoint: "http://127.0.0.1:8899", // websocket inferred as ws://127.0.0.1:8900
205
+ });
206
+ ```
207
+
208
+ Use `resolveCluster` directly when you need the resolved URLs without creating a client:
209
+
210
+ ```ts
211
+ import { resolveCluster } from "@solana/client";
212
+
213
+ const resolved = resolveCluster({ moniker: "testnet" });
214
+ console.log(resolved.endpoint, resolved.websocketEndpoint);
215
+ ```
216
+
217
+ Notes:
218
+
219
+ - Default moniker is `devnet` when nothing is provided; moniker becomes `custom` when you pass a raw `endpoint`.
220
+ - `createClient`, `createDefaultClient` (`resolveClientConfig`), and `SolanaProvider` all use `resolveCluster` under the hood, so the moniker/endpoint behavior is consistent across entrypoints.
221
+
222
+ ## Notes and defaults
223
+
224
+ - Wallet connectors: `autoDiscover()` picks up Wallet Standard injectables; compose `phantom()`, `solflare()`, `backpack()`, or `injected()` when you need explicit control.
225
+ - Store: built on Zustand; pass `createStore` to `createClient` for custom persistence or server-side stores. `serializeSolanaState` / `deserializeSolanaState` help save and restore cluster + wallet metadata.
226
+ - Actions: `fetchAccount`, `fetchBalance`, `fetchLookupTable`, `fetchLookupTables`, `fetchNonceAccount`, `setCluster`, `requestAirdrop`, `sendTransaction`, and wallet connect/disconnect keep the store in sync.
227
+ - Watchers: `watchAccount`, `watchBalance`, and `watchSignature` stream updates into the store and return an `abort()` handle for cleanup.
228
+ - 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.
81
229
 
82
230
  ## Scripts
83
231
 
84
- - `pnpm build` – run JS compilation and type definition emit
85
- - `pnpm test:typecheck` – strict type-checking without emit
232
+ - `pnpm build` – compile JS and type definitions
233
+ - `pnpm test:typecheck` – strict type-checking
86
234
  - `pnpm lint` / `pnpm format` – Biome-powered linting and formatting
235
+
236
+ ## More resources
237
+
238
+ - Playground: `examples/vite-react` (run with `pnpm install && pnpm dev`).
239
+ - Next.js reference app: `examples/nextjs`.
240
+ - Client APIs live in `src/actions.ts`, `src/watchers`, and `src/features/*` for helper internals.