@quicknode/sdk 3.1.0-alpha.17 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,195 +1,1638 @@
1
- # Quicknode SDK
1
+ # @quicknode/sdk (Node.js)
2
2
 
3
- A unified SDK for building on Quicknode.
3
+ Node.js / TypeScript bindings for the Quicknode SDK.
4
4
 
5
- Rust SDK with Python, Node.js, and Ruby bindings.
5
+ This is one of four language bindings published from the same Rust core. See the [project README](https://github.com/quicknode/sdk/blob/main/README.md) for the polyglot overview, development setup, and release process.
6
6
 
7
7
  ## Table of Contents
8
8
 
9
- - [Per-language docs](#per-language-docs)
10
- - [Project Structure](#project-structure)
11
9
  - [Installation](#installation)
12
- - [Development](#development)
13
- - [Prerequisites](#prerequisites)
14
- - [Build Commands](#build-commands)
15
- - [Testing](#testing)
16
- - [Examples](#examples)
17
- - [Releasing](#releasing)
18
- - [Two-phase flow](#two-phase-flow)
19
- - [Building blocks](#building-blocks)
20
- - [Version conventions](#version-conventions)
21
- - [First-time setup](#first-time-setup)
10
+ - [Quick Start](#quick-start)
11
+ - [Configuration](#configuration)
12
+ - [Platform Support](#platform-support)
13
+ - [API Reference](#api-reference)
14
+ - [Admin Client](#admin-client)
15
+ - [Endpoints](#endpoints)
16
+ - [Endpoint Tags](#endpoint-tags)
17
+ - [Teams](#teams)
18
+ - [Usage](#usage)
19
+ - [Logs](#logs)
20
+ - [Endpoint Security](#endpoint-security)
21
+ - [Security Options](#security-options)
22
+ - [Tokens](#tokens)
23
+ - [Referrers](#referrers)
24
+ - [IPs](#ips)
25
+ - [Domain Masks](#domain-masks)
26
+ - [JWTs](#jwts)
27
+ - [Request Filters](#request-filters)
28
+ - [Multichain](#multichain)
29
+ - [IP Custom Headers](#ip-custom-headers)
30
+ - [Method Rate Limits](#method-rate-limits)
31
+ - [Endpoint Rate Limits](#endpoint-rate-limits)
32
+ - [Endpoint URLs](#endpoint-urls)
33
+ - [Metrics](#metrics)
34
+ - [Chains](#chains)
35
+ - [Billing](#billing)
36
+ - [Bulk Operations](#bulk-operations)
37
+ - [Account Tags](#account-tags)
38
+ - [Streams Client](#streams-client)
39
+ - [Datasets, Regions, and Destinations](#datasets-regions-and-destinations)
40
+ - [Streams methods](#streams-methods)
41
+ - [Webhooks Client](#webhooks-client)
42
+ - [Templates and destination](#templates-and-destination)
43
+ - [Webhooks methods](#webhooks-methods)
44
+ - [KV Store Client](#kv-store-client)
45
+ - [Sets](#sets)
46
+ - [Lists](#lists)
47
+ - [Error Handling](#error-handling)
22
48
  - [License](#license)
23
49
 
24
- ## Per-language docs
50
+ ## Installation
51
+
52
+ `npm install @quicknode/sdk`
53
+
54
+ ## Quick Start
55
+
56
+ Construct the SDK once, then reach into the four sub-clients (`admin`, `streams`, `webhooks`, `kvstore`). Subsequent API Reference snippets assume you have a `qn` handle from one of these blocks.
57
+
58
+ ```typescript
59
+ // Node.js
60
+ import { QuicknodeSdk } from "quicknode-sdk";
61
+
62
+ const qn = QuicknodeSdk.fromEnv();
63
+ const resp = await qn.admin.getEndpoints();
64
+ console.log(`${resp.data.length} endpoints`);
65
+ ```
66
+
67
+ ## Configuration
68
+
69
+ There are two ways to configure the SDK.
70
+
71
+ ### Option A — Pass config directly
72
+
73
+ ```typescript
74
+ // Node.js
75
+ import { QuicknodeSdk } from "quicknode-sdk";
76
+ const qn = new QuicknodeSdk({ apiKey: "your-key", http: { timeoutSecs: 30 } });
77
+ ```
78
+
79
+ ### Option B — Load from environment (`from_env()`)
80
+
81
+ ```typescript
82
+ // Node.js
83
+ const qn = QuicknodeSdk.fromEnv();
84
+ ```
85
+
86
+ Environment variables (prefix `QN_SDK__`, separator `__`):
87
+
88
+ | Variable | Required | Default | Description |
89
+ |----------|----------|---------|-------------|
90
+ | `QN_SDK__API_KEY` | yes | — | Your Quicknode API key |
91
+ | `QN_SDK__HTTP__TIMEOUT_SECS` | no | 30 | HTTP request timeout in seconds |
92
+ | `QN_SDK__HTTP__POOL_MAX_IDLE_PER_HOST` | no | — | Max idle HTTP connections per host |
93
+ | `QN_SDK__ADMIN__BASE_URL` | no | `https://api.quicknode.com/v0/` | Override admin API base URL (HTTPS, must end with `/`) |
94
+ | `QN_SDK__STREAMS__BASE_URL` | no | `https://api.quicknode.com/streams/rest/v1/` | Override streams base URL |
95
+ | `QN_SDK__WEBHOOKS__BASE_URL` | no | `https://api.quicknode.com/webhooks/rest/v1/` | Override webhooks base URL |
96
+ | `QN_SDK__KVSTORE__BASE_URL` | no | `https://api.quicknode.com/kv/rest/v1/` | Override KV store base URL |
97
+ | `QN_SDK__HTTP__HEADERS__<NAME>` | no | — | Custom HTTP header sent on every request. Overrides SDK-managed headers (see below). |
98
+
99
+ ### Custom headers and `User-Agent`
100
+
101
+ Every outbound HTTP request includes an auto-generated `User-Agent` of the form:
102
+
103
+ ```
104
+ quicknode-sdk-<language>/<sdk-version> (<os>-<arch>; <language>-<runtime-version>)
105
+ ```
106
+
107
+ You can attach arbitrary headers via `HttpConfig.headers`. **These headers OVERRIDE any SDK-managed header with the same name**, including `User-Agent`, `x-api-key`, `Accept`, and `Content-Type`. Use this to inject correlation IDs, proxy auth, or to replace the default `User-Agent`. Header names are matched case-insensitively.
108
+
109
+ ```ts
110
+ import { QuicknodeSdk } from "@quicknode/sdk";
111
+
112
+ const qn = new QuicknodeSdk({
113
+ apiKey: "your-key",
114
+ http: {
115
+ headers: {
116
+ "X-Correlation-Id": "abc-123",
117
+ "User-Agent": "my-app/1.0", // overrides SDK default
118
+ },
119
+ },
120
+ });
121
+ ```
122
+
123
+ ## Platform Support
124
+
125
+ Precompiled native modules are published for:
126
+
127
+ | Platform | Targets |
128
+ |---|---|
129
+ | Linux (glibc) | `x86_64`, `aarch64` — glibc **2.17+** (manylinux2014) |
130
+ | Linux (musl) | `x86_64`, `aarch64` — Alpine and other musl distros |
131
+ | macOS | Apple Silicon (`arm64`) |
132
+
133
+ Linux glibc binaries are built against glibc 2.17 so they load on any distro from 2014 onward — RHEL 7+, Ubuntu 14.04+, Debian 8+, Amazon Linux 2+, SLES 12+, Fedora 19+. On unsupported platforms, `require('@quicknode/sdk')` throws an error listing the available targets.
134
+
135
+ **Not supported:** RHEL/CentOS 6 (glibc 2.12), Debian 7 (glibc 2.13), Ubuntu 12.04 (glibc 2.15), SLES 11 (glibc 2.11), Intel macOS, Windows.
136
+
137
+ ## API Reference
138
+
139
+ Snippets assume `qn` was already constructed via the Quick Start. Optional parameters are skipped unless showing one is needed to illustrate usage.
140
+
141
+ ### Language conventions
142
+
143
+ - Methods are `async` and take a single options object with camelCase keys.
144
+
145
+ ---
146
+
147
+ ### Admin Client
148
+
149
+ Accessed as `qn.admin`. Manages endpoints, tags, teams, billing, usage, metrics, security, and rate limits. Backed by `https://api.quicknode.com/v0/`.
150
+
151
+ #### Endpoints
152
+
153
+ ##### `get_endpoints` / `getEndpoints`
154
+
155
+ Returns a paginated list of endpoints on the account with optional search, filters (networks, statuses, labels, tags, dedicated, flat-rate), sorting, and pagination.
156
+
157
+ **Parameters** (all optional): `limit` (i32), `offset` (i32), `search` (string), `sort_by` (string), `sort_direction` (`"asc"` | `"desc"`), `networks` (string[]), `statuses` (string[]), `labels` (string[]), `dedicated` (bool), `is_flat_rate` (bool), `tag_ids` (i32[]), `tag_labels` (string[]).
158
+
159
+ **Returns**: `GetEndpointsResponse` — `{ data: Endpoint[], pagination?: Pagination }`.
160
+
161
+ ```typescript
162
+ // Node.js
163
+ const resp = await qn.admin.getEndpoints({
164
+ limit: 20,
165
+ sortBy: "created_at",
166
+ sortDirection: "desc",
167
+ });
168
+ ```
169
+
170
+ ##### `create_endpoint` / `createEndpoint`
171
+
172
+ Creates a new endpoint for the given blockchain and network.
173
+
174
+ **Parameters**: `chain` (string, optional), `network` (string, optional).
175
+
176
+ **Returns**: `CreateEndpointResponse` with `data: SingleEndpoint`.
177
+
178
+ ```typescript
179
+ // Node.js
180
+ const resp = await qn.admin.createEndpoint({ chain: "ethereum", network: "mainnet" });
181
+ ```
182
+
183
+ ##### `show_endpoint` / `showEndpoint`
184
+
185
+ Fetches a single endpoint by id, including its full security configuration and rate limits.
186
+
187
+ **Parameters**: `id` (string, required).
188
+
189
+ **Returns**: `ShowEndpointResponse` with `data: SingleEndpoint`.
190
+
191
+ ```typescript
192
+ // Node.js
193
+ const resp = await qn.admin.showEndpoint("ep-123");
194
+ ```
195
+
196
+ ##### `update_endpoint` / `updateEndpoint`
197
+
198
+ Updates editable fields on an endpoint. Currently supports `label`.
199
+
200
+ **Parameters**: `id` (string, required); body: `label` (string, optional).
201
+
202
+ **Returns**: nothing.
203
+
204
+ ```typescript
205
+ // Node.js
206
+ await qn.admin.updateEndpoint("ep-123", { label: "my label" });
207
+ ```
208
+
209
+ ##### `archive_endpoint` / `archiveEndpoint`
210
+
211
+ Archives an endpoint. The HTTP verb is `DELETE` but the effect is archival, not permanent deletion.
212
+
213
+ **Parameters**: `id` (string, required).
214
+
215
+ **Returns**: nothing.
216
+
217
+ ```typescript
218
+ // Node.js
219
+ await qn.admin.archiveEndpoint("ep-123");
220
+ ```
221
+
222
+ ##### `update_endpoint_status` / `updateEndpointStatus`
223
+
224
+ Pauses or unpauses an endpoint.
225
+
226
+ **Parameters**: `id` (string, required); body: `status` (string, required — `"active"` or `"paused"`).
227
+
228
+ **Returns**: `UpdateEndpointStatusResponse`.
229
+
230
+ ```typescript
231
+ // Node.js
232
+ await qn.admin.updateEndpointStatus("ep-123", { status: "paused" });
233
+ ```
234
+
235
+ #### Endpoint Tags
236
+
237
+ Per-endpoint tag add/remove. For account-wide tag management see [Account Tags](#account-tags).
238
+
239
+ ##### `create_tag` / `createTag`
240
+
241
+ Tags an endpoint with the given label. Creates the tag on the account if it does not exist.
242
+
243
+ **Parameters**: `id` (string, required); body: `label` (string, optional).
244
+
245
+ **Returns**: nothing.
246
+
247
+ ```typescript
248
+ // Node.js
249
+ await qn.admin.createTag("ep-123", { label: "prod" });
250
+ ```
251
+
252
+ ##### `delete_tag` / `deleteTag`
253
+
254
+ Removes a tag from a specific endpoint.
255
+
256
+ **Parameters**: `id` (endpoint id, string, required), `tag_id` (string, required).
257
+
258
+ **Returns**: nothing.
259
+
260
+ ```typescript
261
+ // Node.js
262
+ await qn.admin.deleteTag("ep-123", "42");
263
+ ```
264
+
265
+ #### Teams
266
+
267
+ ##### `list_teams` / `listTeams`
268
+
269
+ Lists all teams on the account.
270
+
271
+ **Parameters**: none.
272
+
273
+ **Returns**: `ListTeamsResponse` with `data: TeamSummary[]`.
274
+
275
+ ```typescript
276
+ // Node.js
277
+ const resp = await qn.admin.listTeams();
278
+ ```
279
+
280
+ ##### `create_team` / `createTeam`
281
+
282
+ Creates a new team.
283
+
284
+ **Parameters**: `name` (string, required).
285
+
286
+ **Returns**: `CreateTeamResponse` with `data: CreateTeamData`.
287
+
288
+ ```typescript
289
+ // Node.js
290
+ const resp = await qn.admin.createTeam({ name: "Payments" });
291
+ ```
292
+
293
+ ##### `get_team` / `getTeam`
294
+
295
+ Fetches team detail including pending invites.
296
+
297
+ **Parameters**: `id` (i64, required).
298
+
299
+ **Returns**: `GetTeamResponse` with `data: TeamDetail`.
300
+
301
+ ```typescript
302
+ // Node.js
303
+ const resp = await qn.admin.getTeam(42);
304
+ ```
305
+
306
+ ##### `delete_team` / `deleteTeam`
307
+
308
+ Deletes a team.
309
+
310
+ **Parameters**: `id` (i64, required).
311
+
312
+ **Returns**: `DeleteTeamResponse`.
313
+
314
+ ```typescript
315
+ // Node.js
316
+ await qn.admin.deleteTeam(42);
317
+ ```
318
+
319
+ ##### `list_team_endpoints` / `listTeamEndpoints`
320
+
321
+ Lists endpoints accessible to a team.
322
+
323
+ **Parameters**: `id` (i64, required).
324
+
325
+ **Returns**: `ListTeamEndpointsResponse` with `data: TeamEndpoint[]`.
326
+
327
+ ```typescript
328
+ // Node.js
329
+ const resp = await qn.admin.listTeamEndpoints(42);
330
+ ```
331
+
332
+ ##### `update_team_endpoints` / `updateTeamEndpoints`
333
+
334
+ Replaces the set of endpoints associated with a team. Pass an empty array to remove all.
335
+
336
+ **Parameters**: `id` (i64, required); body: `endpoint_ids` (string[], required).
337
+
338
+ **Returns**: `UpdateTeamEndpointsResponse`.
339
+
340
+ ```typescript
341
+ // Node.js
342
+ await qn.admin.updateTeamEndpoints(42, { endpointIds: ["ep-123", "ep-456"] });
343
+ ```
344
+
345
+ ##### `invite_team_member` / `inviteTeamMember`
346
+
347
+ Invites a user to a team. Existing users only need `email`; new users require `full_name` and `role`.
348
+
349
+ **Parameters**: `id` (i64, required); body: `email` (string, required), `full_name` (string, optional), `role` (string, optional — `admin` | `viewer` | `billing`).
350
+
351
+ **Returns**: `InviteTeamMemberResponse`.
352
+
353
+ ```typescript
354
+ // Node.js
355
+ await qn.admin.inviteTeamMember(42, { email: "alice@example.com", role: "viewer" });
356
+ ```
357
+
358
+ ##### `remove_team_member` / `removeTeamMember`
359
+
360
+ Removes a user from a team.
361
+
362
+ **Parameters**: `id` (team id, i64, required), `user_id` (i64, required).
363
+
364
+ **Returns**: `RemoveTeamMemberResponse`.
365
+
366
+ ```typescript
367
+ // Node.js
368
+ await qn.admin.removeTeamMember(42, 7);
369
+ ```
370
+
371
+ ##### `resend_team_invite` / `resendTeamInvite`
372
+
373
+ Re-sends a pending team invitation.
374
+
375
+ **Parameters**: `id` (team id, i64, required), `user_id` (i64, required).
376
+
377
+ **Returns**: `ResendTeamInviteResponse`.
378
+
379
+ ```typescript
380
+ // Node.js
381
+ await qn.admin.resendTeamInvite(42, 7);
382
+ ```
383
+
384
+ #### Usage
385
+
386
+ All usage methods accept optional `start_time` and `end_time` Unix timestamps. Omit both for account-to-date totals.
387
+
388
+ ##### `get_usage` / `getUsage`
389
+
390
+ Aggregate account usage for a time window.
391
+
392
+ **Returns**: `GetUsageResponse` with `data: UsageData` (`credits_used`, `credits_remaining`, `limit`, `overages`, `start_time`, `end_time`).
393
+
394
+ ```typescript
395
+ // Node.js
396
+ const resp = await qn.admin.getUsage();
397
+ ```
398
+
399
+ ##### `get_usage_by_endpoint` / `getUsageByEndpoint`
400
+
401
+ Per-endpoint usage breakdown.
402
+
403
+ **Returns**: `GetUsageByEndpointResponse` with `data.endpoints: EndpointUsage[]`.
404
+
405
+ ```typescript
406
+ // Node.js
407
+ const resp = await qn.admin.getUsageByEndpoint();
408
+ ```
409
+
410
+ ##### `get_usage_by_method` / `getUsageByMethod`
411
+
412
+ Per-RPC-method usage breakdown.
413
+
414
+ **Returns**: `GetUsageByMethodResponse` with `data.methods: MethodUsage[]`.
415
+
416
+ ```typescript
417
+ // Node.js
418
+ const resp = await qn.admin.getUsageByMethod();
419
+ ```
420
+
421
+ ##### `get_usage_by_chain` / `getUsageByChain`
422
+
423
+ Per-chain usage breakdown.
424
+
425
+ **Returns**: `GetUsageByChainResponse` with `data.chains: ChainUsage[]`.
426
+
427
+ ```typescript
428
+ // Node.js
429
+ const resp = await qn.admin.getUsageByChain();
430
+ ```
431
+
432
+ ##### `get_usage_by_tag` / `getUsageByTag`
433
+
434
+ Per-tag usage breakdown.
435
+
436
+ **Returns**: `GetUsageByTagResponse` with `data.tags: TagUsage[]`.
437
+
438
+ ```typescript
439
+ // Node.js
440
+ const resp = await qn.admin.getUsageByTag();
441
+ ```
442
+
443
+ #### Logs
444
+
445
+ ##### `get_endpoint_logs` / `getEndpointLogs`
446
+
447
+ Fetches a page of request logs for an endpoint. Set `include_details=true` for full request/response payloads (truncated at 2 KB each).
448
+
449
+ **Parameters**: `id` (endpoint id, required); body: `from` (string timestamp, required), `to` (string timestamp, required), `include_details` (bool, optional), `limit` (i32, optional), `next_at` (string cursor, optional).
450
+
451
+ **Returns**: `GetEndpointLogsResponse` — `{ data: EndpointLog[], next_at?: string }`.
452
+
453
+ ```typescript
454
+ // Node.js
455
+ const resp = await qn.admin.getEndpointLogs("ep-123", {
456
+ from: "2026-04-01T00:00:00Z",
457
+ to: "2026-04-02T00:00:00Z",
458
+ limit: 100,
459
+ });
460
+ ```
461
+
462
+ ##### `get_log_details` / `getLogDetails`
463
+
464
+ Returns the full request/response payloads for a single log entry.
465
+
466
+ **Parameters**: `id` (endpoint id, required), `request_id` (log request uuid, required).
467
+
468
+ **Returns**: `GetLogDetailsResponse` with `data: LogDetails`.
469
+
470
+ ```typescript
471
+ // Node.js
472
+ const resp = await qn.admin.getLogDetails("ep-123", "req-abc");
473
+ ```
474
+
475
+ #### Endpoint Security
476
+
477
+ ##### `get_endpoint_security` / `getEndpointSecurity`
478
+
479
+ Returns the full security configuration for an endpoint: tokens, JWTs, referrers, domain masks, IPs, request filters, and their per-feature toggles.
480
+
481
+ **Parameters**: `id` (string, required).
482
+
483
+ **Returns**: `GetEndpointSecurityResponse` with `data: EndpointSecurity`.
484
+
485
+ ```typescript
486
+ // Node.js
487
+ const resp = await qn.admin.getEndpointSecurity("ep-123");
488
+ ```
489
+
490
+ #### Security Options
491
+
492
+ ##### `get_security_options` / `getSecurityOptions`
493
+
494
+ Returns the list of security features and their enabled state for an endpoint.
495
+
496
+ **Parameters**: `id` (string, required).
497
+
498
+ **Returns**: `GetSecurityOptionsResponse` with `data: SecurityOption[]`.
499
+
500
+ ```typescript
501
+ // Node.js
502
+ const resp = await qn.admin.getSecurityOptions("ep-123");
503
+ ```
504
+
505
+ ##### `update_security_options` / `updateSecurityOptions`
506
+
507
+ Enables or disables individual security features. Each field accepts `"enabled"` or `"disabled"`.
508
+
509
+ **Parameters**: `id` (string, required); `options`: `SecurityOptionsUpdate` (`tokens`, `referrers`, `jwts`, `ips`, `domain_masks`, `hsts`, `cors`, `request_filters`, `ip_custom_header`).
510
+
511
+ **Returns**: `UpdateSecurityOptionsResponse` with updated `SecurityOption[]`.
512
+
513
+ ```typescript
514
+ // Node.js
515
+ await qn.admin.updateSecurityOptions("ep-123", {
516
+ options: { tokens: "enabled", jwts: "disabled" },
517
+ });
518
+ ```
519
+
520
+ #### Tokens
521
+
522
+ ##### `create_token` / `createToken`
523
+
524
+ Generates a new auth token on an endpoint.
525
+
526
+ **Parameters**: `id` (endpoint id, required).
527
+
528
+ **Returns**: nothing.
529
+
530
+ ```typescript
531
+ // Node.js
532
+ await qn.admin.createToken("ep-123");
533
+ ```
534
+
535
+ ##### `delete_token` / `deleteToken`
536
+
537
+ Revokes a token on an endpoint.
538
+
539
+ **Parameters**: `id` (endpoint id, required), `token_id` (string, required).
540
+
541
+ **Returns**: nothing.
542
+
543
+ ```typescript
544
+ // Node.js
545
+ await qn.admin.deleteToken("ep-123", "tok-1");
546
+ ```
547
+
548
+ #### Referrers
549
+
550
+ ##### `create_referrer` / `createReferrer`
551
+
552
+ Whitelists a referrer URL or domain on an endpoint.
553
+
554
+ **Parameters**: `id` (endpoint id, required); body: `referrer` (string, optional).
555
+
556
+ **Returns**: nothing.
557
+
558
+ ```typescript
559
+ // Node.js
560
+ await qn.admin.createReferrer("ep-123", { referrer: "example.com" });
561
+ ```
562
+
563
+ ##### `delete_referrer` / `deleteReferrer`
564
+
565
+ Removes a referrer from the whitelist.
566
+
567
+ **Parameters**: `id` (endpoint id, required), `referrer_id` (string, required).
568
+
569
+ **Returns**: nothing.
570
+
571
+ ```typescript
572
+ // Node.js
573
+ await qn.admin.deleteReferrer("ep-123", "ref-1");
574
+ ```
575
+
576
+ #### IPs
577
+
578
+ ##### `create_ip` / `createIp`
579
+
580
+ Whitelists an IP address on an endpoint.
581
+
582
+ **Parameters**: `id` (endpoint id, required); body: `ip` (string, optional).
583
+
584
+ **Returns**: nothing.
585
+
586
+ ```typescript
587
+ // Node.js
588
+ await qn.admin.createIp("ep-123", { ip: "198.51.100.7" });
589
+ ```
590
+
591
+ ##### `delete_ip` / `deleteIp`
592
+
593
+ Removes an IP from the whitelist.
594
+
595
+ **Parameters**: `id` (endpoint id, required), `ip_id` (string, required).
596
+
597
+ **Returns**: `DeleteBoolResponse`.
598
+
599
+ ```typescript
600
+ // Node.js
601
+ await qn.admin.deleteIp("ep-123", "ip-1");
602
+ ```
603
+
604
+ #### Domain Masks
605
+
606
+ ##### `create_domain_mask` / `createDomainMask`
607
+
608
+ Adds a custom domain mask to an endpoint.
609
+
610
+ **Parameters**: `id` (endpoint id, required); body: `domain_mask` (string, optional).
611
+
612
+ **Returns**: nothing.
613
+
614
+ ```typescript
615
+ // Node.js
616
+ await qn.admin.createDomainMask("ep-123", { domainMask: "rpc.example.com" });
617
+ ```
618
+
619
+ ##### `delete_domain_mask` / `deleteDomainMask`
620
+
621
+ Removes a domain mask.
622
+
623
+ **Parameters**: `id` (endpoint id, required), `domain_mask_id` (string, required).
624
+
625
+ **Returns**: nothing.
626
+
627
+ ```typescript
628
+ // Node.js
629
+ await qn.admin.deleteDomainMask("ep-123", "dm-1");
630
+ ```
631
+
632
+ #### JWTs
633
+
634
+ ##### `create_jwt` / `createJwt`
635
+
636
+ Configures JWT validation on an endpoint.
637
+
638
+ **Parameters**: `id` (endpoint id, required); body: `public_key` (string, optional), `kid` (string, optional), `name` (string, optional).
639
+
640
+ **Returns**: nothing.
641
+
642
+ ```typescript
643
+ // Node.js
644
+ await qn.admin.createJwt("ep-123", {
645
+ publicKey: "-----BEGIN PUBLIC KEY-----\n...",
646
+ kid: "key-1",
647
+ name: "primary",
648
+ });
649
+ ```
650
+
651
+ ##### `delete_jwt` / `deleteJwt`
652
+
653
+ Removes a JWT configuration.
654
+
655
+ **Parameters**: `id` (endpoint id, required), `jwt_id` (string, required).
656
+
657
+ **Returns**: nothing.
658
+
659
+ ```typescript
660
+ // Node.js
661
+ await qn.admin.deleteJwt("ep-123", "jwt-1");
662
+ ```
663
+
664
+ #### Request Filters
665
+
666
+ Whitelist specific RPC methods on an endpoint. Requests for methods not on the list are blocked when the feature is enabled.
667
+
668
+ ##### `create_request_filter` / `createRequestFilter`
669
+
670
+ **Parameters**: `id` (endpoint id, required); body: `method` (string[], optional). Ruby's Hash key is `methods` (plural).
671
+
672
+ **Returns**: `CreateRequestFilterResponse` with `data.id`.
673
+
674
+ ```typescript
675
+ // Node.js
676
+ const resp = await qn.admin.createRequestFilter("ep-123", {
677
+ method: ["eth_blockNumber", "eth_getBalance"],
678
+ });
679
+ ```
680
+
681
+ ##### `update_request_filter` / `updateRequestFilter`
682
+
683
+ **Parameters**: `id` (endpoint id, required), `request_filter_id` (string, required); body: `method` (string[], optional). Ruby's Hash keys are `request_filter_id` and `methods` (plural).
684
+
685
+ **Returns**: nothing.
686
+
687
+ ```typescript
688
+ // Node.js
689
+ await qn.admin.updateRequestFilter("ep-123", "f-1", { method: ["eth_call"] });
690
+ ```
691
+
692
+ ##### `delete_request_filter` / `deleteRequestFilter`
693
+
694
+ **Parameters**: `id` (endpoint id, required), `request_filter_id` (string, required).
695
+
696
+ **Returns**: nothing.
697
+
698
+ ```typescript
699
+ // Node.js
700
+ await qn.admin.deleteRequestFilter("ep-123", "f-1");
701
+ ```
702
+
703
+ #### Multichain
704
+
705
+ ##### `enable_multichain` / `enableMultichain`
706
+
707
+ Enables multichain on an endpoint.
708
+
709
+ **Parameters**: `id` (endpoint id, required).
710
+
711
+ **Returns**: nothing.
712
+
713
+ ```typescript
714
+ // Node.js
715
+ await qn.admin.enableMultichain("ep-123");
716
+ ```
717
+
718
+ ##### `disable_multichain` / `disableMultichain`
719
+
720
+ Disables multichain on an endpoint.
721
+
722
+ **Parameters**: `id` (endpoint id, required).
723
+
724
+ **Returns**: nothing.
725
+
726
+ ```typescript
727
+ // Node.js
728
+ await qn.admin.disableMultichain("ep-123");
729
+ ```
730
+
731
+ #### IP Custom Headers
732
+
733
+ ##### `create_or_update_ip_custom_header` / `createOrUpdateIpCustomHeader`
734
+
735
+ Sets the custom header used to identify the client IP (e.g. when traffic is proxied).
736
+
737
+ **Parameters**: `id` (endpoint id, required); body: `header_name` (string, required).
738
+
739
+ **Returns**: `CreateOrUpdateIpCustomHeaderResponse` with `data.header_name`.
740
+
741
+ ```typescript
742
+ // Node.js
743
+ await qn.admin.createOrUpdateIpCustomHeader("ep-123", { headerName: "X-Forwarded-For" });
744
+ ```
745
+
746
+ ##### `delete_ip_custom_header` / `deleteIpCustomHeader`
747
+
748
+ Removes the custom IP header configuration.
749
+
750
+ **Parameters**: `id` (endpoint id, required).
751
+
752
+ **Returns**: `DeleteBoolResponse`.
753
+
754
+ ```typescript
755
+ // Node.js
756
+ await qn.admin.deleteIpCustomHeader("ep-123");
757
+ ```
758
+
759
+ #### Method Rate Limits
760
+
761
+ ##### `get_method_rate_limits` / `getMethodRateLimits`
762
+
763
+ Lists method-level rate limiters configured on an endpoint.
764
+
765
+ **Parameters**: `id` (endpoint id, required).
766
+
767
+ **Returns**: `GetMethodRateLimitsResponse` with `data.rate_limiters: MethodRateLimiter[]`.
768
+
769
+ ```typescript
770
+ // Node.js
771
+ const resp = await qn.admin.getMethodRateLimits("ep-123");
772
+ ```
773
+
774
+ ##### `create_method_rate_limit` / `createMethodRateLimit`
775
+
776
+ Creates a new method-level rate limiter.
777
+
778
+ **Parameters**: `id` (endpoint id, required); body: `interval` (string, e.g. `"second"`), `methods` (string[]), `rate` (i32).
779
+
780
+ **Returns**: `CreateMethodRateLimitResponse` with `data: MethodRateLimiter`.
781
+
782
+ ```typescript
783
+ // Node.js
784
+ const resp = await qn.admin.createMethodRateLimit("ep-123", {
785
+ interval: "second",
786
+ methods: ["eth_call"],
787
+ rate: 10,
788
+ });
789
+ ```
790
+
791
+ ##### `update_method_rate_limit` / `updateMethodRateLimit`
792
+
793
+ Updates an existing rate limiter. Only provided fields change.
794
+
795
+ **Parameters**: `id` (endpoint id, required), `method_rate_limit_id` (string, required); body: `methods` (string[], optional), `status` (`"enabled"` | `"disabled"`, optional), `rate` (i32, optional).
796
+
797
+ **Returns**: `UpdateMethodRateLimitResponse`.
798
+
799
+ ```typescript
800
+ // Node.js
801
+ await qn.admin.updateMethodRateLimit("ep-123", "rl-1", { rate: 50 });
802
+ ```
803
+
804
+ ##### `delete_method_rate_limit` / `deleteMethodRateLimit`
805
+
806
+ Deletes a rate limiter.
807
+
808
+ **Parameters**: `id` (endpoint id, required), `method_rate_limit_id` (string, required).
809
+
810
+ **Returns**: nothing.
811
+
812
+ ```typescript
813
+ // Node.js
814
+ await qn.admin.deleteMethodRateLimit("ep-123", "rl-1");
815
+ ```
816
+
817
+ #### Endpoint Rate Limits
818
+
819
+ ##### `update_rate_limits` / `updateRateLimits`
820
+
821
+ Partial update of the endpoint-level RPS / RPM / RPD caps. Only buckets included in the request are modified — omitted buckets are left unchanged. Values are capped by the account's plan tier. Sends `PATCH`.
822
+
823
+ **Parameters**: `id` (endpoint id, required); `rate_limits`: `RateLimitSettings` (`rps`, `rpm`, `rpd`, all optional).
824
+
825
+ **Returns**: nothing.
826
+
827
+ ```typescript
828
+ // Node.js
829
+ await qn.admin.updateRateLimits("ep-123", { rateLimits: { rps: 100, rpm: 5000 } });
830
+ ```
831
+
832
+ ##### `get_rate_limits` / `getRateLimits`
833
+
834
+ Returns the rate-limit rows currently enforced on the endpoint, each identifying its `bucket` (`"rps"` / `"rpm"` / `"rpd"`), `rateLimit`, and `source` (`"plan_default"` or `"user_override"`). User-set overrides expose an `id` you can pass to `deleteRateLimitOverride`.
835
+
836
+ **Parameters**: `id` (endpoint id, required).
837
+
838
+ **Returns**: `GetRateLimitsResponse` with `data.rateLimits: RateLimitEntry[]`.
839
+
840
+ ```typescript
841
+ // Node.js
842
+ const resp = await qn.admin.getRateLimits("123");
843
+ for (const row of resp.data.rateLimits) {
844
+ console.log(row.bucket, row.rateLimit, row.source, row.id);
845
+ }
846
+ ```
847
+
848
+ ##### `delete_rate_limit_override` / `deleteRateLimitOverride`
849
+
850
+ Deletes a user-set rate-limit override by UUID. Plan defaults are not deletable — passing a UUID that does not match a user-set override on the endpoint returns 404.
851
+
852
+ **Parameters**: `id` (endpoint id, required); `override_id` / `overrideId` (UUID returned by `getRateLimits`, required).
853
+
854
+ **Returns**: nothing.
855
+
856
+ ```typescript
857
+ // Node.js
858
+ await qn.admin.deleteRateLimitOverride("123", "ovr-uuid");
859
+ ```
860
+
861
+ #### Endpoint URLs
862
+
863
+ ##### `get_endpoint_urls` / `getEndpointUrls`
864
+
865
+ Returns the HTTP and WebSocket URLs for the endpoint without fetching the full endpoint record. For multichain endpoints, `multichain_urls` / `multichainUrls` is a per-network map of additional URLs; for single-chain endpoints it is `null`.
866
+
867
+ **Parameters**: `id` (endpoint id, required).
868
+
869
+ **Returns**: `GetEndpointUrlsResponse` with `data.httpUrl`, `data.wssUrl`, and `data.multichainUrls`.
870
+
871
+ ```typescript
872
+ // Node.js
873
+ const resp = await qn.admin.getEndpointUrls("123");
874
+ console.log(resp.data.httpUrl);
875
+ if (resp.data.multichainUrls) {
876
+ for (const [network, urls] of Object.entries(resp.data.multichainUrls)) {
877
+ console.log(network, urls.httpUrl);
878
+ }
879
+ }
880
+ ```
881
+
882
+ #### Metrics
883
+
884
+ ##### `get_endpoint_metrics` / `getEndpointMetrics`
885
+
886
+ Returns metric series for an endpoint over a time period.
887
+
888
+ **Parameters**: `id` (endpoint id, required); body: `period` (`"hour"` | `"day"` | `"week"` | `"month"`), `metric` (e.g. `"method_calls_over_time"`, `"response_status_breakdown"`).
889
+
890
+ **Returns**: `GetEndpointMetricsResponse` with `data: EndpointMetric[]`. Each `EndpointMetric` has a `tag: string[]` and a `data: [timestamp, value][]`. Single-axis series (e.g. `response_time_over_time` with a percentile) come back as a one-element tag like `["p95"]`; multi-axis series come back as `["network", "arbitrum-mainnet"]`.
891
+
892
+ ```typescript
893
+ // Node.js
894
+ const resp = await qn.admin.getEndpointMetrics("ep-123", {
895
+ period: "day",
896
+ metric: "method_calls_over_time",
897
+ });
898
+ ```
899
+
900
+ ##### `get_account_metrics` / `getAccountMetrics`
901
+
902
+ Returns account-level metric series. Supports an optional `percentile` (e.g. `"p50"`, `"p95"`, `"p99"`) for latency metrics.
903
+
904
+ **Parameters**: `period` (required), `metric` (required), `percentile` (string, optional).
25
905
 
26
- API reference, configuration, and error handling for each language live next to the package those are also the docs that render on each package listing.
906
+ **Returns**: `GetAccountMetricsResponse` with `data: EndpointMetric[]`. See `getEndpointMetrics` above for the `tag: string[]` shape.
27
907
 
28
- - **Rust** — [`crates/core/README.md`](crates/core/README.md) (`quicknode-sdk` on crates.io)
29
- - **Python** — [`python/README.md`](python/README.md) (`quicknode-sdk` on PyPI)
30
- - **Node.js** [`npm/README.md`](npm/README.md) (`@quicknode/sdk` on npm)
31
- - **Ruby** — [`ruby/README.md`](ruby/README.md) (`quicknode_sdk` on RubyGems)
908
+ ```typescript
909
+ // Node.js
910
+ const resp = await qn.admin.getAccountMetrics({
911
+ period: "day",
912
+ metric: "credits_over_time",
913
+ });
914
+ ```
915
+
916
+ #### Chains
917
+
918
+ ##### `list_chains` / `listChains`
919
+
920
+ Lists the blockchains supported by Quicknode along with their networks.
32
921
 
33
- This file covers project structure, install index, and how to develop and release the SDK.
922
+ **Parameters**: none.
34
923
 
35
- ## Project Structure
924
+ **Returns**: `ListChainsResponse` with `data: Chain[]`.
36
925
 
926
+ ```typescript
927
+ // Node.js
928
+ const resp = await qn.admin.listChains();
37
929
  ```
38
- sdk/
39
- ├── crates/
40
- │ ├── core/ # Pure Rust business logic
41
- │ ├── python/ # PyO3 bindings
42
- │ ├── node/ # napi-rs bindings
43
- │ └── ruby/ # magnus bindings
44
- ├── python/sdk/ # Python package with type hints
45
- ├── npm/ # Node.js package with TypeScript types
46
- ├── ruby/ # Ruby package
47
- └── pyproject.toml # maturin build config
930
+
931
+ #### Billing
932
+
933
+ ##### `list_invoices` / `listInvoices`
934
+
935
+ Lists invoices on the account.
936
+
937
+ **Parameters**: none.
938
+
939
+ **Returns**: `ListInvoicesResponse` with `data.invoices: Invoice[]`.
940
+
941
+ ```typescript
942
+ // Node.js
943
+ const resp = await qn.admin.listInvoices();
48
944
  ```
49
945
 
50
- ## Installation
946
+ ##### `list_payments` / `listPayments`
51
947
 
52
- | Language | Install |
53
- |---|---|
54
- | Rust | `cargo add quicknode-sdk` — see [`crates/core/README.md`](crates/core/README.md) |
55
- | Python | `uv add quicknode-sdk` — see [`python/README.md`](python/README.md) |
56
- | Node.js | `npm install @quicknode/sdk` — see [`npm/README.md`](npm/README.md) |
57
- | Ruby | `gem install quicknode_sdk` — see [`ruby/README.md`](ruby/README.md) |
948
+ Lists payments on the account.
949
+
950
+ **Parameters**: none.
951
+
952
+ **Returns**: `ListPaymentsResponse` with `data.payments: Payment[]`.
953
+
954
+ ```typescript
955
+ // Node.js
956
+ const resp = await qn.admin.listPayments();
957
+ ```
58
958
 
59
- ## Development
959
+ #### Bulk Operations
60
960
 
61
- ### Prerequisites
961
+ ##### `bulk_update_endpoint_status` / `bulkUpdateEndpointStatus`
62
962
 
63
- - Rust (stable)
64
- - Python 3.8+ with [uv](https://docs.astral.sh/uv/)
65
- - Node.js 18+
66
- - Ruby 3.0+
67
- - [just](https://github.com/casey/just)
963
+ Activates or pauses many endpoints at once.
68
964
 
69
- ### Build Commands
965
+ **Parameters**: `ids` (string[], required), `status` (`"active"` | `"paused"`, required).
70
966
 
71
- Use the commands in the `Justfile` for the setup and build commands.
967
+ **Returns**: `BulkUpdateEndpointStatusResponse` with per-endpoint `results`.
72
968
 
73
- ```bash
74
- # Core library
75
- cargo check
76
- cargo test -p quicknode-sdk
969
+ ```typescript
970
+ // Node.js
971
+ const resp = await qn.admin.bulkUpdateEndpointStatus({
972
+ ids: ["ep-1", "ep-2"],
973
+ status: "paused",
974
+ });
975
+ ```
976
+
977
+ ##### `bulk_add_tag` / `bulkAddTag`
77
978
 
78
- # Python (from project root)
79
- just python-setup
80
- just python-build
979
+ Applies a tag (created if missing) to many endpoints at once.
81
980
 
82
- # Node.js (from npm/)
83
- just node-build
981
+ **Parameters**: `ids` (string[], required), `label` (string, required).
84
982
 
85
- # Ruby
86
- just ruby-build
983
+ **Returns**: `BulkAddTagResponse`.
87
984
 
88
- # Rust
89
- cargo build -p quicknode-sdk
985
+ ```typescript
986
+ // Node.js
987
+ const resp = await qn.admin.bulkAddTag({ ids: ["ep-1", "ep-2"], label: "prod" });
90
988
  ```
91
989
 
92
- ### Testing
990
+ ##### `bulk_remove_tag` / `bulkRemoveTag`
991
+
992
+ Removes a tag from many endpoints at once.
993
+
994
+ **Parameters**: `ids` (string[], required), `tag_id` (i32, required).
93
995
 
94
- ```bash
95
- just test
996
+ **Returns**: `BulkRemoveTagResponse`.
997
+
998
+ ```typescript
999
+ // Node.js
1000
+ const resp = await qn.admin.bulkRemoveTag({ ids: ["ep-1", "ep-2"], tagId: 42 });
96
1001
  ```
97
1002
 
98
- Runs the Rust unit tests for `quicknode-sdk` using [wiremock](https://github.com/LukeMathWalker/wiremock-rs) to mock HTTP responses — no API key required.
1003
+ #### Account Tags
99
1004
 
100
- ### Examples
1005
+ ##### `list_tags` / `listTags`
101
1006
 
102
- ```bash
103
- # Rust
104
- QN_SDK__API_KEY=replaceme cargo run --example admin -p quicknode-sdk --features rust
1007
+ Lists every tag on the account along with usage counts.
105
1008
 
106
- # Python
107
- QN_SDK__API_KEY=replaceme uv run python/examples/admin.py
108
- QN_SDK__API_KEY=replaceme uv run python/examples/streams.py
1009
+ **Parameters**: none.
109
1010
 
110
- # Node.js
111
- cd npm && QN_SDK__API_KEY=replaceme npx tsx examples/admin.ts
112
- cd npm && QN_SDK__API_KEY=replaceme npx tsx examples/streams.ts
1011
+ **Returns**: `ListTagsResponse` with `data.tags: AccountTag[]`.
113
1012
 
114
- # Ruby (build first, then run)
115
- just ruby-build
116
- QN_SDK__API_KEY=replaceme ruby ruby/examples/admin.rb
117
- QN_SDK__API_KEY=replaceme ruby ruby/examples/admin_e2e.rb
118
- QN_SDK__API_KEY=replaceme ruby ruby/examples/streams.rb
1013
+ ```typescript
1014
+ // Node.js
1015
+ const resp = await qn.admin.listTags();
119
1016
  ```
120
1017
 
121
- ### Releasing
1018
+ ##### `rename_tag` / `renameTag`
1019
+
1020
+ Renames an account-level tag.
122
1021
 
123
- All four packages (Rust crate, Python wheels, Node `.node` module, Ruby gem) ship together from a single project version. The release flow is split into two `just` commands:
1022
+ **Parameters**: `tag_id` (i32, required); body: `label` (string, required).
124
1023
 
125
- - **`just release-prepare <version>`** — bump versions, push, tag, build all Linux + macOS artifacts, attach them to a GitHub release. **No registry publish yet.**
126
- - **`just release-publish <version>`** — push to crates.io and trigger the PyPI / npm / RubyGems publish workflows.
1024
+ **Returns**: `RenameTagResponse` with updated `AccountTag`.
127
1025
 
128
- The pause between the two commands is the natural review point: inspect the GitHub release page and confirm all artifacts are present before anything goes public.
1026
+ ```typescript
1027
+ // Node.js
1028
+ const resp = await qn.admin.renameTag(42, { label: "staging" });
1029
+ ```
129
1030
 
130
- Requires the [`gh` CLI](https://cli.github.com/) authenticated to the repo, an Apple Silicon Mac (macOS arm64 artifacts are built locally to avoid the ~10× CI runner cost), and `cargo login` with a crates.io token.
1031
+ ##### `delete_account_tag` / `deleteAccountTag`
131
1032
 
132
- #### Two-phase flow
1033
+ Deletes a tag from the account. The tag must first be removed from any endpoints using it.
133
1034
 
134
- ```bash
135
- # Phase 1: build a fully-staged GitHub release
136
- just release-prepare 0.2.0
1035
+ **Parameters**: `id` (i32, required).
137
1036
 
138
- # Inspect https://github.com/<org>/<repo>/releases/tag/v0.2.0
139
- # Confirm: Linux Python wheels, Linux .node files, Linux Ruby gem,
140
- # macOS arm64 wheels, index.darwin-arm64.node, arm64-darwin .gem.
1037
+ **Returns**: `DeleteAccountTagResponse`.
141
1038
 
142
- # Phase 2: publish to crates.io + trigger registry publish workflows
143
- just release-publish 0.2.0
1039
+ ```typescript
1040
+ // Node.js
1041
+ await qn.admin.deleteAccountTag(42);
144
1042
  ```
145
1043
 
146
- `release-prepare` prompts twice — once up front before bumping, and once after the bump (showing the diff) before pushing the tag. `release-publish` prompts once before any registry write. Pass `yes=1` to skip prompts (e.g. for automation): `just release-prepare 0.2.0 yes=1`.
1044
+ ---
147
1045
 
148
- #### Building blocks
1046
+ ### Streams Client
149
1047
 
150
- If a phase fails partway, resume with the individual recipes they are also useful for reruns:
1048
+ Accessed as `qn.streams`. Creates and manages blockchain data streams that deliver filtered on-chain events to configured destinations. Backed by `https://api.quicknode.com/streams/rest/v1/`.
151
1049
 
152
- | Recipe | Purpose |
153
- |---|---|
154
- | `release-bump <version>` | Bump versions in all manifests, commit + tag locally |
155
- | `release-push <version>` | `git push` + push tag |
156
- | `release-create-tag <version>` | `gh release create` (triggers Linux CI build) |
157
- | `release-wait-ci <version>` | Block until `release.yml` finishes attaching Linux artifacts |
158
- | `macos-build-and-publish <version>` | Build macOS arm64 wheels / `.node` / `.gem` and `gh release upload` |
159
- | `release-cargo-publish-check` | `cargo publish -p quicknode-sdk --dry-run` |
160
- | `release-cargo-publish` | `cargo publish -p quicknode-sdk` |
161
- | `release-trigger-pypi <version>` | Dispatch `publish-pypi.yml` |
162
- | `release-trigger-npm <version> [npm_tag]` | Dispatch `publish-npm.yml` (default tag: `next`) |
163
- | `release-trigger-rubygems <version>` | Dispatch `publish-rubygems.yml` |
164
- | `release-trigger-all <version> [npm_tag]` | All three trigger recipes in sequence |
165
-
166
- #### Version conventions
167
-
168
- A single version argument drives every manifest, with two automatic translations applied by `release-bump`:
169
-
170
- | Manifest | Format example for `0.1.0-alpha.6` |
1050
+ #### Datasets, Regions, and Destinations
1051
+
1052
+ Enums used across stream methods:
1053
+
1054
+ - **`StreamRegion`**: `UsaEast`, `EuropeCentral`, `AsiaEast` (wire values: `usa_east`, `europe_central`, `asia_east`).
1055
+ - **`StreamDataset`**: `Block`, `BlockWithReceipts`, `Transactions`, `Logs`, `Receipts`, `TraceBlocks`, `DebugTraces`, `BlockWithReceiptsDebugTrace`, `BlockWithReceiptsTraceBlock`, `BlobSidecars`, `ProgramsWithLogs`, `Ledger`, `Events`, `Orders`, `Trades`, `BookUpdates`, `Twap`, `WriterActions`.
1056
+ - **`StreamStatus`**: `Active`, `Paused`, `Terminated`, `Completed`, `Blocked`.
1057
+ - **`FilterLanguage`**: `Javascript`, `Go`, `Wasm`.
1058
+ - **`StreamMetadataLocation`**: `Body`, `Header`, `None`.
1059
+
1060
+ Destinations are expressed via `DestinationAttributes`. Each variant wraps an attribute struct:
1061
+
1062
+ | Variant | Struct | Key fields |
1063
+ |---|---|---|
1064
+ | `Webhook` | `WebhookAttributes` | `url`, `max_retry`, `retry_interval_sec`, `post_timeout_sec`, `compression`, `security_token?` |
1065
+ | `S3` | `S3Attributes` | `endpoint`, `access_key`, `secret_key`, `bucket`, `object_prefix`, `compression`, `file_type`, `max_retry`, `retry_interval_sec`, `use_ssl?` |
1066
+ | `Azure` | `AzureAttributes` | `storage_account`, `sas_token`, `container`, `compression`, `file_type`, `max_retry`, `retry_interval_sec`, `blob_prefix?` |
1067
+ | `Postgres` | `PostgresAttributes` | `host`, `port`, `username`, `password`, `database`, `table_name`, `sslmode`, `max_retry`, `retry_interval_sec` |
1068
+ | `Kafka` | `KafkaAttributes` | `bootstrap_servers`, `topic_name`, `compression_type`, `batch_size`, `linger_ms`, `max_message_bytes`, `timeout_sec`, `max_retry`, `retry_interval_sec`, `username?`, `password?`, `protocol?`, `mechanisms?` |
1069
+
1070
+ Wrapper naming per language:
1071
+
1072
+ - **Rust**: `DestinationAttributes::Webhook(WebhookAttributes { .. })` etc.
1073
+ - **Python**: `StreamWebhookDestination(WebhookAttributes(...))`, `StreamS3Destination(S3Attributes(...))`, etc.
1074
+ - **Node.js**: a discriminated object `{ destination: "webhook", attributes: { ... } }` using string discriminators.
1075
+ - **Ruby**: factory methods on `QuicknodeSdk::DestinationAttributes`, e.g. `QuicknodeSdk::DestinationAttributes.webhook(url: ..., ...)`.
1076
+
1077
+ #### Streams methods
1078
+
1079
+ ##### `create_stream` / `createStream`
1080
+
1081
+ Creates a new stream that delivers filtered data to the configured destination. Start from a specific block for backfills or from the tip for real-time streaming. Supports filters, reorg handling, distance-from-tip, elastic batching, notification emails, and extra destinations.
1082
+
1083
+ **Parameters**: `CreateStreamParams` — required: `name`, `region`, `network`, `dataset`, `start_range` (i64), `end_range` (i64, `-1` = follow tip), `destination_attributes`, `plan`, `threshold_fetch_buffer`. Common optional fields: `dataset_batch_size`, `include_stream_metadata`, `fix_block_reorgs`, `keep_distance_from_tip`, `elastic_batch_enabled`, `filter_function`, `filter_language`, `status`, `notification_email`, `extra_destinations`.
1084
+
1085
+ **Returns**: `Stream`.
1086
+
1087
+ ```typescript
1088
+ // Node.js
1089
+ import { StreamDataset, StreamRegion, StreamStatus } from "quicknode-sdk";
1090
+
1091
+ const stream = await qn.streams.createStream({
1092
+ name: "My Stream",
1093
+ network: "ethereum-mainnet",
1094
+ dataset: StreamDataset.Block,
1095
+ region: StreamRegion.UsaEast,
1096
+ startRange: 24691804,
1097
+ endRange: 24691904,
1098
+ destinationAttributes: {
1099
+ destination: "webhook",
1100
+ attributes: {
1101
+ url: "https://webhook.site/...",
1102
+ maxRetry: 3,
1103
+ retryIntervalSec: 1,
1104
+ postTimeoutSec: 10,
1105
+ compression: "none",
1106
+ },
1107
+ },
1108
+ plan: "growth_plan",
1109
+ thresholdFetchBuffer: 1000,
1110
+ status: StreamStatus.Active,
1111
+ });
1112
+ ```
1113
+
1114
+ ##### `list_streams` / `listStreams`
1115
+
1116
+ Paginated list of streams on the account.
1117
+
1118
+ **Parameters** (all optional): `offset` (i64), `limit` (i64), `order_by` (string), `order_direction` (`"asc"` | `"desc"`), `stream_type` (string).
1119
+
1120
+ **Returns**: `ListStreamsResponse` with `data: Stream[]` and `page_info`.
1121
+
1122
+ ```typescript
1123
+ // Node.js
1124
+ const resp = await qn.streams.listStreams();
1125
+ ```
1126
+
1127
+ ##### `get_stream` / `getStream`
1128
+
1129
+ Fetches one stream by id.
1130
+
1131
+ **Parameters**: `id` (string, required).
1132
+
1133
+ **Returns**: `Stream`.
1134
+
1135
+ ```typescript
1136
+ // Node.js
1137
+ const stream = await qn.streams.getStream("stream-id");
1138
+ ```
1139
+
1140
+ ##### `update_stream` / `updateStream`
1141
+
1142
+ Partially updates a stream. Omitted fields are left unchanged.
1143
+
1144
+ **Parameters**: `id` (string, required); body: any field from `CreateStreamParams` (all optional).
1145
+
1146
+ **Returns**: updated `Stream`.
1147
+
1148
+ ```typescript
1149
+ // Node.js
1150
+ const stream = await qn.streams.updateStream("stream-id", { name: "Renamed" });
1151
+ ```
1152
+
1153
+ ##### `delete_stream` / `deleteStream`
1154
+
1155
+ Deletes one stream by id.
1156
+
1157
+ **Parameters**: `id` (string, required).
1158
+
1159
+ **Returns**: nothing.
1160
+
1161
+ ```typescript
1162
+ // Node.js
1163
+ await qn.streams.deleteStream("stream-id");
1164
+ ```
1165
+
1166
+ ##### `delete_all_streams` / `deleteAllStreams`
1167
+
1168
+ Deletes every stream on the account. Destructive and takes no arguments.
1169
+
1170
+ **Parameters**: none.
1171
+
1172
+ **Returns**: nothing.
1173
+
1174
+ ```typescript
1175
+ // Node.js
1176
+ await qn.streams.deleteAllStreams();
1177
+ ```
1178
+
1179
+ ##### `activate_stream` / `activateStream`
1180
+
1181
+ Resumes delivery on a stream from its current position.
1182
+
1183
+ **Parameters**: `id` (string, required).
1184
+
1185
+ **Returns**: nothing.
1186
+
1187
+ ```typescript
1188
+ // Node.js
1189
+ await qn.streams.activateStream("stream-id");
1190
+ ```
1191
+
1192
+ ##### `pause_stream` / `pauseStream`
1193
+
1194
+ Halts delivery on a stream.
1195
+
1196
+ **Parameters**: `id` (string, required).
1197
+
1198
+ **Returns**: nothing.
1199
+
1200
+ ```typescript
1201
+ // Node.js
1202
+ await qn.streams.pauseStream("stream-id");
1203
+ ```
1204
+
1205
+ ##### `test_filter` / `testFilter`
1206
+
1207
+ Runs a filter function against a block so it can be validated before being attached to a live stream.
1208
+
1209
+ **Parameters**: `network` (string, required), `dataset` (`StreamDataset`, required), `block` (string, required), `filter_function` (string, optional), `filter_language` (`FilterLanguage`, optional), `address_book_config` (optional).
1210
+
1211
+ **Returns**: `TestFilterResponse` with `result` and `logs`.
1212
+
1213
+ ```typescript
1214
+ // Node.js
1215
+ import { StreamDataset } from "quicknode-sdk";
1216
+
1217
+ const resp = await qn.streams.testFilter({
1218
+ network: "ethereum-mainnet",
1219
+ dataset: StreamDataset.Block,
1220
+ block: "17811625",
1221
+ });
1222
+ ```
1223
+
1224
+ ##### `get_enabled_count` / `getEnabledCount`
1225
+
1226
+ Counts currently enabled (active) streams, optionally filtered by type.
1227
+
1228
+ **Parameters**: `stream_type` (string, optional).
1229
+
1230
+ **Returns**: `EnabledCountResponse` with `total`.
1231
+
1232
+ ```typescript
1233
+ // Node.js
1234
+ const resp = await qn.streams.getEnabledCount();
1235
+ ```
1236
+
1237
+ ---
1238
+
1239
+ ### Webhooks Client
1240
+
1241
+ Accessed as `qn.webhooks`. Creates webhooks from filter templates and manages their lifecycle. Backed by `https://api.quicknode.com/webhooks/rest/v1/`.
1242
+
1243
+ #### Templates and destination
1244
+
1245
+ `WebhookTemplateId` identifies the filter template:
1246
+
1247
+ | Variant | Wire value |
171
1248
  |---|---|
172
- | `Cargo.toml` (workspace) | `0.1.0-alpha.6` |
173
- | `crates/core/Cargo.toml` | `0.1.0-alpha.6` |
174
- | `pyproject.toml` (PEP 440) | `0.1.0a6` |
175
- | `ruby/quicknode_sdk.gemspec` | `0.1.0-alpha.6` |
176
- | `npm/package.json` | `3.0.0-alpha.6` (`0.x` → `3.x` because `@quicknode/sdk` 2.x already exists on npm) |
177
-
178
- Pre-release identifiers use SemVer 2.0 syntax: `MAJOR.MINOR.PATCH-<id>.<N>` — e.g. `0.1.0-alpha.4`, `0.2.0-beta.1`, `0.2.0-rc.1`. The npm pre-release period uses the `next` dist-tag so `npm install @quicknode/sdk` continues to resolve to legacy 2.x while `npm install @quicknode/sdk@next` pulls the rewrite.
179
-
180
- `release-bump` only accepts versions starting with `0.`. The `0.x → 3.x` mapping (and the recipe's guard) needs to be revisited when the project graduates to `1.0`.
181
-
182
- #### First-time setup
183
-
184
- - The first crates.io publish claims the `quicknode-sdk` name permanently. Published versions are immutable (only `cargo yank` is reversible, and it only hides).
185
- - The first PyPI upload needs a user-scoped `PYPI_API_TOKEN`; rotate to a project-scoped token after.
186
- - Verify a release reached each registry:
187
- ```bash
188
- cargo search quicknode-sdk
189
- pip install quicknode-sdk==0.1.0a6
190
- npm view @quicknode/sdk dist-tags
191
- gem search -e quicknode_sdk
192
- ```
1249
+ | `EvmWalletFilter` | `evmWalletFilter` |
1250
+ | `EvmContractEvents` | `evmContractEvents` |
1251
+ | `EvmAbiFilter` | `evmAbiFilter` |
1252
+ | `SolanaWalletFilter` | `solanaWalletFilter` |
1253
+ | `BitcoinWalletFilter` | `bitcoinWalletFilter` |
1254
+ | `XrplWalletFilter` | `xrplWalletFilter` |
1255
+ | `HyperliquidWalletEventsFilter` | `hyperliquidWalletEventsFilter` |
1256
+ | `StellarWalletTransactionsSourceAccountFilter` | `stellarWalletTransactionsSourceAccountFilter` |
1257
+
1258
+ `TemplateArgs` carries the arguments; construct one per template via the factory methods:
1259
+
1260
+ | Factory | Argument struct | Fields |
1261
+ |---|---|---|
1262
+ | `evm_wallet_filter` | `EvmWalletFilterTemplate` | `wallets: string[]` |
1263
+ | `evm_contract_events` | `EvmContractEventsTemplate` | `contracts: string[]`, `event_hashes?: string[]` |
1264
+ | `evm_abi_filter` | `EvmAbiFilterTemplate` | `abi: string` (JSON), `contracts: string[]` |
1265
+ | `solana_wallet_filter` | `SolanaWalletFilterTemplate` | `accounts: string[]` |
1266
+ | `bitcoin_wallet_filter` | `BitcoinWalletFilterTemplate` | `wallets: string[]` |
1267
+ | `xrpl_wallet_filter` | `XrplWalletFilterTemplate` | `wallets: string[]` |
1268
+ | `hyperliquid_wallet_events_filter` | `HyperliquidWalletEventsFilterTemplate` | `wallets: string[]` |
1269
+ | `stellar_wallet_transactions_filter` | `StellarWalletTransactionsFilterTemplate` | `source_accounts: string[]` |
1270
+
1271
+ `WebhookDestinationAttributes`: `url` (required), `security_token` (optional — auto-generated if omitted), `compression` (optional — `"none"` | `"gzip"`).
1272
+
1273
+ `WebhookStartFrom`: `Last` (resume from last delivered block) or `Latest` (start from newest).
1274
+
1275
+ In Ruby, `template_args` is passed as a JSON string under the key `template_args_json`; destination is passed as a JSON string under `destination_attributes_json`.
1276
+
1277
+ #### Webhooks methods
1278
+
1279
+ ##### `list_webhooks` / `listWebhooks`
1280
+
1281
+ Paginated list of webhooks.
1282
+
1283
+ **Parameters** (all optional): `limit` (i64), `offset` (i64).
1284
+
1285
+ **Returns**: `ListWebhooksResponse` with `data: Webhook[]` and `pageInfo: WebhookPageInfo { limit, offset, total }`.
1286
+
1287
+ ```typescript
1288
+ // Node.js
1289
+ const resp = await qn.webhooks.listWebhooks();
1290
+ ```
1291
+
1292
+ ##### `get_webhook` / `getWebhook`
1293
+
1294
+ Fetches a webhook by id.
1295
+
1296
+ **Parameters**: `id` (string, required).
1297
+
1298
+ **Returns**: `Webhook`.
1299
+
1300
+ ```typescript
1301
+ // Node.js
1302
+ const webhook = await qn.webhooks.getWebhook("wh-1");
1303
+ ```
1304
+
1305
+ ##### `create_webhook_from_template` / `createWebhookFromTemplate`
1306
+
1307
+ Creates a webhook from a predefined filter template.
1308
+
1309
+ **Parameters**: `name` (required), `network` (required), `destination_attributes` (`WebhookDestinationAttributes`, required), `template_args` (required — use the `TemplateArgs` enum variant for the chosen template), `notification_email` (optional).
1310
+
1311
+ **Returns**: `Webhook`.
1312
+
1313
+ ```typescript
1314
+ // Node.js
1315
+ import { TemplateArgs } from "quicknode-sdk";
1316
+
1317
+ const webhook = await qn.webhooks.createWebhookFromTemplate({
1318
+ name: "Wallet Webhook",
1319
+ network: "ethereum-mainnet",
1320
+ destinationAttributes: { url: "https://webhook.site/..." },
1321
+ templateArgs: TemplateArgs.evmWalletFilter({
1322
+ wallets: ["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"],
1323
+ }),
1324
+ });
1325
+ ```
1326
+
1327
+ ##### `update_webhook` / `updateWebhook`
1328
+
1329
+ Partially updates a webhook's name, notification email, and/or destination. If `destination_attributes` is supplied without `security_token`, a new token is generated automatically.
1330
+
1331
+ **Parameters**: `id` (required); body — all optional: `name`, `notification_email`, `destination_attributes`. In Ruby, `destination_attributes` is passed as a JSON string under the key `destination_attributes_json`.
1332
+
1333
+ **Returns**: updated `Webhook`.
1334
+
1335
+ ```typescript
1336
+ // Node.js
1337
+ const webhook = await qn.webhooks.updateWebhook("wh-1", { name: "Renamed Webhook" });
1338
+ ```
1339
+
1340
+ ##### `update_webhook_template` / `updateWebhookTemplate`
1341
+
1342
+ Updates the template args (and optionally name, email, destination) on an existing template-backed webhook.
1343
+
1344
+ **Parameters**: `webhook_id` (required), `template_args` (required); optional: `name`, `notification_email`, `destination_attributes`.
1345
+
1346
+ **Returns**: updated `Webhook`.
1347
+
1348
+ ```typescript
1349
+ // Node.js
1350
+ const webhook = await qn.webhooks.updateWebhookTemplate("wh-1", {
1351
+ templateArgs: TemplateArgs.evmWalletFilter({ wallets: ["0xnewwallet"] }),
1352
+ });
1353
+ ```
1354
+
1355
+ ##### `delete_webhook` / `deleteWebhook`
1356
+
1357
+ Deletes a webhook.
1358
+
1359
+ **Parameters**: `id` (required).
1360
+
1361
+ **Returns**: nothing.
1362
+
1363
+ ```typescript
1364
+ // Node.js
1365
+ await qn.webhooks.deleteWebhook("wh-1");
1366
+ ```
1367
+
1368
+ ##### `delete_all_webhooks` / `deleteAllWebhooks`
1369
+
1370
+ Deletes every webhook on the account. Destructive and takes no arguments.
1371
+
1372
+ **Parameters**: none.
1373
+
1374
+ **Returns**: nothing.
1375
+
1376
+ ```typescript
1377
+ // Node.js
1378
+ await qn.webhooks.deleteAllWebhooks();
1379
+ ```
1380
+
1381
+ ##### `pause_webhook` / `pauseWebhook`
1382
+
1383
+ Pauses a webhook so it stops delivering events.
1384
+
1385
+ **Parameters**: `id` (required).
1386
+
1387
+ **Returns**: nothing.
1388
+
1389
+ ```typescript
1390
+ // Node.js
1391
+ await qn.webhooks.pauseWebhook("wh-1");
1392
+ ```
1393
+
1394
+ ##### `activate_webhook` / `activateWebhook`
1395
+
1396
+ Activates a paused or new webhook so it resumes delivering events. `start_from` determines where processing resumes.
1397
+
1398
+ **Parameters**: `id` (required), `start_from` (`WebhookStartFrom`, required — `Last` or `Latest`).
1399
+
1400
+ **Returns**: nothing.
1401
+
1402
+ ```typescript
1403
+ // Node.js
1404
+ import { WebhookStartFrom } from "quicknode-sdk";
1405
+
1406
+ await qn.webhooks.activateWebhook("wh-1", { startFrom: WebhookStartFrom.Latest });
1407
+ ```
1408
+
1409
+ ##### `get_enabled_count` / `getEnabledCount`
1410
+
1411
+ Counts currently enabled webhooks.
1412
+
1413
+ **Parameters**: none.
1414
+
1415
+ **Returns**: `WebhookEnabledCountResponse` with `total`.
1416
+
1417
+ ```typescript
1418
+ // Node.js
1419
+ const resp = await qn.webhooks.getEnabledCount();
1420
+ ```
1421
+
1422
+ ---
1423
+
1424
+ ### KV Store Client
1425
+
1426
+ Accessed as `qn.kvstore`. Provides two primitives — **sets** (single string values under a key) and **lists** (ordered collections of strings under a key). Backed by `https://api.quicknode.com/kv/rest/v1/`.
1427
+
1428
+ #### Sets
1429
+
1430
+ ##### `create_set` / `createSet`
1431
+
1432
+ Stores a single string value under a key.
1433
+
1434
+ **Parameters**: `key` (string, required), `value` (string, required).
1435
+
1436
+ **Returns**: nothing.
1437
+
1438
+ ```typescript
1439
+ // Node.js
1440
+ await qn.kvstore.createSet({ key: "my-key", value: "hello" });
1441
+ ```
1442
+
1443
+ ##### `get_sets` / `getSets`
1444
+
1445
+ Paginated page of key/value entries.
1446
+
1447
+ **Parameters** (all optional): `limit` (i64), `cursor` (string).
1448
+
1449
+ **Returns**: `GetSetsResponse` — `{ data: KvSetEntry[], cursor: string }`.
1450
+
1451
+ ```typescript
1452
+ // Node.js
1453
+ const resp = await qn.kvstore.getSets();
1454
+ ```
1455
+
1456
+ ##### `get_set` / `getSet`
1457
+
1458
+ Returns the value stored under a key.
1459
+
1460
+ **Parameters**: `key` (string, required).
1461
+
1462
+ **Returns**: `GetSetResponse` with `value`.
1463
+
1464
+ ```typescript
1465
+ // Node.js
1466
+ const resp = await qn.kvstore.getSet("my-key");
1467
+ ```
1468
+
1469
+ ##### `bulk_sets` / `bulkSets`
1470
+
1471
+ Adds and/or deletes multiple sets in a single request.
1472
+
1473
+ **Parameters** (at least one required): `add_sets` (map<string,string>, optional), `delete_sets` (string[], optional).
1474
+
1475
+ **Returns**: nothing.
1476
+
1477
+ ```typescript
1478
+ // Node.js
1479
+ await qn.kvstore.bulkSets({
1480
+ addSets: { k1: "v1" },
1481
+ deleteSets: ["old-key"],
1482
+ });
1483
+ ```
1484
+
1485
+ ##### `delete_set` / `deleteSet`
1486
+
1487
+ Deletes a single set.
1488
+
1489
+ **Parameters**: `key` (string, required).
1490
+
1491
+ **Returns**: nothing.
1492
+
1493
+ ```typescript
1494
+ // Node.js
1495
+ await qn.kvstore.deleteSet("my-key");
1496
+ ```
1497
+
1498
+ #### Lists
1499
+
1500
+ ##### `create_list` / `createList`
1501
+
1502
+ Creates a list under a key, seeded with the initial items.
1503
+
1504
+ **Parameters**: `key` (string, required), `items` (string[], required).
1505
+
1506
+ **Returns**: nothing.
1507
+
1508
+ ```typescript
1509
+ // Node.js
1510
+ await qn.kvstore.createList({ key: "my-list", items: ["0xabc", "0xdef"] });
1511
+ ```
1512
+
1513
+ ##### `get_lists` / `getLists`
1514
+
1515
+ Paginated page of list keys.
1516
+
1517
+ **Parameters** (all optional): `limit` (i64), `cursor` (string).
1518
+
1519
+ **Returns**: `GetListsResponse` — `{ data: { keys: string[] }, cursor: string }`.
1520
+
1521
+ ```typescript
1522
+ // Node.js
1523
+ const resp = await qn.kvstore.getLists();
1524
+ ```
1525
+
1526
+ ##### `get_list` / `getList`
1527
+
1528
+ Paginated page of items for a specific list.
1529
+
1530
+ **Parameters**: `key` (string, required); optional `limit` (i64), `cursor` (string).
1531
+
1532
+ **Returns**: `GetListResponse` — `{ data: { items: string[] }, cursor: string }`.
1533
+
1534
+ ```typescript
1535
+ // Node.js
1536
+ const resp = await qn.kvstore.getList("my-list");
1537
+ ```
1538
+
1539
+ ##### `update_list` / `updateList`
1540
+
1541
+ Adds and/or removes items in a single operation.
1542
+
1543
+ **Parameters**: `key` (string, required); optional: `add_items` (string[]), `remove_items` (string[]).
1544
+
1545
+ **Returns**: nothing.
1546
+
1547
+ ```typescript
1548
+ // Node.js
1549
+ await qn.kvstore.updateList("my-list", {
1550
+ addItems: ["0x456"],
1551
+ removeItems: ["0xabc"],
1552
+ });
1553
+ ```
1554
+
1555
+ ##### `add_list_item` / `addListItem`
1556
+
1557
+ Appends a single item to a list.
1558
+
1559
+ **Parameters**: `key` (string, required), `item` (string, required).
1560
+
1561
+ **Returns**: nothing.
1562
+
1563
+ ```typescript
1564
+ // Node.js
1565
+ await qn.kvstore.addListItem("my-list", { item: "0x123" });
1566
+ ```
1567
+
1568
+ ##### `list_contains_item` / `listContainsItem`
1569
+
1570
+ Checks whether a list contains a specific item.
1571
+
1572
+ **Parameters**: `key` (string, required), `item` (string, required).
1573
+
1574
+ **Returns**: `ListContainsItemResponse` with `exists: bool`.
1575
+
1576
+ ```typescript
1577
+ // Node.js
1578
+ const resp = await qn.kvstore.listContainsItem("my-list", "0x123");
1579
+ ```
1580
+
1581
+ ##### `delete_list_item` / `deleteListItem`
1582
+
1583
+ Removes a single item from a list.
1584
+
1585
+ **Parameters**: `key` (string, required), `item` (string, required).
1586
+
1587
+ **Returns**: nothing.
1588
+
1589
+ ```typescript
1590
+ // Node.js
1591
+ await qn.kvstore.deleteListItem("my-list", "0x123");
1592
+ ```
1593
+
1594
+ ##### `delete_list` / `deleteList`
1595
+
1596
+ Deletes a list and all of its items.
1597
+
1598
+ **Parameters**: `key` (string, required).
1599
+
1600
+ **Returns**: nothing.
1601
+
1602
+ ```typescript
1603
+ // Node.js
1604
+ await qn.kvstore.deleteList("my-list");
1605
+ ```
1606
+
1607
+ ## Error Handling
1608
+
1609
+ Every binding exposes a typed exception hierarchy derived from the core `SdkError`
1610
+ enum (`crates/core/src/errors.rs`). Catch the base class (`QuicknodeError`) for any SDK-originated failure, or a specific
1611
+ subclass to branch on transport vs. API semantics.
1612
+
1613
+ | Logical class | When it fires | Extra fields |
1614
+ |----------------------|-------------------------------------------------------------|----------------------|
1615
+ | `QuicknodeError` | base class; catches everything below | — |
1616
+ | `ConfigError` | invalid config or URL surfaced at construction time | — |
1617
+ | `HttpError` | transport failure that isn't a timeout/connect | — |
1618
+ | `TimeoutError` | request timed out (subclass of `HttpError`) | — |
1619
+ | `ConnectionError` | connection refused / DNS / TLS (subclass of `HttpError`) | — |
1620
+ | `ApiError` | non-2xx HTTP response | `status`, `body` |
1621
+ | `DecodeError` | 2xx response but JSON parse failed | `body` |
1622
+
1623
+ Class names: Importable from `@quicknode/sdk`: `QuicknodeError`, `ConfigError`, `HttpError`, `TimeoutError`, `ConnectionError`, `ApiError`, `DecodeError`. All extend `Error`.
1624
+
1625
+ ```typescript
1626
+ // Node.js
1627
+ import { ApiError, TimeoutError } from "@quicknode/sdk";
1628
+ try {
1629
+ await qn.admin.showEndpoint("missing");
1630
+ } catch (e) {
1631
+ if (e instanceof ApiError && e.status === 404) console.error("not found:", e.body);
1632
+ else if (e instanceof TimeoutError) console.error("timed out");
1633
+ else throw e;
1634
+ }
1635
+ ```
193
1636
 
194
1637
  ## License
195
1638