quicknode-solana-kit 1.0.2 → 1.0.4
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 +1236 -250
- package/dist/addons.d.ts.map +1 -1
- package/dist/addons.js +190 -0
- package/dist/addons.js.map +1 -1
- package/dist/goldrush/index.d.ts +10 -0
- package/dist/goldrush/index.d.ts.map +1 -0
- package/dist/goldrush/index.js +37 -0
- package/dist/goldrush/index.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -2
- package/dist/index.js.map +1 -1
- package/dist/iris/index.d.ts +3 -0
- package/dist/iris/index.d.ts.map +1 -0
- package/dist/iris/index.js +29 -0
- package/dist/iris/index.js.map +1 -0
- package/dist/mev/index.d.ts +4 -0
- package/dist/mev/index.d.ts.map +1 -0
- package/dist/mev/index.js +52 -0
- package/dist/mev/index.js.map +1 -0
- package/dist/openocean/index.d.ts +13 -0
- package/dist/openocean/index.d.ts.map +1 -0
- package/dist/openocean/index.js +63 -0
- package/dist/openocean/index.js.map +1 -0
- package/dist/pumpfun/index.d.ts +7 -0
- package/dist/pumpfun/index.d.ts.map +1 -0
- package/dist/pumpfun/index.js +54 -0
- package/dist/pumpfun/index.js.map +1 -0
- package/dist/scorechain/index.d.ts +4 -0
- package/dist/scorechain/index.d.ts.map +1 -0
- package/dist/scorechain/index.js +26 -0
- package/dist/scorechain/index.js.map +1 -0
- package/dist/stablecoin/index.d.ts +3 -0
- package/dist/stablecoin/index.d.ts.map +1 -0
- package/dist/stablecoin/index.js +16 -0
- package/dist/stablecoin/index.js.map +1 -0
- package/dist/titan/index.d.ts +5 -0
- package/dist/titan/index.d.ts.map +1 -0
- package/dist/titan/index.js +119 -0
- package/dist/titan/index.js.map +1 -0
- package/dist/types/index.d.ts +234 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/addon-guard.d.ts.map +1 -1
- package/dist/utils/addon-guard.js +47 -0
- package/dist/utils/addon-guard.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,458 +1,1444 @@
|
|
|
1
1
|
# quicknode-solana-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Typed Solana SDK for QuickNode endpoints and QuickNode-powered add-ons.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package gives you one place to work with:
|
|
6
|
+
|
|
7
|
+
- standard Solana RPC
|
|
8
|
+
- standard Solana WebSocket subscriptions
|
|
9
|
+
- QuickNode custom JSON-RPC methods
|
|
10
|
+
- QuickNode REST add-ons mounted on the same endpoint
|
|
11
|
+
|
|
12
|
+
If your current Solana setup looks like this:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { Connection } from '@solana/web3.js';
|
|
16
|
+
|
|
17
|
+
const connection = new Connection(
|
|
18
|
+
'https://your-endpoint.quiknode.pro/TOKEN/',
|
|
19
|
+
'confirmed',
|
|
20
|
+
);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
then `quicknode-solana-kit` is the layer on top of that.
|
|
24
|
+
|
|
25
|
+
It still uses a normal Solana `Connection`, but adds typed helper methods for common QuickNode add-ons and transaction workflows.
|
|
6
26
|
|
|
7
27
|
```bash
|
|
8
28
|
npm install quicknode-solana-kit
|
|
9
29
|
```
|
|
10
30
|
|
|
11
|
-
|
|
31
|
+
## What This Package Is
|
|
32
|
+
|
|
33
|
+
This package is a wrapper around three patterns:
|
|
34
|
+
|
|
35
|
+
1. normal Solana `Connection` calls from `@solana/web3.js`
|
|
36
|
+
2. QuickNode custom RPC methods such as `qn_estimatePriorityFees`
|
|
37
|
+
3. QuickNode REST endpoints such as `/jupiter/v6/quote`
|
|
38
|
+
|
|
39
|
+
It does not replace Solana RPC. It organizes it.
|
|
12
40
|
|
|
13
|
-
|
|
41
|
+
You get:
|
|
14
42
|
|
|
15
|
-
|
|
43
|
+
- `kit.connection` for normal Solana calls
|
|
44
|
+
- `kit.someMethod()` for QuickNode helper methods
|
|
16
45
|
|
|
17
|
-
|
|
46
|
+
Example:
|
|
18
47
|
|
|
19
|
-
**Without this SDK:**
|
|
20
48
|
```ts
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// - confirm and return useful data
|
|
49
|
+
import { QNSolanaKit } from 'quicknode-solana-kit';
|
|
50
|
+
|
|
51
|
+
const kit = new QNSolanaKit({
|
|
52
|
+
endpointUrl: 'https://your-endpoint.quiknode.pro/TOKEN/',
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const slot = await kit.connection.getSlot();
|
|
56
|
+
console.log(slot);
|
|
30
57
|
```
|
|
31
58
|
|
|
32
|
-
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install quicknode-solana-kit
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Requirements:
|
|
66
|
+
|
|
67
|
+
- Node.js 18+
|
|
68
|
+
- a QuickNode Solana endpoint
|
|
69
|
+
|
|
70
|
+
## Quick Start
|
|
71
|
+
|
|
72
|
+
### 1. Create the kit
|
|
73
|
+
|
|
33
74
|
```ts
|
|
34
|
-
|
|
35
|
-
|
|
75
|
+
import { QNSolanaKit } from 'quicknode-solana-kit';
|
|
76
|
+
|
|
77
|
+
const kit = new QNSolanaKit({
|
|
78
|
+
endpointUrl: 'https://your-endpoint.quiknode.pro/TOKEN/',
|
|
79
|
+
commitment: 'confirmed',
|
|
80
|
+
timeout: 30_000,
|
|
81
|
+
addOns: {
|
|
82
|
+
priorityFees: true,
|
|
83
|
+
das: true,
|
|
84
|
+
metis: false,
|
|
85
|
+
yellowstone: false,
|
|
86
|
+
liljit: false,
|
|
87
|
+
pumpfun: false,
|
|
88
|
+
stablecoinBalance: false,
|
|
89
|
+
openocean: false,
|
|
90
|
+
merkle: false,
|
|
91
|
+
blinklabs: false,
|
|
92
|
+
iris: false,
|
|
93
|
+
goldrush: false,
|
|
94
|
+
titan: false,
|
|
95
|
+
scorechain: false,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
36
98
|
```
|
|
37
99
|
|
|
38
|
-
|
|
100
|
+
### 2. Use normal Solana methods
|
|
39
101
|
|
|
40
|
-
|
|
102
|
+
```ts
|
|
103
|
+
import { PublicKey } from '@solana/web3.js';
|
|
41
104
|
|
|
42
|
-
|
|
43
|
-
- A QuickNode Solana endpoint → **free at [dashboard.quicknode.com](https://dashboard.quicknode.com)**
|
|
105
|
+
const wallet = new PublicKey('E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk');
|
|
44
106
|
|
|
45
|
-
|
|
107
|
+
const balance = await kit.connection.getBalance(wallet);
|
|
108
|
+
const slot = await kit.connection.getSlot();
|
|
109
|
+
const blockhash = await kit.connection.getLatestBlockhash();
|
|
46
110
|
|
|
47
|
-
|
|
111
|
+
console.log(balance, slot, blockhash.blockhash);
|
|
112
|
+
```
|
|
48
113
|
|
|
49
|
-
###
|
|
114
|
+
### 3. Use kit helper methods
|
|
50
115
|
|
|
51
|
-
```
|
|
52
|
-
|
|
116
|
+
```ts
|
|
117
|
+
const tokenAccounts = await kit.getTokenAccounts(wallet.toString());
|
|
118
|
+
console.log(tokenAccounts.length);
|
|
53
119
|
```
|
|
54
120
|
|
|
55
|
-
###
|
|
121
|
+
### 4. Check which add-ons are live
|
|
56
122
|
|
|
57
|
-
|
|
58
|
-
|
|
123
|
+
```ts
|
|
124
|
+
const status = await kit.checkAddOns();
|
|
125
|
+
console.log(status.addOns);
|
|
126
|
+
console.log(status.canUse);
|
|
59
127
|
```
|
|
60
|
-
|
|
128
|
+
|
|
129
|
+
CLI:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm run check
|
|
61
133
|
```
|
|
62
134
|
|
|
63
|
-
|
|
135
|
+
## Can You Still Use Built-In Solana `Connection` Methods?
|
|
136
|
+
|
|
137
|
+
Yes.
|
|
64
138
|
|
|
65
|
-
|
|
66
|
-
- Enable **Priority Fee API** (free) → unlocks `estimatePriorityFees()` + auto-fees in `sendSmartTransaction()`
|
|
67
|
-
- Enable **Metaplex DAS API** (free) → unlocks all NFT query methods
|
|
139
|
+
This is one of the most important points in the whole package.
|
|
68
140
|
|
|
69
|
-
|
|
141
|
+
`kit.connection` is a real `Connection` instance from `@solana/web3.js`.
|
|
142
|
+
|
|
143
|
+
That means you can still use methods like:
|
|
70
144
|
|
|
71
145
|
```ts
|
|
72
|
-
|
|
146
|
+
const version = await kit.connection.getVersion();
|
|
147
|
+
const slot = await kit.connection.getSlot();
|
|
148
|
+
const balance = await kit.connection.getBalance(walletPublicKey);
|
|
149
|
+
const blockhash = await kit.connection.getLatestBlockhash();
|
|
150
|
+
const tx = await kit.connection.getTransaction(signature, {
|
|
151
|
+
maxSupportedTransactionVersion: 0,
|
|
152
|
+
});
|
|
153
|
+
```
|
|
73
154
|
|
|
74
|
-
|
|
75
|
-
|
|
155
|
+
So the mental model is:
|
|
156
|
+
|
|
157
|
+
- `kit.connection` = normal Solana SDK access
|
|
158
|
+
- `kit.someMethod()` = helper wrapper provided by this package
|
|
159
|
+
|
|
160
|
+
## Add-On Model
|
|
161
|
+
|
|
162
|
+
Some methods work without add-ons.
|
|
163
|
+
|
|
164
|
+
Some methods require a specific QuickNode add-on.
|
|
165
|
+
|
|
166
|
+
This package handles add-ons in two ways:
|
|
167
|
+
|
|
168
|
+
### 1. Local config guard
|
|
169
|
+
|
|
170
|
+
You tell the SDK what you believe is enabled:
|
|
76
171
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
172
|
+
```ts
|
|
173
|
+
const kit = new QNSolanaKit({
|
|
174
|
+
endpointUrl: process.env.QN_ENDPOINT_URL!,
|
|
80
175
|
addOns: {
|
|
81
|
-
priorityFees: true,
|
|
82
|
-
das:
|
|
83
|
-
metis:
|
|
84
|
-
liljit: false, // PAID — Lil' JIT (Jito bundles)
|
|
85
|
-
yellowstone: false, // PAID — Yellowstone gRPC
|
|
176
|
+
priorityFees: true,
|
|
177
|
+
das: true,
|
|
178
|
+
metis: false,
|
|
86
179
|
},
|
|
87
180
|
});
|
|
88
181
|
```
|
|
89
182
|
|
|
90
|
-
|
|
183
|
+
If you explicitly set an add-on to `false` and call a method that needs it, the SDK throws an `AddOnNotEnabledError`.
|
|
91
184
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
185
|
+
If a value is left `undefined`, the SDK warns and still attempts the network call.
|
|
186
|
+
|
|
187
|
+
### 2. Real endpoint probe
|
|
188
|
+
|
|
189
|
+
`checkAddOns()` performs real test calls to your endpoint and tells you what is actually live.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
const result = await kit.checkAddOns();
|
|
193
|
+
|
|
194
|
+
console.log(result.canUse.smartTransactions);
|
|
195
|
+
console.log(result.canUse.nftQueries);
|
|
196
|
+
console.log(result.canUse.swaps);
|
|
197
|
+
console.log(result.canUse.goldRushData);
|
|
198
|
+
console.log(result.canUse.riskAssessment);
|
|
95
199
|
```
|
|
96
200
|
|
|
97
|
-
|
|
201
|
+
## How This SDK Talks To QuickNode
|
|
202
|
+
|
|
203
|
+
There are three backend styles used in this package.
|
|
204
|
+
|
|
205
|
+
### 1. Standard Solana RPC
|
|
206
|
+
|
|
207
|
+
Example:
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
await kit.connection.getBalance(pubkey);
|
|
98
211
|
```
|
|
99
|
-
@quicknode/solana-kit — Add-on Status
|
|
100
|
-
──────────────────────────────────────────────────────
|
|
101
|
-
Endpoint: https://your-name.solana-mainnet.quiknode.pro...
|
|
102
212
|
|
|
103
|
-
|
|
104
|
-
enabled — Dynamic priority fee estimation for faster tx inclusion
|
|
213
|
+
### 2. QuickNode Custom JSON-RPC
|
|
105
214
|
|
|
106
|
-
|
|
107
|
-
enabled — Query NFTs, compressed NFTs, token metadata
|
|
215
|
+
Example:
|
|
108
216
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
217
|
+
```ts
|
|
218
|
+
await kit.estimatePriorityFees();
|
|
219
|
+
```
|
|
112
220
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
221
|
+
Internally, that becomes a JSON-RPC request similar to:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"jsonrpc": "2.0",
|
|
226
|
+
"id": 1,
|
|
227
|
+
"method": "qn_estimatePriorityFees",
|
|
228
|
+
"params": {
|
|
229
|
+
"last_n_blocks": 100,
|
|
230
|
+
"api_version": 2
|
|
231
|
+
}
|
|
232
|
+
}
|
|
120
233
|
```
|
|
121
234
|
|
|
122
|
-
|
|
235
|
+
### 3. QuickNode REST Add-On Route
|
|
236
|
+
|
|
237
|
+
Example:
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
await kit.getSwapQuote({
|
|
241
|
+
inputMint: TOKENS.SOL,
|
|
242
|
+
outputMint: TOKENS.USDC,
|
|
243
|
+
amount: BigInt(1_000_000_000),
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Internally, that calls a route like:
|
|
248
|
+
|
|
249
|
+
```txt
|
|
250
|
+
https://your-endpoint.quiknode.pro/TOKEN/jupiter/v6/quote?...
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Full Method Count
|
|
254
|
+
|
|
255
|
+
The `QNSolanaKit` class currently exposes **33 methods**.
|
|
256
|
+
|
|
257
|
+
They are:
|
|
258
|
+
|
|
259
|
+
1. `checkAddOns()`
|
|
260
|
+
2. `sendSmartTransaction()`
|
|
261
|
+
3. `prepareSmartTransaction()`
|
|
262
|
+
4. `estimatePriorityFees()`
|
|
263
|
+
5. `getAssetsByOwner()`
|
|
264
|
+
6. `getAsset()`
|
|
265
|
+
7. `getAssetsByCollection()`
|
|
266
|
+
8. `searchAssets()`
|
|
267
|
+
9. `getAssetProof()`
|
|
268
|
+
10. `getTokenAccounts()`
|
|
269
|
+
11. `watchAccount()`
|
|
270
|
+
12. `watchProgram()`
|
|
271
|
+
13. `watchSlot()`
|
|
272
|
+
14. `getSwapQuote()`
|
|
273
|
+
15. `swap()`
|
|
274
|
+
16. `getPumpFunTokens()`
|
|
275
|
+
17. `getPumpFunToken()`
|
|
276
|
+
18. `getPumpFunTokensByCreator()`
|
|
277
|
+
19. `getPumpFunTokenHolders()`
|
|
278
|
+
20. `getPumpFunTokenTrades()`
|
|
279
|
+
21. `getStablecoinBalance()`
|
|
280
|
+
22. `getOpenOceanQuote()`
|
|
281
|
+
23. `openOceanSwap()`
|
|
282
|
+
24. `sendMerkleProtectedTransaction()`
|
|
283
|
+
25. `sendBlinkLabsTransaction()`
|
|
284
|
+
26. `sendIrisTransaction()`
|
|
285
|
+
27. `getGoldRushBalances()`
|
|
286
|
+
28. `getGoldRushTransactions()`
|
|
287
|
+
29. `getTitanSwapQuote()`
|
|
288
|
+
30. `titanSwap()`
|
|
289
|
+
31. `subscribeTitanQuotes()`
|
|
290
|
+
32. `assessWalletRisk()`
|
|
291
|
+
33. `isWalletSafe()`
|
|
292
|
+
|
|
293
|
+
Also important:
|
|
294
|
+
|
|
295
|
+
- `kit.connection` is a property, not a method
|
|
296
|
+
- but it gives you access to normal Solana `Connection` methods
|
|
297
|
+
|
|
298
|
+
## Add-On Requirements Table
|
|
299
|
+
|
|
300
|
+
| Method | What it does | Add-on needed? | Add-on name |
|
|
301
|
+
|---|---|---|---|
|
|
302
|
+
| `checkAddOns()` | probes endpoint capabilities | No | none |
|
|
303
|
+
| `sendSmartTransaction()` | sends a tx with fee/compute helpers | No, but better with add-on | `priorityFees` recommended |
|
|
304
|
+
| `prepareSmartTransaction()` | prepares a tx with fee/compute helpers | No, but better with add-on | `priorityFees` recommended |
|
|
305
|
+
| `estimatePriorityFees()` | gets live priority fee estimates | Yes | `priorityFees` |
|
|
306
|
+
| `getAssetsByOwner()` | gets wallet assets | Yes | `das` |
|
|
307
|
+
| `getAsset()` | gets one digital asset | Yes | `das` |
|
|
308
|
+
| `getAssetsByCollection()` | gets assets by collection | Yes | `das` |
|
|
309
|
+
| `searchAssets()` | searches digital assets | Yes | `das` |
|
|
310
|
+
| `getAssetProof()` | gets compressed NFT proof | Yes | `das` |
|
|
311
|
+
| `getTokenAccounts()` | gets SPL token accounts | No | none |
|
|
312
|
+
| `watchAccount()` | watches one account | No | none |
|
|
313
|
+
| `watchProgram()` | watches program logs | No | none |
|
|
314
|
+
| `watchSlot()` | watches slot changes | No | none |
|
|
315
|
+
| `getSwapQuote()` | gets Jupiter quote | Yes | `metis` |
|
|
316
|
+
| `swap()` | performs Jupiter swap | Yes | `metis` |
|
|
317
|
+
| `getPumpFunTokens()` | gets recent pump.fun tokens | Yes | `pumpfun` |
|
|
318
|
+
| `getPumpFunToken()` | gets one pump.fun token | Yes | `pumpfun` |
|
|
319
|
+
| `getPumpFunTokensByCreator()` | gets pump.fun tokens by creator | Yes | `pumpfun` |
|
|
320
|
+
| `getPumpFunTokenHolders()` | gets token holders | Yes | `pumpfun` |
|
|
321
|
+
| `getPumpFunTokenTrades()` | gets recent token trades | Yes | `pumpfun` |
|
|
322
|
+
| `getStablecoinBalance()` | gets stablecoin balances across chains | Yes | `stablecoinBalance` |
|
|
323
|
+
| `getOpenOceanQuote()` | gets OpenOcean quote | Yes | `openocean` |
|
|
324
|
+
| `openOceanSwap()` | performs OpenOcean swap | Yes | `openocean` |
|
|
325
|
+
| `sendMerkleProtectedTransaction()` | sends tx through Merkle | Yes | `merkle` |
|
|
326
|
+
| `sendBlinkLabsTransaction()` | sends tx through Blink Labs | Yes | `blinklabs` |
|
|
327
|
+
| `sendIrisTransaction()` | sends tx through Iris | Yes | `iris` |
|
|
328
|
+
| `getGoldRushBalances()` | gets balances through GoldRush | Yes | `goldrush` |
|
|
329
|
+
| `getGoldRushTransactions()` | gets tx history through GoldRush | Yes | `goldrush` |
|
|
330
|
+
| `getTitanSwapQuote()` | gets Titan quote | Yes | `titan` |
|
|
331
|
+
| `titanSwap()` | performs Titan swap | Yes | `titan` |
|
|
332
|
+
| `subscribeTitanQuotes()` | subscribes to Titan quote stream | Yes | `titan` |
|
|
333
|
+
| `assessWalletRisk()` | gets Scorechain risk report | Yes | `scorechain` |
|
|
334
|
+
| `isWalletSafe()` | returns simple safe/unsafe boolean | Yes | `scorechain` |
|
|
335
|
+
|
|
336
|
+
## Which Features Need No Add-On?
|
|
337
|
+
|
|
338
|
+
These work without add-ons:
|
|
339
|
+
|
|
340
|
+
- `checkAddOns()`
|
|
341
|
+
- `sendSmartTransaction()` with fallback behavior
|
|
342
|
+
- `prepareSmartTransaction()` with fallback behavior
|
|
343
|
+
- `getTokenAccounts()`
|
|
344
|
+
- `watchAccount()`
|
|
345
|
+
- `watchProgram()`
|
|
346
|
+
- `watchSlot()`
|
|
347
|
+
- all built-in `kit.connection.*` methods
|
|
348
|
+
|
|
349
|
+
## Which Add-On Unlocks What?
|
|
350
|
+
|
|
351
|
+
### `priorityFees`
|
|
352
|
+
|
|
353
|
+
Unlocks:
|
|
354
|
+
|
|
355
|
+
- `estimatePriorityFees()`
|
|
356
|
+
- improved `sendSmartTransaction()`
|
|
357
|
+
- improved `prepareSmartTransaction()`
|
|
358
|
+
|
|
359
|
+
### `das`
|
|
360
|
+
|
|
361
|
+
Unlocks:
|
|
362
|
+
|
|
363
|
+
- `getAssetsByOwner()`
|
|
364
|
+
- `getAsset()`
|
|
365
|
+
- `getAssetsByCollection()`
|
|
366
|
+
- `searchAssets()`
|
|
367
|
+
- `getAssetProof()`
|
|
368
|
+
|
|
369
|
+
### `metis`
|
|
370
|
+
|
|
371
|
+
Unlocks:
|
|
372
|
+
|
|
373
|
+
- `getSwapQuote()`
|
|
374
|
+
- `swap()`
|
|
375
|
+
|
|
376
|
+
### `pumpfun`
|
|
377
|
+
|
|
378
|
+
Unlocks:
|
|
379
|
+
|
|
380
|
+
- `getPumpFunTokens()`
|
|
381
|
+
- `getPumpFunToken()`
|
|
382
|
+
- `getPumpFunTokensByCreator()`
|
|
383
|
+
- `getPumpFunTokenHolders()`
|
|
384
|
+
- `getPumpFunTokenTrades()`
|
|
385
|
+
|
|
386
|
+
### `stablecoinBalance`
|
|
387
|
+
|
|
388
|
+
Unlocks:
|
|
389
|
+
|
|
390
|
+
- `getStablecoinBalance()`
|
|
391
|
+
|
|
392
|
+
### `openocean`
|
|
393
|
+
|
|
394
|
+
Unlocks:
|
|
395
|
+
|
|
396
|
+
- `getOpenOceanQuote()`
|
|
397
|
+
- `openOceanSwap()`
|
|
398
|
+
|
|
399
|
+
### `merkle`
|
|
400
|
+
|
|
401
|
+
Unlocks:
|
|
123
402
|
|
|
124
|
-
|
|
403
|
+
- `sendMerkleProtectedTransaction()`
|
|
125
404
|
|
|
126
|
-
|
|
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 |
|
|
405
|
+
### `blinklabs`
|
|
133
406
|
|
|
134
|
-
|
|
135
|
-
WebSocket streaming (`watchAccount`, `watchProgram`, `watchSlot`) works out of the box with no add-ons.
|
|
407
|
+
Unlocks:
|
|
136
408
|
|
|
137
|
-
|
|
409
|
+
- `sendBlinkLabsTransaction()`
|
|
410
|
+
|
|
411
|
+
### `iris`
|
|
412
|
+
|
|
413
|
+
Unlocks:
|
|
414
|
+
|
|
415
|
+
- `sendIrisTransaction()`
|
|
416
|
+
|
|
417
|
+
### `goldrush`
|
|
418
|
+
|
|
419
|
+
Unlocks:
|
|
420
|
+
|
|
421
|
+
- `getGoldRushBalances()`
|
|
422
|
+
- `getGoldRushTransactions()`
|
|
423
|
+
|
|
424
|
+
### `titan`
|
|
425
|
+
|
|
426
|
+
Unlocks:
|
|
427
|
+
|
|
428
|
+
- `getTitanSwapQuote()`
|
|
429
|
+
- `titanSwap()`
|
|
430
|
+
- `subscribeTitanQuotes()`
|
|
431
|
+
|
|
432
|
+
### `scorechain`
|
|
433
|
+
|
|
434
|
+
Unlocks:
|
|
435
|
+
|
|
436
|
+
- `assessWalletRisk()`
|
|
437
|
+
- `isWalletSafe()`
|
|
138
438
|
|
|
139
439
|
## API Reference
|
|
140
440
|
|
|
141
|
-
### `
|
|
441
|
+
### `checkAddOns()`
|
|
442
|
+
|
|
443
|
+
Checks which add-ons are actually enabled on your endpoint.
|
|
142
444
|
|
|
143
|
-
|
|
445
|
+
Add-on required: none
|
|
144
446
|
|
|
145
447
|
```ts
|
|
448
|
+
const result = await kit.checkAddOns();
|
|
449
|
+
|
|
450
|
+
console.log(result.addOns);
|
|
451
|
+
console.log(result.canUse.smartTransactions);
|
|
452
|
+
console.log(result.canUse.nftQueries);
|
|
453
|
+
console.log(result.canUse.swaps);
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
How it works:
|
|
457
|
+
|
|
458
|
+
- performs real probe calls to your endpoint
|
|
459
|
+
- tests both RPC-based and REST-based add-ons
|
|
460
|
+
- returns a structured capability report
|
|
461
|
+
|
|
462
|
+
### `sendSmartTransaction({ transaction, signer, options })`
|
|
463
|
+
|
|
464
|
+
Sends a transaction with helper logic for compute units, priority fees, and retry behavior.
|
|
465
|
+
|
|
466
|
+
Add-on required: none, but `priorityFees` is strongly recommended
|
|
467
|
+
|
|
468
|
+
```ts
|
|
469
|
+
import bs58 from 'bs58';
|
|
470
|
+
import {
|
|
471
|
+
Keypair,
|
|
472
|
+
LAMPORTS_PER_SOL,
|
|
473
|
+
SystemProgram,
|
|
474
|
+
Transaction,
|
|
475
|
+
} from '@solana/web3.js';
|
|
476
|
+
|
|
477
|
+
const signer = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_PRIVATE_KEY!));
|
|
478
|
+
|
|
479
|
+
const tx = new Transaction().add(
|
|
480
|
+
SystemProgram.transfer({
|
|
481
|
+
fromPubkey: signer.publicKey,
|
|
482
|
+
toPubkey: signer.publicKey,
|
|
483
|
+
lamports: Math.floor(0.001 * LAMPORTS_PER_SOL),
|
|
484
|
+
}),
|
|
485
|
+
);
|
|
486
|
+
|
|
146
487
|
const result = await kit.sendSmartTransaction({
|
|
147
|
-
transaction:
|
|
148
|
-
signer
|
|
488
|
+
transaction: tx,
|
|
489
|
+
signer,
|
|
149
490
|
options: {
|
|
150
|
-
feeLevel:
|
|
151
|
-
|
|
152
|
-
maxRetries:
|
|
153
|
-
|
|
491
|
+
feeLevel: 'recommended',
|
|
492
|
+
simulateFirst: true,
|
|
493
|
+
maxRetries: 5,
|
|
494
|
+
computeUnitBuffer: 10,
|
|
495
|
+
skipPreflight: false,
|
|
154
496
|
},
|
|
155
497
|
});
|
|
156
498
|
|
|
157
|
-
console.log(result.signature);
|
|
158
|
-
console.log(result.slot);
|
|
159
|
-
console.log(result.priorityFeeMicroLamports);
|
|
160
|
-
console.log(result.computeUnitsUsed);
|
|
161
|
-
console.log(result.confirmationMs);
|
|
499
|
+
console.log(result.signature);
|
|
500
|
+
console.log(result.slot);
|
|
501
|
+
console.log(result.priorityFeeMicroLamports);
|
|
502
|
+
console.log(result.computeUnitsUsed);
|
|
503
|
+
console.log(result.confirmationMs);
|
|
162
504
|
```
|
|
163
505
|
|
|
164
|
-
|
|
506
|
+
What it does internally:
|
|
507
|
+
|
|
508
|
+
1. optionally simulates the transaction
|
|
509
|
+
2. estimates compute units
|
|
510
|
+
3. tries to fetch priority fee recommendations
|
|
511
|
+
4. injects compute budget instructions
|
|
512
|
+
5. gets a blockhash
|
|
513
|
+
6. signs the transaction
|
|
514
|
+
7. sends raw transaction
|
|
515
|
+
8. confirms it
|
|
516
|
+
9. retries on failure
|
|
517
|
+
|
|
518
|
+
Important note:
|
|
519
|
+
|
|
520
|
+
- if fee estimation fails, it falls back to a default compute unit price
|
|
521
|
+
- `useJito` exists in options, but Jito routing is not currently wired into this method
|
|
165
522
|
|
|
166
|
-
### `
|
|
523
|
+
### `prepareSmartTransaction({ transaction, payer, options })`
|
|
167
524
|
|
|
168
|
-
|
|
169
|
-
|
|
525
|
+
Prepares a transaction but does not send it.
|
|
526
|
+
|
|
527
|
+
Add-on required: none, but `priorityFees` is strongly recommended
|
|
528
|
+
|
|
529
|
+
This is useful for wallet-adapter flows.
|
|
170
530
|
|
|
171
531
|
```ts
|
|
172
|
-
const
|
|
532
|
+
const prepared = await kit.prepareSmartTransaction({
|
|
173
533
|
transaction: myTx,
|
|
174
|
-
payer:
|
|
175
|
-
options:
|
|
534
|
+
payer: wallet.publicKey,
|
|
535
|
+
options: {
|
|
536
|
+
feeLevel: 'high',
|
|
537
|
+
computeUnitBuffer: 10,
|
|
538
|
+
},
|
|
176
539
|
});
|
|
177
540
|
|
|
178
|
-
|
|
179
|
-
|
|
541
|
+
console.log(prepared.priorityFeeMicroLamports);
|
|
542
|
+
console.log(prepared.computeUnits);
|
|
543
|
+
|
|
544
|
+
const sig = await wallet.sendTransaction(prepared.transaction, kit.connection);
|
|
545
|
+
console.log(sig);
|
|
180
546
|
```
|
|
181
547
|
|
|
182
|
-
|
|
548
|
+
How it works:
|
|
549
|
+
|
|
550
|
+
- gets priority fee if available
|
|
551
|
+
- adds compute budget instructions
|
|
552
|
+
- fetches a recent blockhash
|
|
553
|
+
- sets the fee payer
|
|
554
|
+
- returns the prepared transaction
|
|
555
|
+
|
|
556
|
+
### `estimatePriorityFees(options?)`
|
|
183
557
|
|
|
184
|
-
|
|
558
|
+
Gets live priority fee estimates from QuickNode.
|
|
185
559
|
|
|
186
|
-
|
|
560
|
+
Add-on required: `priorityFees`
|
|
187
561
|
|
|
188
562
|
```ts
|
|
189
563
|
const fees = await kit.estimatePriorityFees({
|
|
190
|
-
|
|
191
|
-
lastNBlocks: 100,
|
|
564
|
+
lastNBlocks: 100,
|
|
192
565
|
});
|
|
193
566
|
|
|
194
|
-
fees.low
|
|
195
|
-
fees.medium
|
|
196
|
-
fees.recommended
|
|
197
|
-
fees.high
|
|
198
|
-
fees.extreme
|
|
199
|
-
fees.networkCongestion
|
|
567
|
+
console.log(fees.low);
|
|
568
|
+
console.log(fees.medium);
|
|
569
|
+
console.log(fees.recommended);
|
|
570
|
+
console.log(fees.high);
|
|
571
|
+
console.log(fees.extreme);
|
|
572
|
+
console.log(fees.networkCongestion);
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
With account filter:
|
|
576
|
+
|
|
577
|
+
```ts
|
|
578
|
+
const fees = await kit.estimatePriorityFees({
|
|
579
|
+
account: 'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
580
|
+
lastNBlocks: 50,
|
|
581
|
+
});
|
|
200
582
|
```
|
|
201
583
|
|
|
202
|
-
|
|
584
|
+
How it works:
|
|
203
585
|
|
|
204
|
-
|
|
586
|
+
- calls QuickNode custom RPC method `qn_estimatePriorityFees`
|
|
587
|
+
- maps response to fee levels
|
|
205
588
|
|
|
206
|
-
|
|
589
|
+
### `getAssetsByOwner(options)`
|
|
590
|
+
|
|
591
|
+
Gets digital assets owned by a wallet.
|
|
592
|
+
|
|
593
|
+
Add-on required: `das`
|
|
207
594
|
|
|
208
595
|
```ts
|
|
209
|
-
const
|
|
210
|
-
ownerAddress: '
|
|
211
|
-
limit:
|
|
212
|
-
|
|
213
|
-
sortDirection: 'desc',
|
|
596
|
+
const assets = await kit.getAssetsByOwner({
|
|
597
|
+
ownerAddress: 'WALLET_ADDRESS',
|
|
598
|
+
limit: 10,
|
|
599
|
+
page: 1,
|
|
214
600
|
});
|
|
215
601
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
console.log(
|
|
220
|
-
|
|
602
|
+
console.log(assets.total);
|
|
603
|
+
|
|
604
|
+
for (const item of assets.items) {
|
|
605
|
+
console.log(item.id);
|
|
606
|
+
console.log(item.content.metadata.name);
|
|
607
|
+
console.log(item.ownership.owner);
|
|
608
|
+
console.log(item.compression?.compressed);
|
|
609
|
+
}
|
|
221
610
|
```
|
|
222
611
|
|
|
223
|
-
|
|
612
|
+
How it works:
|
|
613
|
+
|
|
614
|
+
- calls DAS RPC method `getAssetsByOwner`
|
|
615
|
+
|
|
616
|
+
### `getAsset(mintAddress)`
|
|
224
617
|
|
|
225
|
-
|
|
618
|
+
Gets one digital asset.
|
|
226
619
|
|
|
227
|
-
|
|
620
|
+
Add-on required: `das`
|
|
228
621
|
|
|
229
622
|
```ts
|
|
230
|
-
const asset = await kit.getAsset('
|
|
623
|
+
const asset = await kit.getAsset('ASSET_ID_OR_MINT');
|
|
624
|
+
|
|
625
|
+
console.log(asset.id);
|
|
231
626
|
console.log(asset.content.metadata.name);
|
|
627
|
+
console.log(asset.content.metadata.symbol);
|
|
232
628
|
console.log(asset.content.metadata.image);
|
|
233
|
-
console.log(asset.royalty?.basis_points);
|
|
234
629
|
```
|
|
235
630
|
|
|
236
|
-
|
|
631
|
+
How it works:
|
|
632
|
+
|
|
633
|
+
- calls DAS RPC method `getAsset`
|
|
634
|
+
|
|
635
|
+
### `getAssetsByCollection(options)`
|
|
237
636
|
|
|
238
|
-
|
|
637
|
+
Gets assets by collection.
|
|
239
638
|
|
|
240
|
-
|
|
639
|
+
Add-on required: `das`
|
|
241
640
|
|
|
242
641
|
```ts
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
642
|
+
const collectionAssets = await kit.getAssetsByCollection({
|
|
643
|
+
collectionMint: 'COLLECTION_MINT',
|
|
644
|
+
limit: 20,
|
|
645
|
+
page: 1,
|
|
247
646
|
});
|
|
647
|
+
|
|
648
|
+
console.log(collectionAssets.total);
|
|
248
649
|
```
|
|
249
650
|
|
|
250
|
-
|
|
651
|
+
How it works:
|
|
652
|
+
|
|
653
|
+
- calls DAS RPC method `getAssetsByGroup`
|
|
654
|
+
- uses collection grouping
|
|
655
|
+
|
|
656
|
+
### `searchAssets(options)`
|
|
251
657
|
|
|
252
|
-
|
|
658
|
+
Searches digital assets with filters.
|
|
253
659
|
|
|
254
|
-
|
|
660
|
+
Add-on required: `das`
|
|
661
|
+
|
|
662
|
+
By owner:
|
|
255
663
|
|
|
256
664
|
```ts
|
|
257
|
-
const
|
|
258
|
-
|
|
665
|
+
const result = await kit.searchAssets({
|
|
666
|
+
ownerAddress: 'WALLET_ADDRESS',
|
|
667
|
+
limit: 25,
|
|
668
|
+
});
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
By creator:
|
|
672
|
+
|
|
673
|
+
```ts
|
|
674
|
+
const result = await kit.searchAssets({
|
|
675
|
+
creatorAddress: 'CREATOR_ADDRESS',
|
|
676
|
+
limit: 25,
|
|
677
|
+
});
|
|
259
678
|
```
|
|
260
679
|
|
|
261
|
-
|
|
680
|
+
By collection:
|
|
262
681
|
|
|
263
|
-
|
|
682
|
+
```ts
|
|
683
|
+
const result = await kit.searchAssets({
|
|
684
|
+
collection: 'COLLECTION_MINT',
|
|
685
|
+
limit: 25,
|
|
686
|
+
});
|
|
687
|
+
```
|
|
264
688
|
|
|
265
|
-
|
|
689
|
+
Compressed NFTs only:
|
|
266
690
|
|
|
267
691
|
```ts
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
692
|
+
const result = await kit.searchAssets({
|
|
693
|
+
tokenType: 'compressedNFT',
|
|
694
|
+
compressed: true,
|
|
695
|
+
limit: 25,
|
|
696
|
+
});
|
|
272
697
|
```
|
|
273
698
|
|
|
274
|
-
|
|
699
|
+
How it works:
|
|
275
700
|
|
|
276
|
-
|
|
701
|
+
- builds a DAS search request
|
|
702
|
+
- calls DAS RPC method `searchAssets`
|
|
277
703
|
|
|
278
|
-
|
|
704
|
+
### `getAssetProof(assetId)`
|
|
705
|
+
|
|
706
|
+
Gets the Merkle proof for a compressed NFT.
|
|
707
|
+
|
|
708
|
+
Add-on required: `das`
|
|
279
709
|
|
|
280
710
|
```ts
|
|
281
|
-
const
|
|
282
|
-
console.log('SOL balance:', update.lamports / 1e9);
|
|
283
|
-
console.log('Backend:', update.backend); // 'yellowstone' or 'websocket'
|
|
284
|
-
});
|
|
711
|
+
const proof = await kit.getAssetProof('ASSET_ID');
|
|
285
712
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
713
|
+
console.log(proof.root);
|
|
714
|
+
console.log(proof.proof);
|
|
715
|
+
console.log(proof.tree_id);
|
|
289
716
|
```
|
|
290
717
|
|
|
291
|
-
|
|
718
|
+
How it works:
|
|
292
719
|
|
|
293
|
-
|
|
720
|
+
- calls DAS RPC method `getAssetProof`
|
|
294
721
|
|
|
295
|
-
|
|
722
|
+
### `getTokenAccounts(walletAddress)`
|
|
723
|
+
|
|
724
|
+
Gets SPL token accounts and balances for a wallet.
|
|
725
|
+
|
|
726
|
+
Add-on required: none
|
|
296
727
|
|
|
297
728
|
```ts
|
|
298
|
-
const
|
|
729
|
+
const tokens = await kit.getTokenAccounts('WALLET_ADDRESS');
|
|
730
|
+
|
|
731
|
+
for (const token of tokens) {
|
|
732
|
+
if (token.uiAmount > 0) {
|
|
733
|
+
console.log(token.mint, token.uiAmount);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
How it works:
|
|
299
739
|
|
|
300
|
-
|
|
301
|
-
|
|
740
|
+
- calls normal Solana RPC method `getTokenAccountsByOwner`
|
|
741
|
+
- uses `jsonParsed` encoding
|
|
742
|
+
|
|
743
|
+
### `watchAccount(address, onUpdate, options?)`
|
|
744
|
+
|
|
745
|
+
Watches an account in real time.
|
|
746
|
+
|
|
747
|
+
Add-on required: none
|
|
748
|
+
|
|
749
|
+
```ts
|
|
750
|
+
const handle = kit.watchAccount('WALLET_ADDRESS', (update) => {
|
|
751
|
+
console.log(update.pubkey);
|
|
752
|
+
console.log(update.lamports);
|
|
753
|
+
console.log(update.owner);
|
|
754
|
+
console.log(update.slot);
|
|
755
|
+
console.log(update.backend);
|
|
302
756
|
});
|
|
757
|
+
|
|
758
|
+
setTimeout(() => {
|
|
759
|
+
console.log(handle.isConnected());
|
|
760
|
+
handle.unsubscribe();
|
|
761
|
+
}, 15000);
|
|
303
762
|
```
|
|
304
763
|
|
|
305
|
-
|
|
764
|
+
How it works:
|
|
306
765
|
|
|
307
|
-
|
|
766
|
+
- uses Solana websocket subscriptions through `Connection`
|
|
767
|
+
- if `yellowstone` is set, the code prefers that route
|
|
768
|
+
- current implementation falls back to standard websocket behavior
|
|
308
769
|
|
|
309
|
-
|
|
770
|
+
### `watchProgram(programId, onTx, options?)`
|
|
771
|
+
|
|
772
|
+
Watches program logs in real time.
|
|
773
|
+
|
|
774
|
+
Add-on required: none
|
|
775
|
+
|
|
776
|
+
```ts
|
|
777
|
+
const handle = kit.watchProgram(
|
|
778
|
+
'JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4',
|
|
779
|
+
(tx) => {
|
|
780
|
+
console.log(tx.signature);
|
|
781
|
+
console.log(tx.logs);
|
|
782
|
+
console.log(tx.err);
|
|
783
|
+
},
|
|
784
|
+
);
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
How it works:
|
|
788
|
+
|
|
789
|
+
- uses `connection.onLogs(...)`
|
|
790
|
+
|
|
791
|
+
### `watchSlot(onSlot)`
|
|
792
|
+
|
|
793
|
+
Watches slot changes.
|
|
794
|
+
|
|
795
|
+
Add-on required: none
|
|
310
796
|
|
|
311
797
|
```ts
|
|
312
798
|
const handle = kit.watchSlot((slot) => {
|
|
313
|
-
|
|
799
|
+
console.log(slot);
|
|
314
800
|
});
|
|
801
|
+
|
|
802
|
+
setTimeout(() => handle.unsubscribe(), 10000);
|
|
315
803
|
```
|
|
316
804
|
|
|
317
|
-
|
|
805
|
+
How it works:
|
|
806
|
+
|
|
807
|
+
- uses `connection.onSlotChange(...)`
|
|
318
808
|
|
|
319
|
-
### `
|
|
809
|
+
### `getSwapQuote(options)`
|
|
320
810
|
|
|
321
|
-
|
|
811
|
+
Gets a Jupiter quote through the Metis add-on.
|
|
812
|
+
|
|
813
|
+
Add-on required: `metis`
|
|
322
814
|
|
|
323
815
|
```ts
|
|
324
|
-
import { TOKENS } from '
|
|
816
|
+
import { TOKENS } from 'quicknode-solana-kit';
|
|
325
817
|
|
|
326
818
|
const quote = await kit.getSwapQuote({
|
|
327
|
-
inputMint:
|
|
819
|
+
inputMint: TOKENS.SOL,
|
|
328
820
|
outputMint: TOKENS.USDC,
|
|
329
|
-
amount:
|
|
821
|
+
amount: BigInt(1_000_000_000),
|
|
822
|
+
slippageBps: 50,
|
|
330
823
|
});
|
|
331
824
|
|
|
332
|
-
console.log(
|
|
333
|
-
console.log(
|
|
825
|
+
console.log(quote.inAmount);
|
|
826
|
+
console.log(quote.outAmount);
|
|
827
|
+
console.log(quote.priceImpactPct);
|
|
828
|
+
console.log(quote.routePlan);
|
|
334
829
|
```
|
|
335
830
|
|
|
336
|
-
|
|
831
|
+
How it works:
|
|
832
|
+
|
|
833
|
+
- calls REST route `/jupiter/v6/quote`
|
|
337
834
|
|
|
338
|
-
### `
|
|
835
|
+
### `swap(options)`
|
|
339
836
|
|
|
340
|
-
|
|
837
|
+
Performs a Jupiter swap through Metis.
|
|
838
|
+
|
|
839
|
+
Add-on required: `metis`
|
|
341
840
|
|
|
342
841
|
```ts
|
|
842
|
+
import bs58 from 'bs58';
|
|
843
|
+
import { Keypair } from '@solana/web3.js';
|
|
844
|
+
import { TOKENS } from 'quicknode-solana-kit';
|
|
845
|
+
|
|
846
|
+
const signer = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_PRIVATE_KEY!));
|
|
847
|
+
|
|
343
848
|
const result = await kit.swap({
|
|
344
|
-
inputMint:
|
|
345
|
-
outputMint:
|
|
346
|
-
amount:
|
|
347
|
-
userPublicKey:
|
|
348
|
-
signer
|
|
349
|
-
slippageBps:
|
|
350
|
-
feeLevel:
|
|
849
|
+
inputMint: TOKENS.SOL,
|
|
850
|
+
outputMint: TOKENS.USDC,
|
|
851
|
+
amount: BigInt(10_000_000),
|
|
852
|
+
userPublicKey: signer.publicKey.toString(),
|
|
853
|
+
signer,
|
|
854
|
+
slippageBps: 100,
|
|
855
|
+
feeLevel: 'recommended',
|
|
351
856
|
});
|
|
352
857
|
|
|
353
|
-
console.log(
|
|
858
|
+
console.log(result.signature);
|
|
859
|
+
console.log(result.inputAmount);
|
|
860
|
+
console.log(result.outputAmount);
|
|
861
|
+
console.log(result.priceImpactPct);
|
|
354
862
|
```
|
|
355
863
|
|
|
356
|
-
|
|
864
|
+
How it works:
|
|
865
|
+
|
|
866
|
+
1. gets a quote
|
|
867
|
+
2. requests a serialized swap transaction
|
|
868
|
+
3. deserializes the base64 transaction
|
|
869
|
+
4. signs locally
|
|
870
|
+
5. sends with normal Solana connection
|
|
871
|
+
6. confirms the result
|
|
357
872
|
|
|
358
|
-
|
|
873
|
+
### `getPumpFunTokens(options?)`
|
|
359
874
|
|
|
360
|
-
|
|
875
|
+
Gets recent pump.fun tokens.
|
|
361
876
|
|
|
362
|
-
|
|
877
|
+
Add-on required: `pumpfun`
|
|
363
878
|
|
|
364
879
|
```ts
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
880
|
+
const tokens = await kit.getPumpFunTokens({
|
|
881
|
+
limit: 10,
|
|
882
|
+
offset: 0,
|
|
883
|
+
includeNsfw: false,
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
for (const token of tokens) {
|
|
887
|
+
console.log(token.mint, token.symbol, token.marketCapSol);
|
|
888
|
+
}
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
How it works:
|
|
892
|
+
|
|
893
|
+
- calls REST route `/pump-fun/coins`
|
|
894
|
+
|
|
895
|
+
### `getPumpFunToken(mint)`
|
|
896
|
+
|
|
897
|
+
Gets a single pump.fun token by mint.
|
|
898
|
+
|
|
899
|
+
Add-on required: `pumpfun`
|
|
900
|
+
|
|
901
|
+
```ts
|
|
902
|
+
const token = await kit.getPumpFunToken('TOKEN_MINT');
|
|
903
|
+
|
|
904
|
+
console.log(token.name);
|
|
905
|
+
console.log(token.symbol);
|
|
906
|
+
console.log(token.creator);
|
|
907
|
+
console.log(token.price);
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
How it works:
|
|
911
|
+
|
|
912
|
+
- calls REST route `/pump-fun/coins/:mint`
|
|
913
|
+
|
|
914
|
+
### `getPumpFunTokensByCreator(options)`
|
|
915
|
+
|
|
916
|
+
Gets pump.fun tokens by creator wallet.
|
|
917
|
+
|
|
918
|
+
Add-on required: `pumpfun`
|
|
919
|
+
|
|
920
|
+
```ts
|
|
921
|
+
const created = await kit.getPumpFunTokensByCreator({
|
|
922
|
+
creator: 'CREATOR_WALLET',
|
|
923
|
+
limit: 20,
|
|
924
|
+
offset: 0,
|
|
925
|
+
});
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
How it works:
|
|
929
|
+
|
|
930
|
+
- calls `/pump-fun/coins?creator=...`
|
|
931
|
+
|
|
932
|
+
### `getPumpFunTokenHolders(mint)`
|
|
933
|
+
|
|
934
|
+
Gets holder distribution for a token.
|
|
935
|
+
|
|
936
|
+
Add-on required: `pumpfun`
|
|
937
|
+
|
|
938
|
+
```ts
|
|
939
|
+
const holders = await kit.getPumpFunTokenHolders('TOKEN_MINT');
|
|
940
|
+
|
|
941
|
+
for (const holder of holders.slice(0, 10)) {
|
|
942
|
+
console.log(holder.address, holder.balance, holder.percentage);
|
|
943
|
+
}
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
How it works:
|
|
947
|
+
|
|
948
|
+
- calls REST route `/pump-fun/coins/:mint/holders`
|
|
949
|
+
|
|
950
|
+
### `getPumpFunTokenTrades(mint, options?)`
|
|
951
|
+
|
|
952
|
+
Gets recent trades for a token.
|
|
953
|
+
|
|
954
|
+
Add-on required: `pumpfun`
|
|
955
|
+
|
|
956
|
+
```ts
|
|
957
|
+
const trades = await kit.getPumpFunTokenTrades('TOKEN_MINT', {
|
|
958
|
+
limit: 25,
|
|
959
|
+
offset: 0,
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
for (const trade of trades) {
|
|
963
|
+
console.log(trade.signature, trade.isBuy, trade.solAmount, trade.tokenAmount);
|
|
964
|
+
}
|
|
369
965
|
```
|
|
370
966
|
|
|
371
|
-
|
|
967
|
+
How it works:
|
|
968
|
+
|
|
969
|
+
- calls REST route `/pump-fun/trades/all`
|
|
970
|
+
|
|
971
|
+
### `getStablecoinBalance(options)`
|
|
972
|
+
|
|
973
|
+
Gets stablecoin balances across multiple chains.
|
|
974
|
+
|
|
975
|
+
Add-on required: `stablecoinBalance`
|
|
976
|
+
|
|
977
|
+
```ts
|
|
978
|
+
const balances = await kit.getStablecoinBalance({
|
|
979
|
+
walletAddress: 'WALLET_ADDRESS',
|
|
980
|
+
chains: ['solana', 'ethereum', 'base'],
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
console.log(balances.totalUsdValue);
|
|
984
|
+
|
|
985
|
+
for (const balance of balances.balances) {
|
|
986
|
+
console.log(balance.chain, balance.symbol, balance.balance, balance.usdValue);
|
|
987
|
+
}
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
How it works:
|
|
991
|
+
|
|
992
|
+
- calls custom RPC method `qn_getWalletStablecoinBalances`
|
|
993
|
+
|
|
994
|
+
### `getOpenOceanQuote(options)`
|
|
995
|
+
|
|
996
|
+
Gets a swap quote from OpenOcean.
|
|
997
|
+
|
|
998
|
+
Add-on required: `openocean`
|
|
999
|
+
|
|
1000
|
+
```ts
|
|
1001
|
+
const quote = await kit.getOpenOceanQuote({
|
|
1002
|
+
inTokenAddress: 'So11111111111111111111111111111111111111112',
|
|
1003
|
+
outTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
1004
|
+
amount: '1000000000',
|
|
1005
|
+
slippage: 1,
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
console.log(quote.inAmount);
|
|
1009
|
+
console.log(quote.outAmount);
|
|
1010
|
+
console.log(quote.minOutAmount);
|
|
1011
|
+
console.log(quote.priceImpact);
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
How it works:
|
|
1015
|
+
|
|
1016
|
+
- calls REST route `/openocean/v4/solana/quote`
|
|
1017
|
+
|
|
1018
|
+
### `openOceanSwap(options)`
|
|
1019
|
+
|
|
1020
|
+
Performs a swap through OpenOcean.
|
|
1021
|
+
|
|
1022
|
+
Add-on required: `openocean`
|
|
1023
|
+
|
|
1024
|
+
```ts
|
|
1025
|
+
import bs58 from 'bs58';
|
|
1026
|
+
import { Keypair } from '@solana/web3.js';
|
|
1027
|
+
|
|
1028
|
+
const signer = Keypair.fromSecretKey(bs58.decode(process.env.WALLET_PRIVATE_KEY!));
|
|
1029
|
+
|
|
1030
|
+
const result = await kit.openOceanSwap({
|
|
1031
|
+
inTokenAddress: 'So11111111111111111111111111111111111111112',
|
|
1032
|
+
outTokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
1033
|
+
amount: '10000000',
|
|
1034
|
+
slippage: 1,
|
|
1035
|
+
userAddress: signer.publicKey.toString(),
|
|
1036
|
+
signer,
|
|
1037
|
+
});
|
|
1038
|
+
|
|
1039
|
+
console.log(result.signature);
|
|
1040
|
+
console.log(result.inAmount);
|
|
1041
|
+
console.log(result.outAmount);
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
How it works:
|
|
1045
|
+
|
|
1046
|
+
1. requests serialized transaction from add-on
|
|
1047
|
+
2. decodes base64 transaction
|
|
1048
|
+
3. signs locally
|
|
1049
|
+
4. sends using normal Solana connection
|
|
1050
|
+
5. confirms it
|
|
1051
|
+
|
|
1052
|
+
### `sendMerkleProtectedTransaction(options)`
|
|
1053
|
+
|
|
1054
|
+
Sends a signed transaction through Merkle for MEV protection.
|
|
1055
|
+
|
|
1056
|
+
Add-on required: `merkle`
|
|
1057
|
+
|
|
1058
|
+
```ts
|
|
1059
|
+
const result = await kit.sendMerkleProtectedTransaction({
|
|
1060
|
+
serializedTransaction: signedTxBase64,
|
|
1061
|
+
tipLamports: 10_000,
|
|
1062
|
+
});
|
|
1063
|
+
|
|
1064
|
+
console.log(result.signature);
|
|
1065
|
+
console.log(result.provider);
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
How it works:
|
|
1069
|
+
|
|
1070
|
+
- calls custom RPC method `mev_sendTransaction`
|
|
1071
|
+
- confirms with normal Solana connection
|
|
1072
|
+
|
|
1073
|
+
### `sendBlinkLabsTransaction(options)`
|
|
1074
|
+
|
|
1075
|
+
Sends a signed transaction through Blink Labs.
|
|
1076
|
+
|
|
1077
|
+
Add-on required: `blinklabs`
|
|
1078
|
+
|
|
1079
|
+
```ts
|
|
1080
|
+
const result = await kit.sendBlinkLabsTransaction({
|
|
1081
|
+
serializedTransaction: signedTxBase64,
|
|
1082
|
+
tipLamports: 5_000,
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
console.log(result.signature);
|
|
1086
|
+
console.log(result.provider);
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
How it works:
|
|
1090
|
+
|
|
1091
|
+
- calls custom RPC method `blinklabs_sendTransaction`
|
|
1092
|
+
- confirms with normal Solana connection
|
|
1093
|
+
|
|
1094
|
+
### `sendIrisTransaction(options)`
|
|
1095
|
+
|
|
1096
|
+
Sends a signed transaction through the Iris add-on.
|
|
1097
|
+
|
|
1098
|
+
Add-on required: `iris`
|
|
1099
|
+
|
|
1100
|
+
```ts
|
|
1101
|
+
const result = await kit.sendIrisTransaction({
|
|
1102
|
+
serializedTransaction: signedTxBase64,
|
|
1103
|
+
skipPreflight: false,
|
|
1104
|
+
maxRetries: 3,
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
console.log(result.signature);
|
|
1108
|
+
console.log(result.slot);
|
|
1109
|
+
console.log(result.confirmationMs);
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
How it works:
|
|
1113
|
+
|
|
1114
|
+
- calls custom RPC method `iris_sendTransaction`
|
|
1115
|
+
- confirms with normal Solana RPC
|
|
1116
|
+
|
|
1117
|
+
### `getGoldRushBalances(options)`
|
|
1118
|
+
|
|
1119
|
+
Gets multichain balances through GoldRush.
|
|
1120
|
+
|
|
1121
|
+
Add-on required: `goldrush`
|
|
1122
|
+
|
|
1123
|
+
```ts
|
|
1124
|
+
const balances = await kit.getGoldRushBalances({
|
|
1125
|
+
walletAddress: 'WALLET_ADDRESS',
|
|
1126
|
+
chain: 'solana-mainnet',
|
|
1127
|
+
noSpam: true,
|
|
1128
|
+
quoteCurrency: 'USD',
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
console.log(balances.chain);
|
|
1132
|
+
console.log(balances.address);
|
|
1133
|
+
|
|
1134
|
+
for (const item of balances.items) {
|
|
1135
|
+
console.log(item.symbol, item.balance, item.usdBalance);
|
|
1136
|
+
}
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
How it works:
|
|
1140
|
+
|
|
1141
|
+
- calls REST route under `/goldrush/v1/`
|
|
1142
|
+
|
|
1143
|
+
### `getGoldRushTransactions(options)`
|
|
1144
|
+
|
|
1145
|
+
Gets multichain transaction history through GoldRush.
|
|
1146
|
+
|
|
1147
|
+
Add-on required: `goldrush`
|
|
1148
|
+
|
|
1149
|
+
```ts
|
|
1150
|
+
const txs = await kit.getGoldRushTransactions({
|
|
1151
|
+
walletAddress: 'WALLET_ADDRESS',
|
|
1152
|
+
chain: 'solana-mainnet',
|
|
1153
|
+
pageSize: 25,
|
|
1154
|
+
pageNumber: 0,
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
for (const tx of txs.items) {
|
|
1158
|
+
console.log(tx.txHash, tx.successful, tx.value);
|
|
1159
|
+
}
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
How it works:
|
|
1163
|
+
|
|
1164
|
+
- calls REST route under `/goldrush/v1/`
|
|
1165
|
+
|
|
1166
|
+
### `getTitanSwapQuote(options)`
|
|
1167
|
+
|
|
1168
|
+
Gets a swap quote from Titan.
|
|
1169
|
+
|
|
1170
|
+
Add-on required: `titan`
|
|
1171
|
+
|
|
1172
|
+
```ts
|
|
1173
|
+
const quote = await kit.getTitanSwapQuote({
|
|
1174
|
+
inputMint: 'So11111111111111111111111111111111111111112',
|
|
1175
|
+
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
1176
|
+
amount: '1000000000',
|
|
1177
|
+
slippageBps: 50,
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
console.log(quote.inAmount);
|
|
1181
|
+
console.log(quote.outAmount);
|
|
1182
|
+
console.log(quote.routes);
|
|
1183
|
+
```
|
|
1184
|
+
|
|
1185
|
+
How it works:
|
|
1186
|
+
|
|
1187
|
+
- calls REST route `/titan/v1/quote`
|
|
1188
|
+
|
|
1189
|
+
### `titanSwap(options)`
|
|
1190
|
+
|
|
1191
|
+
Performs a swap through Titan.
|
|
1192
|
+
|
|
1193
|
+
Add-on required: `titan`
|
|
1194
|
+
|
|
1195
|
+
```ts
|
|
1196
|
+
const result = await kit.titanSwap({
|
|
1197
|
+
inputMint: 'So11111111111111111111111111111111111111112',
|
|
1198
|
+
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
1199
|
+
amount: '10000000',
|
|
1200
|
+
slippageBps: 50,
|
|
1201
|
+
userPublicKey: 'WALLET_PUBLIC_KEY',
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1204
|
+
console.log(result.signature);
|
|
1205
|
+
console.log(result.inAmount);
|
|
1206
|
+
console.log(result.outAmount);
|
|
1207
|
+
```
|
|
1208
|
+
|
|
1209
|
+
How it works:
|
|
1210
|
+
|
|
1211
|
+
1. gets a Titan quote
|
|
1212
|
+
2. requests a serialized transaction
|
|
1213
|
+
3. deserializes it
|
|
1214
|
+
4. sends it through normal Solana connection
|
|
1215
|
+
5. confirms it
|
|
1216
|
+
|
|
1217
|
+
### `subscribeTitanQuotes(options, onQuote, onError?)`
|
|
1218
|
+
|
|
1219
|
+
Subscribes to live quote updates from Titan over WebSocket.
|
|
1220
|
+
|
|
1221
|
+
Add-on required: `titan`
|
|
1222
|
+
|
|
1223
|
+
```ts
|
|
1224
|
+
const unsubscribe = kit.subscribeTitanQuotes(
|
|
1225
|
+
{
|
|
1226
|
+
inputMint: 'So11111111111111111111111111111111111111112',
|
|
1227
|
+
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
1228
|
+
amount: '1000000000',
|
|
1229
|
+
slippageBps: 50,
|
|
1230
|
+
},
|
|
1231
|
+
(quote) => {
|
|
1232
|
+
console.log('quote', quote.outAmount);
|
|
1233
|
+
},
|
|
1234
|
+
(err) => {
|
|
1235
|
+
console.error(err);
|
|
1236
|
+
},
|
|
1237
|
+
);
|
|
1238
|
+
|
|
1239
|
+
setTimeout(() => unsubscribe(), 15000);
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
How it works:
|
|
1243
|
+
|
|
1244
|
+
- opens a WebSocket to the Titan stream route on your endpoint
|
|
1245
|
+
|
|
1246
|
+
### `assessWalletRisk(options)`
|
|
1247
|
+
|
|
1248
|
+
Gets Scorechain risk information for a wallet.
|
|
1249
|
+
|
|
1250
|
+
Add-on required: `scorechain`
|
|
1251
|
+
|
|
1252
|
+
```ts
|
|
1253
|
+
const assessment = await kit.assessWalletRisk({
|
|
1254
|
+
address: 'WALLET_ADDRESS',
|
|
1255
|
+
network: 'solana',
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
console.log(assessment.address);
|
|
1259
|
+
console.log(assessment.riskScore);
|
|
1260
|
+
console.log(assessment.riskLevel);
|
|
1261
|
+
console.log(assessment.amlStatus);
|
|
1262
|
+
console.log(assessment.flags);
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
How it works:
|
|
1266
|
+
|
|
1267
|
+
- calls REST route `/scorechain/v1/risk`
|
|
1268
|
+
|
|
1269
|
+
### `isWalletSafe(address)`
|
|
1270
|
+
|
|
1271
|
+
Returns a simple safe/unsafe boolean using Scorechain.
|
|
1272
|
+
|
|
1273
|
+
Add-on required: `scorechain`
|
|
1274
|
+
|
|
1275
|
+
This returns `true` only when:
|
|
1276
|
+
|
|
1277
|
+
- `amlStatus === 'clean'`
|
|
1278
|
+
- `riskLevel === 'low'`
|
|
1279
|
+
|
|
1280
|
+
```ts
|
|
1281
|
+
const safe = await kit.isWalletSafe('WALLET_ADDRESS');
|
|
1282
|
+
console.log(safe);
|
|
1283
|
+
```
|
|
1284
|
+
|
|
1285
|
+
How it works:
|
|
1286
|
+
|
|
1287
|
+
- first calls `assessWalletRisk()`
|
|
1288
|
+
- then applies a simple clean + low-risk check
|
|
1289
|
+
|
|
1290
|
+
## Token Constants
|
|
1291
|
+
|
|
1292
|
+
### `TOKENS`
|
|
1293
|
+
|
|
1294
|
+
Useful for Jupiter / Metis examples.
|
|
1295
|
+
|
|
1296
|
+
```ts
|
|
1297
|
+
import { TOKENS } from 'quicknode-solana-kit';
|
|
1298
|
+
|
|
1299
|
+
console.log(TOKENS.SOL);
|
|
1300
|
+
console.log(TOKENS.USDC);
|
|
1301
|
+
console.log(TOKENS.USDT);
|
|
1302
|
+
console.log(TOKENS.BONK);
|
|
1303
|
+
console.log(TOKENS.JUP);
|
|
1304
|
+
console.log(TOKENS.RAY);
|
|
1305
|
+
console.log(TOKENS.WIF);
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
### `OO_TOKENS`
|
|
1309
|
+
|
|
1310
|
+
Useful for OpenOcean examples.
|
|
1311
|
+
|
|
1312
|
+
```ts
|
|
1313
|
+
import { OO_TOKENS } from 'quicknode-solana-kit';
|
|
1314
|
+
|
|
1315
|
+
console.log(OO_TOKENS.SOL);
|
|
1316
|
+
console.log(OO_TOKENS.USDC);
|
|
1317
|
+
console.log(OO_TOKENS.USDT);
|
|
1318
|
+
console.log(OO_TOKENS.BONK);
|
|
1319
|
+
```
|
|
372
1320
|
|
|
373
1321
|
## Error Handling
|
|
374
1322
|
|
|
375
|
-
|
|
1323
|
+
The package exports custom errors:
|
|
1324
|
+
|
|
1325
|
+
- `AddOnNotEnabledError`
|
|
1326
|
+
- `TransactionFailedError`
|
|
1327
|
+
- `TransactionTimeoutError`
|
|
1328
|
+
- `MaxRetriesExceededError`
|
|
1329
|
+
- `InvalidEndpointError`
|
|
1330
|
+
- `RPCError`
|
|
1331
|
+
|
|
1332
|
+
Example:
|
|
376
1333
|
|
|
377
1334
|
```ts
|
|
378
1335
|
import {
|
|
379
1336
|
AddOnNotEnabledError,
|
|
1337
|
+
RPCError,
|
|
380
1338
|
TransactionFailedError,
|
|
381
|
-
TransactionTimeoutError,
|
|
382
1339
|
MaxRetriesExceededError,
|
|
383
|
-
|
|
384
|
-
} from '@quicknode/solana-kit';
|
|
1340
|
+
} from 'quicknode-solana-kit';
|
|
385
1341
|
|
|
386
1342
|
try {
|
|
387
1343
|
await kit.sendSmartTransaction({ transaction, signer });
|
|
388
1344
|
} catch (err) {
|
|
389
1345
|
if (err instanceof AddOnNotEnabledError) {
|
|
390
|
-
|
|
391
|
-
console.error(err.message);
|
|
1346
|
+
console.error('Enable the missing add-on in QuickNode and update kit config.');
|
|
392
1347
|
} else if (err instanceof TransactionFailedError) {
|
|
393
|
-
|
|
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.');
|
|
1348
|
+
console.error('On-chain failure:', err.signature, err.reason);
|
|
398
1349
|
} else if (err instanceof MaxRetriesExceededError) {
|
|
399
|
-
console.error(
|
|
1350
|
+
console.error('Retries exhausted:', err.maxRetries);
|
|
400
1351
|
} else if (err instanceof RPCError) {
|
|
401
|
-
console.error(
|
|
1352
|
+
console.error('RPC error:', err.statusCode, err.message);
|
|
1353
|
+
} else {
|
|
1354
|
+
console.error(err);
|
|
402
1355
|
}
|
|
403
1356
|
}
|
|
404
1357
|
```
|
|
405
1358
|
|
|
406
|
-
|
|
1359
|
+
## Included Example Scripts
|
|
407
1360
|
|
|
408
|
-
|
|
1361
|
+
```bash
|
|
1362
|
+
npm run example:tx
|
|
1363
|
+
npm run example:nft
|
|
1364
|
+
npm run example:stream
|
|
1365
|
+
npm run example:swap
|
|
1366
|
+
npm run example:all
|
|
1367
|
+
```
|
|
409
1368
|
|
|
410
|
-
|
|
1369
|
+
Suggested `.env` values:
|
|
411
1370
|
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
1371
|
+
```bash
|
|
1372
|
+
QN_ENDPOINT_URL=
|
|
1373
|
+
WALLET_PRIVATE_KEY=
|
|
1374
|
+
WALLET_ADDRESS=
|
|
1375
|
+
ADDON_PRIORITY_FEES=true
|
|
1376
|
+
ADDON_DAS=true
|
|
1377
|
+
ADDON_METIS=true
|
|
1378
|
+
EXECUTE_SWAP=false
|
|
418
1379
|
```
|
|
419
1380
|
|
|
420
|
-
|
|
1381
|
+
## Recommended Learning Order
|
|
421
1382
|
|
|
422
|
-
|
|
1383
|
+
If you are new to Solana or QuickNode, this order works well:
|
|
423
1384
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
1385
|
+
1. create `kit`
|
|
1386
|
+
2. use `kit.connection.getBalance()`
|
|
1387
|
+
3. use `kit.getTokenAccounts()`
|
|
1388
|
+
4. run `kit.checkAddOns()`
|
|
1389
|
+
5. if `priorityFees` is enabled, try `kit.estimatePriorityFees()`
|
|
1390
|
+
6. if `das` is enabled, try `kit.getAssetsByOwner()`
|
|
1391
|
+
7. if `metis` is enabled, try `kit.getSwapQuote()`
|
|
429
1392
|
|
|
430
|
-
|
|
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
|
|
1393
|
+
## Starter Example
|
|
434
1394
|
|
|
435
|
-
|
|
436
|
-
|
|
1395
|
+
```ts
|
|
1396
|
+
import { PublicKey } from '@solana/web3.js';
|
|
1397
|
+
import { QNSolanaKit } from 'quicknode-solana-kit';
|
|
1398
|
+
|
|
1399
|
+
const kit = new QNSolanaKit({
|
|
1400
|
+
endpointUrl: process.env.QN_ENDPOINT_URL!,
|
|
1401
|
+
addOns: {
|
|
1402
|
+
priorityFees: true,
|
|
1403
|
+
das: true,
|
|
1404
|
+
},
|
|
1405
|
+
});
|
|
437
1406
|
|
|
438
|
-
|
|
439
|
-
|
|
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)
|
|
1407
|
+
async function main() {
|
|
1408
|
+
const wallet = new PublicKey('E645TckHQnDcavVv92Etc6xSWQaq8zzPtPRGBheviRAk');
|
|
443
1409
|
|
|
444
|
-
|
|
445
|
-
|
|
1410
|
+
const balance = await kit.connection.getBalance(wallet);
|
|
1411
|
+
console.log('SOL balance:', balance / 1e9);
|
|
1412
|
+
|
|
1413
|
+
const tokenAccounts = await kit.getTokenAccounts(wallet.toString());
|
|
1414
|
+
console.log('Token accounts:', tokenAccounts.length);
|
|
1415
|
+
|
|
1416
|
+
const fees = await kit.estimatePriorityFees();
|
|
1417
|
+
console.log('Recommended priority fee:', fees.recommended);
|
|
1418
|
+
|
|
1419
|
+
const assets = await kit.getAssetsByOwner({
|
|
1420
|
+
ownerAddress: wallet.toString(),
|
|
1421
|
+
limit: 5,
|
|
1422
|
+
});
|
|
1423
|
+
console.log('Assets:', assets.items.length);
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
main().catch(console.error);
|
|
446
1427
|
```
|
|
447
1428
|
|
|
1429
|
+
## Current Limitations
|
|
1430
|
+
|
|
1431
|
+
- `yellowstone` is exposed in config and add-on checks, but account streaming currently falls back to standard Solana WebSockets
|
|
1432
|
+
- `liljit` is probed by `checkAddOns()`, but `sendSmartTransaction()` does not currently route through Jito bundles
|
|
1433
|
+
- `sendSmartTransaction()` works without `priorityFees`, but falls back to a default compute unit price
|
|
1434
|
+
- several swap integrations return a serialized transaction that the SDK then signs and sends locally
|
|
1435
|
+
|
|
1436
|
+
## Beginner Guide
|
|
1437
|
+
|
|
1438
|
+
If you want a more beginner-first walkthrough, see:
|
|
448
1439
|
|
|
449
|
-
|
|
1440
|
+
- [readmetounderstand.md](/home/rachit/Videos/QuickNode-Starter-Kit/qn-solana-kit-v2/readmetounderstand.md)
|
|
450
1441
|
|
|
451
|
-
|
|
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
|
|
1442
|
+
## License
|
|
457
1443
|
|
|
458
|
-
|
|
1444
|
+
MIT
|