quicknode_sdk 0.1.0-x86_64-linux → 0.1.1-x86_64-linux

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