quicknode-solana-kit 1.0.2 → 1.0.3

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.
Files changed (46) hide show
  1. package/README.md +953 -257
  2. package/dist/addons.d.ts.map +1 -1
  3. package/dist/addons.js +190 -0
  4. package/dist/addons.js.map +1 -1
  5. package/dist/goldrush/index.d.ts +10 -0
  6. package/dist/goldrush/index.d.ts.map +1 -0
  7. package/dist/goldrush/index.js +37 -0
  8. package/dist/goldrush/index.js.map +1 -0
  9. package/dist/index.d.ts +33 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +92 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/iris/index.d.ts +3 -0
  14. package/dist/iris/index.d.ts.map +1 -0
  15. package/dist/iris/index.js +29 -0
  16. package/dist/iris/index.js.map +1 -0
  17. package/dist/mev/index.d.ts +4 -0
  18. package/dist/mev/index.d.ts.map +1 -0
  19. package/dist/mev/index.js +52 -0
  20. package/dist/mev/index.js.map +1 -0
  21. package/dist/openocean/index.d.ts +13 -0
  22. package/dist/openocean/index.d.ts.map +1 -0
  23. package/dist/openocean/index.js +63 -0
  24. package/dist/openocean/index.js.map +1 -0
  25. package/dist/pumpfun/index.d.ts +7 -0
  26. package/dist/pumpfun/index.d.ts.map +1 -0
  27. package/dist/pumpfun/index.js +54 -0
  28. package/dist/pumpfun/index.js.map +1 -0
  29. package/dist/scorechain/index.d.ts +4 -0
  30. package/dist/scorechain/index.d.ts.map +1 -0
  31. package/dist/scorechain/index.js +26 -0
  32. package/dist/scorechain/index.js.map +1 -0
  33. package/dist/stablecoin/index.d.ts +3 -0
  34. package/dist/stablecoin/index.d.ts.map +1 -0
  35. package/dist/stablecoin/index.js +16 -0
  36. package/dist/stablecoin/index.js.map +1 -0
  37. package/dist/titan/index.d.ts +5 -0
  38. package/dist/titan/index.d.ts.map +1 -0
  39. package/dist/titan/index.js +119 -0
  40. package/dist/titan/index.js.map +1 -0
  41. package/dist/types/index.d.ts +234 -0
  42. package/dist/types/index.d.ts.map +1 -1
  43. package/dist/utils/addon-guard.d.ts.map +1 -1
  44. package/dist/utils/addon-guard.js +47 -0
  45. package/dist/utils/addon-guard.js.map +1 -1
  46. package/package.json +1 -1
package/README.md CHANGED
@@ -1,458 +1,1154 @@
1
1
  # quicknode-solana-kit
2
2
 
3
- **The unified TypeScript SDK for every QuickNode Solana add-on.**
3
+ Typed Solana SDK for QuickNode endpoints and QuickNode-powered add-ons.
4
4
 
5
- One install. One config. Priority fees, Jito bundles, NFT queries, Jupiter swaps, and live streaming — all typed, all in one place.
5
+ This package gives you one client for:
6
6
 
7
- ```bash
8
- npm install quicknode-solana-kit
9
- ```
7
+ - normal Solana RPC via `@solana/web3.js`
8
+ - QuickNode custom RPC methods
9
+ - QuickNode-mounted REST add-ons
10
+ - real-time subscriptions through Solana WebSockets
10
11
 
11
- ---
12
+ If all you know today is:
12
13
 
13
- ## What Is This?
14
+ ```ts
15
+ import { Connection } from '@solana/web3.js';
14
16
 
15
- This is an **npm package for Solana developers**.
17
+ const connection = new Connection('https://your-endpoint.quiknode.pro/TOKEN/', 'confirmed');
18
+ ```
16
19
 
17
- Every developer building on Solana using QuickNode has to wire up each add-on manually — read separate docs pages, figure out separate API shapes, write hundreds of lines of boilerplate glue code. This SDK replaces all of that.
20
+ this package is the next layer on top of that.
18
21
 
19
- **Without this SDK:**
20
- ```ts
21
- // ~200 lines of manual code every time:
22
- // - call qn_estimatePriorityFees, parse it
23
- // - figure out which level to pick
24
- // - build SetComputeUnitLimit instruction
25
- // - build SetComputeUnitPrice instruction
26
- // - remove existing compute budget ixs to avoid duplicates
27
- // - simulate to estimate compute units
28
- // - handle retry when blockhash expires
29
- // - confirm and return useful data
30
- ```
22
+ It still uses a normal Solana `Connection`, but wraps common QuickNode features into a single typed API.
31
23
 
32
- **With this SDK:**
33
- ```ts
34
- const result = await kit.sendSmartTransaction({ transaction, signer });
35
- // That's it. Everything above is handled.
24
+ ```bash
25
+ npm install quicknode-solana-kit
36
26
  ```
37
27
 
38
- ---
28
+ ## What This Package Actually Does
39
29
 
40
- ## Requirements
30
+ `quicknode-solana-kit` is not a replacement for Solana RPC.
41
31
 
42
- - Node.js 18+
43
- - A QuickNode Solana endpoint → **free at [dashboard.quicknode.com](https://dashboard.quicknode.com)**
32
+ It is a wrapper around three patterns:
44
33
 
45
- ---
34
+ 1. Standard Solana RPC and WebSocket calls through `@solana/web3.js`
35
+ 2. QuickNode custom JSON-RPC methods like `qn_estimatePriorityFees`
36
+ 3. REST-style add-ons mounted on your QuickNode endpoint like `/jupiter/v6/quote`
46
37
 
47
- ## Quickstart
38
+ The package creates a normal Solana `Connection` internally, then adds methods like:
48
39
 
49
- ### 1. Install
40
+ - `sendSmartTransaction()`
41
+ - `estimatePriorityFees()`
42
+ - `getAssetsByOwner()`
43
+ - `getSwapQuote()`
44
+ - `getPumpFunTokens()`
45
+ - `sendMerkleProtectedTransaction()`
46
+ - `getGoldRushBalances()`
47
+ - `assessWalletRisk()`
48
+
49
+ ## Install
50
50
 
51
51
  ```bash
52
52
  npm install quicknode-solana-kit
53
53
  ```
54
54
 
55
- ### 2. Get a QuickNode endpoint
55
+ Peer/runtime requirements:
56
56
 
57
- Go to [dashboard.quicknode.com](https://dashboard.quicknode.com) → Create Endpoint → Solana.
58
- Copy the endpoint URL. It looks like:
59
- ```
60
- https://your-name.solana-mainnet.quiknode.pro/YOUR_TOKEN/
61
- ```
57
+ - Node.js 18+
58
+ - a QuickNode Solana endpoint
62
59
 
63
- ### 3. (Optional) Enable free add-ons
60
+ ## Quick Start
64
61
 
65
- In the QuickNode dashboard your endpoint → Add-ons tab:
66
- - Enable **Priority Fee API** (free) → unlocks `estimatePriorityFees()` + auto-fees in `sendSmartTransaction()`
67
- - Enable **Metaplex DAS API** (free) → unlocks all NFT query methods
62
+ ### 1. Create a QuickNode Solana endpoint
68
63
 
69
- ### 4. Create the kit
64
+ Example endpoint:
65
+
66
+ ```txt
67
+ https://your-name.solana-mainnet.quiknode.pro/YOUR_TOKEN/
68
+ ```
69
+
70
+ ### 2. Create the client
70
71
 
71
72
  ```ts
72
- import { QNSolanaKit } from '@quicknode/solana-kit';
73
+ import { QNSolanaKit } from 'quicknode-solana-kit';
73
74
 
74
75
  const kit = new QNSolanaKit({
75
- endpointUrl: 'https://your-name.solana-mainnet.quiknode.pro/TOKEN/',
76
-
77
- // Tell the SDK which add-ons you've enabled.
78
- // The SDK works without any — it just shows helpful messages
79
- // when you call a method that needs an add-on you haven't enabled.
76
+ endpointUrl: 'https://your-name.solana-mainnet.quiknode.pro/YOUR_TOKEN/',
77
+ commitment: 'confirmed',
78
+ timeout: 30_000,
80
79
  addOns: {
81
- priorityFees: true, // FREE — Priority Fee API
82
- das: true, // FREE — Metaplex DAS API
83
- metis: false, // PAID — Metis (Jupiter Swap)
84
- liljit: false, // PAID — Lil' JIT (Jito bundles)
85
- yellowstone: false, // PAID — Yellowstone gRPC
80
+ priorityFees: true,
81
+ das: true,
82
+ metis: false,
83
+ yellowstone: false,
84
+ liljit: false,
85
+ pumpfun: false,
86
+ stablecoinBalance: false,
87
+ openocean: false,
88
+ merkle: false,
89
+ blinklabs: false,
90
+ iris: false,
91
+ goldrush: false,
92
+ titan: false,
93
+ scorechain: false,
86
94
  },
87
95
  });
88
96
  ```
89
97
 
90
- ### 5. Check what's available
98
+ ### 3. Use the built-in Solana connection
99
+
100
+ ```ts
101
+ const blockhash = await kit.connection.getLatestBlockhash();
102
+ console.log(blockhash.blockhash);
103
+ ```
104
+
105
+ ### 4. Probe your endpoint
106
+
107
+ ```ts
108
+ const status = await kit.checkAddOns();
109
+ console.log(status.addOns);
110
+ console.log(status.canUse);
111
+ ```
112
+
113
+ You can also run the CLI:
91
114
 
92
115
  ```bash
93
- # Probes your endpoint and shows exactly which add-ons are active
94
116
  npm run check
95
117
  ```
96
118
 
97
- Output:
119
+ ## How Add-Ons Work
120
+
121
+ This package uses add-ons in two ways:
122
+
123
+ ### 1. Local config guard
124
+
125
+ You declare what you think is enabled:
126
+
127
+ ```ts
128
+ const kit = new QNSolanaKit({
129
+ endpointUrl: process.env.QN_ENDPOINT_URL!,
130
+ addOns: {
131
+ priorityFees: true,
132
+ das: true,
133
+ metis: false,
134
+ },
135
+ });
98
136
  ```
99
- @quicknode/solana-kit — Add-on Status
100
- ──────────────────────────────────────────────────────
101
- Endpoint: https://your-name.solana-mainnet.quiknode.pro...
102
137
 
103
- Priority Fee API [FREE]
104
- enabled — Dynamic priority fee estimation for faster tx inclusion
138
+ If you explicitly set an add-on to `false` and call a method that requires it, the SDK throws an `AddOnNotEnabledError`.
105
139
 
106
- Metaplex DAS API [FREE]
107
- enabled — Query NFTs, compressed NFTs, token metadata
140
+ If you leave a value `undefined`, the SDK warns and still tries the network call.
108
141
 
109
- Metis Jupiter V6 Swap API [PAID]
110
- not enabled — Best-price token swaps via Jupiter aggregator
111
- Enable: https://marketplace.quicknode.com/add-ons/metis-jupiter-v6-swap-api
142
+ ### 2. Real endpoint capability
112
143
 
113
- Features Available:
114
- ✓ Smart Transactions (auto fees + retry)
115
- ✓ NFT / Digital Asset Queries
116
- ✗ Jupiter Token Swaps
117
- ✗ Yellowstone gRPC Streaming
118
- ✗ Jito Bundle (MEV protection)
119
- ✓ WebSocket Streaming (slot/account/logs)
144
+ The actual source of truth is your endpoint.
145
+
146
+ `checkAddOns()` probes the endpoint by making sample RPC or REST calls and returns what is live.
147
+
148
+ ```ts
149
+ const result = await kit.checkAddOns();
150
+
151
+ console.log(result.canUse.smartTransactions);
152
+ console.log(result.canUse.nftQueries);
153
+ console.log(result.canUse.swaps);
154
+ console.log(result.canUse.openOceanSwaps);
155
+ console.log(result.canUse.goldRushData);
120
156
  ```
121
157
 
122
- ---
158
+ ## Add-On Map
123
159
 
124
- ## Add-on Tiers
160
+ Here is how each add-on is implemented inside the package.
125
161
 
126
- | Add-on | Tier | What it unlocks |
127
- |---|---|---|
128
- | Priority Fee API | **FREE** | `estimatePriorityFees()`, auto-fees in `sendSmartTransaction()` |
129
- | Metaplex DAS API | **FREE** | `getAssetsByOwner()`, `getAsset()`, `searchAssets()`, `getAssetProof()` |
130
- | Metis (Jupiter Swap) | **PAID** | `swap()`, `getSwapQuote()` |
131
- | Lil' JIT (Jito) | **PAID** | `sendSmartTransaction({ options: { useJito: true } })` |
132
- | Yellowstone gRPC | **PAID** | `watchAccount()` uses gRPC instead of WebSocket |
162
+ | Add-on key | What it unlocks | Transport used by SDK | Example endpoint shape |
163
+ |---|---|---|---|
164
+ | `priorityFees` | live fee estimation and smart tx fee selection | JSON-RPC | `qn_estimatePriorityFees` |
165
+ | `das` | NFT / digital asset queries | JSON-RPC | `getAssetsByOwner` |
166
+ | `metis` | Jupiter quote and swap | REST | `/jupiter/v6/quote` |
167
+ | `yellowstone` | account streaming preference | currently falls back to WebSocket | no active gRPC client yet |
168
+ | `liljit` | intended Jito support | checked by probe, not fully wired into smart tx flow yet | `sendBundle` |
169
+ | `pumpfun` | pump.fun market data | REST | `/pump-fun/coins` |
170
+ | `stablecoinBalance` | stablecoin balances across chains | JSON-RPC | `qn_getWalletStablecoinBalances` |
171
+ | `openocean` | OpenOcean quote and swap | REST | `/openocean/v4/solana/quote` |
172
+ | `merkle` | MEV-protected tx submission | JSON-RPC | `mev_sendTransaction` |
173
+ | `blinklabs` | alternate protected tx submission | JSON-RPC | `blinklabs_sendTransaction` |
174
+ | `iris` | low-latency tx sender | JSON-RPC | `iris_sendTransaction` |
175
+ | `goldrush` | multichain balances and tx history | REST | `/goldrush/v1/...` |
176
+ | `titan` | swap quote, swap, quote stream | REST + WebSocket | `/titan/v1/quote` |
177
+ | `scorechain` | wallet risk checks | REST | `/scorechain/v1/risk` |
133
178
 
134
- **Everything except swaps and Jito works on free tier.**
135
- WebSocket streaming (`watchAccount`, `watchProgram`, `watchSlot`) works out of the box with no add-ons.
179
+ ## Common Pattern
136
180
 
137
- ---
181
+ Most features follow one of these flows.
138
182
 
139
- ## API Reference
183
+ ### Standard Solana RPC
140
184
 
141
- ### `kit.sendSmartTransaction(params)`
185
+ ```ts
186
+ const accounts = await kit.connection.getTokenAccountsByOwner(
187
+ wallet,
188
+ { programId: TOKEN_PROGRAM_ID },
189
+ );
190
+ ```
191
+
192
+ ### QuickNode custom RPC
142
193
 
143
- Send a transaction with automatic priority fees, compute unit optimization, and retry.
194
+ The SDK hides the raw method call:
144
195
 
145
196
  ```ts
146
- const result = await kit.sendSmartTransaction({
147
- transaction: myTx, // your @solana/web3.js Transaction
148
- signer: keypair, // Keypair that signs + pays fees
149
- options: {
150
- feeLevel: 'recommended', // 'low'|'medium'|'recommended'|'high'|'extreme'
151
- useJito: false, // true = Jito bundle (requires liljit add-on)
152
- maxRetries: 5, // retries on blockhash expiry
153
- simulateFirst: true, // simulate to right-size compute units
154
- },
197
+ const fees = await kit.estimatePriorityFees();
198
+ ```
199
+
200
+ instead of:
201
+
202
+ ```ts
203
+ await fetch(endpoint, {
204
+ method: 'POST',
205
+ headers: { 'Content-Type': 'application/json' },
206
+ body: JSON.stringify({
207
+ jsonrpc: '2.0',
208
+ id: 1,
209
+ method: 'qn_estimatePriorityFees',
210
+ params: { last_n_blocks: 100, api_version: 2 },
211
+ }),
155
212
  });
213
+ ```
156
214
 
157
- console.log(result.signature); // 'abc123...'
158
- console.log(result.slot); // 320481923
159
- console.log(result.priorityFeeMicroLamports); // 5000
160
- console.log(result.computeUnitsUsed); // 12500
161
- console.log(result.confirmationMs); // 843
215
+ ### REST add-on mounted on the same endpoint
216
+
217
+ The SDK also hides path-building:
218
+
219
+ ```ts
220
+ const quote = await kit.getSwapQuote({
221
+ inputMint: TOKENS.SOL,
222
+ outputMint: TOKENS.USDC,
223
+ amount: BigInt(1_000_000_000),
224
+ });
162
225
  ```
163
226
 
164
- ---
227
+ instead of manually calling:
165
228
 
166
- ### `kit.prepareSmartTransaction(params)`
229
+ ```txt
230
+ https://your-endpoint.quiknode.pro/TOKEN/jupiter/v6/quote?...
231
+ ```
167
232
 
168
- Same as `sendSmartTransaction` but returns the prepared transaction without sending.
169
- **Use this with wallet adapters** (Phantom, Backpack, etc.) where you don't hold the key.
233
+ ## Client Configuration
170
234
 
171
235
  ```ts
172
- const { transaction } = await kit.prepareSmartTransaction({
173
- transaction: myTx,
174
- payer: wallet.publicKey,
175
- options: { feeLevel: 'high' },
236
+ import { QNSolanaKit } from 'quicknode-solana-kit';
237
+
238
+ const kit = new QNSolanaKit({
239
+ endpointUrl: process.env.QN_ENDPOINT_URL!,
240
+ commitment: 'confirmed',
241
+ timeout: 30_000,
242
+ addOns: {
243
+ priorityFees: true,
244
+ das: true,
245
+ },
176
246
  });
247
+ ```
248
+
249
+ ### Config fields
177
250
 
178
- // Pass to wallet adapter:
179
- const sig = await wallet.sendTransaction(transaction, kit.connection);
251
+ ```ts
252
+ interface QNConfig {
253
+ endpointUrl: string;
254
+ commitment?: 'processed' | 'confirmed' | 'finalized';
255
+ timeout?: number;
256
+ addOns?: {
257
+ priorityFees?: boolean;
258
+ liljit?: boolean;
259
+ das?: boolean;
260
+ metis?: boolean;
261
+ yellowstone?: boolean;
262
+ pumpfun?: boolean;
263
+ stablecoinBalance?: boolean;
264
+ openocean?: boolean;
265
+ merkle?: boolean;
266
+ blinklabs?: boolean;
267
+ iris?: boolean;
268
+ goldrush?: boolean;
269
+ titan?: boolean;
270
+ scorechain?: boolean;
271
+ };
272
+ }
180
273
  ```
181
274
 
182
- ---
275
+ ## API Reference
276
+
277
+ ### Diagnostics
278
+
279
+ #### `kit.checkAddOns()`
280
+
281
+ Probes your endpoint and returns add-on availability.
282
+
283
+ ```ts
284
+ const status = await kit.checkAddOns();
183
285
 
184
- ### `kit.estimatePriorityFees(options?)`
286
+ for (const addon of status.addOns) {
287
+ console.log(addon.name, addon.enabled, addon.tier);
288
+ }
289
+
290
+ console.log(status.canUse.smartTransactions);
291
+ console.log(status.canUse.nftQueries);
292
+ console.log(status.canUse.swaps);
293
+ console.log(status.canUse.pumpFun);
294
+ console.log(status.canUse.goldRushData);
295
+ console.log(status.canUse.riskAssessment);
296
+ ```
297
+
298
+ ### Transactions
299
+
300
+ #### `kit.estimatePriorityFees(options?)`
301
+
302
+ Requires: `priorityFees`
303
+
304
+ Gets live priority fee estimates from QuickNode.
305
+
306
+ ```ts
307
+ const fees = await kit.estimatePriorityFees();
308
+
309
+ console.log(fees.low);
310
+ console.log(fees.medium);
311
+ console.log(fees.recommended);
312
+ console.log(fees.high);
313
+ console.log(fees.extreme);
314
+ console.log(fees.networkCongestion);
315
+ ```
185
316
 
186
- Get current priority fees for all levels.
317
+ With an account filter:
187
318
 
188
319
  ```ts
189
320
  const fees = await kit.estimatePriorityFees({
190
- account: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4', // optional filter
191
- lastNBlocks: 100,
321
+ account: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
322
+ lastNBlocks: 50,
192
323
  });
324
+ ```
325
+
326
+ #### `kit.sendSmartTransaction({ transaction, signer, options })`
327
+
328
+ Uses:
329
+
330
+ - Solana simulation to estimate compute units
331
+ - QuickNode Priority Fee API when available
332
+ - compute budget instruction injection
333
+ - retry loop with backoff
334
+
335
+ Requires: no add-on strictly required, but `priorityFees` makes it much better
336
+
337
+ ```ts
338
+ import bs58 from 'bs58';
339
+ import {
340
+ Keypair,
341
+ LAMPORTS_PER_SOL,
342
+ SystemProgram,
343
+ Transaction,
344
+ } from '@solana/web3.js';
345
+ import { QNSolanaKit } from 'quicknode-solana-kit';
346
+
347
+ const kit = new QNSolanaKit({
348
+ endpointUrl: process.env.QN_ENDPOINT_URL!,
349
+ addOns: { priorityFees: true },
350
+ });
351
+
352
+ const signer = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_PRIVATE_KEY!));
353
+
354
+ const transaction = new Transaction().add(
355
+ SystemProgram.transfer({
356
+ fromPubkey: signer.publicKey,
357
+ toPubkey: signer.publicKey,
358
+ lamports: Math.floor(0.001 * LAMPORTS_PER_SOL),
359
+ }),
360
+ );
361
+
362
+ const result = await kit.sendSmartTransaction({
363
+ transaction,
364
+ signer,
365
+ options: {
366
+ feeLevel: 'recommended',
367
+ simulateFirst: true,
368
+ maxRetries: 5,
369
+ computeUnitBuffer: 10,
370
+ skipPreflight: false,
371
+ },
372
+ });
373
+
374
+ console.log(result.signature);
375
+ console.log(result.slot);
376
+ console.log(result.priorityFeeMicroLamports);
377
+ console.log(result.computeUnitsUsed);
378
+ console.log(result.confirmationMs);
379
+ ```
380
+
381
+ #### `kit.prepareSmartTransaction({ transaction, payer, options })`
382
+
383
+ Prepares a transaction with compute budget instructions and recent blockhash, but does not send it.
193
384
 
194
- fees.low // 500 µlamports/CU
195
- fees.medium // 1200 µlamports/CU
196
- fees.recommended // 3000 µlamports/CU
197
- fees.high // 8000 µlamports/CU
198
- fees.extreme // 25000 µlamports/CU
199
- fees.networkCongestion // 0.42 (0=quiet, 1=congested)
385
+ This is useful for wallet adapters.
386
+
387
+ ```ts
388
+ const prepared = await kit.prepareSmartTransaction({
389
+ transaction: myTransaction,
390
+ payer: wallet.publicKey,
391
+ options: {
392
+ feeLevel: 'high',
393
+ computeUnitBuffer: 10,
394
+ },
395
+ });
396
+
397
+ console.log(prepared.priorityFeeMicroLamports);
398
+ console.log(prepared.computeUnits);
399
+
400
+ const signature = await wallet.sendTransaction(prepared.transaction, kit.connection);
401
+ console.log(signature);
200
402
  ```
201
403
 
202
- ---
404
+ ### Digital Assets and Tokens
405
+
406
+ #### `kit.getAssetsByOwner(options)`
203
407
 
204
- ### `kit.getAssetsByOwner(options)`
408
+ Requires: `das`
205
409
 
206
- Get all NFTs, cNFTs, and tokens owned by a wallet.
410
+ Gets digital assets owned by a wallet.
207
411
 
208
412
  ```ts
209
- const { items, total } = await kit.getAssetsByOwner({
210
- ownerAddress: 'WalletAddress',
211
- limit: 50,
212
- sortBy: 'created',
213
- sortDirection: 'desc',
413
+ const result = await kit.getAssetsByOwner({
414
+ ownerAddress: 'E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk',
415
+ limit: 10,
416
+ page: 1,
214
417
  });
215
418
 
216
- items.forEach(asset => {
419
+ console.log(result.total);
420
+
421
+ for (const asset of result.items) {
422
+ console.log(asset.id);
217
423
  console.log(asset.content.metadata.name);
218
424
  console.log(asset.ownership.owner);
219
- console.log(asset.compression?.compressed); // true = cNFT
220
- });
425
+ console.log(asset.compression?.compressed);
426
+ }
221
427
  ```
222
428
 
223
- ---
429
+ #### `kit.getAsset(mintAddress)`
224
430
 
225
- ### `kit.getAsset(mintAddress)`
431
+ Requires: `das`
226
432
 
227
- Get a single digital asset by mint address.
433
+ Gets one asset by id or mint address.
228
434
 
229
435
  ```ts
230
- const asset = await kit.getAsset('NFTMintAddress');
436
+ const asset = await kit.getAsset('NFT_MINT_OR_ASSET_ID');
437
+
438
+ console.log(asset.id);
231
439
  console.log(asset.content.metadata.name);
440
+ console.log(asset.content.metadata.symbol);
232
441
  console.log(asset.content.metadata.image);
233
442
  console.log(asset.royalty?.basis_points);
234
443
  ```
235
444
 
236
- ---
445
+ #### `kit.getAssetsByCollection(options)`
237
446
 
238
- ### `kit.searchAssets(options)`
447
+ Requires: `das`
239
448
 
240
- Search with filters: owner, creator, collection, token type.
449
+ Gets assets by collection mint.
241
450
 
242
451
  ```ts
243
- const { items } = await kit.searchAssets({
244
- ownerAddress: 'WalletAddress',
245
- tokenType: 'compressedNFT', // only cNFTs
246
- limit: 100,
452
+ const collectionAssets = await kit.getAssetsByCollection({
453
+ collectionMint: 'COLLECTION_MINT',
454
+ limit: 20,
455
+ page: 1,
247
456
  });
457
+
458
+ console.log(collectionAssets.total);
459
+ console.log(collectionAssets.items.map(item => item.content.metadata.name));
248
460
  ```
249
461
 
250
- ---
462
+ #### `kit.searchAssets(options)`
251
463
 
252
- ### `kit.getAssetProof(assetId)`
464
+ Requires: `das`
253
465
 
254
- Get the Merkle proof for a compressed NFT. Required for cNFT transfers via Bubblegum.
466
+ Searches by owner, creator, collection, token type, or compressed status.
255
467
 
256
468
  ```ts
257
- const proof = await kit.getAssetProof('cNFTAssetId');
258
- // proof.root + proof.proof → use with mpl-bubblegum transfer instruction
469
+ const compressed = await kit.searchAssets({
470
+ ownerAddress: 'WALLET_ADDRESS',
471
+ tokenType: 'compressedNFT',
472
+ compressed: true,
473
+ limit: 50,
474
+ page: 1,
475
+ });
476
+
477
+ console.log(compressed.items.length);
259
478
  ```
260
479
 
261
- ---
480
+ By creator:
262
481
 
263
- ### `kit.getTokenAccounts(walletAddress)`
482
+ ```ts
483
+ const created = await kit.searchAssets({
484
+ creatorAddress: 'CREATOR_ADDRESS',
485
+ limit: 25,
486
+ });
487
+ ```
264
488
 
265
- Get all SPL token accounts and balances for a wallet.
489
+ By collection:
266
490
 
267
491
  ```ts
268
- const tokens = await kit.getTokenAccounts('WalletAddress');
269
- tokens
270
- .filter(t => t.uiAmount > 0)
271
- .forEach(t => console.log(`${t.mint}: ${t.uiAmount}`));
492
+ const byCollection = await kit.searchAssets({
493
+ collection: 'COLLECTION_MINT',
494
+ limit: 25,
495
+ });
272
496
  ```
273
497
 
274
- ---
498
+ #### `kit.getAssetProof(assetId)`
275
499
 
276
- ### `kit.watchAccount(address, callback, options?)`
500
+ Requires: `das`
277
501
 
278
- Watch an account for real-time updates. Auto-uses Yellowstone if enabled, WebSocket otherwise.
502
+ Gets the Merkle proof for a compressed asset.
279
503
 
280
504
  ```ts
281
- const handle = kit.watchAccount('WalletAddress', (update) => {
282
- console.log('SOL balance:', update.lamports / 1e9);
283
- console.log('Backend:', update.backend); // 'yellowstone' or 'websocket'
284
- });
505
+ const proof = await kit.getAssetProof('ASSET_ID');
285
506
 
286
- // Stop watching:
287
- handle.unsubscribe();
288
- handle.isConnected(); // boolean
507
+ console.log(proof.root);
508
+ console.log(proof.proof);
509
+ console.log(proof.tree_id);
289
510
  ```
290
511
 
291
- ---
512
+ #### `kit.getTokenAccounts(walletAddress)`
292
513
 
293
- ### `kit.watchProgram(programId, callback, options?)`
514
+ No add-on required.
294
515
 
295
- Watch all transactions for a program in real time.
516
+ Gets parsed SPL token accounts using standard Solana RPC.
296
517
 
297
518
  ```ts
298
- const JUPITER = 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4';
519
+ const tokenAccounts = await kit.getTokenAccounts('WALLET_ADDRESS');
299
520
 
300
- const handle = kit.watchProgram(JUPITER, (tx) => {
301
- if (!tx.err) console.log('Swap:', tx.signature);
302
- });
521
+ for (const token of tokenAccounts) {
522
+ if (token.uiAmount > 0) {
523
+ console.log(token.mint, token.uiAmount);
524
+ }
525
+ }
526
+ ```
527
+
528
+ ### Streaming
529
+
530
+ #### `kit.watchAccount(address, onUpdate, options?)`
531
+
532
+ No paid add-on required for basic usage.
533
+
534
+ If `yellowstone` is enabled in config, the package prefers that path, but the current implementation falls back to standard WebSocket subscriptions.
535
+
536
+ ```ts
537
+ const handle = kit.watchAccount(
538
+ 'E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk',
539
+ (update) => {
540
+ console.log(update.pubkey);
541
+ console.log(update.lamports);
542
+ console.log(update.owner);
543
+ console.log(update.slot);
544
+ console.log(update.backend);
545
+ },
546
+ {
547
+ backend: 'auto',
548
+ commitment: 'confirmed',
549
+ },
550
+ );
551
+
552
+ setTimeout(() => {
553
+ console.log(handle.isConnected());
554
+ handle.unsubscribe();
555
+ }, 15_000);
303
556
  ```
304
557
 
305
- ---
558
+ #### `kit.watchProgram(programId, onTx, options?)`
306
559
 
307
- ### `kit.watchSlot(callback)`
560
+ Watches program logs through Solana WebSockets.
308
561
 
309
- Subscribe to slot updates (~every 400ms). Free tier, no add-ons needed.
562
+ ```ts
563
+ const handle = kit.watchProgram(
564
+ 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
565
+ (tx) => {
566
+ console.log(tx.signature);
567
+ console.log(tx.logs);
568
+ console.log(tx.err);
569
+ },
570
+ { commitment: 'confirmed' },
571
+ );
572
+ ```
573
+
574
+ #### `kit.watchSlot(onSlot)`
575
+
576
+ Watches slot changes.
310
577
 
311
578
  ```ts
312
579
  const handle = kit.watchSlot((slot) => {
313
- process.stdout.write(`\r Slot: ${slot.toLocaleString()}`);
580
+ console.log('slot', slot);
314
581
  });
582
+
583
+ setTimeout(() => handle.unsubscribe(), 10_000);
315
584
  ```
316
585
 
317
- ---
586
+ ### Jupiter / Metis
318
587
 
319
- ### `kit.getSwapQuote(options)` — PAID (Metis)
588
+ Requires: `metis`
320
589
 
321
- Get a Jupiter swap quote without executing.
590
+ The SDK builds URLs under your endpoint like:
591
+
592
+ ```txt
593
+ https://your-endpoint.quiknode.pro/TOKEN/jupiter/v6/quote
594
+ https://your-endpoint.quiknode.pro/TOKEN/jupiter/v6/swap
595
+ ```
596
+
597
+ #### `kit.getSwapQuote(options)`
322
598
 
323
599
  ```ts
324
- import { TOKENS } from '@quicknode/solana-kit';
600
+ import { TOKENS } from 'quicknode-solana-kit';
325
601
 
326
602
  const quote = await kit.getSwapQuote({
327
- inputMint: TOKENS.SOL,
603
+ inputMint: TOKENS.SOL,
328
604
  outputMint: TOKENS.USDC,
329
- amount: BigInt(1_000_000_000), // 1 SOL
605
+ amount: BigInt(1_000_000_000),
606
+ slippageBps: 50,
330
607
  });
331
608
 
332
- console.log(`1 SOL → ${Number(quote.outAmount) / 1e6} USDC`);
333
- console.log(`Price impact: ${quote.priceImpactPct}%`);
609
+ console.log(quote.inAmount);
610
+ console.log(quote.outAmount);
611
+ console.log(quote.priceImpactPct);
612
+ console.log(quote.routePlan);
334
613
  ```
335
614
 
336
- ---
615
+ #### `kit.swap(options)`
337
616
 
338
- ### `kit.swap(options)` PAID (Metis)
617
+ The SDK flow is:
339
618
 
340
- Execute a token swap in one call.
619
+ 1. fetch quote
620
+ 2. request serialized swap transaction
621
+ 3. deserialize transaction
622
+ 4. sign locally
623
+ 5. send with normal Solana connection
624
+ 6. confirm
341
625
 
342
626
  ```ts
343
- const result = await kit.swap({
344
- inputMint: TOKENS.SOL,
345
- outputMint: TOKENS.USDC,
346
- amount: BigInt(100_000_000), // 0.1 SOL
347
- userPublicKey: keypair.publicKey.toString(),
348
- signer: keypair,
349
- slippageBps: 50, // 0.5%
350
- feeLevel: 'recommended',
627
+ import bs58 from 'bs58';
628
+ import { Keypair } from '@solana/web3.js';
629
+ import { QNSolanaKit, TOKENS } from 'quicknode-solana-kit';
630
+
631
+ const signer = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_PRIVATE_KEY!));
632
+
633
+ const kit = new QNSolanaKit({
634
+ endpointUrl: process.env.QN_ENDPOINT_URL!,
635
+ addOns: { metis: true },
636
+ });
637
+
638
+ const swapResult = await kit.swap({
639
+ inputMint: TOKENS.SOL,
640
+ outputMint: TOKENS.USDC,
641
+ amount: BigInt(100_000_000),
642
+ userPublicKey: signer.publicKey.toString(),
643
+ signer,
644
+ slippageBps: 50,
645
+ feeLevel: 'recommended',
351
646
  });
352
647
 
353
- console.log('Swapped!', result.signature);
648
+ console.log(swapResult.signature);
649
+ console.log(swapResult.inputAmount);
650
+ console.log(swapResult.outputAmount);
651
+ console.log(swapResult.priceImpactPct);
354
652
  ```
355
653
 
356
- Token shortcuts: `TOKENS.SOL`, `TOKENS.USDC`, `TOKENS.USDT`, `TOKENS.BONK`, `TOKENS.JUP`, `TOKENS.RAY`, `TOKENS.WIF`
654
+ #### `TOKENS`
357
655
 
358
- ---
656
+ Token shortcuts:
359
657
 
360
- ### `kit.checkAddOns()`
658
+ ```ts
659
+ import { TOKENS } from 'quicknode-solana-kit';
660
+
661
+ console.log(TOKENS.SOL);
662
+ console.log(TOKENS.USDC);
663
+ console.log(TOKENS.USDT);
664
+ console.log(TOKENS.BONK);
665
+ console.log(TOKENS.JUP);
666
+ console.log(TOKENS.RAY);
667
+ console.log(TOKENS.WIF);
668
+ ```
669
+
670
+ ### Pump.fun
671
+
672
+ Requires: `pumpfun`
673
+
674
+ The SDK uses REST paths under your endpoint:
675
+
676
+ ```txt
677
+ /pump-fun/coins
678
+ /pump-fun/coins/:mint
679
+ /pump-fun/coins/:mint/holders
680
+ /pump-fun/trades/all
681
+ ```
361
682
 
362
- Probe your endpoint to see which add-ons are live.
683
+ #### `kit.getPumpFunTokens(options?)`
363
684
 
364
685
  ```ts
365
- const status = await kit.checkAddOns();
366
- console.log(status.canUse.smartTransactions); // true/false
367
- console.log(status.canUse.nftQueries); // true/false
368
- console.log(status.addOns); // per-add-on detail
686
+ const tokens = await kit.getPumpFunTokens({
687
+ limit: 10,
688
+ offset: 0,
689
+ includeNsfw: false,
690
+ });
691
+
692
+ for (const token of tokens) {
693
+ console.log(token.mint, token.symbol, token.marketCapSol);
694
+ }
695
+ ```
696
+
697
+ #### `kit.getPumpFunToken(mint)`
698
+
699
+ ```ts
700
+ const token = await kit.getPumpFunToken('TOKEN_MINT');
701
+
702
+ console.log(token.name);
703
+ console.log(token.symbol);
704
+ console.log(token.creator);
705
+ console.log(token.price);
706
+ console.log(token.bondingCurve.complete);
369
707
  ```
370
708
 
371
- ---
709
+ #### `kit.getPumpFunTokensByCreator(options)`
710
+
711
+ ```ts
712
+ const created = await kit.getPumpFunTokensByCreator({
713
+ creator: 'CREATOR_WALLET',
714
+ limit: 20,
715
+ offset: 0,
716
+ });
717
+ ```
718
+
719
+ #### `kit.getPumpFunTokenHolders(mint)`
720
+
721
+ ```ts
722
+ const holders = await kit.getPumpFunTokenHolders('TOKEN_MINT');
723
+
724
+ for (const holder of holders.slice(0, 10)) {
725
+ console.log(holder.address, holder.balance, holder.percentage);
726
+ }
727
+ ```
728
+
729
+ #### `kit.getPumpFunTokenTrades(mint, options?)`
730
+
731
+ ```ts
732
+ const trades = await kit.getPumpFunTokenTrades('TOKEN_MINT', {
733
+ limit: 25,
734
+ offset: 0,
735
+ });
736
+
737
+ for (const trade of trades) {
738
+ console.log(trade.signature, trade.isBuy, trade.solAmount, trade.tokenAmount);
739
+ }
740
+ ```
741
+
742
+ ### Stablecoin Balance API
743
+
744
+ Requires: `stablecoinBalance`
745
+
746
+ Uses QuickNode custom RPC method `qn_getWalletStablecoinBalances`.
747
+
748
+ #### `kit.getStablecoinBalance(options)`
749
+
750
+ ```ts
751
+ const balances = await kit.getStablecoinBalance({
752
+ walletAddress: 'WALLET_ADDRESS',
753
+ chains: ['solana', 'ethereum', 'base'],
754
+ });
755
+
756
+ console.log(balances.walletAddress);
757
+ console.log(balances.totalUsdValue);
758
+
759
+ for (const balance of balances.balances) {
760
+ console.log(balance.chain, balance.symbol, balance.balance, balance.usdValue);
761
+ }
762
+ ```
763
+
764
+ ### OpenOcean
765
+
766
+ Requires: `openocean`
767
+
768
+ The SDK uses REST paths under:
769
+
770
+ ```txt
771
+ /openocean/v4/solana/quote
772
+ /openocean/v4/solana/swap_quote
773
+ ```
774
+
775
+ #### `kit.getOpenOceanQuote(options)`
776
+
777
+ ```ts
778
+ const quote = await kit.getOpenOceanQuote({
779
+ inTokenAddress: 'So11111111111111111111111111111111111111112',
780
+ outTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
781
+ amount: '1000000000',
782
+ slippage: 1,
783
+ });
784
+
785
+ console.log(quote.inAmount);
786
+ console.log(quote.outAmount);
787
+ console.log(quote.minOutAmount);
788
+ console.log(quote.priceImpact);
789
+ ```
790
+
791
+ #### `kit.openOceanSwap(options)`
792
+
793
+ Like the Metis integration, this fetches a serialized transaction, signs locally, sends, then confirms.
794
+
795
+ ```ts
796
+ import bs58 from 'bs58';
797
+ import { Keypair } from '@solana/web3.js';
798
+
799
+ const signer = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_PRIVATE_KEY!));
800
+
801
+ const result = await kit.openOceanSwap({
802
+ inTokenAddress: 'So11111111111111111111111111111111111111112',
803
+ outTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
804
+ amount: '10000000',
805
+ slippage: 1,
806
+ userAddress: signer.publicKey.toString(),
807
+ signer,
808
+ });
809
+
810
+ console.log(result.signature);
811
+ console.log(result.inAmount);
812
+ console.log(result.outAmount);
813
+ ```
814
+
815
+ #### `OO_TOKENS`
816
+
817
+ ```ts
818
+ import { OO_TOKENS } from 'quicknode-solana-kit';
819
+
820
+ console.log(OO_TOKENS.SOL);
821
+ console.log(OO_TOKENS.USDC);
822
+ console.log(OO_TOKENS.USDT);
823
+ console.log(OO_TOKENS.BONK);
824
+ ```
825
+
826
+ ### MEV Protection
827
+
828
+ These methods accept a base64-encoded signed transaction and submit it through the add-on provider, then confirm using a normal Solana connection.
829
+
830
+ #### `kit.sendMerkleProtectedTransaction(options)`
831
+
832
+ Requires: `merkle`
833
+
834
+ ```ts
835
+ const result = await kit.sendMerkleProtectedTransaction({
836
+ serializedTransaction: signedTxBase64,
837
+ tipLamports: 10_000,
838
+ });
839
+
840
+ console.log(result.signature);
841
+ console.log(result.provider);
842
+ console.log(result.confirmationMs);
843
+ ```
844
+
845
+ #### `kit.sendBlinkLabsTransaction(options)`
846
+
847
+ Requires: `blinklabs`
848
+
849
+ ```ts
850
+ const result = await kit.sendBlinkLabsTransaction({
851
+ serializedTransaction: signedTxBase64,
852
+ tipLamports: 5_000,
853
+ });
854
+
855
+ console.log(result.signature);
856
+ console.log(result.provider);
857
+ console.log(result.confirmationMs);
858
+ ```
859
+
860
+ ### Iris Transaction Sender
861
+
862
+ Requires: `iris`
863
+
864
+ Uses QuickNode custom RPC method `iris_sendTransaction`.
865
+
866
+ #### `kit.sendIrisTransaction(options)`
867
+
868
+ ```ts
869
+ const result = await kit.sendIrisTransaction({
870
+ serializedTransaction: signedTxBase64,
871
+ skipPreflight: false,
872
+ maxRetries: 3,
873
+ });
874
+
875
+ console.log(result.signature);
876
+ console.log(result.slot);
877
+ console.log(result.confirmationMs);
878
+ ```
879
+
880
+ ### GoldRush
881
+
882
+ Requires: `goldrush`
883
+
884
+ Uses REST paths under `/goldrush/v1`.
885
+
886
+ #### `kit.getGoldRushBalances(options)`
887
+
888
+ ```ts
889
+ const balances = await kit.getGoldRushBalances({
890
+ walletAddress: 'WALLET_ADDRESS',
891
+ chain: 'solana-mainnet',
892
+ noSpam: true,
893
+ quoteCurrency: 'USD',
894
+ });
895
+
896
+ console.log(balances.chain);
897
+ console.log(balances.address);
898
+
899
+ for (const item of balances.items) {
900
+ console.log(item.symbol, item.balance, item.usdBalance);
901
+ }
902
+ ```
903
+
904
+ #### `kit.getGoldRushTransactions(options)`
905
+
906
+ ```ts
907
+ const txs = await kit.getGoldRushTransactions({
908
+ walletAddress: 'WALLET_ADDRESS',
909
+ chain: 'solana-mainnet',
910
+ pageSize: 25,
911
+ pageNumber: 0,
912
+ });
913
+
914
+ console.log(txs.currentPage);
915
+
916
+ for (const tx of txs.items) {
917
+ console.log(tx.txHash, tx.successful, tx.value);
918
+ }
919
+ ```
920
+
921
+ ### Titan
922
+
923
+ Requires: `titan`
924
+
925
+ The SDK supports:
926
+
927
+ - point-in-time quote
928
+ - swap execution
929
+ - quote streaming over WebSocket
930
+
931
+ #### `kit.getTitanSwapQuote(options)`
932
+
933
+ ```ts
934
+ const quote = await kit.getTitanSwapQuote({
935
+ inputMint: 'So11111111111111111111111111111111111111112',
936
+ outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
937
+ amount: '1000000000',
938
+ slippageBps: 50,
939
+ });
940
+
941
+ console.log(quote.inAmount);
942
+ console.log(quote.outAmount);
943
+ console.log(quote.minOutAmount);
944
+ console.log(quote.routes);
945
+ ```
946
+
947
+ #### `kit.titanSwap(options)`
948
+
949
+ ```ts
950
+ const result = await kit.titanSwap({
951
+ inputMint: 'So11111111111111111111111111111111111111112',
952
+ outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
953
+ amount: '10000000',
954
+ slippageBps: 50,
955
+ userPublicKey: walletPublicKey,
956
+ });
957
+
958
+ console.log(result.signature);
959
+ console.log(result.inAmount);
960
+ console.log(result.outAmount);
961
+ ```
962
+
963
+ #### `kit.subscribeTitanQuotes(options, onQuote, onError?)`
964
+
965
+ ```ts
966
+ const unsubscribe = kit.subscribeTitanQuotes(
967
+ {
968
+ inputMint: 'So11111111111111111111111111111111111111112',
969
+ outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
970
+ amount: '1000000000',
971
+ slippageBps: 50,
972
+ },
973
+ (quote) => {
974
+ console.log('quote', quote.outAmount, quote.priceImpactPct);
975
+ },
976
+ (err) => {
977
+ console.error(err);
978
+ },
979
+ );
980
+
981
+ setTimeout(() => unsubscribe(), 15_000);
982
+ ```
983
+
984
+ ### Scorechain
985
+
986
+ Requires: `scorechain`
987
+
988
+ Uses REST path `/scorechain/v1/risk`.
989
+
990
+ #### `kit.assessWalletRisk(options)`
991
+
992
+ ```ts
993
+ const assessment = await kit.assessWalletRisk({
994
+ address: 'WALLET_ADDRESS',
995
+ network: 'solana',
996
+ });
997
+
998
+ console.log(assessment.address);
999
+ console.log(assessment.riskScore);
1000
+ console.log(assessment.riskLevel);
1001
+ console.log(assessment.amlStatus);
1002
+ console.log(assessment.flags);
1003
+ console.log(assessment.reportUrl);
1004
+ ```
1005
+
1006
+ #### `kit.isWalletSafe(address)`
1007
+
1008
+ Returns `true` only when:
1009
+
1010
+ - `amlStatus === 'clean'`
1011
+ - `riskLevel === 'low'`
1012
+
1013
+ ```ts
1014
+ const safe = await kit.isWalletSafe('WALLET_ADDRESS');
1015
+ console.log(safe);
1016
+ ```
372
1017
 
373
1018
  ## Error Handling
374
1019
 
375
- Every error is typed and tells you exactly what went wrong and how to fix it.
1020
+ The package exports custom errors:
1021
+
1022
+ - `AddOnNotEnabledError`
1023
+ - `TransactionFailedError`
1024
+ - `TransactionTimeoutError`
1025
+ - `MaxRetriesExceededError`
1026
+ - `InvalidEndpointError`
1027
+ - `RPCError`
1028
+
1029
+ Example:
376
1030
 
377
1031
  ```ts
378
1032
  import {
379
1033
  AddOnNotEnabledError,
1034
+ RPCError,
380
1035
  TransactionFailedError,
381
- TransactionTimeoutError,
382
1036
  MaxRetriesExceededError,
383
- RPCError,
384
- } from '@quicknode/solana-kit';
1037
+ } from 'quicknode-solana-kit';
385
1038
 
386
1039
  try {
387
1040
  await kit.sendSmartTransaction({ transaction, signer });
388
1041
  } catch (err) {
389
1042
  if (err instanceof AddOnNotEnabledError) {
390
- // Clear message with link to enable the add-on in the dashboard
391
- console.error(err.message);
1043
+ console.error('Enable the missing add-on in QuickNode and update kit config.');
392
1044
  } else if (err instanceof TransactionFailedError) {
393
- // On-chain failure check logs
394
- console.error('Failed on-chain:', err.reason);
395
- console.error('Explorer:', `https://explorer.solana.com/tx/${err.signature}`);
396
- } else if (err instanceof TransactionTimeoutError) {
397
- console.error('Timed out. Try a higher feeLevel.');
1045
+ console.error('On-chain failure:', err.signature, err.reason);
398
1046
  } else if (err instanceof MaxRetriesExceededError) {
399
- console.error(`Failed after ${err.maxRetries} retries.`);
1047
+ console.error('Retries exhausted:', err.maxRetries);
400
1048
  } else if (err instanceof RPCError) {
401
- console.error(`RPC ${err.statusCode}:`, err.message);
1049
+ console.error('RPC error:', err.statusCode, err.message);
1050
+ } else {
1051
+ console.error(err);
402
1052
  }
403
1053
  }
404
1054
  ```
405
1055
 
406
- ---
1056
+ ## Examples Included In The Package
1057
+
1058
+ Run the examples from the package folder:
1059
+
1060
+ ```bash
1061
+ npm run example:tx
1062
+ npm run example:nft
1063
+ npm run example:stream
1064
+ npm run example:swap
1065
+ npm run example:all
1066
+ ```
1067
+
1068
+ Environment variables used by the examples:
1069
+
1070
+ ```bash
1071
+ QN_ENDPOINT_URL=
1072
+ WALLET_PRIVATE_KEY=
1073
+ WALLET_ADDRESS=
1074
+ ADDON_PRIORITY_FEES=true
1075
+ ADDON_DAS=true
1076
+ ADDON_METIS=true
1077
+ EXECUTE_SWAP=false
1078
+ ```
407
1079
 
408
- ## Tree-Shaking
1080
+ ## Minimal Examples
409
1081
 
410
- Import only what you need for smaller bundles:
1082
+ ### Minimal client
411
1083
 
412
1084
  ```ts
413
- // Individual function imports (fully tree-shakeable)
414
- import { estimatePriorityFees } from '@quicknode/solana-kit';
415
- import { getAssetsByOwner } from '@quicknode/solana-kit';
416
- import { watchAccount } from '@quicknode/solana-kit';
417
- import { swap, TOKENS } from '@quicknode/solana-kit';
1085
+ import { QNSolanaKit } from 'quicknode-solana-kit';
1086
+
1087
+ const kit = new QNSolanaKit({
1088
+ endpointUrl: process.env.QN_ENDPOINT_URL!,
1089
+ });
418
1090
  ```
419
1091
 
420
- ---
1092
+ ### Minimal fee estimate
421
1093
 
422
- ## Running the Examples
1094
+ ```ts
1095
+ const fees = await kit.estimatePriorityFees();
1096
+ console.log(fees.recommended);
1097
+ ```
423
1098
 
424
- ```bash
425
- # Clone and install
426
- git clone https://github.com/quiknode-labs/qn-solana-kit
427
- cd qn-solana-kit
428
- npm install
1099
+ ### Minimal NFT query
429
1100
 
430
- # Setup environment
431
- cp .env.example .env
432
- # Fill in QN_ENDPOINT_URL (required)
433
- # Fill in WALLET_ADDRESS and WALLET_PRIVATE_KEY for tx/swap examples
1101
+ ```ts
1102
+ const assets = await kit.getAssetsByOwner({
1103
+ ownerAddress: 'WALLET_ADDRESS',
1104
+ });
434
1105
 
435
- # Check which add-ons are active on your endpoint
436
- npm run check
1106
+ console.log(assets.items.length);
1107
+ ```
437
1108
 
438
- # Run individual examples
439
- npm run example:tx # Smart transaction (needs Priority Fee API add-on)
440
- npm run example:nft # NFT queries (needs DAS API add-on)
441
- npm run example:stream # Live streaming (works on free tier)
442
- npm run example:swap # Jupiter swap quote (needs Metis add-on)
1109
+ ### Minimal swap quote
443
1110
 
444
- # Run all
445
- npm run example:all
1111
+ ```ts
1112
+ import { TOKENS } from 'quicknode-solana-kit';
1113
+
1114
+ const quote = await kit.getSwapQuote({
1115
+ inputMint: TOKENS.SOL,
1116
+ outputMint: TOKENS.USDC,
1117
+ amount: BigInt(1_000_000_000),
1118
+ });
1119
+
1120
+ console.log(quote.outAmount);
446
1121
  ```
447
1122
 
1123
+ ## Notes and Current Limitations
448
1124
 
449
- ## Links
1125
+ - `yellowstone` is exposed in config and add-on checks, but account streaming currently falls back to standard Solana WebSockets.
1126
+ - `liljit` is probed by `checkAddOns()`, but `sendSmartTransaction()` does not currently route through Jito bundles yet.
1127
+ - `sendSmartTransaction()` works without `priorityFees`, but falls back to a default compute unit price.
1128
+ - some add-ons return serialized transactions; the SDK signs and sends those locally using `@solana/web3.js`
1129
+
1130
+ ## Import Patterns
1131
+
1132
+ Class-based usage:
1133
+
1134
+ ```ts
1135
+ import { QNSolanaKit } from 'quicknode-solana-kit';
1136
+ ```
1137
+
1138
+ Function-level usage:
1139
+
1140
+ ```ts
1141
+ import {
1142
+ estimatePriorityFees,
1143
+ getAssetsByOwner,
1144
+ getSwapQuote,
1145
+ swap,
1146
+ watchAccount,
1147
+ TOKENS,
1148
+ OO_TOKENS,
1149
+ } from 'quicknode-solana-kit';
1150
+ ```
450
1151
 
451
- - QuickNode Dashboard: https://dashboard.quicknode.com
452
- - Add-ons Marketplace: https://marketplace.quicknode.com
453
- - Priority Fee API: https://www.quicknode.com/docs/solana/qn_estimatePriorityFees
454
- - Metaplex DAS API: https://www.quicknode.com/docs/solana/getAsset
455
- - Metis (Jupiter): https://marketplace.quicknode.com/add-ons/metis-jupiter-v6-swap-api
456
- - Yellowstone gRPC: https://marketplace.quicknode.com/add-ons/yellowstone-grpc
1152
+ ## License
457
1153
 
458
- ---
1154
+ MIT